3ced15080373246e514df81d768e2412c0330a1c
[ira/wip.git] / source3 / passdb / passdb.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Jeremy Allison                 1996-2001
5    Copyright (C) Luke Kenneth Casson Leighton   1996-1998
6    Copyright (C) Gerald (Jerry) Carter          2000-2006
7    Copyright (C) Andrew Bartlett                2001-2002
8    Copyright (C) Simo Sorce                     2003
9    Copyright (C) Volker Lendecke                2006
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 "../libcli/auth/libcli_auth.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_PASSDB
30
31 /******************************************************************
32  Get the default domain/netbios name to be used when
33  testing authentication.
34
35  LEGACY: this function provides the legacy domain mapping used with
36          the lp_map_untrusted_to_domain() parameter
37 ******************************************************************/
38
39 const char *my_sam_name(void)
40 {
41        /* Standalone servers can only use the local netbios name */
42        if ( lp_server_role() == ROLE_STANDALONE )
43                return global_myname();
44
45        /* Default to the DOMAIN name when not specified */
46        return lp_workgroup();
47 }
48
49 /**********************************************************************
50 ***********************************************************************/
51
52 static int samu_destroy(struct samu *user) 
53 {
54         data_blob_clear_free( &user->lm_pw );
55         data_blob_clear_free( &user->nt_pw );
56
57         if ( user->plaintext_pw )
58                 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
59
60         return 0;
61 }
62
63 /**********************************************************************
64  generate a new struct samuser
65 ***********************************************************************/
66
67 struct samu *samu_new( TALLOC_CTX *ctx )
68 {
69         struct samu *user;
70
71         if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
72                 DEBUG(0,("samuser_new: Talloc failed!\n"));
73                 return NULL;
74         }
75
76         talloc_set_destructor( user, samu_destroy );
77
78         /* no initial methods */
79
80         user->methods = NULL;
81
82         /* Don't change these timestamp settings without a good reason.
83            They are important for NT member server compatibility. */
84
85         user->logon_time            = (time_t)0;
86         user->pass_last_set_time    = (time_t)0;
87         user->pass_can_change_time  = (time_t)0;
88         user->logoff_time           = get_time_t_max();
89         user->kickoff_time          = get_time_t_max();
90         user->pass_must_change_time = get_time_t_max();
91         user->fields_present        = 0x00ffffff;
92         user->logon_divs = 168;         /* hours per week */
93         user->hours_len = 21;           /* 21 times 8 bits = 168 */
94         memset(user->hours, 0xff, user->hours_len); /* available at all hours */
95         user->bad_password_count = 0;
96         user->logon_count = 0;
97         user->unknown_6 = 0x000004ec; /* don't know */
98
99         /* Some parts of samba strlen their pdb_get...() returns, 
100            so this keeps the interface unchanged for now. */
101
102         user->username = "";
103         user->domain = "";
104         user->nt_username = "";
105         user->full_name = "";
106         user->home_dir = "";
107         user->logon_script = "";
108         user->profile_path = "";
109         user->acct_desc = "";
110         user->workstations = "";
111         user->comment = "";
112         user->munged_dial = "";
113
114         user->plaintext_pw = NULL;
115
116         /* Unless we know otherwise have a Account Control Bit
117            value of 'normal user'.  This helps User Manager, which
118            asks for a filtered list of users. */
119
120         user->acct_ctrl = ACB_NORMAL;
121
122         return user;
123 }
124
125 /*********************************************************************
126  Initialize a struct samu from a struct passwd including the user 
127  and group SIDs.  The *user structure is filled out with the Unix
128  attributes and a user SID.
129 *********************************************************************/
130
131 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create)
132 {
133         const char *guest_account = lp_guestaccount();
134         const char *domain = global_myname();
135         uint32 urid;
136
137         if ( !pwd ) {
138                 return NT_STATUS_NO_SUCH_USER;
139         }
140
141         /* Basic properties based upon the Unix account information */
142
143         pdb_set_username(user, pwd->pw_name, PDB_SET);
144         pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
145         pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
146 #if 0
147         /* This can lead to a primary group of S-1-22-2-XX which 
148            will be rejected by other parts of the Samba code. 
149            Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)  
150            --jerry */
151
152         gid_to_sid(&group_sid, pwd->pw_gid);
153         pdb_set_group_sid(user, &group_sid, PDB_SET);
154 #endif
155
156         /* save the password structure for later use */
157
158         user->unix_pw = tcopy_passwd( user, pwd );
159
160         /* Special case for the guest account which must have a RID of 501 */
161
162         if ( strequal( pwd->pw_name, guest_account ) ) {
163                 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
164                         return NT_STATUS_NO_SUCH_USER;
165                 }
166                 return NT_STATUS_OK;
167         }
168
169         /* Non-guest accounts...Check for a workstation or user account */
170
171         if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
172                 /* workstation */
173
174                 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
175                         DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n", 
176                                 pwd->pw_name));
177                         return NT_STATUS_INVALID_COMPUTER_NAME;
178                 }       
179         } 
180         else {
181                 /* user */
182
183                 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
184                         DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", 
185                                 pwd->pw_name));
186                         return NT_STATUS_INVALID_ACCOUNT_NAME;
187                 }
188
189                 /* set some basic attributes */
190
191                 pdb_set_profile_path(user, talloc_sub_specified(user, 
192                         lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 
193                         PDB_DEFAULT);           
194                 pdb_set_homedir(user, talloc_sub_specified(user, 
195                         lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
196                         PDB_DEFAULT);
197                 pdb_set_dir_drive(user, talloc_sub_specified(user, 
198                         lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
199                         PDB_DEFAULT);
200                 pdb_set_logon_script(user, talloc_sub_specified(user, 
201                         lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), 
202                         PDB_DEFAULT);
203         }
204
205         /* Now deal with the user SID.  If we have a backend that can generate 
206            RIDs, then do so.  But sometimes the caller just wanted a structure 
207            initialized and will fill in these fields later (such as from a 
208            netr_SamInfo3 structure) */
209
210         if ( create && (pdb_capabilities() & PDB_CAP_STORE_RIDS)) {
211                 uint32 user_rid;
212                 DOM_SID user_sid;
213
214                 if ( !pdb_new_rid( &user_rid ) ) {
215                         DEBUG(3, ("Could not allocate a new RID\n"));
216                         return NT_STATUS_ACCESS_DENIED;
217                 }
218
219                 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
220
221                 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
222                         DEBUG(3, ("pdb_set_user_sid failed\n"));
223                         return NT_STATUS_INTERNAL_ERROR;
224                 }
225
226                 return NT_STATUS_OK;
227         }
228
229         /* generate a SID for the user with the RID algorithm */
230
231         urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
232
233         if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
234                 return NT_STATUS_INTERNAL_ERROR;
235         }
236
237         return NT_STATUS_OK;
238 }
239
240 /********************************************************************
241  Set the Unix user attributes
242 ********************************************************************/
243
244 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
245 {
246         return samu_set_unix_internal( user, pwd, False );
247 }
248
249 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
250 {
251         return samu_set_unix_internal( user, pwd, True );
252 }
253
254 /**********************************************************
255  Encode the account control bits into a string.
256  length = length of string to encode into (including terminating
257  null). length *MUST BE MORE THAN 2* !
258  **********************************************************/
259
260 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
261 {
262         fstring acct_str;
263         char *result;
264
265         size_t i = 0;
266
267         SMB_ASSERT(length <= sizeof(acct_str));
268
269         acct_str[i++] = '[';
270
271         if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
272         if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
273         if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
274         if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
275         if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
276         if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
277         if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
278         if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
279         if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
280         if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
281         if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
282
283         for ( ; i < length - 2 ; i++ )
284                 acct_str[i] = ' ';
285
286         i = length - 2;
287         acct_str[i++] = ']';
288         acct_str[i++] = '\0';
289
290         result = talloc_strdup(talloc_tos(), acct_str);
291         SMB_ASSERT(result != NULL);
292         return result;
293 }     
294
295 /**********************************************************
296  Decode the account control bits from a string.
297  **********************************************************/
298
299 uint32_t pdb_decode_acct_ctrl(const char *p)
300 {
301         uint32_t acct_ctrl = 0;
302         bool finished = false;
303
304         /*
305          * Check if the account type bits have been encoded after the
306          * NT password (in the form [NDHTUWSLXI]).
307          */
308
309         if (*p != '[')
310                 return 0;
311
312         for (p++; *p && !finished; p++) {
313                 switch (*p) {
314                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
315                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
316                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
317                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
318                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
319                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
320                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
321                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
322                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
323                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
324                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
325             case ' ': { break; }
326                         case ':':
327                         case '\n':
328                         case '\0': 
329                         case ']':
330                         default:  { finished = true; }
331                 }
332         }
333
334         return acct_ctrl;
335 }
336
337 /*************************************************************
338  Routine to set 32 hex password characters from a 16 byte array.
339 **************************************************************/
340
341 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32 acct_ctrl)
342 {
343         if (pwd != NULL) {
344                 int i;
345                 for (i = 0; i < 16; i++)
346                         slprintf(&p[i*2], 3, "%02X", pwd[i]);
347         } else {
348                 if (acct_ctrl & ACB_PWNOTREQ)
349                         safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
350                 else
351                         safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
352         }
353 }
354
355 /*************************************************************
356  Routine to get the 32 hex characters and turn them
357  into a 16 byte array.
358 **************************************************************/
359
360 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
361 {
362         int i;
363         unsigned char   lonybble, hinybble;
364         const char      *hexchars = "0123456789ABCDEF";
365         char           *p1, *p2;
366
367         if (!p)
368                 return false;
369
370         for (i = 0; i < 32; i += 2) {
371                 hinybble = toupper_ascii(p[i]);
372                 lonybble = toupper_ascii(p[i + 1]);
373
374                 p1 = strchr(hexchars, hinybble);
375                 p2 = strchr(hexchars, lonybble);
376
377                 if (!p1 || !p2)
378                         return false;
379
380                 hinybble = PTR_DIFF(p1, hexchars);
381                 lonybble = PTR_DIFF(p2, hexchars);
382
383                 pwd[i / 2] = (hinybble << 4) | lonybble;
384         }
385         return true;
386 }
387
388 /*************************************************************
389  Routine to set 42 hex hours characters from a 21 byte array.
390 **************************************************************/
391
392 void pdb_sethexhours(char *p, const unsigned char *hours)
393 {
394         if (hours != NULL) {
395                 int i;
396                 for (i = 0; i < 21; i++) {
397                         slprintf(&p[i*2], 3, "%02X", hours[i]);
398                 }
399         } else {
400                 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
401         }
402 }
403
404 /*************************************************************
405  Routine to get the 42 hex characters and turn them
406  into a 21 byte array.
407 **************************************************************/
408
409 bool pdb_gethexhours(const char *p, unsigned char *hours)
410 {
411         int i;
412         unsigned char   lonybble, hinybble;
413         const char      *hexchars = "0123456789ABCDEF";
414         char           *p1, *p2;
415
416         if (!p) {
417                 return (False);
418         }
419
420         for (i = 0; i < 42; i += 2) {
421                 hinybble = toupper_ascii(p[i]);
422                 lonybble = toupper_ascii(p[i + 1]);
423
424                 p1 = strchr(hexchars, hinybble);
425                 p2 = strchr(hexchars, lonybble);
426
427                 if (!p1 || !p2) {
428                         return (False);
429                 }
430
431                 hinybble = PTR_DIFF(p1, hexchars);
432                 lonybble = PTR_DIFF(p2, hexchars);
433
434                 hours[i / 2] = (hinybble << 4) | lonybble;
435         }
436         return (True);
437 }
438
439 /********************************************************************
440 ********************************************************************/
441
442 int algorithmic_rid_base(void)
443 {
444         int rid_offset;
445
446         rid_offset = lp_algorithmic_rid_base();
447
448         if (rid_offset < BASE_RID) {  
449                 /* Try to prevent admin foot-shooting, we can't put algorithmic
450                    rids below 1000, that's the 'well known RIDs' on NT */
451                 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
452                 rid_offset = BASE_RID;
453         }
454         if (rid_offset & 1) {
455                 DEBUG(0, ("algorithmic rid base must be even\n"));
456                 rid_offset += 1;
457         }
458         return rid_offset;
459 }
460
461 /*******************************************************************
462  Converts NT user RID to a UNIX uid.
463  ********************************************************************/
464
465 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
466 {
467         int rid_offset = algorithmic_rid_base();
468         return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
469 }
470
471 uid_t max_algorithmic_uid(void)
472 {
473         return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
474 }
475
476 /*******************************************************************
477  converts UNIX uid to an NT User RID.
478  ********************************************************************/
479
480 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
481 {
482         int rid_offset = algorithmic_rid_base();
483         return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
484 }
485
486 /*******************************************************************
487  Converts NT group RID to a UNIX gid.
488  ********************************************************************/
489
490 gid_t pdb_group_rid_to_gid(uint32 group_rid)
491 {
492         int rid_offset = algorithmic_rid_base();
493         return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
494 }
495
496 gid_t max_algorithmic_gid(void)
497 {
498         return pdb_group_rid_to_gid(0xffffffff);
499 }
500
501 /*******************************************************************
502  converts NT Group RID to a UNIX uid.
503  
504  warning: you must not call that function only
505  you must do a call to the group mapping first.
506  there is not anymore a direct link between the gid and the rid.
507  ********************************************************************/
508
509 uint32 algorithmic_pdb_gid_to_group_rid(gid_t gid)
510 {
511         int rid_offset = algorithmic_rid_base();
512         return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
513 }
514
515 /*******************************************************************
516  Decides if a RID is a well known RID.
517  ********************************************************************/
518
519 static bool rid_is_well_known(uint32 rid)
520 {
521         /* Not using rid_offset here, because this is the actual
522            NT fixed value (1000) */
523
524         return (rid < BASE_RID);
525 }
526
527 /*******************************************************************
528  Decides if a RID is a user or group RID.
529  ********************************************************************/
530
531 bool algorithmic_pdb_rid_is_user(uint32 rid)
532 {
533         if ( rid_is_well_known(rid) ) {
534                 /*
535                  * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
536                  * and DOMAIN_USER_RID_GUEST.
537                  */
538                 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
539                         return True;
540         } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
541                 return True;
542         }
543         return False;
544 }
545
546 /*******************************************************************
547  Convert a name into a SID. Used in the lookup name rpc.
548  ********************************************************************/
549
550 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
551                             enum lsa_SidType *type)
552 {
553         GROUP_MAP map;
554         bool ret;
555
556         /* Windows treats "MACHINE\None" as a special name for 
557            rid 513 on non-DCs.  You cannot create a user or group
558            name "None" on Windows.  You will get an error that 
559            the group already exists. */
560
561         if ( strequal( name, "None" ) ) {
562                 *rid = DOMAIN_GROUP_RID_USERS;
563                 *type = SID_NAME_DOM_GRP;
564
565                 return True;
566         }
567
568         /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
569          * correctly in the case where foo also exists as a user. If the flag
570          * is set, don't look for users at all. */
571
572         if ((flags & LOOKUP_NAME_GROUP) == 0) {
573                 struct samu *sam_account = NULL;
574                 DOM_SID user_sid;
575
576                 if ( !(sam_account = samu_new( NULL )) ) {
577                         return False;
578                 }
579
580                 become_root();
581                 ret =  pdb_getsampwnam(sam_account, name);
582                 unbecome_root();
583
584                 if (ret) {
585                         sid_copy(&user_sid, pdb_get_user_sid(sam_account));
586                 }
587
588                 TALLOC_FREE(sam_account);
589
590                 if (ret) {
591                         if (!sid_check_is_in_our_domain(&user_sid)) {
592                                 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
593                                           name, sid_string_dbg(&user_sid)));
594                                 return False;
595                         }
596
597                         sid_peek_rid(&user_sid, rid);
598                         *type = SID_NAME_USER;
599                         return True;
600                 }
601         }
602
603         /*
604          * Maybe it is a group ?
605          */
606
607         become_root();
608         ret = pdb_getgrnam(&map, name);
609         unbecome_root();
610
611         if (!ret) {
612                 return False;
613         }
614
615         /* BUILTIN groups are looked up elsewhere */
616         if (!sid_check_is_in_our_domain(&map.sid)) {
617                 DEBUG(10, ("Found group %s (%s) not in our domain -- "
618                            "ignoring.", name, sid_string_dbg(&map.sid)));
619                 return False;
620         }
621
622         /* yes it's a mapped group */
623         sid_peek_rid(&map.sid, rid);
624         *type = map.sid_name_use;
625         return True;
626 }
627
628 /*************************************************************
629  Change a password entry in the local passdb backend.
630
631  Assumptions:
632   - always called as root
633   - ignores the account type except when adding a new account
634   - will create/delete the unix account if the relative
635     add/delete user script is configured
636
637  *************************************************************/
638
639 NTSTATUS local_password_change(const char *user_name,
640                                 int local_flags,
641                                 const char *new_passwd, 
642                                 char **pp_err_str,
643                                 char **pp_msg_str)
644 {
645         TALLOC_CTX *tosctx;
646         struct samu *sam_pass;
647         uint32_t acb;
648         uint32_t rid;
649         NTSTATUS result;
650         bool user_exists;
651         int ret = -1;
652
653         *pp_err_str = NULL;
654         *pp_msg_str = NULL;
655
656         tosctx = talloc_tos();
657
658         sam_pass = samu_new(tosctx);
659         if (!sam_pass) {
660                 result = NT_STATUS_NO_MEMORY;
661                 goto done;
662         }
663
664         /* Get the smb passwd entry for this user */
665         user_exists = pdb_getsampwnam(sam_pass, user_name);
666
667         /* Check delete first, we don't need to do anything else if we
668          * are going to delete the acocunt */
669         if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
670
671                 result = pdb_delete_user(tosctx, sam_pass);
672                 if (!NT_STATUS_IS_OK(result)) {
673                         ret = asprintf(pp_err_str,
674                                         "Failed to delete entry for user %s.\n",
675                                         user_name);
676                         if (ret < 0) {
677                                 *pp_err_str = NULL;
678                         }
679                         result = NT_STATUS_UNSUCCESSFUL;
680                 } else {
681                         ret = asprintf(pp_msg_str,
682                                         "Deleted user %s.\n",
683                                         user_name);
684                         if (ret < 0) {
685                                 *pp_msg_str = NULL;
686                         }
687                 }
688                 goto done;
689         }
690
691         if (user_exists && (local_flags & LOCAL_ADD_USER)) {
692                 /* the entry already existed */
693                 local_flags &= ~LOCAL_ADD_USER;
694         }
695
696         if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
697                 ret = asprintf(pp_err_str,
698                                 "Failed to find entry for user %s.\n",
699                                 user_name);
700                 if (ret < 0) {
701                         *pp_err_str = NULL;
702                 }
703                 result = NT_STATUS_NO_SUCH_USER;
704                 goto done;
705         }
706
707         /* First thing add the new user if we are required to do so */
708         if (local_flags & LOCAL_ADD_USER) {
709
710                 if (local_flags & LOCAL_TRUST_ACCOUNT) {
711                         acb = ACB_WSTRUST;
712                 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
713                         acb = ACB_DOMTRUST;
714                 } else {
715                         acb = ACB_NORMAL;
716                 }
717
718                 result = pdb_create_user(tosctx, user_name, acb, &rid);
719                 if (!NT_STATUS_IS_OK(result)) {
720                         ret = asprintf(pp_err_str,
721                                         "Failed to add entry for user %s.\n",
722                                         user_name);
723                         if (ret < 0) {
724                                 *pp_err_str = NULL;
725                         }
726                         result = NT_STATUS_UNSUCCESSFUL;
727                         goto done;
728                 }
729
730                 sam_pass = samu_new(tosctx);
731                 if (!sam_pass) {
732                         result = NT_STATUS_NO_MEMORY;
733                         goto done;
734                 }
735
736                 /* Now get back the smb passwd entry for this new user */
737                 user_exists = pdb_getsampwnam(sam_pass, user_name);
738                 if (!user_exists) {
739                         ret = asprintf(pp_err_str,
740                                         "Failed to add entry for user %s.\n",
741                                         user_name);
742                         if (ret < 0) {
743                                 *pp_err_str = NULL;
744                         }
745                         result = NT_STATUS_UNSUCCESSFUL;
746                         goto done;
747                 }
748         }
749
750         acb = pdb_get_acct_ctrl(sam_pass);
751
752         /*
753          * We are root - just write the new password
754          * and the valid last change time.
755          */
756         if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
757                 acb |= ACB_PWNOTREQ;
758                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
759                         ret = asprintf(pp_err_str,
760                                         "Failed to set 'no password required' "
761                                         "flag for user %s.\n", user_name);
762                         if (ret < 0) {
763                                 *pp_err_str = NULL;
764                         }
765                         result = NT_STATUS_UNSUCCESSFUL;
766                         goto done;
767                 }
768         }
769
770         if (local_flags & LOCAL_SET_PASSWORD) {
771                 /*
772                  * If we're dealing with setting a completely empty user account
773                  * ie. One with a password of 'XXXX', but not set disabled (like
774                  * an account created from scratch) then if the old password was
775                  * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
776                  * We remove that as we're giving this user their first password
777                  * and the decision hasn't really been made to disable them (ie.
778                  * don't create them disabled). JRA.
779                  */
780                 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
781                     (acb & ACB_DISABLED)) {
782                         acb &= (~ACB_DISABLED);
783                         if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
784                                 ret = asprintf(pp_err_str,
785                                                 "Failed to unset 'disabled' "
786                                                 "flag for user %s.\n",
787                                                 user_name);
788                                 if (ret < 0) {
789                                         *pp_err_str = NULL;
790                                 }
791                                 result = NT_STATUS_UNSUCCESSFUL;
792                                 goto done;
793                         }
794                 }
795
796                 acb &= (~ACB_PWNOTREQ);
797                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
798                         ret = asprintf(pp_err_str,
799                                         "Failed to unset 'no password required'"
800                                         " flag for user %s.\n", user_name);
801                         if (ret < 0) {
802                                 *pp_err_str = NULL;
803                         }
804                         result = NT_STATUS_UNSUCCESSFUL;
805                         goto done;
806                 }
807
808                 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
809                         ret = asprintf(pp_err_str,
810                                         "Failed to set password for "
811                                         "user %s.\n", user_name);
812                                 if (ret < 0) {
813                                 *pp_err_str = NULL;
814                         }
815                         result = NT_STATUS_UNSUCCESSFUL;
816                         goto done;
817                 }
818         }
819
820         if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
821                 acb |= ACB_DISABLED;
822                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
823                         ret = asprintf(pp_err_str,
824                                         "Failed to set 'disabled' flag for "
825                                         "user %s.\n", user_name);
826                         if (ret < 0) {
827                                 *pp_err_str = NULL;
828                         }
829                         result = NT_STATUS_UNSUCCESSFUL;
830                         goto done;
831                 }
832         }
833
834         if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
835                 acb &= (~ACB_DISABLED);
836                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
837                         ret = asprintf(pp_err_str,
838                                         "Failed to unset 'disabled' flag for "
839                                         "user %s.\n", user_name);
840                         if (ret < 0) {
841                                 *pp_err_str = NULL;
842                         }
843                         result = NT_STATUS_UNSUCCESSFUL;
844                         goto done;
845                 }
846         }
847
848         /* now commit changes if any */
849         result = pdb_update_sam_account(sam_pass);
850         if (!NT_STATUS_IS_OK(result)) {
851                 ret = asprintf(pp_err_str,
852                                 "Failed to modify entry for user %s.\n",
853                                 user_name);
854                 if (ret < 0) {
855                         *pp_err_str = NULL;
856                 }
857                 goto done;
858         }
859
860         if (local_flags & LOCAL_ADD_USER) {
861                 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
862         } else if (local_flags & LOCAL_DISABLE_USER) {
863                 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
864         } else if (local_flags & LOCAL_ENABLE_USER) {
865                 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
866         } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
867                 ret = asprintf(pp_msg_str,
868                                 "User %s password set to none.\n", user_name);
869         }
870
871         if (ret < 0) {
872                 *pp_msg_str = NULL;
873         }
874
875         result = NT_STATUS_OK;
876
877 done:
878         TALLOC_FREE(sam_pass);
879         return result;
880 }
881
882 /**********************************************************************
883  Marshall/unmarshall struct samu structs.
884  *********************************************************************/
885
886 #define SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
887 #define SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
888 #define SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
889 #define SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
890 /* nothing changed between V3 and V4 */
891
892 /*********************************************************************
893 *********************************************************************/
894
895 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen)
896 {
897
898         /* times are stored as 32bit integer
899            take care on system with 64bit wide time_t
900            --SSS */
901         uint32  logon_time,
902                 logoff_time,
903                 kickoff_time,
904                 pass_last_set_time,
905                 pass_can_change_time,
906                 pass_must_change_time;
907         char *username = NULL;
908         char *domain = NULL;
909         char *nt_username = NULL;
910         char *dir_drive = NULL;
911         char *unknown_str = NULL;
912         char *munged_dial = NULL;
913         char *fullname = NULL;
914         char *homedir = NULL;
915         char *logon_script = NULL;
916         char *profile_path = NULL;
917         char *acct_desc = NULL;
918         char *workstations = NULL;
919         uint32  username_len, domain_len, nt_username_len,
920                 dir_drive_len, unknown_str_len, munged_dial_len,
921                 fullname_len, homedir_len, logon_script_len,
922                 profile_path_len, acct_desc_len, workstations_len;
923
924         uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
925         uint16  acct_ctrl, logon_divs;
926         uint16  bad_password_count, logon_count;
927         uint8   *hours = NULL;
928         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
929         uint32          len = 0;
930         uint32          lm_pw_len, nt_pw_len, hourslen;
931         bool ret = True;
932
933         if(sampass == NULL || buf == NULL) {
934                 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
935                 return False;
936         }
937
938 /* SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
939
940         /* unpack the buffer into variables */
941         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
942                 &logon_time,                                            /* d */
943                 &logoff_time,                                           /* d */
944                 &kickoff_time,                                          /* d */
945                 &pass_last_set_time,                                    /* d */
946                 &pass_can_change_time,                                  /* d */
947                 &pass_must_change_time,                                 /* d */
948                 &username_len, &username,                               /* B */
949                 &domain_len, &domain,                                   /* B */
950                 &nt_username_len, &nt_username,                         /* B */
951                 &fullname_len, &fullname,                               /* B */
952                 &homedir_len, &homedir,                                 /* B */
953                 &dir_drive_len, &dir_drive,                             /* B */
954                 &logon_script_len, &logon_script,                       /* B */
955                 &profile_path_len, &profile_path,                       /* B */
956                 &acct_desc_len, &acct_desc,                             /* B */
957                 &workstations_len, &workstations,                       /* B */
958                 &unknown_str_len, &unknown_str,                         /* B */
959                 &munged_dial_len, &munged_dial,                         /* B */
960                 &user_rid,                                              /* d */
961                 &group_rid,                                             /* d */
962                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
963                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
964                 &acct_ctrl,                                             /* w */
965                 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
966                 &logon_divs,                                            /* w */
967                 &hours_len,                                             /* d */
968                 &hourslen, &hours,                                      /* B */
969                 &bad_password_count,                                    /* w */
970                 &logon_count,                                           /* w */
971                 &unknown_6);                                            /* d */
972
973         if (len == (uint32) -1)  {
974                 ret = False;
975                 goto done;
976         }
977
978         pdb_set_logon_time(sampass, logon_time, PDB_SET);
979         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
980         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
981         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
982         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
983         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
984
985         pdb_set_username(sampass, username, PDB_SET); 
986         pdb_set_domain(sampass, domain, PDB_SET);
987         pdb_set_nt_username(sampass, nt_username, PDB_SET);
988         pdb_set_fullname(sampass, fullname, PDB_SET);
989
990         if (homedir) {
991                 pdb_set_homedir(sampass, homedir, PDB_SET);
992         }
993         else {
994                 pdb_set_homedir(sampass, 
995                         talloc_sub_basic(sampass, username, domain,
996                                          lp_logon_home()),
997                         PDB_DEFAULT);
998         }
999
1000         if (dir_drive)  
1001                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1002         else {
1003                 pdb_set_dir_drive(sampass, 
1004                         talloc_sub_basic(sampass, username, domain,
1005                                          lp_logon_drive()),
1006                         PDB_DEFAULT);
1007         }
1008
1009         if (logon_script) 
1010                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1011         else {
1012                 pdb_set_logon_script(sampass, 
1013                         talloc_sub_basic(sampass, username, domain,
1014                                          lp_logon_script()),
1015                         PDB_DEFAULT);
1016         }
1017
1018         if (profile_path) {     
1019                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1020         } else {
1021                 pdb_set_profile_path(sampass, 
1022                         talloc_sub_basic(sampass, username, domain,
1023                                          lp_logon_path()),
1024                         PDB_DEFAULT);
1025         }
1026
1027         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1028         pdb_set_workstations(sampass, workstations, PDB_SET);
1029         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1030
1031         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1032                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1033                         ret = False;
1034                         goto done;
1035                 }
1036         }
1037
1038         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1039                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1040                         ret = False;
1041                         goto done;
1042                 }
1043         }
1044
1045         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1046         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1047         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1048         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1049         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1050         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1051         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1052         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1053         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1054         pdb_set_hours(sampass, hours, PDB_SET);
1055
1056 done:
1057
1058         SAFE_FREE(username);
1059         SAFE_FREE(domain);
1060         SAFE_FREE(nt_username);
1061         SAFE_FREE(fullname);
1062         SAFE_FREE(homedir);
1063         SAFE_FREE(dir_drive);
1064         SAFE_FREE(logon_script);
1065         SAFE_FREE(profile_path);
1066         SAFE_FREE(acct_desc);
1067         SAFE_FREE(workstations);
1068         SAFE_FREE(munged_dial);
1069         SAFE_FREE(unknown_str);
1070         SAFE_FREE(lm_pw_ptr);
1071         SAFE_FREE(nt_pw_ptr);
1072         SAFE_FREE(hours);
1073
1074         return ret;
1075 }
1076
1077 /*********************************************************************
1078 *********************************************************************/
1079
1080 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen)
1081 {
1082
1083         /* times are stored as 32bit integer
1084            take care on system with 64bit wide time_t
1085            --SSS */
1086         uint32  logon_time,
1087                 logoff_time,
1088                 kickoff_time,
1089                 bad_password_time,
1090                 pass_last_set_time,
1091                 pass_can_change_time,
1092                 pass_must_change_time;
1093         char *username = NULL;
1094         char *domain = NULL;
1095         char *nt_username = NULL;
1096         char *dir_drive = NULL;
1097         char *unknown_str = NULL;
1098         char *munged_dial = NULL;
1099         char *fullname = NULL;
1100         char *homedir = NULL;
1101         char *logon_script = NULL;
1102         char *profile_path = NULL;
1103         char *acct_desc = NULL;
1104         char *workstations = NULL;
1105         uint32  username_len, domain_len, nt_username_len,
1106                 dir_drive_len, unknown_str_len, munged_dial_len,
1107                 fullname_len, homedir_len, logon_script_len,
1108                 profile_path_len, acct_desc_len, workstations_len;
1109
1110         uint32  user_rid, group_rid, remove_me, hours_len, unknown_6;
1111         uint16  acct_ctrl, logon_divs;
1112         uint16  bad_password_count, logon_count;
1113         uint8   *hours = NULL;
1114         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1115         uint32          len = 0;
1116         uint32          lm_pw_len, nt_pw_len, hourslen;
1117         bool ret = True;
1118
1119         if(sampass == NULL || buf == NULL) {
1120                 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1121                 return False;
1122         }
1123
1124 /* SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1125
1126         /* unpack the buffer into variables */
1127         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1128                 &logon_time,                                            /* d */
1129                 &logoff_time,                                           /* d */
1130                 &kickoff_time,                                          /* d */
1131                 /* Change from V0 is addition of bad_password_time field. */
1132                 &bad_password_time,                                     /* d */
1133                 &pass_last_set_time,                                    /* d */
1134                 &pass_can_change_time,                                  /* d */
1135                 &pass_must_change_time,                                 /* d */
1136                 &username_len, &username,                               /* B */
1137                 &domain_len, &domain,                                   /* B */
1138                 &nt_username_len, &nt_username,                         /* B */
1139                 &fullname_len, &fullname,                               /* B */
1140                 &homedir_len, &homedir,                                 /* B */
1141                 &dir_drive_len, &dir_drive,                             /* B */
1142                 &logon_script_len, &logon_script,                       /* B */
1143                 &profile_path_len, &profile_path,                       /* B */
1144                 &acct_desc_len, &acct_desc,                             /* B */
1145                 &workstations_len, &workstations,                       /* B */
1146                 &unknown_str_len, &unknown_str,                         /* B */
1147                 &munged_dial_len, &munged_dial,                         /* B */
1148                 &user_rid,                                              /* d */
1149                 &group_rid,                                             /* d */
1150                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1151                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1152                 &acct_ctrl,                                             /* w */
1153                 &remove_me,                                             /* d */
1154                 &logon_divs,                                            /* w */
1155                 &hours_len,                                             /* d */
1156                 &hourslen, &hours,                                      /* B */
1157                 &bad_password_count,                                    /* w */
1158                 &logon_count,                                           /* w */
1159                 &unknown_6);                                            /* d */
1160
1161         if (len == (uint32) -1)  {
1162                 ret = False;
1163                 goto done;
1164         }
1165
1166         pdb_set_logon_time(sampass, logon_time, PDB_SET);
1167         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1168         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1169
1170         /* Change from V0 is addition of bad_password_time field. */
1171         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1172         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1173         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1174         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1175
1176         pdb_set_username(sampass, username, PDB_SET); 
1177         pdb_set_domain(sampass, domain, PDB_SET);
1178         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1179         pdb_set_fullname(sampass, fullname, PDB_SET);
1180
1181         if (homedir) {
1182                 pdb_set_homedir(sampass, homedir, PDB_SET);
1183         }
1184         else {
1185                 pdb_set_homedir(sampass, 
1186                         talloc_sub_basic(sampass, username, domain,
1187                                          lp_logon_home()),
1188                         PDB_DEFAULT);
1189         }
1190
1191         if (dir_drive)  
1192                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1193         else {
1194                 pdb_set_dir_drive(sampass, 
1195                         talloc_sub_basic(sampass, username, domain,
1196                                          lp_logon_drive()),
1197                         PDB_DEFAULT);
1198         }
1199
1200         if (logon_script) 
1201                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1202         else {
1203                 pdb_set_logon_script(sampass, 
1204                         talloc_sub_basic(sampass, username, domain,
1205                                          lp_logon_script()),
1206                         PDB_DEFAULT);
1207         }
1208
1209         if (profile_path) {     
1210                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1211         } else {
1212                 pdb_set_profile_path(sampass, 
1213                         talloc_sub_basic(sampass, username, domain,
1214                                          lp_logon_path()),
1215                         PDB_DEFAULT);
1216         }
1217
1218         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1219         pdb_set_workstations(sampass, workstations, PDB_SET);
1220         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1221
1222         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1223                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1224                         ret = False;
1225                         goto done;
1226                 }
1227         }
1228
1229         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1230                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1231                         ret = False;
1232                         goto done;
1233                 }
1234         }
1235
1236         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1237
1238         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1239         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1240         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1241         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1242         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1243         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1244         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1245         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1246         pdb_set_hours(sampass, hours, PDB_SET);
1247
1248 done:
1249
1250         SAFE_FREE(username);
1251         SAFE_FREE(domain);
1252         SAFE_FREE(nt_username);
1253         SAFE_FREE(fullname);
1254         SAFE_FREE(homedir);
1255         SAFE_FREE(dir_drive);
1256         SAFE_FREE(logon_script);
1257         SAFE_FREE(profile_path);
1258         SAFE_FREE(acct_desc);
1259         SAFE_FREE(workstations);
1260         SAFE_FREE(munged_dial);
1261         SAFE_FREE(unknown_str);
1262         SAFE_FREE(lm_pw_ptr);
1263         SAFE_FREE(nt_pw_ptr);
1264         SAFE_FREE(hours);
1265
1266         return ret;
1267 }
1268
1269 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
1270 {
1271
1272         /* times are stored as 32bit integer
1273            take care on system with 64bit wide time_t
1274            --SSS */
1275         uint32  logon_time,
1276                 logoff_time,
1277                 kickoff_time,
1278                 bad_password_time,
1279                 pass_last_set_time,
1280                 pass_can_change_time,
1281                 pass_must_change_time;
1282         char *username = NULL;
1283         char *domain = NULL;
1284         char *nt_username = NULL;
1285         char *dir_drive = NULL;
1286         char *unknown_str = NULL;
1287         char *munged_dial = NULL;
1288         char *fullname = NULL;
1289         char *homedir = NULL;
1290         char *logon_script = NULL;
1291         char *profile_path = NULL;
1292         char *acct_desc = NULL;
1293         char *workstations = NULL;
1294         uint32  username_len, domain_len, nt_username_len,
1295                 dir_drive_len, unknown_str_len, munged_dial_len,
1296                 fullname_len, homedir_len, logon_script_len,
1297                 profile_path_len, acct_desc_len, workstations_len;
1298
1299         uint32  user_rid, group_rid, hours_len, unknown_6;
1300         uint16  acct_ctrl, logon_divs;
1301         uint16  bad_password_count, logon_count;
1302         uint8   *hours = NULL;
1303         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1304         uint32          len = 0;
1305         uint32          lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1306         uint32 pwHistLen = 0;
1307         bool ret = True;
1308         fstring tmp_string;
1309         bool expand_explicit = lp_passdb_expand_explicit();
1310
1311         if(sampass == NULL || buf == NULL) {
1312                 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1313                 return False;
1314         }
1315
1316 /* SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1317
1318         /* unpack the buffer into variables */
1319         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1320                 &logon_time,                                            /* d */
1321                 &logoff_time,                                           /* d */
1322                 &kickoff_time,                                          /* d */
1323                 &bad_password_time,                                     /* d */
1324                 &pass_last_set_time,                                    /* d */
1325                 &pass_can_change_time,                                  /* d */
1326                 &pass_must_change_time,                                 /* d */
1327                 &username_len, &username,                               /* B */
1328                 &domain_len, &domain,                                   /* B */
1329                 &nt_username_len, &nt_username,                         /* B */
1330                 &fullname_len, &fullname,                               /* B */
1331                 &homedir_len, &homedir,                                 /* B */
1332                 &dir_drive_len, &dir_drive,                             /* B */
1333                 &logon_script_len, &logon_script,                       /* B */
1334                 &profile_path_len, &profile_path,                       /* B */
1335                 &acct_desc_len, &acct_desc,                             /* B */
1336                 &workstations_len, &workstations,                       /* B */
1337                 &unknown_str_len, &unknown_str,                         /* B */
1338                 &munged_dial_len, &munged_dial,                         /* B */
1339                 &user_rid,                                              /* d */
1340                 &group_rid,                                             /* d */
1341                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1342                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1343                 /* Change from V1 is addition of password history field. */
1344                 &nt_pw_hist_len, &nt_pw_hist_ptr,                       /* B */
1345                 &acct_ctrl,                                             /* w */
1346                 /* Also "remove_me" field was removed. */
1347                 &logon_divs,                                            /* w */
1348                 &hours_len,                                             /* d */
1349                 &hourslen, &hours,                                      /* B */
1350                 &bad_password_count,                                    /* w */
1351                 &logon_count,                                           /* w */
1352                 &unknown_6);                                            /* d */
1353
1354         if (len == (uint32) -1)  {
1355                 ret = False;
1356                 goto done;
1357         }
1358
1359         pdb_set_logon_time(sampass, logon_time, PDB_SET);
1360         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1361         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1362         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1363         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1364         pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1365         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1366
1367         pdb_set_username(sampass, username, PDB_SET); 
1368         pdb_set_domain(sampass, domain, PDB_SET);
1369         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1370         pdb_set_fullname(sampass, fullname, PDB_SET);
1371
1372         if (homedir) {
1373                 fstrcpy( tmp_string, homedir );
1374                 if (expand_explicit) {
1375                         standard_sub_basic( username, domain, tmp_string,
1376                                             sizeof(tmp_string) );
1377                 }
1378                 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1379         }
1380         else {
1381                 pdb_set_homedir(sampass, 
1382                         talloc_sub_basic(sampass, username, domain,
1383                                          lp_logon_home()),
1384                         PDB_DEFAULT);
1385         }
1386
1387         if (dir_drive)  
1388                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1389         else
1390                 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1391
1392         if (logon_script) {
1393                 fstrcpy( tmp_string, logon_script );
1394                 if (expand_explicit) {
1395                         standard_sub_basic( username, domain, tmp_string,
1396                                             sizeof(tmp_string) );
1397                 }
1398                 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1399         }
1400         else {
1401                 pdb_set_logon_script(sampass, 
1402                         talloc_sub_basic(sampass, username, domain,
1403                                          lp_logon_script()),
1404                         PDB_DEFAULT);
1405         }
1406
1407         if (profile_path) {     
1408                 fstrcpy( tmp_string, profile_path );
1409                 if (expand_explicit) {
1410                         standard_sub_basic( username, domain, tmp_string,
1411                                             sizeof(tmp_string) );
1412                 }
1413                 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1414         } 
1415         else {
1416                 pdb_set_profile_path(sampass, 
1417                         talloc_sub_basic(sampass, username, domain,
1418                                          lp_logon_path()),
1419                         PDB_DEFAULT);
1420         }
1421
1422         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1423         pdb_set_workstations(sampass, workstations, PDB_SET);
1424         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1425
1426         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1427                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1428                         ret = False;
1429                         goto done;
1430                 }
1431         }
1432
1433         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1434                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1435                         ret = False;
1436                         goto done;
1437                 }
1438         }
1439
1440         /* Change from V1 is addition of password history field. */
1441         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1442         if (pwHistLen) {
1443                 uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
1444                 if (!pw_hist) {
1445                         ret = False;
1446                         goto done;
1447                 }
1448                 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1449                 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1450                         int i;
1451                         SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1452                         nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1453                         for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1454                                 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1455                                         &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1456                                         PW_HISTORY_ENTRY_LEN);
1457                         }
1458                 }
1459                 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1460                         SAFE_FREE(pw_hist);
1461                         ret = False;
1462                         goto done;
1463                 }
1464                 SAFE_FREE(pw_hist);
1465         } else {
1466                 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1467         }
1468
1469         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1470         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1471         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1472         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1473         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1474         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1475         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1476         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1477         pdb_set_hours(sampass, hours, PDB_SET);
1478
1479 done:
1480
1481         SAFE_FREE(username);
1482         SAFE_FREE(domain);
1483         SAFE_FREE(nt_username);
1484         SAFE_FREE(fullname);
1485         SAFE_FREE(homedir);
1486         SAFE_FREE(dir_drive);
1487         SAFE_FREE(logon_script);
1488         SAFE_FREE(profile_path);
1489         SAFE_FREE(acct_desc);
1490         SAFE_FREE(workstations);
1491         SAFE_FREE(munged_dial);
1492         SAFE_FREE(unknown_str);
1493         SAFE_FREE(lm_pw_ptr);
1494         SAFE_FREE(nt_pw_ptr);
1495         SAFE_FREE(nt_pw_hist_ptr);
1496         SAFE_FREE(hours);
1497
1498         return ret;
1499 }
1500
1501 /*********************************************************************
1502 *********************************************************************/
1503
1504 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
1505 {
1506
1507         /* times are stored as 32bit integer
1508            take care on system with 64bit wide time_t
1509            --SSS */
1510         uint32  logon_time,
1511                 logoff_time,
1512                 kickoff_time,
1513                 bad_password_time,
1514                 pass_last_set_time,
1515                 pass_can_change_time,
1516                 pass_must_change_time;
1517         char *username = NULL;
1518         char *domain = NULL;
1519         char *nt_username = NULL;
1520         char *dir_drive = NULL;
1521         char *comment = NULL;
1522         char *munged_dial = NULL;
1523         char *fullname = NULL;
1524         char *homedir = NULL;
1525         char *logon_script = NULL;
1526         char *profile_path = NULL;
1527         char *acct_desc = NULL;
1528         char *workstations = NULL;
1529         uint32  username_len, domain_len, nt_username_len,
1530                 dir_drive_len, comment_len, munged_dial_len,
1531                 fullname_len, homedir_len, logon_script_len,
1532                 profile_path_len, acct_desc_len, workstations_len;
1533
1534         uint32  user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1535         uint16  logon_divs;
1536         uint16  bad_password_count, logon_count;
1537         uint8   *hours = NULL;
1538         uint8   *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1539         uint32          len = 0;
1540         uint32          lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1541         uint32 pwHistLen = 0;
1542         bool ret = True;
1543         fstring tmp_string;
1544         bool expand_explicit = lp_passdb_expand_explicit();
1545
1546         if(sampass == NULL || buf == NULL) {
1547                 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1548                 return False;
1549         }
1550
1551 /* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1552
1553         /* unpack the buffer into variables */
1554         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1555                 &logon_time,                                            /* d */
1556                 &logoff_time,                                           /* d */
1557                 &kickoff_time,                                          /* d */
1558                 &bad_password_time,                                     /* d */
1559                 &pass_last_set_time,                                    /* d */
1560                 &pass_can_change_time,                                  /* d */
1561                 &pass_must_change_time,                                 /* d */
1562                 &username_len, &username,                               /* B */
1563                 &domain_len, &domain,                                   /* B */
1564                 &nt_username_len, &nt_username,                         /* B */
1565                 &fullname_len, &fullname,                               /* B */
1566                 &homedir_len, &homedir,                                 /* B */
1567                 &dir_drive_len, &dir_drive,                             /* B */
1568                 &logon_script_len, &logon_script,                       /* B */
1569                 &profile_path_len, &profile_path,                       /* B */
1570                 &acct_desc_len, &acct_desc,                             /* B */
1571                 &workstations_len, &workstations,                       /* B */
1572                 &comment_len, &comment,                                 /* B */
1573                 &munged_dial_len, &munged_dial,                         /* B */
1574                 &user_rid,                                              /* d */
1575                 &group_rid,                                             /* d */
1576                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
1577                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
1578                 /* Change from V1 is addition of password history field. */
1579                 &nt_pw_hist_len, &nt_pw_hist_ptr,                       /* B */
1580                 /* Change from V2 is the uint32 acb_mask */
1581                 &acct_ctrl,                                             /* d */
1582                 /* Also "remove_me" field was removed. */
1583                 &logon_divs,                                            /* w */
1584                 &hours_len,                                             /* d */
1585                 &hourslen, &hours,                                      /* B */
1586                 &bad_password_count,                                    /* w */
1587                 &logon_count,                                           /* w */
1588                 &unknown_6);                                            /* d */
1589
1590         if (len == (uint32) -1)  {
1591                 ret = False;
1592                 goto done;
1593         }
1594
1595         pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET);
1596         pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET);
1597         pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET);
1598         pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET);
1599         pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET);
1600         pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET);
1601         pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET);
1602
1603         pdb_set_username(sampass, username, PDB_SET); 
1604         pdb_set_domain(sampass, domain, PDB_SET);
1605         pdb_set_nt_username(sampass, nt_username, PDB_SET);
1606         pdb_set_fullname(sampass, fullname, PDB_SET);
1607
1608         if (homedir) {
1609                 fstrcpy( tmp_string, homedir );
1610                 if (expand_explicit) {
1611                         standard_sub_basic( username, domain, tmp_string,
1612                                             sizeof(tmp_string) );
1613                 }
1614                 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1615         }
1616         else {
1617                 pdb_set_homedir(sampass, 
1618                         talloc_sub_basic(sampass, username, domain,
1619                                          lp_logon_home()),
1620                         PDB_DEFAULT);
1621         }
1622
1623         if (dir_drive)  
1624                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1625         else
1626                 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1627
1628         if (logon_script) {
1629                 fstrcpy( tmp_string, logon_script );
1630                 if (expand_explicit) {
1631                         standard_sub_basic( username, domain, tmp_string,
1632                                             sizeof(tmp_string) );
1633                 }
1634                 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1635         }
1636         else {
1637                 pdb_set_logon_script(sampass, 
1638                         talloc_sub_basic(sampass, username, domain,
1639                                          lp_logon_script()),
1640                         PDB_DEFAULT);
1641         }
1642
1643         if (profile_path) {     
1644                 fstrcpy( tmp_string, profile_path );
1645                 if (expand_explicit) {
1646                         standard_sub_basic( username, domain, tmp_string,
1647                                             sizeof(tmp_string) );
1648                 }
1649                 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1650         } 
1651         else {
1652                 pdb_set_profile_path(sampass, 
1653                         talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1654                         PDB_DEFAULT);
1655         }
1656
1657         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1658         pdb_set_comment(sampass, comment, PDB_SET);
1659         pdb_set_workstations(sampass, workstations, PDB_SET);
1660         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1661
1662         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1663                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1664                         ret = False;
1665                         goto done;
1666                 }
1667         }
1668
1669         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1670                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1671                         ret = False;
1672                         goto done;
1673                 }
1674         }
1675
1676         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1677         if (pwHistLen) {
1678                 uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1679                 if (!pw_hist) {
1680                         ret = False;
1681                         goto done;
1682                 }
1683                 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1684                 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1685                         int i;
1686                         SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1687                         nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1688                         for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1689                                 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1690                                         &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1691                                         PW_HISTORY_ENTRY_LEN);
1692                         }
1693                 }
1694                 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1695                         SAFE_FREE(pw_hist);
1696                         ret = False;
1697                         goto done;
1698                 }
1699                 SAFE_FREE(pw_hist);
1700         } else {
1701                 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1702         }
1703
1704         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1705         pdb_set_hours_len(sampass, hours_len, PDB_SET);
1706         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1707         pdb_set_logon_count(sampass, logon_count, PDB_SET);
1708         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1709         /* Change from V2 is the uint32 acct_ctrl */
1710         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1711         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1712         pdb_set_hours(sampass, hours, PDB_SET);
1713
1714 done:
1715
1716         SAFE_FREE(username);
1717         SAFE_FREE(domain);
1718         SAFE_FREE(nt_username);
1719         SAFE_FREE(fullname);
1720         SAFE_FREE(homedir);
1721         SAFE_FREE(dir_drive);
1722         SAFE_FREE(logon_script);
1723         SAFE_FREE(profile_path);
1724         SAFE_FREE(acct_desc);
1725         SAFE_FREE(workstations);
1726         SAFE_FREE(munged_dial);
1727         SAFE_FREE(comment);
1728         SAFE_FREE(lm_pw_ptr);
1729         SAFE_FREE(nt_pw_ptr);
1730         SAFE_FREE(nt_pw_hist_ptr);
1731         SAFE_FREE(hours);
1732
1733         return ret;
1734 }
1735
1736 /*********************************************************************
1737 *********************************************************************/
1738
1739 static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool size_only)
1740 {
1741         size_t len, buflen;
1742
1743         /* times are stored as 32bit integer
1744            take care on system with 64bit wide time_t
1745            --SSS */
1746         uint32  logon_time,
1747                 logoff_time,
1748                 kickoff_time,
1749                 bad_password_time,
1750                 pass_last_set_time,
1751                 pass_can_change_time,
1752                 pass_must_change_time;
1753
1754         uint32  user_rid, group_rid;
1755
1756         const char *username;
1757         const char *domain;
1758         const char *nt_username;
1759         const char *dir_drive;
1760         const char *comment;
1761         const char *munged_dial;
1762         const char *fullname;
1763         const char *homedir;
1764         const char *logon_script;
1765         const char *profile_path;
1766         const char *acct_desc;
1767         const char *workstations;
1768         uint32  username_len, domain_len, nt_username_len,
1769                 dir_drive_len, comment_len, munged_dial_len,
1770                 fullname_len, homedir_len, logon_script_len,
1771                 profile_path_len, acct_desc_len, workstations_len;
1772
1773         const uint8 *lm_pw;
1774         const uint8 *nt_pw;
1775         const uint8 *nt_pw_hist;
1776         uint32  lm_pw_len = 16;
1777         uint32  nt_pw_len = 16;
1778         uint32  nt_pw_hist_len;
1779         uint32 pwHistLen = 0;
1780
1781         *buf = NULL;
1782         buflen = 0;
1783
1784         logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass));
1785         logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass));
1786         kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass));
1787         bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass));
1788         pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass));
1789         pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass));
1790         pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass));
1791
1792         user_rid = pdb_get_user_rid(sampass);
1793         group_rid = pdb_get_group_rid(sampass);
1794
1795         username = pdb_get_username(sampass);
1796         if (username) {
1797                 username_len = strlen(username) +1;
1798         } else {
1799                 username_len = 0;
1800         }
1801
1802         domain = pdb_get_domain(sampass);
1803         if (domain) {
1804                 domain_len = strlen(domain) +1;
1805         } else {
1806                 domain_len = 0;
1807         }
1808
1809         nt_username = pdb_get_nt_username(sampass);
1810         if (nt_username) {
1811                 nt_username_len = strlen(nt_username) +1;
1812         } else {
1813                 nt_username_len = 0;
1814         }
1815
1816         fullname = pdb_get_fullname(sampass);
1817         if (fullname) {
1818                 fullname_len = strlen(fullname) +1;
1819         } else {
1820                 fullname_len = 0;
1821         }
1822
1823         /*
1824          * Only updates fields which have been set (not defaults from smb.conf)
1825          */
1826
1827         if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1828                 dir_drive = pdb_get_dir_drive(sampass);
1829         } else {
1830                 dir_drive = NULL;
1831         }
1832         if (dir_drive) {
1833                 dir_drive_len = strlen(dir_drive) +1;
1834         } else {
1835                 dir_drive_len = 0;
1836         }
1837
1838         if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1839                 homedir = pdb_get_homedir(sampass);
1840         } else {
1841                 homedir = NULL;
1842         }
1843         if (homedir) {
1844                 homedir_len = strlen(homedir) +1;
1845         } else {
1846                 homedir_len = 0;
1847         }
1848
1849         if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1850                 logon_script = pdb_get_logon_script(sampass);
1851         } else {
1852                 logon_script = NULL;
1853         }
1854         if (logon_script) {
1855                 logon_script_len = strlen(logon_script) +1;
1856         } else {
1857                 logon_script_len = 0;
1858         }
1859
1860         if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1861                 profile_path = pdb_get_profile_path(sampass);
1862         } else {
1863                 profile_path = NULL;
1864         }
1865         if (profile_path) {
1866                 profile_path_len = strlen(profile_path) +1;
1867         } else {
1868                 profile_path_len = 0;
1869         }
1870
1871         lm_pw = pdb_get_lanman_passwd(sampass);
1872         if (!lm_pw) {
1873                 lm_pw_len = 0;
1874         }
1875
1876         nt_pw = pdb_get_nt_passwd(sampass);
1877         if (!nt_pw) {
1878                 nt_pw_len = 0;
1879         }
1880
1881         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1882         nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
1883         if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1884                 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1885         } else {
1886                 nt_pw_hist_len = 0;
1887         }
1888
1889         acct_desc = pdb_get_acct_desc(sampass);
1890         if (acct_desc) {
1891                 acct_desc_len = strlen(acct_desc) +1;
1892         } else {
1893                 acct_desc_len = 0;
1894         }
1895
1896         workstations = pdb_get_workstations(sampass);
1897         if (workstations) {
1898                 workstations_len = strlen(workstations) +1;
1899         } else {
1900                 workstations_len = 0;
1901         }
1902
1903         comment = pdb_get_comment(sampass);
1904         if (comment) {
1905                 comment_len = strlen(comment) +1;
1906         } else {
1907                 comment_len = 0;
1908         }
1909
1910         munged_dial = pdb_get_munged_dial(sampass);
1911         if (munged_dial) {
1912                 munged_dial_len = strlen(munged_dial) +1;
1913         } else {
1914                 munged_dial_len = 0;    
1915         }
1916
1917 /* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1918
1919         /* one time to get the size needed */
1920         len = tdb_pack(NULL, 0,  SAMU_BUFFER_FORMAT_V3,
1921                 logon_time,                             /* d */
1922                 logoff_time,                            /* d */
1923                 kickoff_time,                           /* d */
1924                 bad_password_time,                      /* d */
1925                 pass_last_set_time,                     /* d */
1926                 pass_can_change_time,                   /* d */
1927                 pass_must_change_time,                  /* d */
1928                 username_len, username,                 /* B */
1929                 domain_len, domain,                     /* B */
1930                 nt_username_len, nt_username,           /* B */
1931                 fullname_len, fullname,                 /* B */
1932                 homedir_len, homedir,                   /* B */
1933                 dir_drive_len, dir_drive,               /* B */
1934                 logon_script_len, logon_script,         /* B */
1935                 profile_path_len, profile_path,         /* B */
1936                 acct_desc_len, acct_desc,               /* B */
1937                 workstations_len, workstations,         /* B */
1938                 comment_len, comment,                   /* B */
1939                 munged_dial_len, munged_dial,           /* B */
1940                 user_rid,                               /* d */
1941                 group_rid,                              /* d */
1942                 lm_pw_len, lm_pw,                       /* B */
1943                 nt_pw_len, nt_pw,                       /* B */
1944                 nt_pw_hist_len, nt_pw_hist,             /* B */
1945                 pdb_get_acct_ctrl(sampass),             /* d */
1946                 pdb_get_logon_divs(sampass),            /* w */
1947                 pdb_get_hours_len(sampass),             /* d */
1948                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
1949                 pdb_get_bad_password_count(sampass),    /* w */
1950                 pdb_get_logon_count(sampass),           /* w */
1951                 pdb_get_unknown_6(sampass));            /* d */
1952
1953         if (size_only) {
1954                 return buflen;
1955         }
1956
1957         /* malloc the space needed */
1958         if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1959                 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1960                 return (-1);
1961         }
1962
1963         /* now for the real call to tdb_pack() */
1964         buflen = tdb_pack(*buf, len,  SAMU_BUFFER_FORMAT_V3,
1965                 logon_time,                             /* d */
1966                 logoff_time,                            /* d */
1967                 kickoff_time,                           /* d */
1968                 bad_password_time,                      /* d */
1969                 pass_last_set_time,                     /* d */
1970                 pass_can_change_time,                   /* d */
1971                 pass_must_change_time,                  /* d */
1972                 username_len, username,                 /* B */
1973                 domain_len, domain,                     /* B */
1974                 nt_username_len, nt_username,           /* B */
1975                 fullname_len, fullname,                 /* B */
1976                 homedir_len, homedir,                   /* B */
1977                 dir_drive_len, dir_drive,               /* B */
1978                 logon_script_len, logon_script,         /* B */
1979                 profile_path_len, profile_path,         /* B */
1980                 acct_desc_len, acct_desc,               /* B */
1981                 workstations_len, workstations,         /* B */
1982                 comment_len, comment,                   /* B */
1983                 munged_dial_len, munged_dial,           /* B */
1984                 user_rid,                               /* d */
1985                 group_rid,                              /* d */
1986                 lm_pw_len, lm_pw,                       /* B */
1987                 nt_pw_len, nt_pw,                       /* B */
1988                 nt_pw_hist_len, nt_pw_hist,             /* B */
1989                 pdb_get_acct_ctrl(sampass),             /* d */
1990                 pdb_get_logon_divs(sampass),            /* w */
1991                 pdb_get_hours_len(sampass),             /* d */
1992                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
1993                 pdb_get_bad_password_count(sampass),    /* w */
1994                 pdb_get_logon_count(sampass),           /* w */
1995                 pdb_get_unknown_6(sampass));            /* d */
1996
1997         /* check to make sure we got it correct */
1998         if (buflen != len) {
1999                 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", 
2000                           (unsigned long)buflen, (unsigned long)len));  
2001                 /* error */
2002                 SAFE_FREE (*buf);
2003                 return (-1);
2004         }
2005
2006         return (buflen);
2007 }
2008
2009 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8 *buf, uint32 buflen)
2010 {
2011         /* nothing changed between V3 and V4 */
2012         return init_samu_from_buffer_v3(sampass, buf, buflen);
2013 }
2014
2015 static uint32 init_buffer_from_samu_v4(uint8 **buf, struct samu *sampass, bool size_only)
2016 {
2017         /* nothing changed between V3 and V4 */
2018         return init_buffer_from_samu_v3(buf, sampass, size_only);
2019 }
2020
2021 /**********************************************************************
2022  Intialize a struct samu struct from a BYTE buffer of size len
2023  *********************************************************************/
2024
2025 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2026                            uint8 *buf, uint32 buflen)
2027 {
2028         switch (level) {
2029         case SAMU_BUFFER_V0:
2030                 return init_samu_from_buffer_v0(sampass, buf, buflen);
2031         case SAMU_BUFFER_V1:
2032                 return init_samu_from_buffer_v1(sampass, buf, buflen);
2033         case SAMU_BUFFER_V2:
2034                 return init_samu_from_buffer_v2(sampass, buf, buflen);
2035         case SAMU_BUFFER_V3:
2036                 return init_samu_from_buffer_v3(sampass, buf, buflen);
2037         case SAMU_BUFFER_V4:
2038                 return init_samu_from_buffer_v4(sampass, buf, buflen);
2039         }
2040
2041         return false;
2042 }
2043
2044 /**********************************************************************
2045  Intialize a BYTE buffer from a struct samu struct
2046  *********************************************************************/
2047
2048 uint32 init_buffer_from_samu (uint8 **buf, struct samu *sampass, bool size_only)
2049 {
2050         return init_buffer_from_samu_v4(buf, sampass, size_only);
2051 }
2052
2053 /*********************************************************************
2054 *********************************************************************/
2055
2056 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2057 {
2058         uint8 *buf = NULL;
2059         int len;
2060
2061         len = init_buffer_from_samu(&buf, src, False);
2062         if (len == -1 || !buf) {
2063                 SAFE_FREE(buf);
2064                 return False;
2065         }
2066
2067         if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2068                 free(buf);
2069                 return False;
2070         }
2071
2072         dst->methods = src->methods;
2073
2074         if ( src->unix_pw ) {
2075                 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2076                 if (!dst->unix_pw) {
2077                         free(buf);
2078                         return False;
2079                 }
2080         }
2081
2082         free(buf);
2083         return True;
2084 }
2085
2086 /*********************************************************************
2087  Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2088 *********************************************************************/
2089
2090 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2091 {
2092         time_t LastBadPassword;
2093         uint16 BadPasswordCount;
2094         uint32 resettime; 
2095         bool res;
2096
2097         BadPasswordCount = pdb_get_bad_password_count(sampass);
2098         if (!BadPasswordCount) {
2099                 DEBUG(9, ("No bad password attempts.\n"));
2100                 return True;
2101         }
2102
2103         become_root();
2104         res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2105         unbecome_root();
2106
2107         if (!res) {
2108                 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2109                 return False;
2110         }
2111
2112         /* First, check if there is a reset time to compare */
2113         if ((resettime == (uint32) -1) || (resettime == 0)) {
2114                 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2115                 return True;
2116         }
2117
2118         LastBadPassword = pdb_get_bad_password_time(sampass);
2119         DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n", 
2120                    (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2121         if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){
2122                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2123                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2124                 if (updated) {
2125                         *updated = True;
2126                 }
2127         }
2128
2129         return True;
2130 }
2131
2132 /*********************************************************************
2133  Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2134 *********************************************************************/
2135
2136 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2137 {
2138         uint32 duration;
2139         time_t LastBadPassword;
2140         bool res;
2141
2142         if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2143                 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2144                         pdb_get_username(sampass)));
2145                 return True;
2146         }
2147
2148         become_root();
2149         res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2150         unbecome_root();
2151
2152         if (!res) {
2153                 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2154                 return False;
2155         }
2156
2157         /* First, check if there is a duration to compare */
2158         if ((duration == (uint32) -1)  || (duration == 0)) {
2159                 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2160                 return True;
2161         }
2162
2163         LastBadPassword = pdb_get_bad_password_time(sampass);
2164         DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2165                   pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2166
2167         if (LastBadPassword == (time_t)0) {
2168                 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2169                          "administratively locked out with no bad password "
2170                          "time. Leaving locked out.\n",
2171                          pdb_get_username(sampass) ));
2172                 return True;
2173         }
2174
2175         if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) {
2176                 pdb_set_acct_ctrl(sampass,
2177                                   pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2178                                   PDB_CHANGED);
2179                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2180                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2181                 if (updated) {
2182                         *updated = True;
2183                 }
2184         }
2185
2186         return True;
2187 }
2188
2189 /*********************************************************************
2190  Increment the bad_password_count 
2191 *********************************************************************/
2192
2193 bool pdb_increment_bad_password_count(struct samu *sampass)
2194 {
2195         uint32 account_policy_lockout;
2196         bool autolock_updated = False, badpw_updated = False;
2197         bool ret;
2198
2199         /* Retrieve the account lockout policy */
2200         become_root();
2201         ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2202         unbecome_root();
2203         if ( !ret ) {
2204                 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2205                 return False;
2206         }
2207
2208         /* If there is no policy, we don't need to continue checking */
2209         if (!account_policy_lockout) {
2210                 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2211                 return True;
2212         }
2213
2214         /* Check if the autolock needs to be cleared */
2215         if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2216                 return False;
2217
2218         /* Check if the badpw count needs to be reset */
2219         if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2220                 return False;
2221
2222         /*
2223           Ok, now we can assume that any resetting that needs to be 
2224           done has been done, and just get on with incrementing
2225           and autolocking if necessary
2226         */
2227
2228         pdb_set_bad_password_count(sampass, 
2229                                    pdb_get_bad_password_count(sampass)+1,
2230                                    PDB_CHANGED);
2231         pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2232
2233
2234         if (pdb_get_bad_password_count(sampass) < account_policy_lockout) 
2235                 return True;
2236
2237         if (!pdb_set_acct_ctrl(sampass,
2238                                pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2239                                PDB_CHANGED)) {
2240                 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); 
2241                 return False;
2242         }
2243
2244         return True;
2245 }
2246
2247 bool is_dc_trusted_domain_situation(const char *domain_name)
2248 {
2249         return IS_DC && !strequal(domain_name, lp_workgroup());
2250 }
2251
2252 /*******************************************************************
2253  Wrapper around retrieving the clear text trust account password.
2254  appropriate account name is stored in account_name.
2255  Caller must free password, but not account_name.
2256 *******************************************************************/
2257
2258 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2259                         const char **account_name,
2260                         enum netr_SchannelType *channel)
2261 {
2262         char *pwd;
2263         time_t last_set_time;
2264
2265         /* if we are a DC and this is not our domain, then lookup an account
2266          * for the domain trust */
2267
2268         if (is_dc_trusted_domain_situation(domain)) {
2269                 if (!lp_allow_trusted_domains()) {
2270                         return false;
2271                 }
2272
2273                 if (!pdb_get_trusteddom_pw(domain, ret_pwd, NULL,
2274                                            &last_set_time))
2275                 {
2276                         DEBUG(0, ("get_trust_pw: could not fetch trust "
2277                                 "account password for trusted domain %s\n",
2278                                 domain));
2279                         return false;
2280                 }
2281
2282                 if (channel != NULL) {
2283                         *channel = SEC_CHAN_DOMAIN;
2284                 }
2285
2286                 if (account_name != NULL) {
2287                         *account_name = lp_workgroup();
2288                 }
2289
2290                 return true;
2291         }
2292
2293         /*
2294          * Since we can only be member of one single domain, we are now
2295          * in a member situation:
2296          *
2297          *  -  Either we are a DC (selfjoined) and the domain is our
2298          *     own domain.
2299          *  -  Or we are on a member and the domain is our own or some
2300          *     other (potentially trusted) domain.
2301          *
2302          * In both cases, we can only get the machine account password
2303          * for our own domain to connect to our own dc. (For a member,
2304          * request to trusted domains are performed through our dc.)
2305          *
2306          * So we simply use our own domain name to retrieve the
2307          * machine account passowrd and ignore the request domain here.
2308          */
2309
2310         pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2311
2312         if (pwd != NULL) {
2313                 *ret_pwd = pwd;
2314                 if (account_name != NULL) {
2315                         *account_name = global_myname();
2316                 }
2317
2318                 return true;
2319         }
2320
2321         DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2322                   "account password for domain %s\n", domain));
2323         return false;
2324 }
2325
2326 /*******************************************************************
2327  Wrapper around retrieving the trust account password.
2328  appropriate account name is stored in account_name.
2329 *******************************************************************/
2330
2331 bool get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
2332                        const char **account_name,
2333                        enum netr_SchannelType *channel)
2334 {
2335         char *pwd = NULL;
2336         time_t last_set_time;
2337
2338         if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
2339                 E_md4hash(pwd, ret_pwd);
2340                 SAFE_FREE(pwd);
2341                 return true;
2342         } else if (is_dc_trusted_domain_situation(domain)) {
2343                 return false;
2344         }
2345
2346         /* as a fallback, try to get the hashed pwd directly from the tdb... */
2347
2348         if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
2349                                                         &last_set_time,
2350                                                         channel))
2351         {
2352                 if (account_name != NULL) {
2353                         *account_name = global_myname();
2354                 }
2355
2356                 return true;
2357         }
2358
2359         DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2360                 "password for domain %s\n", domain));
2361         return False;
2362 }
2363
2364 struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx,
2365                                                 struct samu *pw)
2366 {
2367         struct samr_LogonHours hours;
2368         const int units_per_week = 168;
2369
2370         ZERO_STRUCT(hours);
2371         hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
2372         if (!hours.bits) {
2373                 return hours;
2374         }
2375
2376         hours.units_per_week = units_per_week;
2377         memset(hours.bits, 0xFF, units_per_week);
2378
2379         if (pdb_get_hours(pw)) {
2380                 memcpy(hours.bits, pdb_get_hours(pw),
2381                        MIN(pdb_get_hours_len(pw), units_per_week));
2382         }
2383
2384         return hours;
2385 }