8f136b12165d4846f6edc7cc5b37db699eda64a2
[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                         if (!(from->acct_flags & ACB_AUTOLOCK) &&
538                              (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
539                                 /* We're unlocking a previously locked user. Reset bad password counts.
540                                    Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
541                                 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
542                                 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
543                         }
544                         pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
545                 }
546         }
547
548         if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
549                 char oldstr[44]; /* hours strings are 42 bytes. */
550                 char newstr[44];
551                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
552                         pdb_get_logon_divs(to), from->logon_hours.units_per_week));
553                 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
554                         pdb_set_logon_divs(to,
555                                 from->logon_hours.units_per_week, PDB_CHANGED);
556                 }
557
558                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
559                         pdb_get_hours_len(to),
560                         from->logon_hours.units_per_week/8));
561                 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
562                         pdb_set_hours_len(to,
563                                 from->logon_hours.units_per_week/8, PDB_CHANGED);
564                 }
565
566                 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
567                         pdb_get_hours(to), from->logon_hours.bits));
568                 pdb_sethexhours(oldstr, pdb_get_hours(to));
569                 pdb_sethexhours(newstr, from->logon_hours.bits);
570                 if (!strequal(oldstr, newstr)) {
571                         pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
572                 }
573         }
574
575         if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
576                 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
577                         pdb_get_bad_password_count(to), from->bad_password_count));
578                 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
579                         pdb_set_bad_password_count(to,
580                                 from->bad_password_count, PDB_CHANGED);
581                 }
582         }
583
584         if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
585                 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
586                         pdb_get_logon_count(to), from->logon_count));
587                 if (from->logon_count != pdb_get_logon_count(to)) {
588                         pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
589                 }
590         }
591
592         /* If the must change flag is set, the last set time goes to zero.
593            the must change and can change fields also do, but they are
594            calculated from policy, not set from the wire */
595
596         if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
597                 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
598                         from->password_expired));
599                 if (from->password_expired != 0) {
600                         pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
601                 } else {
602                         /* A subtlety here: some windows commands will
603                            clear the expired flag even though it's not
604                            set, and we don't want to reset the time
605                            in these caess.  "net user /dom <user> /active:y"
606                            for example, to clear an autolocked acct.
607                            We must check to see if it's expired first. jmcd */
608
609                         uint32_t pwd_max_age = 0;
610                         time_t now = time(NULL);
611
612                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
613
614                         if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
615                                 pwd_max_age = get_time_t_max();
616                         }
617
618                         stored_time = pdb_get_pass_last_set_time(to);
619
620                         /* we will only *set* a pwdlastset date when
621                            a) the last pwdlastset time was 0 (user was forced to
622                               change password).
623                            b) the users password has not expired. gd. */
624
625                         if ((stored_time == 0) ||
626                             ((now - stored_time) > pwd_max_age)) {
627                                 pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
628                         }
629                 }
630         }
631 }
632
633
634 /*************************************************************
635  Copies a struct samr_UserInfo23 to a struct samu
636 **************************************************************/
637
638 void copy_id23_to_sam_passwd(struct samu *to,
639                              struct samr_UserInfo23 *from)
640 {
641         if (from == NULL || to == NULL) {
642                 return;
643         }
644
645         copy_id21_to_sam_passwd("INFO 23", to, &from->info);
646 }
647
648 /*************************************************************
649  Copies a struct samr_UserInfo24 to a struct samu
650 **************************************************************/
651
652 void copy_id24_to_sam_passwd(struct samu *to,
653                              struct samr_UserInfo24 *from)
654 {
655         struct samr_UserInfo21 i;
656
657         if (from == NULL || to == NULL) {
658                 return;
659         }
660
661         ZERO_STRUCT(i);
662
663         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
664         i.password_expired      = from->password_expired;
665
666         copy_id21_to_sam_passwd("INFO_24", to, &i);
667 }
668
669 /*************************************************************
670  Copies a struct samr_UserInfo25 to a struct samu
671 **************************************************************/
672
673 void copy_id25_to_sam_passwd(struct samu *to,
674                              struct samr_UserInfo25 *from)
675 {
676         if (from == NULL || to == NULL) {
677                 return;
678         }
679
680         copy_id21_to_sam_passwd("INFO_25", to, &from->info);
681 }
682
683 /*************************************************************
684  Copies a struct samr_UserInfo26 to a struct samu
685 **************************************************************/
686
687 void copy_id26_to_sam_passwd(struct samu *to,
688                              struct samr_UserInfo26 *from)
689 {
690         struct samr_UserInfo21 i;
691
692         if (from == NULL || to == NULL) {
693                 return;
694         }
695
696         ZERO_STRUCT(i);
697
698         i.fields_present        = SAMR_FIELD_EXPIRED_FLAG;
699         i.password_expired      = from->password_expired;
700
701         copy_id21_to_sam_passwd("INFO_26", to, &i);
702 }