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