s4: reorder action to permit old provision to be correctly upgraded
[Samba/nascimento.git] / source3 / rpc_server / srv_samr_util.c
blob1e5988af330c15f2cb9ae8c5e621eefe2bdf58fb
1 /*
2 Unix SMB/CIFS implementation.
3 SAMR Pipe utility functions.
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
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.
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.
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/>.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_SRV
30 #define STRING_CHANGED (old_string && !new_string) ||\
31 (!old_string && new_string) ||\
32 (old_string && new_string && (strcmp(old_string, new_string) != 0))
34 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
35 (!(s1) && (s2)) ||\
36 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
38 /*************************************************************
39 Copies a struct samr_UserInfo2 to a struct samu
40 **************************************************************/
42 void copy_id2_to_sam_passwd(struct samu *to,
43 struct samr_UserInfo2 *from)
45 struct samr_UserInfo21 i;
47 if (from == NULL || to == NULL) {
48 return;
51 ZERO_STRUCT(i);
53 i.fields_present = SAMR_FIELD_COMMENT |
54 SAMR_FIELD_COUNTRY_CODE |
55 SAMR_FIELD_CODE_PAGE;
56 i.comment = from->comment;
57 i.country_code = from->country_code;
58 i.code_page = from->code_page;
60 copy_id21_to_sam_passwd("INFO_2", to, &i);
63 /*************************************************************
64 Copies a struct samr_UserInfo4 to a struct samu
65 **************************************************************/
67 void copy_id4_to_sam_passwd(struct samu *to,
68 struct samr_UserInfo4 *from)
70 struct samr_UserInfo21 i;
72 if (from == NULL || to == NULL) {
73 return;
76 ZERO_STRUCT(i);
78 i.fields_present = SAMR_FIELD_LOGON_HOURS;
79 i.logon_hours = from->logon_hours;
81 copy_id21_to_sam_passwd("INFO_4", to, &i);
84 /*************************************************************
85 Copies a struct samr_UserInfo6 to a struct samu
86 **************************************************************/
88 void copy_id6_to_sam_passwd(struct samu *to,
89 struct samr_UserInfo6 *from)
91 struct samr_UserInfo21 i;
93 if (from == NULL || to == NULL) {
94 return;
97 ZERO_STRUCT(i);
99 i.fields_present = SAMR_FIELD_ACCOUNT_NAME |
100 SAMR_FIELD_FULL_NAME;
101 i.account_name = from->account_name;
102 i.full_name = from->full_name;
104 copy_id21_to_sam_passwd("INFO_6", to, &i);
107 /*************************************************************
108 Copies a struct samr_UserInfo8 to a struct samu
109 **************************************************************/
111 void copy_id8_to_sam_passwd(struct samu *to,
112 struct samr_UserInfo8 *from)
114 struct samr_UserInfo21 i;
116 if (from == NULL || to == NULL) {
117 return;
120 ZERO_STRUCT(i);
122 i.fields_present = SAMR_FIELD_FULL_NAME;
123 i.full_name = from->full_name;
125 copy_id21_to_sam_passwd("INFO_8", to, &i);
128 /*************************************************************
129 Copies a struct samr_UserInfo10 to a struct samu
130 **************************************************************/
132 void copy_id10_to_sam_passwd(struct samu *to,
133 struct samr_UserInfo10 *from)
135 struct samr_UserInfo21 i;
137 if (from == NULL || to == NULL) {
138 return;
141 ZERO_STRUCT(i);
143 i.fields_present = SAMR_FIELD_HOME_DIRECTORY |
144 SAMR_FIELD_HOME_DRIVE;
145 i.home_directory = from->home_directory;
146 i.home_drive = from->home_drive;
148 copy_id21_to_sam_passwd("INFO_10", to, &i);
151 /*************************************************************
152 Copies a struct samr_UserInfo11 to a struct samu
153 **************************************************************/
155 void copy_id11_to_sam_passwd(struct samu *to,
156 struct samr_UserInfo11 *from)
158 struct samr_UserInfo21 i;
160 if (from == NULL || to == NULL) {
161 return;
164 ZERO_STRUCT(i);
166 i.fields_present = SAMR_FIELD_LOGON_SCRIPT;
167 i.logon_script = from->logon_script;
169 copy_id21_to_sam_passwd("INFO_11", to, &i);
172 /*************************************************************
173 Copies a struct samr_UserInfo12 to a struct samu
174 **************************************************************/
176 void copy_id12_to_sam_passwd(struct samu *to,
177 struct samr_UserInfo12 *from)
179 struct samr_UserInfo21 i;
181 if (from == NULL || to == NULL) {
182 return;
185 ZERO_STRUCT(i);
187 i.fields_present = SAMR_FIELD_PROFILE_PATH;
188 i.profile_path = from->profile_path;
190 copy_id21_to_sam_passwd("INFO_12", to, &i);
193 /*************************************************************
194 Copies a struct samr_UserInfo13 to a struct samu
195 **************************************************************/
197 void copy_id13_to_sam_passwd(struct samu *to,
198 struct samr_UserInfo13 *from)
200 struct samr_UserInfo21 i;
202 if (from == NULL || to == NULL) {
203 return;
206 ZERO_STRUCT(i);
208 i.fields_present = SAMR_FIELD_DESCRIPTION;
209 i.description = from->description;
211 copy_id21_to_sam_passwd("INFO_13", to, &i);
214 /*************************************************************
215 Copies a struct samr_UserInfo14 to a struct samu
216 **************************************************************/
218 void copy_id14_to_sam_passwd(struct samu *to,
219 struct samr_UserInfo14 *from)
221 struct samr_UserInfo21 i;
223 if (from == NULL || to == NULL) {
224 return;
227 ZERO_STRUCT(i);
229 i.fields_present = SAMR_FIELD_WORKSTATIONS;
230 i.workstations = from->workstations;
232 copy_id21_to_sam_passwd("INFO_14", to, &i);
235 /*************************************************************
236 Copies a struct samr_UserInfo16 to a struct samu
237 **************************************************************/
239 void copy_id16_to_sam_passwd(struct samu *to,
240 struct samr_UserInfo16 *from)
242 struct samr_UserInfo21 i;
244 if (from == NULL || to == NULL) {
245 return;
248 ZERO_STRUCT(i);
250 i.fields_present = SAMR_FIELD_ACCT_FLAGS;
251 i.acct_flags = from->acct_flags;
253 copy_id21_to_sam_passwd("INFO_16", to, &i);
256 /*************************************************************
257 Copies a struct samr_UserInfo17 to a struct samu
258 **************************************************************/
260 void copy_id17_to_sam_passwd(struct samu *to,
261 struct samr_UserInfo17 *from)
263 struct samr_UserInfo21 i;
265 if (from == NULL || to == NULL) {
266 return;
269 ZERO_STRUCT(i);
271 i.fields_present = SAMR_FIELD_ACCT_EXPIRY;
272 i.acct_expiry = from->acct_expiry;
274 copy_id21_to_sam_passwd("INFO_17", to, &i);
277 /*************************************************************
278 Copies a struct samr_UserInfo18 to a struct samu
279 **************************************************************/
281 void copy_id18_to_sam_passwd(struct samu *to,
282 struct samr_UserInfo18 *from)
284 struct samr_UserInfo21 i;
286 if (from == NULL || to == NULL) {
287 return;
290 ZERO_STRUCT(i);
292 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
293 i.password_expired = from->password_expired;
295 copy_id21_to_sam_passwd("INFO_18", to, &i);
298 /*************************************************************
299 Copies a struct samr_UserInfo20 to a struct samu
300 **************************************************************/
302 void copy_id20_to_sam_passwd(struct samu *to,
303 struct samr_UserInfo20 *from)
305 const char *old_string;
306 char *new_string;
307 DATA_BLOB mung;
309 if (from == NULL || to == NULL) {
310 return;
313 if (from->parameters.array) {
314 old_string = pdb_get_munged_dial(to);
315 mung = data_blob_const(from->parameters.array,
316 from->parameters.length);
317 new_string = (mung.length == 0) ?
318 NULL : base64_encode_data_blob(talloc_tos(), mung);
319 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
320 old_string, new_string));
321 if (STRING_CHANGED_NC(old_string,new_string)) {
322 pdb_set_munged_dial(to, new_string, PDB_CHANGED);
325 TALLOC_FREE(new_string);
329 /*************************************************************
330 Copies a struct samr_UserInfo21 to a struct samu
331 **************************************************************/
333 void copy_id21_to_sam_passwd(const char *log_prefix,
334 struct samu *to,
335 struct samr_UserInfo21 *from)
337 time_t unix_time, stored_time;
338 const char *old_string, *new_string;
339 const char *l;
341 if (from == NULL || to == NULL) {
342 return;
345 if (log_prefix) {
346 l = log_prefix;
347 } else {
348 l = "INFO_21";
351 if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
352 unix_time = nt_time_to_unix(from->last_logon);
353 stored_time = pdb_get_logon_time(to);
354 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
355 (long unsigned int)stored_time,
356 (long unsigned int)unix_time));
357 if (stored_time != unix_time) {
358 pdb_set_logon_time(to, unix_time, PDB_CHANGED);
362 if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
363 unix_time = nt_time_to_unix(from->last_logoff);
364 stored_time = pdb_get_logoff_time(to);
365 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
366 (long unsigned int)stored_time,
367 (long unsigned int)unix_time));
368 if (stored_time != unix_time) {
369 pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
373 if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
374 unix_time = nt_time_to_unix(from->acct_expiry);
375 stored_time = pdb_get_kickoff_time(to);
376 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
377 (long unsigned int)stored_time,
378 (long unsigned int)unix_time));
379 if (stored_time != unix_time) {
380 pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
384 if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
385 unix_time = nt_time_to_unix(from->last_password_change);
386 stored_time = pdb_get_pass_last_set_time(to);
387 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
388 (long unsigned int)stored_time,
389 (long unsigned int)unix_time));
390 if (stored_time != unix_time) {
391 pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
395 if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
396 (from->account_name.string)) {
397 old_string = pdb_get_username(to);
398 new_string = from->account_name.string;
399 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
400 old_string, new_string));
401 if (STRING_CHANGED) {
402 pdb_set_username(to, new_string, PDB_CHANGED);
406 if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
407 (from->full_name.string)) {
408 old_string = pdb_get_fullname(to);
409 new_string = from->full_name.string;
410 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
411 old_string, new_string));
412 if (STRING_CHANGED) {
413 pdb_set_fullname(to, new_string, PDB_CHANGED);
417 if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
418 (from->home_directory.string)) {
419 old_string = pdb_get_homedir(to);
420 new_string = from->home_directory.string;
421 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
422 old_string, new_string));
423 if (STRING_CHANGED) {
424 pdb_set_homedir(to, new_string, PDB_CHANGED);
428 if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
429 (from->home_drive.string)) {
430 old_string = pdb_get_dir_drive(to);
431 new_string = from->home_drive.string;
432 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
433 old_string, new_string));
434 if (STRING_CHANGED) {
435 pdb_set_dir_drive(to, new_string, PDB_CHANGED);
439 if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
440 (from->logon_script.string)) {
441 old_string = pdb_get_logon_script(to);
442 new_string = from->logon_script.string;
443 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
444 old_string, new_string));
445 if (STRING_CHANGED) {
446 pdb_set_logon_script(to , new_string, PDB_CHANGED);
450 if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
451 (from->profile_path.string)) {
452 old_string = pdb_get_profile_path(to);
453 new_string = from->profile_path.string;
454 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
455 old_string, new_string));
456 if (STRING_CHANGED) {
457 pdb_set_profile_path(to , new_string, PDB_CHANGED);
461 if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
462 (from->description.string)) {
463 old_string = pdb_get_acct_desc(to);
464 new_string = from->description.string;
465 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
466 old_string, new_string));
467 if (STRING_CHANGED) {
468 pdb_set_acct_desc(to, new_string, PDB_CHANGED);
472 if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
473 (from->workstations.string)) {
474 old_string = pdb_get_workstations(to);
475 new_string = from->workstations.string;
476 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
477 old_string, new_string));
478 if (STRING_CHANGED) {
479 pdb_set_workstations(to , new_string, PDB_CHANGED);
483 if ((from->fields_present & SAMR_FIELD_COMMENT) &&
484 (from->comment.string)) {
485 old_string = pdb_get_comment(to);
486 new_string = from->comment.string;
487 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
488 old_string, new_string));
489 if (STRING_CHANGED) {
490 pdb_set_comment(to, new_string, PDB_CHANGED);
494 if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
495 (from->parameters.array)) {
496 char *newstr;
497 DATA_BLOB mung;
498 old_string = pdb_get_munged_dial(to);
500 mung = data_blob_const(from->parameters.array,
501 from->parameters.length);
502 newstr = (mung.length == 0) ?
503 NULL : base64_encode_data_blob(talloc_tos(), mung);
504 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
505 old_string, newstr));
506 if (STRING_CHANGED_NC(old_string,newstr)) {
507 pdb_set_munged_dial(to, newstr, PDB_CHANGED);
510 TALLOC_FREE(newstr);
513 if (from->fields_present & SAMR_FIELD_RID) {
514 if (from->rid == 0) {
515 DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
516 } else if (from->rid != pdb_get_user_rid(to)) {
517 DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
518 pdb_get_user_rid(to), from->rid));
522 if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
523 if (from->primary_gid == 0) {
524 DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
525 } else if (from->primary_gid != pdb_get_group_rid(to)) {
526 DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
527 pdb_get_group_rid(to), from->primary_gid));
528 pdb_set_group_sid_from_rid(to,
529 from->primary_gid, PDB_CHANGED);
533 if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
534 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
535 pdb_get_acct_ctrl(to), from->acct_flags));
536 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
538 /* You cannot autolock an unlocked account via
539 * setuserinfo calls, so make sure to remove the
540 * ACB_AUTOLOCK bit here - gd */
542 if ((from->acct_flags & ACB_AUTOLOCK) &&
543 !(pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
544 from->acct_flags &= ~ACB_AUTOLOCK;
547 if (!(from->acct_flags & ACB_AUTOLOCK) &&
548 (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
549 /* We're unlocking a previously locked user. Reset bad password counts.
550 Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
551 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
552 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
554 pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
558 if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
559 char oldstr[44]; /* hours strings are 42 bytes. */
560 char newstr[44];
561 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
562 pdb_get_logon_divs(to), from->logon_hours.units_per_week));
563 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
564 pdb_set_logon_divs(to,
565 from->logon_hours.units_per_week, PDB_CHANGED);
568 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
569 pdb_get_hours_len(to),
570 from->logon_hours.units_per_week/8));
571 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
572 pdb_set_hours_len(to,
573 from->logon_hours.units_per_week/8, PDB_CHANGED);
576 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
577 pdb_get_hours(to), from->logon_hours.bits));
578 pdb_sethexhours(oldstr, pdb_get_hours(to));
579 pdb_sethexhours(newstr, from->logon_hours.bits);
580 if (!strequal(oldstr, newstr)) {
581 pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
585 if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
586 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
587 pdb_get_bad_password_count(to), from->bad_password_count));
588 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
589 pdb_set_bad_password_count(to,
590 from->bad_password_count, PDB_CHANGED);
594 if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
595 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
596 pdb_get_logon_count(to), from->logon_count));
597 if (from->logon_count != pdb_get_logon_count(to)) {
598 pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
602 /* If the must change flag is set, the last set time goes to zero.
603 the must change and can change fields also do, but they are
604 calculated from policy, not set from the wire */
606 if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
607 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
608 from->password_expired));
609 if (from->password_expired != 0) {
610 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
611 } else {
612 /* A subtlety here: some windows commands will
613 clear the expired flag even though it's not
614 set, and we don't want to reset the time
615 in these caess. "net user /dom <user> /active:y"
616 for example, to clear an autolocked acct.
617 We must check to see if it's expired first. jmcd */
619 uint32_t pwd_max_age = 0;
620 time_t now = time(NULL);
622 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age);
624 if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
625 pwd_max_age = get_time_t_max();
628 stored_time = pdb_get_pass_last_set_time(to);
630 /* we will only *set* a pwdlastset date when
631 a) the last pwdlastset time was 0 (user was forced to
632 change password).
633 b) the users password has not expired. gd. */
635 if ((stored_time == 0) ||
636 ((now - stored_time) > pwd_max_age)) {
637 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
644 /*************************************************************
645 Copies a struct samr_UserInfo23 to a struct samu
646 **************************************************************/
648 void copy_id23_to_sam_passwd(struct samu *to,
649 struct samr_UserInfo23 *from)
651 if (from == NULL || to == NULL) {
652 return;
655 copy_id21_to_sam_passwd("INFO 23", to, &from->info);
658 /*************************************************************
659 Copies a struct samr_UserInfo24 to a struct samu
660 **************************************************************/
662 void copy_id24_to_sam_passwd(struct samu *to,
663 struct samr_UserInfo24 *from)
665 struct samr_UserInfo21 i;
667 if (from == NULL || to == NULL) {
668 return;
671 ZERO_STRUCT(i);
673 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
674 i.password_expired = from->password_expired;
676 copy_id21_to_sam_passwd("INFO_24", to, &i);
679 /*************************************************************
680 Copies a struct samr_UserInfo25 to a struct samu
681 **************************************************************/
683 void copy_id25_to_sam_passwd(struct samu *to,
684 struct samr_UserInfo25 *from)
686 if (from == NULL || to == NULL) {
687 return;
690 copy_id21_to_sam_passwd("INFO_25", to, &from->info);
693 /*************************************************************
694 Copies a struct samr_UserInfo26 to a struct samu
695 **************************************************************/
697 void copy_id26_to_sam_passwd(struct samu *to,
698 struct samr_UserInfo26 *from)
700 struct samr_UserInfo21 i;
702 if (from == NULL || to == NULL) {
703 return;
706 ZERO_STRUCT(i);
708 i.fields_present = SAMR_FIELD_EXPIRED_FLAG;
709 i.password_expired = from->password_expired;
711 copy_id21_to_sam_passwd("INFO_26", to, &i);