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