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