source: branches/samba-3.3.x/source/rpc_server/srv_samr_util.c@ 614

Last change on this file since 614 was 224, checked in by Herwig Bauernfeind, 17 years ago

Update Samba 3.3 branch to 3.3.4

File size: 14.4 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 SAMR Pipe utility functions.
4
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2001
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
9 Copyright (C) Guenther Deschner 2008
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26
27#undef DBGC_CLASS
28#define DBGC_CLASS DBGC_RPC_SRV
29
30#define STRING_CHANGED (old_string && !new_string) ||\
31 (!old_string && new_string) ||\
32 (old_string && new_string && (strcmp(old_string, new_string) != 0))
33
34#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
35 (!(s1) && (s2)) ||\
36 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
37
38/*************************************************************
39 Copies a struct samr_UserInfo18 to a struct samu
40**************************************************************/
41
42void copy_id18_to_sam_passwd(struct samu *to,
43 struct samr_UserInfo18 *from)
44{
45 struct samr_UserInfo21 i;
46
47 if (from == NULL || to == NULL) {
48 return;
49 }
50
51 ZERO_STRUCT(i);
52
53 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
54 i.password_expired = from->password_expired;
55
56 copy_id21_to_sam_passwd("INFO_18", to, &i);
57}
58
59/*************************************************************
60 Copies a struct samr_UserInfo20 to a struct samu
61**************************************************************/
62
63void copy_id20_to_sam_passwd(struct samu *to,
64 struct samr_UserInfo20 *from)
65{
66 const char *old_string;
67 char *new_string;
68 DATA_BLOB mung;
69
70 if (from == NULL || to == NULL) {
71 return;
72 }
73
74 if (from->parameters.array) {
75 old_string = pdb_get_munged_dial(to);
76 mung = data_blob_const(from->parameters.array,
77 from->parameters.length);
78 new_string = (mung.length == 0) ?
79 NULL : base64_encode_data_blob(talloc_tos(), mung);
80 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
81 old_string, new_string));
82 if (STRING_CHANGED_NC(old_string,new_string)) {
83 pdb_set_munged_dial(to, new_string, PDB_CHANGED);
84 }
85
86 TALLOC_FREE(new_string);
87 }
88}
89
90/*************************************************************
91 Copies a struct samr_UserInfo21 to a struct samu
92**************************************************************/
93
94void copy_id21_to_sam_passwd(const char *log_prefix,
95 struct samu *to,
96 struct samr_UserInfo21 *from)
97{
98 time_t unix_time, stored_time;
99 const char *old_string, *new_string;
100 const char *l;
101
102 if (from == NULL || to == NULL) {
103 return;
104 }
105
106 if (log_prefix) {
107 l = log_prefix;
108 } else {
109 l = "INFO_21";
110 }
111
112 if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
113 unix_time = nt_time_to_unix(from->last_logon);
114 stored_time = pdb_get_logon_time(to);
115 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
116 (long unsigned int)stored_time,
117 (long unsigned int)unix_time));
118 if (stored_time != unix_time) {
119 pdb_set_logon_time(to, unix_time, PDB_CHANGED);
120 }
121 }
122
123 if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
124 unix_time = nt_time_to_unix(from->last_logoff);
125 stored_time = pdb_get_logoff_time(to);
126 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
127 (long unsigned int)stored_time,
128 (long unsigned int)unix_time));
129 if (stored_time != unix_time) {
130 pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
131 }
132 }
133
134 if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
135 unix_time = nt_time_to_unix(from->acct_expiry);
136 stored_time = pdb_get_kickoff_time(to);
137 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
138 (long unsigned int)stored_time,
139 (long unsigned int)unix_time));
140 if (stored_time != unix_time) {
141 pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
142 }
143 }
144
145 if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
146 unix_time = nt_time_to_unix(from->last_password_change);
147 stored_time = pdb_get_pass_last_set_time(to);
148 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
149 (long unsigned int)stored_time,
150 (long unsigned int)unix_time));
151 if (stored_time != unix_time) {
152 pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
153 }
154 }
155
156 if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
157 (from->account_name.string)) {
158 old_string = pdb_get_username(to);
159 new_string = from->account_name.string;
160 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
161 old_string, new_string));
162 if (STRING_CHANGED) {
163 pdb_set_username(to, new_string, PDB_CHANGED);
164 }
165 }
166
167 if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
168 (from->full_name.string)) {
169 old_string = pdb_get_fullname(to);
170 new_string = from->full_name.string;
171 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
172 old_string, new_string));
173 if (STRING_CHANGED) {
174 pdb_set_fullname(to, new_string, PDB_CHANGED);
175 }
176 }
177
178 if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
179 (from->home_directory.string)) {
180 old_string = pdb_get_homedir(to);
181 new_string = from->home_directory.string;
182 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
183 old_string, new_string));
184 if (STRING_CHANGED) {
185 pdb_set_homedir(to, new_string, PDB_CHANGED);
186 }
187 }
188
189 if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
190 (from->home_drive.string)) {
191 old_string = pdb_get_dir_drive(to);
192 new_string = from->home_drive.string;
193 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
194 old_string, new_string));
195 if (STRING_CHANGED) {
196 pdb_set_dir_drive(to, new_string, PDB_CHANGED);
197 }
198 }
199
200 if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
201 (from->logon_script.string)) {
202 old_string = pdb_get_logon_script(to);
203 new_string = from->logon_script.string;
204 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
205 old_string, new_string));
206 if (STRING_CHANGED) {
207 pdb_set_logon_script(to , new_string, PDB_CHANGED);
208 }
209 }
210
211 if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
212 (from->profile_path.string)) {
213 old_string = pdb_get_profile_path(to);
214 new_string = from->profile_path.string;
215 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
216 old_string, new_string));
217 if (STRING_CHANGED) {
218 pdb_set_profile_path(to , new_string, PDB_CHANGED);
219 }
220 }
221
222 if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
223 (from->description.string)) {
224 old_string = pdb_get_acct_desc(to);
225 new_string = from->description.string;
226 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
227 old_string, new_string));
228 if (STRING_CHANGED) {
229 pdb_set_acct_desc(to, new_string, PDB_CHANGED);
230 }
231 }
232
233 if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
234 (from->workstations.string)) {
235 old_string = pdb_get_workstations(to);
236 new_string = from->workstations.string;
237 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
238 old_string, new_string));
239 if (STRING_CHANGED) {
240 pdb_set_workstations(to , new_string, PDB_CHANGED);
241 }
242 }
243
244 if ((from->fields_present & SAMR_FIELD_COMMENT) &&
245 (from->comment.string)) {
246 old_string = pdb_get_comment(to);
247 new_string = from->comment.string;
248 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
249 old_string, new_string));
250 if (STRING_CHANGED) {
251 pdb_set_comment(to, new_string, PDB_CHANGED);
252 }
253 }
254
255 if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
256 (from->parameters.array)) {
257 char *newstr;
258 DATA_BLOB mung;
259 old_string = pdb_get_munged_dial(to);
260
261 mung = data_blob_const(from->parameters.array,
262 from->parameters.length);
263 newstr = (mung.length == 0) ?
264 NULL : base64_encode_data_blob(talloc_tos(), mung);
265 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
266 old_string, newstr));
267 if (STRING_CHANGED_NC(old_string,newstr)) {
268 pdb_set_munged_dial(to, newstr, PDB_CHANGED);
269 }
270
271 TALLOC_FREE(newstr);
272 }
273
274 if (from->fields_present & SAMR_FIELD_RID) {
275 if (from->rid == 0) {
276 DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
277 } else if (from->rid != pdb_get_user_rid(to)) {
278 DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
279 pdb_get_user_rid(to), from->rid));
280 }
281 }
282
283 if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
284 if (from->primary_gid == 0) {
285 DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
286 } else if (from->primary_gid != pdb_get_group_rid(to)) {
287 DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
288 pdb_get_group_rid(to), from->primary_gid));
289 pdb_set_group_sid_from_rid(to,
290 from->primary_gid, PDB_CHANGED);
291 }
292 }
293
294 if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
295 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
296 pdb_get_acct_ctrl(to), from->acct_flags));
297 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
298 if (!(from->acct_flags & ACB_AUTOLOCK) &&
299 (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
300 /* We're unlocking a previously locked user. Reset bad password counts.
301 Patch from Jianliang Lu. <[email protected]> */
302 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
303 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
304 }
305 pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
306 }
307 }
308
309 if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
310 char oldstr[44]; /* hours strings are 42 bytes. */
311 char newstr[44];
312 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
313 pdb_get_logon_divs(to), from->logon_hours.units_per_week));
314 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
315 pdb_set_logon_divs(to,
316 from->logon_hours.units_per_week, PDB_CHANGED);
317 }
318
319 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
320 pdb_get_hours_len(to),
321 from->logon_hours.units_per_week/8));
322 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
323 pdb_set_hours_len(to,
324 from->logon_hours.units_per_week/8, PDB_CHANGED);
325 }
326
327 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
328 pdb_get_hours(to), from->logon_hours.bits));
329 pdb_sethexhours(oldstr, pdb_get_hours(to));
330 pdb_sethexhours(newstr, from->logon_hours.bits);
331 if (!strequal(oldstr, newstr)) {
332 pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
333 }
334 }
335
336 if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
337 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
338 pdb_get_bad_password_count(to), from->bad_password_count));
339 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
340 pdb_set_bad_password_count(to,
341 from->bad_password_count, PDB_CHANGED);
342 }
343 }
344
345 if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
346 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
347 pdb_get_logon_count(to), from->logon_count));
348 if (from->logon_count != pdb_get_logon_count(to)) {
349 pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
350 }
351 }
352
353 /* If the must change flag is set, the last set time goes to zero.
354 the must change and can change fields also do, but they are
355 calculated from policy, not set from the wire */
356
357 if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
358 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
359 from->password_expired));
360 if (from->password_expired != 0) {
361 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
362 } else {
363 /* A subtlety here: some windows commands will
364 clear the expired flag even though it's not
365 set, and we don't want to reset the time
366 in these caess. "net user /dom <user> /active:y"
367 for example, to clear an autolocked acct.
368 We must check to see if it's expired first. jmcd */
369
370 uint32_t pwd_max_age = 0;
371 time_t now = time(NULL);
372
373 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
374
375 if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
376 pwd_max_age = get_time_t_max();
377 }
378
379 stored_time = pdb_get_pass_last_set_time(to);
380
381 /* we will only *set* a pwdlastset date when
382 a) the last pwdlastset time was 0 (user was forced to
383 change password).
384 b) the users password has not expired. gd. */
385
386 if ((stored_time == 0) ||
387 ((now - stored_time) > pwd_max_age)) {
388 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
389 }
390 }
391 }
392}
393
394
395/*************************************************************
396 Copies a struct samr_UserInfo23 to a struct samu
397**************************************************************/
398
399void copy_id23_to_sam_passwd(struct samu *to,
400 struct samr_UserInfo23 *from)
401{
402 if (from == NULL || to == NULL) {
403 return;
404 }
405
406 copy_id21_to_sam_passwd("INFO 23", to, &from->info);
407}
408
409/*************************************************************
410 Copies a struct samr_UserInfo24 to a struct samu
411**************************************************************/
412
413void copy_id24_to_sam_passwd(struct samu *to,
414 struct samr_UserInfo24 *from)
415{
416 struct samr_UserInfo21 i;
417
418 if (from == NULL || to == NULL) {
419 return;
420 }
421
422 ZERO_STRUCT(i);
423
424 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
425 i.password_expired = from->password_expired;
426
427 copy_id21_to_sam_passwd("INFO_24", to, &i);
428}
429
430/*************************************************************
431 Copies a struct samr_UserInfo25 to a struct samu
432**************************************************************/
433
434void copy_id25_to_sam_passwd(struct samu *to,
435 struct samr_UserInfo25 *from)
436{
437 if (from == NULL || to == NULL) {
438 return;
439 }
440
441 copy_id21_to_sam_passwd("INFO_25", to, &from->info);
442}
443
444/*************************************************************
445 Copies a struct samr_UserInfo26 to a struct samu
446**************************************************************/
447
448void copy_id26_to_sam_passwd(struct samu *to,
449 struct samr_UserInfo26 *from)
450{
451 struct samr_UserInfo21 i;
452
453 if (from == NULL || to == NULL) {
454 return;
455 }
456
457 ZERO_STRUCT(i);
458
459 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
460 i.password_expired = from->password_expired;
461
462 copy_id21_to_sam_passwd("INFO_26", to, &i);
463}
Note: See TracBrowser for help on using the repository browser.