s3-samr: Fix SetUserInfo level 16 and 21 w.r.t. ACB_AUTOLOCK acct_flag.
[ira/wip.git] / source3 / rpc_server / 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
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_UserInfo2 to a struct samu
40 **************************************************************/
41
42 void copy_id2_to_sam_passwd(struct samu *to,
43                             struct samr_UserInfo2 *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_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;
59
60         copy_id21_to_sam_passwd("INFO_2", to, &i);
61 }
62
63 /*************************************************************
64  Copies a struct samr_UserInfo4 to a struct samu
65 **************************************************************/
66
67 void copy_id4_to_sam_passwd(struct samu *to,
68                             struct samr_UserInfo4 *from)
69 {
70         struct samr_UserInfo21 i;
71
72         if (from == NULL || to == NULL) {
73                 return;
74         }
75
76         ZERO_STRUCT(i);
77
78         i.fields_present        = SAMR_FIELD_LOGON_HOURS;
79         i.logon_hours           = from->logon_hours;
80
81         copy_id21_to_sam_passwd("INFO_4", to, &i);
82 }
83
84 /*************************************************************
85  Copies a struct samr_UserInfo6 to a struct samu
86 **************************************************************/
87
88 void copy_id6_to_sam_passwd(struct samu *to,
89                             struct samr_UserInfo6 *from)
90 {
91         struct samr_UserInfo21 i;
92
93         if (from == NULL || to == NULL) {
94                 return;
95         }
96
97         ZERO_STRUCT(i);
98
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;
103
104         copy_id21_to_sam_passwd("INFO_6", to, &i);
105 }
106
107 /*************************************************************
108  Copies a struct samr_UserInfo8 to a struct samu
109 **************************************************************/
110
111 void copy_id8_to_sam_passwd(struct samu *to,
112                             struct samr_UserInfo8 *from)
113 {
114         struct samr_UserInfo21 i;
115
116         if (from == NULL || to == NULL) {
117                 return;
118         }
119
120         ZERO_STRUCT(i);
121
122         i.fields_present        = SAMR_FIELD_FULL_NAME;
123         i.full_name             = from->full_name;
124
125         copy_id21_to_sam_passwd("INFO_8", to, &i);
126 }
127
128 /*************************************************************
129  Copies a struct samr_UserInfo10 to a struct samu
130 **************************************************************/
131
132 void copy_id10_to_sam_passwd(struct samu *to,
133                              struct samr_UserInfo10 *from)
134 {
135         struct samr_UserInfo21 i;
136
137         if (from == NULL || to == NULL) {
138                 return;
139         }
140
141         ZERO_STRUCT(i);
142
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;
147
148         copy_id21_to_sam_passwd("INFO_10", to, &i);
149 }
150
151 /*************************************************************
152  Copies a struct samr_UserInfo11 to a struct samu
153 **************************************************************/
154
155 void copy_id11_to_sam_passwd(struct samu *to,
156                              struct samr_UserInfo11 *from)
157 {
158         struct samr_UserInfo21 i;
159
160         if (from == NULL || to == NULL) {
161                 return;
162         }
163
164         ZERO_STRUCT(i);
165
166         i.fields_present        = SAMR_FIELD_LOGON_SCRIPT;
167         i.logon_script          = from->logon_script;
168
169         copy_id21_to_sam_passwd("INFO_11", to, &i);
170 }
171
172 /*************************************************************
173  Copies a struct samr_UserInfo12 to a struct samu
174 **************************************************************/
175
176 void copy_id12_to_sam_passwd(struct samu *to,
177                              struct samr_UserInfo12 *from)
178 {
179         struct samr_UserInfo21 i;
180
181         if (from == NULL || to == NULL) {
182                 return;
183         }
184
185         ZERO_STRUCT(i);
186
187         i.fields_present        = SAMR_FIELD_PROFILE_PATH;
188         i.profile_path          = from->profile_path;
189
190         copy_id21_to_sam_passwd("INFO_12", to, &i);
191 }
192
193 /*************************************************************
194  Copies a struct samr_UserInfo13 to a struct samu
195 **************************************************************/
196
197 void copy_id13_to_sam_passwd(struct samu *to,
198                              struct samr_UserInfo13 *from)
199 {
200         struct samr_UserInfo21 i;
201
202         if (from == NULL || to == NULL) {
203                 return;
204         }
205
206         ZERO_STRUCT(i);
207
208         i.fields_present        = SAMR_FIELD_DESCRIPTION;
209         i.description           = from->description;
210
211         copy_id21_to_sam_passwd("INFO_13", to, &i);
212 }
213
214 /*************************************************************
215  Copies a struct samr_UserInfo14 to a struct samu
216 **************************************************************/
217
218 void copy_id14_to_sam_passwd(struct samu *to,
219                              struct samr_UserInfo14 *from)
220 {
221         struct samr_UserInfo21 i;
222
223         if (from == NULL || to == NULL) {
224                 return;
225         }
226
227         ZERO_STRUCT(i);
228
229         i.fields_present        = SAMR_FIELD_WORKSTATIONS;
230         i.workstations          = from->workstations;
231
232         copy_id21_to_sam_passwd("INFO_14", to, &i);
233 }
234
235 /*************************************************************
236  Copies a struct samr_UserInfo16 to a struct samu
237 **************************************************************/
238
239 void copy_id16_to_sam_passwd(struct samu *to,
240                              struct samr_UserInfo16 *from)
241 {
242         struct samr_UserInfo21 i;
243
244         if (from == NULL || to == NULL) {
245                 return;
246         }
247
248         ZERO_STRUCT(i);
249
250         i.fields_present        = SAMR_FIELD_ACCT_FLAGS;
251         i.acct_flags            = from->acct_flags;
252
253         copy_id21_to_sam_passwd("INFO_16", to, &i);
254 }
255
256 /*************************************************************
257  Copies a struct samr_UserInfo17 to a struct samu
258 **************************************************************/
259
260 void copy_id17_to_sam_passwd(struct samu *to,
261                              struct samr_UserInfo17 *from)
262 {
263         struct samr_UserInfo21 i;
264
265         if (from == NULL || to == NULL) {
266                 return;
267         }
268
269         ZERO_STRUCT(i);
270
271         i.fields_present        = SAMR_FIELD_ACCT_EXPIRY;
272         i.acct_expiry           = from->acct_expiry;
273
274         copy_id21_to_sam_passwd("INFO_17", to, &i);
275 }
276
277 /*************************************************************
278  Copies a struct samr_UserInfo18 to a struct samu
279 **************************************************************/
280
281 void copy_id18_to_sam_passwd(struct samu *to,
282                              struct samr_UserInfo18 *from)
283 {
284         struct samr_UserInfo21 i;
285
286         if (from == NULL || to == NULL) {
287                 return;
288         }
289
290         ZERO_STRUCT(i);
291
292         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
293         i.password_expired      = from->password_expired;
294
295         copy_id21_to_sam_passwd("INFO_18", to, &i);
296 }
297
298 /*************************************************************
299  Copies a struct samr_UserInfo20 to a struct samu
300 **************************************************************/
301
302 void copy_id20_to_sam_passwd(struct samu *to,
303                              struct samr_UserInfo20 *from)
304 {
305         const char *old_string;
306         char *new_string;
307         DATA_BLOB mung;
308
309         if (from == NULL || to == NULL) {
310                 return;
311         }
312
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);
323                 }
324
325                 TALLOC_FREE(new_string);
326         }
327 }
328
329 /*************************************************************
330  Copies a struct samr_UserInfo21 to a struct samu
331 **************************************************************/
332
333 void copy_id21_to_sam_passwd(const char *log_prefix,
334                              struct samu *to,
335                              struct samr_UserInfo21 *from)
336 {
337         time_t unix_time, stored_time;
338         const char *old_string, *new_string;
339         const char *l;
340
341         if (from == NULL || to == NULL) {
342                 return;
343         }
344
345         if (log_prefix) {
346                 l = log_prefix;
347         } else {
348                 l = "INFO_21";
349         }
350
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);
359                 }
360         }
361
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);
370                 }
371         }
372
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);
381                 }
382         }
383
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);
392                 }
393         }
394
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);
403                 }
404         }
405
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);
414                 }
415         }
416
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);
425                 }
426         }
427
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);
436                 }
437         }
438
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);
447                 }
448         }
449
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);
458                 }
459         }
460
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);
469                 }
470         }
471
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);
480                 }
481         }
482
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);
491                 }
492         }
493
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);
499
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);
508                 }
509
510                 TALLOC_FREE(newstr);
511         }
512
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));
519                 }
520         }
521
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);
530                 }
531         }
532
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)) {
537
538                         /* You cannot autolock an unlocked account via
539                          * setuserinfo calls, so make sure to remove the
540                          * ACB_AUTOLOCK bit here - gd */
541
542                         if ((from->acct_flags & ACB_AUTOLOCK) &&
543                             !(pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
544                                 from->acct_flags &= ~ACB_AUTOLOCK;
545                         }
546
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);
553                         }
554                         pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
555                 }
556         }
557
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);
566                 }
567
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);
574                 }
575
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);
582                 }
583         }
584
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);
591                 }
592         }
593
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);
599                 }
600         }
601
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 */
605
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 */
618
619                         uint32_t pwd_max_age = 0;
620                         time_t now = time(NULL);
621
622                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
623
624                         if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
625                                 pwd_max_age = get_time_t_max();
626                         }
627
628                         stored_time = pdb_get_pass_last_set_time(to);
629
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. */
634
635                         if ((stored_time == 0) ||
636                             ((now - stored_time) > pwd_max_age)) {
637                                 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
638                         }
639                 }
640         }
641 }
642
643
644 /*************************************************************
645  Copies a struct samr_UserInfo23 to a struct samu
646 **************************************************************/
647
648 void copy_id23_to_sam_passwd(struct samu *to,
649                              struct samr_UserInfo23 *from)
650 {
651         if (from == NULL || to == NULL) {
652                 return;
653         }
654
655         copy_id21_to_sam_passwd("INFO 23", to, &from->info);
656 }
657
658 /*************************************************************
659  Copies a struct samr_UserInfo24 to a struct samu
660 **************************************************************/
661
662 void copy_id24_to_sam_passwd(struct samu *to,
663                              struct samr_UserInfo24 *from)
664 {
665         struct samr_UserInfo21 i;
666
667         if (from == NULL || to == NULL) {
668                 return;
669         }
670
671         ZERO_STRUCT(i);
672
673         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
674         i.password_expired      = from->password_expired;
675
676         copy_id21_to_sam_passwd("INFO_24", to, &i);
677 }
678
679 /*************************************************************
680  Copies a struct samr_UserInfo25 to a struct samu
681 **************************************************************/
682
683 void copy_id25_to_sam_passwd(struct samu *to,
684                              struct samr_UserInfo25 *from)
685 {
686         if (from == NULL || to == NULL) {
687                 return;
688         }
689
690         copy_id21_to_sam_passwd("INFO_25", to, &from->info);
691 }
692
693 /*************************************************************
694  Copies a struct samr_UserInfo26 to a struct samu
695 **************************************************************/
696
697 void copy_id26_to_sam_passwd(struct samu *to,
698                              struct samr_UserInfo26 *from)
699 {
700         struct samr_UserInfo21 i;
701
702         if (from == NULL || to == NULL) {
703                 return;
704         }
705
706         ZERO_STRUCT(i);
707
708         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
709         i.password_expired      = from->password_expired;
710
711         copy_id21_to_sam_passwd("INFO_26", to, &i);
712 }