s3-samr: support some more info levels in samr_SetUserInfo calls.
[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_UserInfo17 to a struct samu
237 **************************************************************/
238
239 void copy_id17_to_sam_passwd(struct samu *to,
240                              struct samr_UserInfo17 *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_EXPIRY;
251         i.acct_expiry           = from->acct_expiry;
252
253         copy_id21_to_sam_passwd("INFO_17", to, &i);
254 }
255
256 /*************************************************************
257  Copies a struct samr_UserInfo18 to a struct samu
258 **************************************************************/
259
260 void copy_id18_to_sam_passwd(struct samu *to,
261                              struct samr_UserInfo18 *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_EXPIRED_FLAG;
272         i.password_expired      = from->password_expired;
273
274         copy_id21_to_sam_passwd("INFO_18", to, &i);
275 }
276
277 /*************************************************************
278  Copies a struct samr_UserInfo20 to a struct samu
279 **************************************************************/
280
281 void copy_id20_to_sam_passwd(struct samu *to,
282                              struct samr_UserInfo20 *from)
283 {
284         const char *old_string;
285         char *new_string;
286         DATA_BLOB mung;
287
288         if (from == NULL || to == NULL) {
289                 return;
290         }
291
292         if (from->parameters.array) {
293                 old_string = pdb_get_munged_dial(to);
294                 mung = data_blob_const(from->parameters.array,
295                                        from->parameters.length);
296                 new_string = (mung.length == 0) ?
297                         NULL : base64_encode_data_blob(talloc_tos(), mung);
298                 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
299                         old_string, new_string));
300                 if (STRING_CHANGED_NC(old_string,new_string)) {
301                         pdb_set_munged_dial(to, new_string, PDB_CHANGED);
302                 }
303
304                 TALLOC_FREE(new_string);
305         }
306 }
307
308 /*************************************************************
309  Copies a struct samr_UserInfo21 to a struct samu
310 **************************************************************/
311
312 void copy_id21_to_sam_passwd(const char *log_prefix,
313                              struct samu *to,
314                              struct samr_UserInfo21 *from)
315 {
316         time_t unix_time, stored_time;
317         const char *old_string, *new_string;
318         const char *l;
319
320         if (from == NULL || to == NULL) {
321                 return;
322         }
323
324         if (log_prefix) {
325                 l = log_prefix;
326         } else {
327                 l = "INFO_21";
328         }
329
330         if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
331                 unix_time = nt_time_to_unix(from->last_logon);
332                 stored_time = pdb_get_logon_time(to);
333                 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
334                         (long unsigned int)stored_time,
335                         (long unsigned int)unix_time));
336                 if (stored_time != unix_time) {
337                         pdb_set_logon_time(to, unix_time, PDB_CHANGED);
338                 }
339         }
340
341         if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
342                 unix_time = nt_time_to_unix(from->last_logoff);
343                 stored_time = pdb_get_logoff_time(to);
344                 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
345                         (long unsigned int)stored_time,
346                         (long unsigned int)unix_time));
347                 if (stored_time != unix_time) {
348                         pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
349                 }
350         }
351
352         if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
353                 unix_time = nt_time_to_unix(from->acct_expiry);
354                 stored_time = pdb_get_kickoff_time(to);
355                 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
356                         (long unsigned int)stored_time,
357                         (long unsigned int)unix_time));
358                 if (stored_time != unix_time) {
359                         pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
360                 }
361         }
362
363         if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
364                 unix_time = nt_time_to_unix(from->last_password_change);
365                 stored_time = pdb_get_pass_last_set_time(to);
366                 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
367                         (long unsigned int)stored_time,
368                         (long unsigned int)unix_time));
369                 if (stored_time != unix_time) {
370                         pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
371                 }
372         }
373
374         if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
375             (from->account_name.string)) {
376                 old_string = pdb_get_username(to);
377                 new_string = from->account_name.string;
378                 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
379                         old_string, new_string));
380                 if (STRING_CHANGED) {
381                         pdb_set_username(to, new_string, PDB_CHANGED);
382                 }
383         }
384
385         if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
386             (from->full_name.string)) {
387                 old_string = pdb_get_fullname(to);
388                 new_string = from->full_name.string;
389                 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
390                         old_string, new_string));
391                 if (STRING_CHANGED) {
392                         pdb_set_fullname(to, new_string, PDB_CHANGED);
393                 }
394         }
395
396         if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
397             (from->home_directory.string)) {
398                 old_string = pdb_get_homedir(to);
399                 new_string = from->home_directory.string;
400                 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
401                         old_string, new_string));
402                 if (STRING_CHANGED) {
403                         pdb_set_homedir(to, new_string, PDB_CHANGED);
404                 }
405         }
406
407         if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
408             (from->home_drive.string)) {
409                 old_string = pdb_get_dir_drive(to);
410                 new_string = from->home_drive.string;
411                 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
412                         old_string, new_string));
413                 if (STRING_CHANGED) {
414                         pdb_set_dir_drive(to, new_string, PDB_CHANGED);
415                 }
416         }
417
418         if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
419             (from->logon_script.string)) {
420                 old_string = pdb_get_logon_script(to);
421                 new_string = from->logon_script.string;
422                 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
423                         old_string, new_string));
424                 if (STRING_CHANGED) {
425                         pdb_set_logon_script(to  , new_string, PDB_CHANGED);
426                 }
427         }
428
429         if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
430             (from->profile_path.string)) {
431                 old_string = pdb_get_profile_path(to);
432                 new_string = from->profile_path.string;
433                 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
434                         old_string, new_string));
435                 if (STRING_CHANGED) {
436                         pdb_set_profile_path(to  , new_string, PDB_CHANGED);
437                 }
438         }
439
440         if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
441             (from->description.string)) {
442                 old_string = pdb_get_acct_desc(to);
443                 new_string = from->description.string;
444                 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
445                         old_string, new_string));
446                 if (STRING_CHANGED) {
447                         pdb_set_acct_desc(to, new_string, PDB_CHANGED);
448                 }
449         }
450
451         if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
452             (from->workstations.string)) {
453                 old_string = pdb_get_workstations(to);
454                 new_string = from->workstations.string;
455                 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
456                         old_string, new_string));
457                 if (STRING_CHANGED) {
458                         pdb_set_workstations(to  , new_string, PDB_CHANGED);
459                 }
460         }
461
462         if ((from->fields_present & SAMR_FIELD_COMMENT) &&
463             (from->comment.string)) {
464                 old_string = pdb_get_comment(to);
465                 new_string = from->comment.string;
466                 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
467                         old_string, new_string));
468                 if (STRING_CHANGED) {
469                         pdb_set_comment(to, new_string, PDB_CHANGED);
470                 }
471         }
472
473         if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
474             (from->parameters.array)) {
475                 char *newstr;
476                 DATA_BLOB mung;
477                 old_string = pdb_get_munged_dial(to);
478
479                 mung = data_blob_const(from->parameters.array,
480                                        from->parameters.length);
481                 newstr = (mung.length == 0) ?
482                         NULL : base64_encode_data_blob(talloc_tos(), mung);
483                 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
484                         old_string, newstr));
485                 if (STRING_CHANGED_NC(old_string,newstr)) {
486                         pdb_set_munged_dial(to, newstr, PDB_CHANGED);
487                 }
488
489                 TALLOC_FREE(newstr);
490         }
491
492         if (from->fields_present & SAMR_FIELD_RID) {
493                 if (from->rid == 0) {
494                         DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
495                 } else if (from->rid != pdb_get_user_rid(to)) {
496                         DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
497                                 pdb_get_user_rid(to), from->rid));
498                 }
499         }
500
501         if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
502                 if (from->primary_gid == 0) {
503                         DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
504                 } else if (from->primary_gid != pdb_get_group_rid(to)) {
505                         DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
506                                 pdb_get_group_rid(to), from->primary_gid));
507                         pdb_set_group_sid_from_rid(to,
508                                 from->primary_gid, PDB_CHANGED);
509                 }
510         }
511
512         if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
513                 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
514                         pdb_get_acct_ctrl(to), from->acct_flags));
515                 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
516                         if (!(from->acct_flags & ACB_AUTOLOCK) &&
517                              (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
518                                 /* We're unlocking a previously locked user. Reset bad password counts.
519                                    Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
520                                 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
521                                 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
522                         }
523                         pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
524                 }
525         }
526
527         if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
528                 char oldstr[44]; /* hours strings are 42 bytes. */
529                 char newstr[44];
530                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
531                         pdb_get_logon_divs(to), from->logon_hours.units_per_week));
532                 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
533                         pdb_set_logon_divs(to,
534                                 from->logon_hours.units_per_week, PDB_CHANGED);
535                 }
536
537                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
538                         pdb_get_hours_len(to),
539                         from->logon_hours.units_per_week/8));
540                 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
541                         pdb_set_hours_len(to,
542                                 from->logon_hours.units_per_week/8, PDB_CHANGED);
543                 }
544
545                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
546                         pdb_get_hours(to), from->logon_hours.bits));
547                 pdb_sethexhours(oldstr, pdb_get_hours(to));
548                 pdb_sethexhours(newstr, from->logon_hours.bits);
549                 if (!strequal(oldstr, newstr)) {
550                         pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
551                 }
552         }
553
554         if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
555                 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
556                         pdb_get_bad_password_count(to), from->bad_password_count));
557                 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
558                         pdb_set_bad_password_count(to,
559                                 from->bad_password_count, PDB_CHANGED);
560                 }
561         }
562
563         if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
564                 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
565                         pdb_get_logon_count(to), from->logon_count));
566                 if (from->logon_count != pdb_get_logon_count(to)) {
567                         pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
568                 }
569         }
570
571         /* If the must change flag is set, the last set time goes to zero.
572            the must change and can change fields also do, but they are
573            calculated from policy, not set from the wire */
574
575         if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
576                 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
577                         from->password_expired));
578                 if (from->password_expired != 0) {
579                         pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
580                 } else {
581                         /* A subtlety here: some windows commands will
582                            clear the expired flag even though it's not
583                            set, and we don't want to reset the time
584                            in these caess.  "net user /dom <user> /active:y"
585                            for example, to clear an autolocked acct.
586                            We must check to see if it's expired first. jmcd */
587
588                         uint32_t pwd_max_age = 0;
589                         time_t now = time(NULL);
590
591                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
592
593                         if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
594                                 pwd_max_age = get_time_t_max();
595                         }
596
597                         stored_time = pdb_get_pass_last_set_time(to);
598
599                         /* we will only *set* a pwdlastset date when
600                            a) the last pwdlastset time was 0 (user was forced to
601                               change password).
602                            b) the users password has not expired. gd. */
603
604                         if ((stored_time == 0) ||
605                             ((now - stored_time) > pwd_max_age)) {
606                                 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
607                         }
608                 }
609         }
610 }
611
612
613 /*************************************************************
614  Copies a struct samr_UserInfo23 to a struct samu
615 **************************************************************/
616
617 void copy_id23_to_sam_passwd(struct samu *to,
618                              struct samr_UserInfo23 *from)
619 {
620         if (from == NULL || to == NULL) {
621                 return;
622         }
623
624         copy_id21_to_sam_passwd("INFO 23", to, &from->info);
625 }
626
627 /*************************************************************
628  Copies a struct samr_UserInfo24 to a struct samu
629 **************************************************************/
630
631 void copy_id24_to_sam_passwd(struct samu *to,
632                              struct samr_UserInfo24 *from)
633 {
634         struct samr_UserInfo21 i;
635
636         if (from == NULL || to == NULL) {
637                 return;
638         }
639
640         ZERO_STRUCT(i);
641
642         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
643         i.password_expired      = from->password_expired;
644
645         copy_id21_to_sam_passwd("INFO_24", to, &i);
646 }
647
648 /*************************************************************
649  Copies a struct samr_UserInfo25 to a struct samu
650 **************************************************************/
651
652 void copy_id25_to_sam_passwd(struct samu *to,
653                              struct samr_UserInfo25 *from)
654 {
655         if (from == NULL || to == NULL) {
656                 return;
657         }
658
659         copy_id21_to_sam_passwd("INFO_25", to, &from->info);
660 }
661
662 /*************************************************************
663  Copies a struct samr_UserInfo26 to a struct samu
664 **************************************************************/
665
666 void copy_id26_to_sam_passwd(struct samu *to,
667                              struct samr_UserInfo26 *from)
668 {
669         struct samr_UserInfo21 i;
670
671         if (from == NULL || to == NULL) {
672                 return;
673         }
674
675         ZERO_STRUCT(i);
676
677         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
678         i.password_expired      = from->password_expired;
679
680         copy_id21_to_sam_passwd("INFO_26", to, &i);
681 }