Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
[amitay/samba.git] / source3 / rpc_server / samr / srv_samr_util.c
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 #include "../librpc/gen_ndr/samr.h"
27 #include "rpc_server/samr/srv_samr_util.h"
28 #include "passdb.h"
29
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
32
33 #define STRING_CHANGED (old_string && !new_string) ||\
34                     (!old_string && new_string) ||\
35                 (old_string && new_string && (strcmp(old_string, new_string) != 0))
36
37 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
38                     (!(s1) && (s2)) ||\
39                 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
40
41 /*************************************************************
42  Copies a struct samr_UserInfo2 to a struct samu
43 **************************************************************/
44
45 void copy_id2_to_sam_passwd(struct samu *to,
46                             struct samr_UserInfo2 *from)
47 {
48         struct samr_UserInfo21 i;
49
50         if (from == NULL || to == NULL) {
51                 return;
52         }
53
54         ZERO_STRUCT(i);
55
56         i.fields_present        = SAMR_FIELD_COMMENT |
57                                   SAMR_FIELD_COUNTRY_CODE |
58                                   SAMR_FIELD_CODE_PAGE;
59         i.comment               = from->comment;
60         i.country_code          = from->country_code;
61         i.code_page             = from->code_page;
62
63         copy_id21_to_sam_passwd("INFO_2", to, &i);
64 }
65
66 /*************************************************************
67  Copies a struct samr_UserInfo4 to a struct samu
68 **************************************************************/
69
70 void copy_id4_to_sam_passwd(struct samu *to,
71                             struct samr_UserInfo4 *from)
72 {
73         struct samr_UserInfo21 i;
74
75         if (from == NULL || to == NULL) {
76                 return;
77         }
78
79         ZERO_STRUCT(i);
80
81         i.fields_present        = SAMR_FIELD_LOGON_HOURS;
82         i.logon_hours           = from->logon_hours;
83
84         copy_id21_to_sam_passwd("INFO_4", to, &i);
85 }
86
87 /*************************************************************
88  Copies a struct samr_UserInfo6 to a struct samu
89 **************************************************************/
90
91 void copy_id6_to_sam_passwd(struct samu *to,
92                             struct samr_UserInfo6 *from)
93 {
94         struct samr_UserInfo21 i;
95
96         if (from == NULL || to == NULL) {
97                 return;
98         }
99
100         ZERO_STRUCT(i);
101
102         i.fields_present        = SAMR_FIELD_ACCOUNT_NAME |
103                                   SAMR_FIELD_FULL_NAME;
104         i.account_name          = from->account_name;
105         i.full_name             = from->full_name;
106
107         copy_id21_to_sam_passwd("INFO_6", to, &i);
108 }
109
110 /*************************************************************
111  Copies a struct samr_UserInfo8 to a struct samu
112 **************************************************************/
113
114 void copy_id8_to_sam_passwd(struct samu *to,
115                             struct samr_UserInfo8 *from)
116 {
117         struct samr_UserInfo21 i;
118
119         if (from == NULL || to == NULL) {
120                 return;
121         }
122
123         ZERO_STRUCT(i);
124
125         i.fields_present        = SAMR_FIELD_FULL_NAME;
126         i.full_name             = from->full_name;
127
128         copy_id21_to_sam_passwd("INFO_8", to, &i);
129 }
130
131 /*************************************************************
132  Copies a struct samr_UserInfo10 to a struct samu
133 **************************************************************/
134
135 void copy_id10_to_sam_passwd(struct samu *to,
136                              struct samr_UserInfo10 *from)
137 {
138         struct samr_UserInfo21 i;
139
140         if (from == NULL || to == NULL) {
141                 return;
142         }
143
144         ZERO_STRUCT(i);
145
146         i.fields_present        = SAMR_FIELD_HOME_DIRECTORY |
147                                   SAMR_FIELD_HOME_DRIVE;
148         i.home_directory        = from->home_directory;
149         i.home_drive            = from->home_drive;
150
151         copy_id21_to_sam_passwd("INFO_10", to, &i);
152 }
153
154 /*************************************************************
155  Copies a struct samr_UserInfo11 to a struct samu
156 **************************************************************/
157
158 void copy_id11_to_sam_passwd(struct samu *to,
159                              struct samr_UserInfo11 *from)
160 {
161         struct samr_UserInfo21 i;
162
163         if (from == NULL || to == NULL) {
164                 return;
165         }
166
167         ZERO_STRUCT(i);
168
169         i.fields_present        = SAMR_FIELD_LOGON_SCRIPT;
170         i.logon_script          = from->logon_script;
171
172         copy_id21_to_sam_passwd("INFO_11", to, &i);
173 }
174
175 /*************************************************************
176  Copies a struct samr_UserInfo12 to a struct samu
177 **************************************************************/
178
179 void copy_id12_to_sam_passwd(struct samu *to,
180                              struct samr_UserInfo12 *from)
181 {
182         struct samr_UserInfo21 i;
183
184         if (from == NULL || to == NULL) {
185                 return;
186         }
187
188         ZERO_STRUCT(i);
189
190         i.fields_present        = SAMR_FIELD_PROFILE_PATH;
191         i.profile_path          = from->profile_path;
192
193         copy_id21_to_sam_passwd("INFO_12", to, &i);
194 }
195
196 /*************************************************************
197  Copies a struct samr_UserInfo13 to a struct samu
198 **************************************************************/
199
200 void copy_id13_to_sam_passwd(struct samu *to,
201                              struct samr_UserInfo13 *from)
202 {
203         struct samr_UserInfo21 i;
204
205         if (from == NULL || to == NULL) {
206                 return;
207         }
208
209         ZERO_STRUCT(i);
210
211         i.fields_present        = SAMR_FIELD_DESCRIPTION;
212         i.description           = from->description;
213
214         copy_id21_to_sam_passwd("INFO_13", to, &i);
215 }
216
217 /*************************************************************
218  Copies a struct samr_UserInfo14 to a struct samu
219 **************************************************************/
220
221 void copy_id14_to_sam_passwd(struct samu *to,
222                              struct samr_UserInfo14 *from)
223 {
224         struct samr_UserInfo21 i;
225
226         if (from == NULL || to == NULL) {
227                 return;
228         }
229
230         ZERO_STRUCT(i);
231
232         i.fields_present        = SAMR_FIELD_WORKSTATIONS;
233         i.workstations          = from->workstations;
234
235         copy_id21_to_sam_passwd("INFO_14", to, &i);
236 }
237
238 /*************************************************************
239  Copies a struct samr_UserInfo16 to a struct samu
240 **************************************************************/
241
242 void copy_id16_to_sam_passwd(struct samu *to,
243                              struct samr_UserInfo16 *from)
244 {
245         struct samr_UserInfo21 i;
246
247         if (from == NULL || to == NULL) {
248                 return;
249         }
250
251         ZERO_STRUCT(i);
252
253         i.fields_present        = SAMR_FIELD_ACCT_FLAGS;
254         i.acct_flags            = from->acct_flags;
255
256         copy_id21_to_sam_passwd("INFO_16", to, &i);
257 }
258
259 /*************************************************************
260  Copies a struct samr_UserInfo17 to a struct samu
261 **************************************************************/
262
263 void copy_id17_to_sam_passwd(struct samu *to,
264                              struct samr_UserInfo17 *from)
265 {
266         struct samr_UserInfo21 i;
267
268         if (from == NULL || to == NULL) {
269                 return;
270         }
271
272         ZERO_STRUCT(i);
273
274         i.fields_present        = SAMR_FIELD_ACCT_EXPIRY;
275         i.acct_expiry           = from->acct_expiry;
276
277         copy_id21_to_sam_passwd("INFO_17", to, &i);
278 }
279
280 /*************************************************************
281  Copies a struct samr_UserInfo18 to a struct samu
282 **************************************************************/
283
284 void copy_id18_to_sam_passwd(struct samu *to,
285                              struct samr_UserInfo18 *from)
286 {
287         struct samr_UserInfo21 i;
288
289         if (from == NULL || to == NULL) {
290                 return;
291         }
292
293         ZERO_STRUCT(i);
294
295         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
296         i.password_expired      = from->password_expired;
297
298         copy_id21_to_sam_passwd("INFO_18", to, &i);
299 }
300
301 /*************************************************************
302  Copies a struct samr_UserInfo20 to a struct samu
303 **************************************************************/
304
305 void copy_id20_to_sam_passwd(struct samu *to,
306                              struct samr_UserInfo20 *from)
307 {
308         const char *old_string;
309         char *new_string;
310         DATA_BLOB mung;
311
312         if (from == NULL || to == NULL) {
313                 return;
314         }
315
316         if (from->parameters.array) {
317                 old_string = pdb_get_munged_dial(to);
318                 mung = data_blob_const(from->parameters.array,
319                                        from->parameters.length);
320                 new_string = (mung.length == 0) ?
321                         NULL : base64_encode_data_blob(talloc_tos(), mung);
322                 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
323                         old_string, new_string));
324                 if (STRING_CHANGED_NC(old_string,new_string)) {
325                         pdb_set_munged_dial(to, new_string, PDB_CHANGED);
326                 }
327
328                 TALLOC_FREE(new_string);
329         }
330 }
331
332 /*************************************************************
333  Copies a struct samr_UserInfo21 to a struct samu
334 **************************************************************/
335
336 void copy_id21_to_sam_passwd(const char *log_prefix,
337                              struct samu *to,
338                              struct samr_UserInfo21 *from)
339 {
340         time_t unix_time, stored_time;
341         const char *old_string, *new_string;
342         const char *l;
343
344         if (from == NULL || to == NULL) {
345                 return;
346         }
347
348         if (log_prefix) {
349                 l = log_prefix;
350         } else {
351                 l = "INFO_21";
352         }
353
354         if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
355                 unix_time = nt_time_to_unix(from->last_logon);
356                 stored_time = pdb_get_logon_time(to);
357                 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
358                         (long unsigned int)stored_time,
359                         (long unsigned int)unix_time));
360                 if (stored_time != unix_time) {
361                         pdb_set_logon_time(to, unix_time, PDB_CHANGED);
362                 }
363         }
364
365         if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
366                 unix_time = nt_time_to_unix(from->last_logoff);
367                 stored_time = pdb_get_logoff_time(to);
368                 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
369                         (long unsigned int)stored_time,
370                         (long unsigned int)unix_time));
371                 if (stored_time != unix_time) {
372                         pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
373                 }
374         }
375
376         if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
377                 unix_time = nt_time_to_unix(from->acct_expiry);
378                 stored_time = pdb_get_kickoff_time(to);
379                 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
380                         (long unsigned int)stored_time,
381                         (long unsigned int)unix_time));
382                 if (stored_time != unix_time) {
383                         pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
384                 }
385         }
386
387         if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
388                 unix_time = nt_time_to_unix(from->last_password_change);
389                 stored_time = pdb_get_pass_last_set_time(to);
390                 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
391                         (long unsigned int)stored_time,
392                         (long unsigned int)unix_time));
393                 if (stored_time != unix_time) {
394                         pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
395                 }
396         }
397
398         if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
399             (from->account_name.string)) {
400                 old_string = pdb_get_username(to);
401                 new_string = from->account_name.string;
402                 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
403                         old_string, new_string));
404                 if (STRING_CHANGED) {
405                         pdb_set_username(to, new_string, PDB_CHANGED);
406                 }
407         }
408
409         if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
410             (from->full_name.string)) {
411                 old_string = pdb_get_fullname(to);
412                 new_string = from->full_name.string;
413                 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
414                         old_string, new_string));
415                 if (STRING_CHANGED) {
416                         pdb_set_fullname(to, new_string, PDB_CHANGED);
417                 }
418         }
419
420         if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
421             (from->home_directory.string)) {
422                 old_string = pdb_get_homedir(to);
423                 new_string = from->home_directory.string;
424                 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
425                         old_string, new_string));
426                 if (STRING_CHANGED) {
427                         pdb_set_homedir(to, new_string, PDB_CHANGED);
428                 }
429         }
430
431         if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
432             (from->home_drive.string)) {
433                 old_string = pdb_get_dir_drive(to);
434                 new_string = from->home_drive.string;
435                 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
436                         old_string, new_string));
437                 if (STRING_CHANGED) {
438                         pdb_set_dir_drive(to, new_string, PDB_CHANGED);
439                 }
440         }
441
442         if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
443             (from->logon_script.string)) {
444                 old_string = pdb_get_logon_script(to);
445                 new_string = from->logon_script.string;
446                 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
447                         old_string, new_string));
448                 if (STRING_CHANGED) {
449                         pdb_set_logon_script(to  , new_string, PDB_CHANGED);
450                 }
451         }
452
453         if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
454             (from->profile_path.string)) {
455                 old_string = pdb_get_profile_path(to);
456                 new_string = from->profile_path.string;
457                 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
458                         old_string, new_string));
459                 if (STRING_CHANGED) {
460                         pdb_set_profile_path(to  , new_string, PDB_CHANGED);
461                 }
462         }
463
464         if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
465             (from->description.string)) {
466                 old_string = pdb_get_acct_desc(to);
467                 new_string = from->description.string;
468                 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
469                         old_string, new_string));
470                 if (STRING_CHANGED) {
471                         pdb_set_acct_desc(to, new_string, PDB_CHANGED);
472                 }
473         }
474
475         if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
476             (from->workstations.string)) {
477                 old_string = pdb_get_workstations(to);
478                 new_string = from->workstations.string;
479                 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
480                         old_string, new_string));
481                 if (STRING_CHANGED) {
482                         pdb_set_workstations(to  , new_string, PDB_CHANGED);
483                 }
484         }
485
486         if ((from->fields_present & SAMR_FIELD_COMMENT) &&
487             (from->comment.string)) {
488                 old_string = pdb_get_comment(to);
489                 new_string = from->comment.string;
490                 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
491                         old_string, new_string));
492                 if (STRING_CHANGED) {
493                         pdb_set_comment(to, new_string, PDB_CHANGED);
494                 }
495         }
496
497         if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
498             (from->parameters.array)) {
499                 char *newstr;
500                 DATA_BLOB mung;
501                 old_string = pdb_get_munged_dial(to);
502
503                 mung = data_blob_const(from->parameters.array,
504                                        from->parameters.length);
505                 newstr = (mung.length == 0) ?
506                         NULL : base64_encode_data_blob(talloc_tos(), mung);
507                 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
508                         old_string, newstr));
509                 if (STRING_CHANGED_NC(old_string,newstr)) {
510                         pdb_set_munged_dial(to, newstr, PDB_CHANGED);
511                 }
512
513                 TALLOC_FREE(newstr);
514         }
515
516         if (from->fields_present & SAMR_FIELD_RID) {
517                 if (from->rid == 0) {
518                         DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
519                 } else if (from->rid != pdb_get_user_rid(to)) {
520                         DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
521                                 pdb_get_user_rid(to), from->rid));
522                 }
523         }
524
525         if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
526                 if (from->primary_gid == 0) {
527                         DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
528                 } else if (from->primary_gid != pdb_get_group_rid(to)) {
529                         DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
530                                 pdb_get_group_rid(to), from->primary_gid));
531                         pdb_set_group_sid_from_rid(to,
532                                 from->primary_gid, PDB_CHANGED);
533                 }
534         }
535
536         if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
537                 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
538                         pdb_get_acct_ctrl(to), from->acct_flags));
539                 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
540
541                         /* You cannot autolock an unlocked account via
542                          * setuserinfo calls, so make sure to remove the
543                          * ACB_AUTOLOCK bit here - gd */
544
545                         if ((from->acct_flags & ACB_AUTOLOCK) &&
546                             !(pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
547                                 from->acct_flags &= ~ACB_AUTOLOCK;
548                         }
549
550                         if (!(from->acct_flags & ACB_AUTOLOCK) &&
551                              (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
552                                 /* We're unlocking a previously locked user. Reset bad password counts.
553                                    Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
554                                 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
555                                 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
556                         }
557                         pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
558                 }
559         }
560
561         if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
562                 char oldstr[44]; /* hours strings are 42 bytes. */
563                 char newstr[44];
564                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
565                         pdb_get_logon_divs(to), from->logon_hours.units_per_week));
566                 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
567                         pdb_set_logon_divs(to,
568                                 from->logon_hours.units_per_week, PDB_CHANGED);
569                 }
570
571                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
572                         pdb_get_hours_len(to),
573                         from->logon_hours.units_per_week/8));
574                 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
575                         pdb_set_hours_len(to,
576                                 from->logon_hours.units_per_week/8, PDB_CHANGED);
577                 }
578
579                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
580                         pdb_get_hours(to), from->logon_hours.bits));
581                 pdb_sethexhours(oldstr, pdb_get_hours(to));
582                 pdb_sethexhours(newstr, from->logon_hours.bits);
583                 if (!strequal(oldstr, newstr)) {
584                         pdb_set_hours(to, from->logon_hours.bits,
585                                       from->logon_hours.units_per_week/8,
586                                       PDB_CHANGED);
587                 }
588         }
589
590         if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
591                 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
592                         pdb_get_bad_password_count(to), from->bad_password_count));
593                 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
594                         pdb_set_bad_password_count(to,
595                                 from->bad_password_count, PDB_CHANGED);
596                 }
597         }
598
599         if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
600                 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
601                         pdb_get_logon_count(to), from->logon_count));
602                 if (from->logon_count != pdb_get_logon_count(to)) {
603                         pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
604                 }
605         }
606
607         /* If the must change flag is set, the last set time goes to zero.
608            the must change and can change fields also do, but they are
609            calculated from policy, not set from the wire */
610
611         if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
612                 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
613                         from->password_expired));
614                 if (from->password_expired != 0) {
615                         /* Only allow the set_time to zero (which means
616                            "User Must Change Password on Next Login"
617                            if the user object allows password change. */
618                         if (pdb_get_pass_can_change(to)) {
619                                 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
620                         } else {
621                                 DEBUG(10,("%s Disallowing set of 'User Must "
622                                         "Change Password on Next Login' as "
623                                         "user object disallows this.\n", l));
624                         }
625                 } else {
626                         /* A subtlety here: some windows commands will
627                            clear the expired flag even though it's not
628                            set, and we don't want to reset the time
629                            in these caess.  "net user /dom <user> /active:y"
630                            for example, to clear an autolocked acct.
631                            We must check to see if it's expired first. jmcd */
632
633                         uint32_t pwd_max_age = 0;
634                         time_t now = time(NULL);
635
636                         pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age);
637
638                         if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
639                                 pwd_max_age = get_time_t_max();
640                         }
641
642                         stored_time = pdb_get_pass_last_set_time(to);
643
644                         /* we will only *set* a pwdlastset date when
645                            a) the last pwdlastset time was 0 (user was forced to
646                               change password).
647                            b) the users password has not expired. gd. */
648
649                         if ((stored_time == 0) ||
650                             ((now - stored_time) > pwd_max_age)) {
651                                 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
652                         }
653                 }
654         }
655
656         if (from->fields_present & SAMR_FIELD_COUNTRY_CODE) {
657                 DEBUG(10,("%s SAMR_FIELD_COUNTRY_CODE: %08X -> %08X\n", l,
658                         pdb_get_country_code(to), from->country_code));
659                 if (from->country_code != pdb_get_country_code(to)) {
660                         pdb_set_country_code(to,
661                                 from->country_code, PDB_CHANGED);
662                 }
663         }
664
665         if (from->fields_present & SAMR_FIELD_CODE_PAGE) {
666                 DEBUG(10,("%s SAMR_FIELD_CODE_PAGE: %08X -> %08X\n", l,
667                         pdb_get_code_page(to), from->code_page));
668                 if (from->code_page != pdb_get_code_page(to)) {
669                         pdb_set_code_page(to,
670                                 from->code_page, PDB_CHANGED);
671                 }
672         }
673 }
674
675
676 /*************************************************************
677  Copies a struct samr_UserInfo23 to a struct samu
678 **************************************************************/
679
680 void copy_id23_to_sam_passwd(struct samu *to,
681                              struct samr_UserInfo23 *from)
682 {
683         if (from == NULL || to == NULL) {
684                 return;
685         }
686
687         copy_id21_to_sam_passwd("INFO 23", to, &from->info);
688 }
689
690 /*************************************************************
691  Copies a struct samr_UserInfo24 to a struct samu
692 **************************************************************/
693
694 void copy_id24_to_sam_passwd(struct samu *to,
695                              struct samr_UserInfo24 *from)
696 {
697         struct samr_UserInfo21 i;
698
699         if (from == NULL || to == NULL) {
700                 return;
701         }
702
703         ZERO_STRUCT(i);
704
705         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
706         i.password_expired      = from->password_expired;
707
708         copy_id21_to_sam_passwd("INFO_24", to, &i);
709 }
710
711 /*************************************************************
712  Copies a struct samr_UserInfo25 to a struct samu
713 **************************************************************/
714
715 void copy_id25_to_sam_passwd(struct samu *to,
716                              struct samr_UserInfo25 *from)
717 {
718         if (from == NULL || to == NULL) {
719                 return;
720         }
721
722         copy_id21_to_sam_passwd("INFO_25", to, &from->info);
723 }
724
725 /*************************************************************
726  Copies a struct samr_UserInfo26 to a struct samu
727 **************************************************************/
728
729 void copy_id26_to_sam_passwd(struct samu *to,
730                              struct samr_UserInfo26 *from)
731 {
732         struct samr_UserInfo21 i;
733
734         if (from == NULL || to == NULL) {
735                 return;
736         }
737
738         ZERO_STRUCT(i);
739
740         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
741         i.password_expired      = from->password_expired;
742
743         copy_id21_to_sam_passwd("INFO_26", to, &i);
744 }