winbind: Keep "force_reauth" in invalidate_cm_connection
[Samba.git] / source3 / passdb / passdb.c
blob64e05b346de02f580cfb8c1180b7fff81de81e20
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
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.
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.
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/>.
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"
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_PASSDB
39 /**********************************************************************
40 ***********************************************************************/
42 static int samu_destroy(struct samu *user)
44 data_blob_clear_free( &user->lm_pw );
45 data_blob_clear_free( &user->nt_pw );
47 if ( user->plaintext_pw )
48 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
50 return 0;
53 /**********************************************************************
54 generate a new struct samuser
55 ***********************************************************************/
57 struct samu *samu_new( TALLOC_CTX *ctx )
59 struct samu *user;
61 if ( !(user = talloc_zero( ctx, struct samu )) ) {
62 DEBUG(0,("samuser_new: Talloc failed!\n"));
63 return NULL;
66 talloc_set_destructor( user, samu_destroy );
68 /* no initial methods */
70 user->methods = NULL;
72 /* Don't change these timestamp settings without a good reason.
73 They are important for NT member server compatibility. */
75 user->logon_time = (time_t)0;
76 user->pass_last_set_time = (time_t)0;
77 user->pass_can_change_time = (time_t)0;
78 user->logoff_time = get_time_t_max();
79 user->kickoff_time = get_time_t_max();
80 user->fields_present = 0x00ffffff;
81 user->logon_divs = 168; /* hours per week */
82 user->hours_len = 21; /* 21 times 8 bits = 168 */
83 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
84 user->bad_password_count = 0;
85 user->logon_count = 0;
86 user->unknown_6 = 0x000004ec; /* don't know */
88 /* Some parts of samba strlen their pdb_get...() returns,
89 so this keeps the interface unchanged for now. */
91 user->username = "";
92 user->domain = "";
93 user->nt_username = "";
94 user->full_name = "";
95 user->home_dir = "";
96 user->logon_script = "";
97 user->profile_path = "";
98 user->acct_desc = "";
99 user->workstations = "";
100 user->comment = "";
101 user->munged_dial = "";
103 user->plaintext_pw = NULL;
105 /* Unless we know otherwise have a Account Control Bit
106 value of 'normal user'. This helps User Manager, which
107 asks for a filtered list of users. */
109 user->acct_ctrl = ACB_NORMAL;
111 return user;
114 static int count_commas(const char *str)
116 int num_commas = 0;
117 const char *comma = str;
119 while ((comma = strchr(comma, ',')) != NULL) {
120 comma += 1;
121 num_commas += 1;
123 return num_commas;
126 /*********************************************************************
127 Initialize a struct samu from a struct passwd including the user
128 and group SIDs. The *user structure is filled out with the Unix
129 attributes and a user SID.
130 *********************************************************************/
132 static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods,
133 struct samu *user, const struct passwd *pwd, bool create)
135 const char *guest_account = lp_guest_account();
136 const char *domain = lp_netbios_name();
137 char *fullname;
138 uint32_t urid;
140 if ( !pwd ) {
141 return NT_STATUS_NO_SUCH_USER;
144 /* Basic properties based upon the Unix account information */
146 pdb_set_username(user, pwd->pw_name, PDB_SET);
148 fullname = NULL;
150 if (count_commas(pwd->pw_gecos) == 3) {
152 * Heuristic: This seems to be a gecos field that has been
153 * edited by chfn(1). Only use the part before the first
154 * comma. Fixes bug 5198.
156 fullname = talloc_strndup(
157 talloc_tos(), pwd->pw_gecos,
158 strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
161 if (fullname != NULL) {
162 pdb_set_fullname(user, fullname, PDB_SET);
163 } else {
164 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
166 TALLOC_FREE(fullname);
168 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
169 #if 0
170 /* This can lead to a primary group of S-1-22-2-XX which
171 will be rejected by other parts of the Samba code.
172 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
173 --jerry */
175 gid_to_sid(&group_sid, pwd->pw_gid);
176 pdb_set_group_sid(user, &group_sid, PDB_SET);
177 #endif
179 /* save the password structure for later use */
181 user->unix_pw = tcopy_passwd( user, pwd );
183 /* Special case for the guest account which must have a RID of 501 */
185 if ( strequal( pwd->pw_name, guest_account ) ) {
186 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
187 return NT_STATUS_NO_SUCH_USER;
189 return NT_STATUS_OK;
192 /* Non-guest accounts...Check for a workstation or user account */
194 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
195 /* workstation */
197 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
198 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
199 pwd->pw_name));
200 return NT_STATUS_INVALID_COMPUTER_NAME;
203 else {
204 /* user */
206 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
207 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
208 pwd->pw_name));
209 return NT_STATUS_INVALID_ACCOUNT_NAME;
212 /* set some basic attributes */
214 pdb_set_profile_path(user, talloc_sub_specified(user,
215 lp_logon_path(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
216 PDB_DEFAULT);
217 pdb_set_homedir(user, talloc_sub_specified(user,
218 lp_logon_home(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
219 PDB_DEFAULT);
220 pdb_set_dir_drive(user, talloc_sub_specified(user,
221 lp_logon_drive(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
222 PDB_DEFAULT);
223 pdb_set_logon_script(user, talloc_sub_specified(user,
224 lp_logon_script(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid),
225 PDB_DEFAULT);
228 /* Now deal with the user SID. If we have a backend that can generate
229 RIDs, then do so. But sometimes the caller just wanted a structure
230 initialized and will fill in these fields later (such as from a
231 netr_SamInfo3 structure) */
233 if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
234 uint32_t user_rid;
235 struct dom_sid user_sid;
237 if ( !methods->new_rid(methods, &user_rid) ) {
238 DEBUG(3, ("Could not allocate a new RID\n"));
239 return NT_STATUS_ACCESS_DENIED;
242 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
244 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
245 DEBUG(3, ("pdb_set_user_sid failed\n"));
246 return NT_STATUS_INTERNAL_ERROR;
249 return NT_STATUS_OK;
252 /* generate a SID for the user with the RID algorithm */
254 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
256 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
257 return NT_STATUS_INTERNAL_ERROR;
260 return NT_STATUS_OK;
263 /********************************************************************
264 Set the Unix user attributes
265 ********************************************************************/
267 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
269 return samu_set_unix_internal( NULL, user, pwd, False );
272 NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
273 struct samu *user, const struct passwd *pwd)
275 return samu_set_unix_internal( methods, user, pwd, True );
278 /**********************************************************
279 Encode the account control bits into a string.
280 length = length of string to encode into (including terminating
281 null). length *MUST BE MORE THAN 2* !
282 **********************************************************/
284 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
286 fstring acct_str;
287 char *result;
289 size_t i = 0;
291 SMB_ASSERT(length <= sizeof(acct_str));
293 acct_str[i++] = '[';
295 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
296 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
297 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
298 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
299 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
300 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
301 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
302 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
303 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
304 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
305 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
307 for ( ; i < length - 2 ; i++ )
308 acct_str[i] = ' ';
310 i = length - 2;
311 acct_str[i++] = ']';
312 acct_str[i++] = '\0';
314 result = talloc_strdup(talloc_tos(), acct_str);
315 SMB_ASSERT(result != NULL);
316 return result;
319 /**********************************************************
320 Decode the account control bits from a string.
321 **********************************************************/
323 uint32_t pdb_decode_acct_ctrl(const char *p)
325 uint32_t acct_ctrl = 0;
326 bool finished = false;
329 * Check if the account type bits have been encoded after the
330 * NT password (in the form [NDHTUWSLXI]).
333 if (*p != '[')
334 return 0;
336 for (p++; *p && !finished; p++) {
337 switch (*p) {
338 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
339 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
340 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
341 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
342 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
343 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
344 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
345 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
346 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
347 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
348 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
349 case ' ': { break; }
350 case ':':
351 case '\n':
352 case '\0':
353 case ']':
354 default: { finished = true; }
358 return acct_ctrl;
361 /*************************************************************
362 Routine to set 32 hex password characters from a 16 byte array.
363 **************************************************************/
365 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
367 if (pwd != NULL) {
368 hex_encode_buf(p, pwd, 16);
369 } else {
370 if (acct_ctrl & ACB_PWNOTREQ)
371 strlcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
372 else
373 strlcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
377 /*************************************************************
378 Routine to get the 32 hex characters and turn them
379 into a 16 byte array.
380 **************************************************************/
382 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
384 int i;
385 unsigned char lonybble, hinybble;
386 const char *hexchars = "0123456789ABCDEF";
387 char *p1, *p2;
389 if (!p)
390 return false;
392 for (i = 0; i < 32; i += 2) {
393 hinybble = toupper_m(p[i]);
394 lonybble = toupper_m(p[i + 1]);
396 p1 = strchr(hexchars, hinybble);
397 p2 = strchr(hexchars, lonybble);
399 if (!p1 || !p2)
400 return false;
402 hinybble = PTR_DIFF(p1, hexchars);
403 lonybble = PTR_DIFF(p2, hexchars);
405 pwd[i / 2] = (hinybble << 4) | lonybble;
407 return true;
410 /*************************************************************
411 Routine to set 42 hex hours characters from a 21 byte array.
412 **************************************************************/
414 void pdb_sethexhours(char *p, const unsigned char *hours)
416 if (hours != NULL) {
417 hex_encode_buf(p, hours, 21);
418 } else {
419 strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
423 /*************************************************************
424 Routine to get the 42 hex characters and turn them
425 into a 21 byte array.
426 **************************************************************/
428 bool pdb_gethexhours(const char *p, unsigned char *hours)
430 int i;
431 unsigned char lonybble, hinybble;
432 const char *hexchars = "0123456789ABCDEF";
433 char *p1, *p2;
435 if (!p) {
436 return (False);
439 for (i = 0; i < 42; i += 2) {
440 hinybble = toupper_m(p[i]);
441 lonybble = toupper_m(p[i + 1]);
443 p1 = strchr(hexchars, hinybble);
444 p2 = strchr(hexchars, lonybble);
446 if (!p1 || !p2) {
447 return (False);
450 hinybble = PTR_DIFF(p1, hexchars);
451 lonybble = PTR_DIFF(p2, hexchars);
453 hours[i / 2] = (hinybble << 4) | lonybble;
455 return (True);
458 /********************************************************************
459 ********************************************************************/
461 int algorithmic_rid_base(void)
463 int rid_offset;
465 rid_offset = lp_algorithmic_rid_base();
467 if (rid_offset < BASE_RID) {
468 /* Try to prevent admin foot-shooting, we can't put algorithmic
469 rids below 1000, that's the 'well known RIDs' on NT */
470 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
471 rid_offset = BASE_RID;
473 if (rid_offset & 1) {
474 DEBUG(0, ("algorithmic rid base must be even\n"));
475 rid_offset += 1;
477 return rid_offset;
480 /*******************************************************************
481 Converts NT user RID to a UNIX uid.
482 ********************************************************************/
484 uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
486 int rid_offset = algorithmic_rid_base();
487 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
490 uid_t max_algorithmic_uid(void)
492 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
495 /*******************************************************************
496 converts UNIX uid to an NT User RID.
497 ********************************************************************/
499 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
501 int rid_offset = algorithmic_rid_base();
502 return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
505 /*******************************************************************
506 Converts NT group RID to a UNIX gid.
507 ********************************************************************/
509 gid_t pdb_group_rid_to_gid(uint32_t group_rid)
511 int rid_offset = algorithmic_rid_base();
512 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
515 gid_t max_algorithmic_gid(void)
517 return pdb_group_rid_to_gid(0xffffffff);
520 /*******************************************************************
521 converts NT Group RID to a UNIX uid.
523 warning: you must not call that function only
524 you must do a call to the group mapping first.
525 there is not anymore a direct link between the gid and the rid.
526 ********************************************************************/
528 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
530 int rid_offset = algorithmic_rid_base();
531 return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
534 /*******************************************************************
535 Decides if a RID is a well known RID.
536 ********************************************************************/
538 static bool rid_is_well_known(uint32_t rid)
540 /* Not using rid_offset here, because this is the actual
541 NT fixed value (1000) */
543 return (rid < BASE_RID);
546 /*******************************************************************
547 Decides if a RID is a user or group RID.
548 ********************************************************************/
550 bool algorithmic_pdb_rid_is_user(uint32_t rid)
552 if ( rid_is_well_known(rid) ) {
554 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
555 * and DOMAIN_RID_GUEST.
557 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
558 return True;
559 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
560 return True;
562 return False;
565 /*******************************************************************
566 Convert a name into a SID. Used in the lookup name rpc.
567 ********************************************************************/
569 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
570 enum lsa_SidType *type)
572 GROUP_MAP *map;
573 bool ret;
575 /* Windows treats "MACHINE\None" as a special name for
576 rid 513 on non-DCs. You cannot create a user or group
577 name "None" on Windows. You will get an error that
578 the group already exists. */
580 if ( strequal( name, "None" ) ) {
581 *rid = DOMAIN_RID_USERS;
582 *type = SID_NAME_DOM_GRP;
584 return True;
587 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
588 * correctly in the case where foo also exists as a user. If the flag
589 * is set, don't look for users at all. */
591 if ((flags & LOOKUP_NAME_GROUP) == 0) {
592 struct samu *sam_account = NULL;
593 struct dom_sid user_sid;
595 if ( !(sam_account = samu_new( NULL )) ) {
596 return False;
599 become_root();
600 ret = pdb_getsampwnam(sam_account, name);
601 unbecome_root();
603 if (ret) {
604 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
607 TALLOC_FREE(sam_account);
609 if (ret) {
610 if (!sid_check_is_in_our_sam(&user_sid)) {
611 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
612 name, sid_string_dbg(&user_sid)));
613 return False;
616 sid_peek_rid(&user_sid, rid);
617 *type = SID_NAME_USER;
618 return True;
623 * Maybe it is a group ?
626 map = talloc_zero(NULL, GROUP_MAP);
627 if (!map) {
628 return false;
631 become_root();
632 ret = pdb_getgrnam(map, name);
633 unbecome_root();
635 if (!ret) {
636 TALLOC_FREE(map);
637 return False;
640 /* BUILTIN groups are looked up elsewhere */
641 if (!sid_check_is_in_our_sam(&map->sid)) {
642 DEBUG(10, ("Found group %s (%s) not in our domain -- "
643 "ignoring.\n",
644 name, sid_string_dbg(&map->sid)));
645 TALLOC_FREE(map);
646 return False;
649 /* yes it's a mapped group */
650 sid_peek_rid(&map->sid, rid);
651 *type = map->sid_name_use;
652 TALLOC_FREE(map);
653 return True;
656 /*************************************************************
657 Change a password entry in the local passdb backend.
659 Assumptions:
660 - always called as root
661 - ignores the account type except when adding a new account
662 - will create/delete the unix account if the relative
663 add/delete user script is configured
665 *************************************************************/
667 NTSTATUS local_password_change(const char *user_name,
668 int local_flags,
669 const char *new_passwd,
670 char **pp_err_str,
671 char **pp_msg_str)
673 TALLOC_CTX *tosctx;
674 struct samu *sam_pass;
675 uint32_t acb;
676 uint32_t rid;
677 NTSTATUS result;
678 bool user_exists;
679 int ret = -1;
681 *pp_err_str = NULL;
682 *pp_msg_str = NULL;
684 tosctx = talloc_tos();
686 sam_pass = samu_new(tosctx);
687 if (!sam_pass) {
688 result = NT_STATUS_NO_MEMORY;
689 goto done;
692 /* Get the smb passwd entry for this user */
693 user_exists = pdb_getsampwnam(sam_pass, user_name);
695 /* Check delete first, we don't need to do anything else if we
696 * are going to delete the acocunt */
697 if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
699 result = pdb_delete_user(tosctx, sam_pass);
700 if (!NT_STATUS_IS_OK(result)) {
701 ret = asprintf(pp_err_str,
702 "Failed to delete entry for user %s.\n",
703 user_name);
704 if (ret < 0) {
705 *pp_err_str = NULL;
707 result = NT_STATUS_UNSUCCESSFUL;
708 } else {
709 ret = asprintf(pp_msg_str,
710 "Deleted user %s.\n",
711 user_name);
712 if (ret < 0) {
713 *pp_msg_str = NULL;
716 goto done;
719 if (user_exists && (local_flags & LOCAL_ADD_USER)) {
720 /* the entry already existed */
721 local_flags &= ~LOCAL_ADD_USER;
724 if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
725 ret = asprintf(pp_err_str,
726 "Failed to find entry for user %s.\n",
727 user_name);
728 if (ret < 0) {
729 *pp_err_str = NULL;
731 result = NT_STATUS_NO_SUCH_USER;
732 goto done;
735 /* First thing add the new user if we are required to do so */
736 if (local_flags & LOCAL_ADD_USER) {
738 if (local_flags & LOCAL_TRUST_ACCOUNT) {
739 acb = ACB_WSTRUST;
740 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
741 acb = ACB_DOMTRUST;
742 } else {
743 acb = ACB_NORMAL;
746 result = pdb_create_user(tosctx, user_name, acb, &rid);
747 if (!NT_STATUS_IS_OK(result)) {
748 ret = asprintf(pp_err_str,
749 "Failed to add entry for user %s.\n",
750 user_name);
751 if (ret < 0) {
752 *pp_err_str = NULL;
754 result = NT_STATUS_UNSUCCESSFUL;
755 goto done;
758 sam_pass = samu_new(tosctx);
759 if (!sam_pass) {
760 result = NT_STATUS_NO_MEMORY;
761 goto done;
764 /* Now get back the smb passwd entry for this new user */
765 user_exists = pdb_getsampwnam(sam_pass, user_name);
766 if (!user_exists) {
767 ret = asprintf(pp_err_str,
768 "Failed to add entry for user %s.\n",
769 user_name);
770 if (ret < 0) {
771 *pp_err_str = NULL;
773 result = NT_STATUS_UNSUCCESSFUL;
774 goto done;
778 acb = pdb_get_acct_ctrl(sam_pass);
781 * We are root - just write the new password
782 * and the valid last change time.
784 if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
785 acb |= ACB_PWNOTREQ;
786 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
787 ret = asprintf(pp_err_str,
788 "Failed to set 'no password required' "
789 "flag for user %s.\n", user_name);
790 if (ret < 0) {
791 *pp_err_str = NULL;
793 result = NT_STATUS_UNSUCCESSFUL;
794 goto done;
798 if (local_flags & LOCAL_SET_PASSWORD) {
800 * If we're dealing with setting a completely empty user account
801 * ie. One with a password of 'XXXX', but not set disabled (like
802 * an account created from scratch) then if the old password was
803 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
804 * We remove that as we're giving this user their first password
805 * and the decision hasn't really been made to disable them (ie.
806 * don't create them disabled). JRA.
808 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
809 (acb & ACB_DISABLED)) {
810 acb &= (~ACB_DISABLED);
811 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
812 ret = asprintf(pp_err_str,
813 "Failed to unset 'disabled' "
814 "flag for user %s.\n",
815 user_name);
816 if (ret < 0) {
817 *pp_err_str = NULL;
819 result = NT_STATUS_UNSUCCESSFUL;
820 goto done;
824 acb &= (~ACB_PWNOTREQ);
825 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
826 ret = asprintf(pp_err_str,
827 "Failed to unset 'no password required'"
828 " flag for user %s.\n", user_name);
829 if (ret < 0) {
830 *pp_err_str = NULL;
832 result = NT_STATUS_UNSUCCESSFUL;
833 goto done;
836 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
837 ret = asprintf(pp_err_str,
838 "Failed to set password for "
839 "user %s.\n", user_name);
840 if (ret < 0) {
841 *pp_err_str = NULL;
843 result = NT_STATUS_UNSUCCESSFUL;
844 goto done;
848 if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
849 acb |= ACB_DISABLED;
850 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
851 ret = asprintf(pp_err_str,
852 "Failed to set 'disabled' flag for "
853 "user %s.\n", user_name);
854 if (ret < 0) {
855 *pp_err_str = NULL;
857 result = NT_STATUS_UNSUCCESSFUL;
858 goto done;
862 if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
863 acb &= (~ACB_DISABLED);
864 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
865 ret = asprintf(pp_err_str,
866 "Failed to unset 'disabled' flag for "
867 "user %s.\n", user_name);
868 if (ret < 0) {
869 *pp_err_str = NULL;
871 result = NT_STATUS_UNSUCCESSFUL;
872 goto done;
876 /* now commit changes if any */
877 result = pdb_update_sam_account(sam_pass);
878 if (!NT_STATUS_IS_OK(result)) {
879 ret = asprintf(pp_err_str,
880 "Failed to modify entry for user %s.\n",
881 user_name);
882 if (ret < 0) {
883 *pp_err_str = NULL;
885 goto done;
888 if (local_flags & LOCAL_ADD_USER) {
889 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
890 } else if (local_flags & LOCAL_DISABLE_USER) {
891 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
892 } else if (local_flags & LOCAL_ENABLE_USER) {
893 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
894 } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
895 ret = asprintf(pp_msg_str,
896 "User %s password set to none.\n", user_name);
899 if (ret < 0) {
900 *pp_msg_str = NULL;
903 result = NT_STATUS_OK;
905 done:
906 TALLOC_FREE(sam_pass);
907 return result;
910 /**********************************************************************
911 Marshall/unmarshall struct samu structs.
912 *********************************************************************/
914 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
915 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
916 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
917 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
918 /* nothing changed between V3 and V4 */
920 /*********************************************************************
921 *********************************************************************/
923 static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
926 /* times are stored as 32bit integer
927 take care on system with 64bit wide time_t
928 --SSS */
929 uint32_t logon_time,
930 logoff_time,
931 kickoff_time,
932 pass_last_set_time,
933 pass_can_change_time,
934 pass_must_change_time;
935 char *username = NULL;
936 char *domain = NULL;
937 char *nt_username = NULL;
938 char *dir_drive = NULL;
939 char *unknown_str = NULL;
940 char *munged_dial = NULL;
941 char *fullname = NULL;
942 char *homedir = NULL;
943 char *logon_script = NULL;
944 char *profile_path = NULL;
945 char *acct_desc = NULL;
946 char *workstations = NULL;
947 uint32_t username_len, domain_len, nt_username_len,
948 dir_drive_len, unknown_str_len, munged_dial_len,
949 fullname_len, homedir_len, logon_script_len,
950 profile_path_len, acct_desc_len, workstations_len;
952 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
953 uint16_t acct_ctrl, logon_divs;
954 uint16_t bad_password_count, logon_count;
955 uint8_t *hours = NULL;
956 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
957 uint32_t len = 0;
958 uint32_t lm_pw_len, nt_pw_len, hourslen;
959 bool ret = True;
961 if(sampass == NULL || buf == NULL) {
962 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
963 return False;
966 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
968 /* unpack the buffer into variables */
969 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
970 &logon_time, /* d */
971 &logoff_time, /* d */
972 &kickoff_time, /* d */
973 &pass_last_set_time, /* d */
974 &pass_can_change_time, /* d */
975 &pass_must_change_time, /* d */
976 &username_len, &username, /* B */
977 &domain_len, &domain, /* B */
978 &nt_username_len, &nt_username, /* B */
979 &fullname_len, &fullname, /* B */
980 &homedir_len, &homedir, /* B */
981 &dir_drive_len, &dir_drive, /* B */
982 &logon_script_len, &logon_script, /* B */
983 &profile_path_len, &profile_path, /* B */
984 &acct_desc_len, &acct_desc, /* B */
985 &workstations_len, &workstations, /* B */
986 &unknown_str_len, &unknown_str, /* B */
987 &munged_dial_len, &munged_dial, /* B */
988 &user_rid, /* d */
989 &group_rid, /* d */
990 &lm_pw_len, &lm_pw_ptr, /* B */
991 &nt_pw_len, &nt_pw_ptr, /* B */
992 &acct_ctrl, /* w */
993 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
994 &logon_divs, /* w */
995 &hours_len, /* d */
996 &hourslen, &hours, /* B */
997 &bad_password_count, /* w */
998 &logon_count, /* w */
999 &unknown_6); /* d */
1001 if (len == (uint32_t) -1) {
1002 ret = False;
1003 goto done;
1006 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1007 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1008 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1009 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1010 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1012 pdb_set_username(sampass, username, PDB_SET);
1013 pdb_set_domain(sampass, domain, PDB_SET);
1014 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1015 pdb_set_fullname(sampass, fullname, PDB_SET);
1017 if (homedir) {
1018 pdb_set_homedir(sampass, homedir, PDB_SET);
1020 else {
1021 pdb_set_homedir(sampass,
1022 talloc_sub_basic(sampass, username, domain,
1023 lp_logon_home()),
1024 PDB_DEFAULT);
1027 if (dir_drive)
1028 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1029 else {
1030 pdb_set_dir_drive(sampass,
1031 talloc_sub_basic(sampass, username, domain,
1032 lp_logon_drive()),
1033 PDB_DEFAULT);
1036 if (logon_script)
1037 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1038 else {
1039 pdb_set_logon_script(sampass,
1040 talloc_sub_basic(sampass, username, domain,
1041 lp_logon_script()),
1042 PDB_DEFAULT);
1045 if (profile_path) {
1046 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1047 } else {
1048 pdb_set_profile_path(sampass,
1049 talloc_sub_basic(sampass, username, domain,
1050 lp_logon_path()),
1051 PDB_DEFAULT);
1054 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1055 pdb_set_workstations(sampass, workstations, PDB_SET);
1056 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1058 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1059 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1060 ret = False;
1061 goto done;
1065 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1066 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1067 ret = False;
1068 goto done;
1072 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1073 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1074 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1075 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1076 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1077 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1078 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1079 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1080 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1081 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1083 done:
1085 SAFE_FREE(username);
1086 SAFE_FREE(domain);
1087 SAFE_FREE(nt_username);
1088 SAFE_FREE(fullname);
1089 SAFE_FREE(homedir);
1090 SAFE_FREE(dir_drive);
1091 SAFE_FREE(logon_script);
1092 SAFE_FREE(profile_path);
1093 SAFE_FREE(acct_desc);
1094 SAFE_FREE(workstations);
1095 SAFE_FREE(munged_dial);
1096 SAFE_FREE(unknown_str);
1097 SAFE_FREE(lm_pw_ptr);
1098 SAFE_FREE(nt_pw_ptr);
1099 SAFE_FREE(hours);
1101 return ret;
1104 /*********************************************************************
1105 *********************************************************************/
1107 static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1110 /* times are stored as 32bit integer
1111 take care on system with 64bit wide time_t
1112 --SSS */
1113 uint32_t logon_time,
1114 logoff_time,
1115 kickoff_time,
1116 bad_password_time,
1117 pass_last_set_time,
1118 pass_can_change_time,
1119 pass_must_change_time;
1120 char *username = NULL;
1121 char *domain = NULL;
1122 char *nt_username = NULL;
1123 char *dir_drive = NULL;
1124 char *unknown_str = NULL;
1125 char *munged_dial = NULL;
1126 char *fullname = NULL;
1127 char *homedir = NULL;
1128 char *logon_script = NULL;
1129 char *profile_path = NULL;
1130 char *acct_desc = NULL;
1131 char *workstations = NULL;
1132 uint32_t username_len, domain_len, nt_username_len,
1133 dir_drive_len, unknown_str_len, munged_dial_len,
1134 fullname_len, homedir_len, logon_script_len,
1135 profile_path_len, acct_desc_len, workstations_len;
1137 uint32_t user_rid, group_rid, remove_me, hours_len, unknown_6;
1138 uint16_t acct_ctrl, logon_divs;
1139 uint16_t bad_password_count, logon_count;
1140 uint8_t *hours = NULL;
1141 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1142 uint32_t len = 0;
1143 uint32_t lm_pw_len, nt_pw_len, hourslen;
1144 bool ret = True;
1146 if(sampass == NULL || buf == NULL) {
1147 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1148 return False;
1151 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1153 /* unpack the buffer into variables */
1154 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1155 &logon_time, /* d */
1156 &logoff_time, /* d */
1157 &kickoff_time, /* d */
1158 /* Change from V0 is addition of bad_password_time field. */
1159 &bad_password_time, /* d */
1160 &pass_last_set_time, /* d */
1161 &pass_can_change_time, /* d */
1162 &pass_must_change_time, /* d */
1163 &username_len, &username, /* B */
1164 &domain_len, &domain, /* B */
1165 &nt_username_len, &nt_username, /* B */
1166 &fullname_len, &fullname, /* B */
1167 &homedir_len, &homedir, /* B */
1168 &dir_drive_len, &dir_drive, /* B */
1169 &logon_script_len, &logon_script, /* B */
1170 &profile_path_len, &profile_path, /* B */
1171 &acct_desc_len, &acct_desc, /* B */
1172 &workstations_len, &workstations, /* B */
1173 &unknown_str_len, &unknown_str, /* B */
1174 &munged_dial_len, &munged_dial, /* B */
1175 &user_rid, /* d */
1176 &group_rid, /* d */
1177 &lm_pw_len, &lm_pw_ptr, /* B */
1178 &nt_pw_len, &nt_pw_ptr, /* B */
1179 &acct_ctrl, /* w */
1180 &remove_me, /* d */
1181 &logon_divs, /* w */
1182 &hours_len, /* d */
1183 &hourslen, &hours, /* B */
1184 &bad_password_count, /* w */
1185 &logon_count, /* w */
1186 &unknown_6); /* d */
1188 if (len == (uint32_t) -1) {
1189 ret = False;
1190 goto done;
1193 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1194 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1195 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1197 /* Change from V0 is addition of bad_password_time field. */
1198 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1199 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1200 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1202 pdb_set_username(sampass, username, PDB_SET);
1203 pdb_set_domain(sampass, domain, PDB_SET);
1204 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1205 pdb_set_fullname(sampass, fullname, PDB_SET);
1207 if (homedir) {
1208 pdb_set_homedir(sampass, homedir, PDB_SET);
1210 else {
1211 pdb_set_homedir(sampass,
1212 talloc_sub_basic(sampass, username, domain,
1213 lp_logon_home()),
1214 PDB_DEFAULT);
1217 if (dir_drive)
1218 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1219 else {
1220 pdb_set_dir_drive(sampass,
1221 talloc_sub_basic(sampass, username, domain,
1222 lp_logon_drive()),
1223 PDB_DEFAULT);
1226 if (logon_script)
1227 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1228 else {
1229 pdb_set_logon_script(sampass,
1230 talloc_sub_basic(sampass, username, domain,
1231 lp_logon_script()),
1232 PDB_DEFAULT);
1235 if (profile_path) {
1236 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1237 } else {
1238 pdb_set_profile_path(sampass,
1239 talloc_sub_basic(sampass, username, domain,
1240 lp_logon_path()),
1241 PDB_DEFAULT);
1244 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1245 pdb_set_workstations(sampass, workstations, PDB_SET);
1246 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1248 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1249 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1250 ret = False;
1251 goto done;
1255 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1256 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1257 ret = False;
1258 goto done;
1262 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1264 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1265 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1266 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1267 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1268 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1269 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1270 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1271 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1272 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1274 done:
1276 SAFE_FREE(username);
1277 SAFE_FREE(domain);
1278 SAFE_FREE(nt_username);
1279 SAFE_FREE(fullname);
1280 SAFE_FREE(homedir);
1281 SAFE_FREE(dir_drive);
1282 SAFE_FREE(logon_script);
1283 SAFE_FREE(profile_path);
1284 SAFE_FREE(acct_desc);
1285 SAFE_FREE(workstations);
1286 SAFE_FREE(munged_dial);
1287 SAFE_FREE(unknown_str);
1288 SAFE_FREE(lm_pw_ptr);
1289 SAFE_FREE(nt_pw_ptr);
1290 SAFE_FREE(hours);
1292 return ret;
1295 static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1298 /* times are stored as 32bit integer
1299 take care on system with 64bit wide time_t
1300 --SSS */
1301 uint32_t logon_time,
1302 logoff_time,
1303 kickoff_time,
1304 bad_password_time,
1305 pass_last_set_time,
1306 pass_can_change_time,
1307 pass_must_change_time;
1308 char *username = NULL;
1309 char *domain = NULL;
1310 char *nt_username = NULL;
1311 char *dir_drive = NULL;
1312 char *unknown_str = NULL;
1313 char *munged_dial = NULL;
1314 char *fullname = NULL;
1315 char *homedir = NULL;
1316 char *logon_script = NULL;
1317 char *profile_path = NULL;
1318 char *acct_desc = NULL;
1319 char *workstations = NULL;
1320 uint32_t username_len, domain_len, nt_username_len,
1321 dir_drive_len, unknown_str_len, munged_dial_len,
1322 fullname_len, homedir_len, logon_script_len,
1323 profile_path_len, acct_desc_len, workstations_len;
1325 uint32_t user_rid, group_rid, hours_len, unknown_6;
1326 uint16_t acct_ctrl, logon_divs;
1327 uint16_t bad_password_count, logon_count;
1328 uint8_t *hours = NULL;
1329 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1330 uint32_t len = 0;
1331 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1332 uint32_t pwHistLen = 0;
1333 bool ret = True;
1334 fstring tmp_string;
1335 bool expand_explicit = lp_passdb_expand_explicit();
1337 if(sampass == NULL || buf == NULL) {
1338 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1339 return False;
1342 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1344 /* unpack the buffer into variables */
1345 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1346 &logon_time, /* d */
1347 &logoff_time, /* d */
1348 &kickoff_time, /* d */
1349 &bad_password_time, /* d */
1350 &pass_last_set_time, /* d */
1351 &pass_can_change_time, /* d */
1352 &pass_must_change_time, /* d */
1353 &username_len, &username, /* B */
1354 &domain_len, &domain, /* B */
1355 &nt_username_len, &nt_username, /* B */
1356 &fullname_len, &fullname, /* B */
1357 &homedir_len, &homedir, /* B */
1358 &dir_drive_len, &dir_drive, /* B */
1359 &logon_script_len, &logon_script, /* B */
1360 &profile_path_len, &profile_path, /* B */
1361 &acct_desc_len, &acct_desc, /* B */
1362 &workstations_len, &workstations, /* B */
1363 &unknown_str_len, &unknown_str, /* B */
1364 &munged_dial_len, &munged_dial, /* B */
1365 &user_rid, /* d */
1366 &group_rid, /* d */
1367 &lm_pw_len, &lm_pw_ptr, /* B */
1368 &nt_pw_len, &nt_pw_ptr, /* B */
1369 /* Change from V1 is addition of password history field. */
1370 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1371 &acct_ctrl, /* w */
1372 /* Also "remove_me" field was removed. */
1373 &logon_divs, /* w */
1374 &hours_len, /* d */
1375 &hourslen, &hours, /* B */
1376 &bad_password_count, /* w */
1377 &logon_count, /* w */
1378 &unknown_6); /* d */
1380 if (len == (uint32_t) -1) {
1381 ret = False;
1382 goto done;
1385 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1386 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1387 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1388 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1389 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1390 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1392 pdb_set_username(sampass, username, PDB_SET);
1393 pdb_set_domain(sampass, domain, PDB_SET);
1394 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1395 pdb_set_fullname(sampass, fullname, PDB_SET);
1397 if (homedir) {
1398 fstrcpy( tmp_string, homedir );
1399 if (expand_explicit) {
1400 standard_sub_basic( username, domain, tmp_string,
1401 sizeof(tmp_string) );
1403 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1405 else {
1406 pdb_set_homedir(sampass,
1407 talloc_sub_basic(sampass, username, domain,
1408 lp_logon_home()),
1409 PDB_DEFAULT);
1412 if (dir_drive)
1413 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1414 else
1415 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1417 if (logon_script) {
1418 fstrcpy( tmp_string, logon_script );
1419 if (expand_explicit) {
1420 standard_sub_basic( username, domain, tmp_string,
1421 sizeof(tmp_string) );
1423 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1425 else {
1426 pdb_set_logon_script(sampass,
1427 talloc_sub_basic(sampass, username, domain,
1428 lp_logon_script()),
1429 PDB_DEFAULT);
1432 if (profile_path) {
1433 fstrcpy( tmp_string, profile_path );
1434 if (expand_explicit) {
1435 standard_sub_basic( username, domain, tmp_string,
1436 sizeof(tmp_string) );
1438 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1440 else {
1441 pdb_set_profile_path(sampass,
1442 talloc_sub_basic(sampass, username, domain,
1443 lp_logon_path()),
1444 PDB_DEFAULT);
1447 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1448 pdb_set_workstations(sampass, workstations, PDB_SET);
1449 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1451 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1452 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1453 ret = False;
1454 goto done;
1458 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1459 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1460 ret = False;
1461 goto done;
1465 /* Change from V1 is addition of password history field. */
1466 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1467 if (pwHistLen) {
1468 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1469 if (!pw_hist) {
1470 ret = False;
1471 goto done;
1473 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1474 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1475 int i;
1476 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1477 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1478 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1479 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1480 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1481 PW_HISTORY_ENTRY_LEN);
1484 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1485 SAFE_FREE(pw_hist);
1486 ret = False;
1487 goto done;
1489 SAFE_FREE(pw_hist);
1490 } else {
1491 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1494 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1495 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1496 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1497 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1498 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1499 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1500 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1501 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1502 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1504 done:
1506 SAFE_FREE(username);
1507 SAFE_FREE(domain);
1508 SAFE_FREE(nt_username);
1509 SAFE_FREE(fullname);
1510 SAFE_FREE(homedir);
1511 SAFE_FREE(dir_drive);
1512 SAFE_FREE(logon_script);
1513 SAFE_FREE(profile_path);
1514 SAFE_FREE(acct_desc);
1515 SAFE_FREE(workstations);
1516 SAFE_FREE(munged_dial);
1517 SAFE_FREE(unknown_str);
1518 SAFE_FREE(lm_pw_ptr);
1519 SAFE_FREE(nt_pw_ptr);
1520 SAFE_FREE(nt_pw_hist_ptr);
1521 SAFE_FREE(hours);
1523 return ret;
1526 /*********************************************************************
1527 *********************************************************************/
1529 static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1532 /* times are stored as 32bit integer
1533 take care on system with 64bit wide time_t
1534 --SSS */
1535 uint32_t logon_time,
1536 logoff_time,
1537 kickoff_time,
1538 bad_password_time,
1539 pass_last_set_time,
1540 pass_can_change_time,
1541 pass_must_change_time;
1542 char *username = NULL;
1543 char *domain = NULL;
1544 char *nt_username = NULL;
1545 char *dir_drive = NULL;
1546 char *comment = NULL;
1547 char *munged_dial = NULL;
1548 char *fullname = NULL;
1549 char *homedir = NULL;
1550 char *logon_script = NULL;
1551 char *profile_path = NULL;
1552 char *acct_desc = NULL;
1553 char *workstations = NULL;
1554 uint32_t username_len, domain_len, nt_username_len,
1555 dir_drive_len, comment_len, munged_dial_len,
1556 fullname_len, homedir_len, logon_script_len,
1557 profile_path_len, acct_desc_len, workstations_len;
1559 uint32_t user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1560 uint16_t logon_divs;
1561 uint16_t bad_password_count, logon_count;
1562 uint8_t *hours = NULL;
1563 uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1564 uint32_t len = 0;
1565 uint32_t lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1566 uint32_t pwHistLen = 0;
1567 bool ret = True;
1568 fstring tmp_string;
1569 bool expand_explicit = lp_passdb_expand_explicit();
1571 if(sampass == NULL || buf == NULL) {
1572 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1573 return False;
1576 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1578 /* unpack the buffer into variables */
1579 len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1580 &logon_time, /* d */
1581 &logoff_time, /* d */
1582 &kickoff_time, /* d */
1583 &bad_password_time, /* d */
1584 &pass_last_set_time, /* d */
1585 &pass_can_change_time, /* d */
1586 &pass_must_change_time, /* d */
1587 &username_len, &username, /* B */
1588 &domain_len, &domain, /* B */
1589 &nt_username_len, &nt_username, /* B */
1590 &fullname_len, &fullname, /* B */
1591 &homedir_len, &homedir, /* B */
1592 &dir_drive_len, &dir_drive, /* B */
1593 &logon_script_len, &logon_script, /* B */
1594 &profile_path_len, &profile_path, /* B */
1595 &acct_desc_len, &acct_desc, /* B */
1596 &workstations_len, &workstations, /* B */
1597 &comment_len, &comment, /* B */
1598 &munged_dial_len, &munged_dial, /* B */
1599 &user_rid, /* d */
1600 &group_rid, /* d */
1601 &lm_pw_len, &lm_pw_ptr, /* B */
1602 &nt_pw_len, &nt_pw_ptr, /* B */
1603 /* Change from V1 is addition of password history field. */
1604 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1605 /* Change from V2 is the uint32_t acb_mask */
1606 &acct_ctrl, /* d */
1607 /* Also "remove_me" field was removed. */
1608 &logon_divs, /* w */
1609 &hours_len, /* d */
1610 &hourslen, &hours, /* B */
1611 &bad_password_count, /* w */
1612 &logon_count, /* w */
1613 &unknown_6); /* d */
1615 if (len == (uint32_t) -1) {
1616 ret = False;
1617 goto done;
1620 pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1621 pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1622 pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1623 pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1624 pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1625 pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1627 pdb_set_username(sampass, username, PDB_SET);
1628 pdb_set_domain(sampass, domain, PDB_SET);
1629 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1630 pdb_set_fullname(sampass, fullname, PDB_SET);
1632 if (homedir) {
1633 fstrcpy( tmp_string, homedir );
1634 if (expand_explicit) {
1635 standard_sub_basic( username, domain, tmp_string,
1636 sizeof(tmp_string) );
1638 pdb_set_homedir(sampass, tmp_string, PDB_SET);
1640 else {
1641 pdb_set_homedir(sampass,
1642 talloc_sub_basic(sampass, username, domain,
1643 lp_logon_home()),
1644 PDB_DEFAULT);
1647 if (dir_drive)
1648 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1649 else
1650 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1652 if (logon_script) {
1653 fstrcpy( tmp_string, logon_script );
1654 if (expand_explicit) {
1655 standard_sub_basic( username, domain, tmp_string,
1656 sizeof(tmp_string) );
1658 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1660 else {
1661 pdb_set_logon_script(sampass,
1662 talloc_sub_basic(sampass, username, domain,
1663 lp_logon_script()),
1664 PDB_DEFAULT);
1667 if (profile_path) {
1668 fstrcpy( tmp_string, profile_path );
1669 if (expand_explicit) {
1670 standard_sub_basic( username, domain, tmp_string,
1671 sizeof(tmp_string) );
1673 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1675 else {
1676 pdb_set_profile_path(sampass,
1677 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1678 PDB_DEFAULT);
1681 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1682 pdb_set_comment(sampass, comment, PDB_SET);
1683 pdb_set_workstations(sampass, workstations, PDB_SET);
1684 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1686 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1687 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1688 ret = False;
1689 goto done;
1693 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1694 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1695 ret = False;
1696 goto done;
1700 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1701 if (pwHistLen) {
1702 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1703 if (!pw_hist) {
1704 ret = False;
1705 goto done;
1707 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1708 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1709 int i;
1710 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1711 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1712 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1713 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1714 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1715 PW_HISTORY_ENTRY_LEN);
1718 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1719 SAFE_FREE(pw_hist);
1720 ret = False;
1721 goto done;
1723 SAFE_FREE(pw_hist);
1724 } else {
1725 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1728 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1729 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1730 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1731 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1732 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1733 /* Change from V2 is the uint32_t acct_ctrl */
1734 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1735 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1736 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1738 done:
1740 SAFE_FREE(username);
1741 SAFE_FREE(domain);
1742 SAFE_FREE(nt_username);
1743 SAFE_FREE(fullname);
1744 SAFE_FREE(homedir);
1745 SAFE_FREE(dir_drive);
1746 SAFE_FREE(logon_script);
1747 SAFE_FREE(profile_path);
1748 SAFE_FREE(acct_desc);
1749 SAFE_FREE(workstations);
1750 SAFE_FREE(munged_dial);
1751 SAFE_FREE(comment);
1752 SAFE_FREE(lm_pw_ptr);
1753 SAFE_FREE(nt_pw_ptr);
1754 SAFE_FREE(nt_pw_hist_ptr);
1755 SAFE_FREE(hours);
1757 return ret;
1760 /*********************************************************************
1761 *********************************************************************/
1763 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1765 size_t len, buflen;
1767 /* times are stored as 32bit integer
1768 take care on system with 64bit wide time_t
1769 --SSS */
1770 uint32_t logon_time,
1771 logoff_time,
1772 kickoff_time,
1773 bad_password_time,
1774 pass_last_set_time,
1775 pass_can_change_time,
1776 pass_must_change_time;
1778 uint32_t user_rid, group_rid;
1780 const char *username;
1781 const char *domain;
1782 const char *nt_username;
1783 const char *dir_drive;
1784 const char *comment;
1785 const char *munged_dial;
1786 const char *fullname;
1787 const char *homedir;
1788 const char *logon_script;
1789 const char *profile_path;
1790 const char *acct_desc;
1791 const char *workstations;
1792 uint32_t username_len, domain_len, nt_username_len,
1793 dir_drive_len, comment_len, munged_dial_len,
1794 fullname_len, homedir_len, logon_script_len,
1795 profile_path_len, acct_desc_len, workstations_len;
1797 const uint8_t *lm_pw;
1798 const uint8_t *nt_pw;
1799 const uint8_t *nt_pw_hist;
1800 uint32_t lm_pw_len = 16;
1801 uint32_t nt_pw_len = 16;
1802 uint32_t nt_pw_hist_len;
1803 uint32_t pwHistLen = 0;
1805 *buf = NULL;
1806 buflen = 0;
1808 logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1809 logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1810 kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1811 bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1812 pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1813 pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1814 pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1816 user_rid = pdb_get_user_rid(sampass);
1817 group_rid = pdb_get_group_rid(sampass);
1819 username = pdb_get_username(sampass);
1820 if (username) {
1821 username_len = strlen(username) +1;
1822 } else {
1823 username_len = 0;
1826 domain = pdb_get_domain(sampass);
1827 if (domain) {
1828 domain_len = strlen(domain) +1;
1829 } else {
1830 domain_len = 0;
1833 nt_username = pdb_get_nt_username(sampass);
1834 if (nt_username) {
1835 nt_username_len = strlen(nt_username) +1;
1836 } else {
1837 nt_username_len = 0;
1840 fullname = pdb_get_fullname(sampass);
1841 if (fullname) {
1842 fullname_len = strlen(fullname) +1;
1843 } else {
1844 fullname_len = 0;
1848 * Only updates fields which have been set (not defaults from smb.conf)
1851 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1852 dir_drive = pdb_get_dir_drive(sampass);
1853 } else {
1854 dir_drive = NULL;
1856 if (dir_drive) {
1857 dir_drive_len = strlen(dir_drive) +1;
1858 } else {
1859 dir_drive_len = 0;
1862 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1863 homedir = pdb_get_homedir(sampass);
1864 } else {
1865 homedir = NULL;
1867 if (homedir) {
1868 homedir_len = strlen(homedir) +1;
1869 } else {
1870 homedir_len = 0;
1873 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1874 logon_script = pdb_get_logon_script(sampass);
1875 } else {
1876 logon_script = NULL;
1878 if (logon_script) {
1879 logon_script_len = strlen(logon_script) +1;
1880 } else {
1881 logon_script_len = 0;
1884 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1885 profile_path = pdb_get_profile_path(sampass);
1886 } else {
1887 profile_path = NULL;
1889 if (profile_path) {
1890 profile_path_len = strlen(profile_path) +1;
1891 } else {
1892 profile_path_len = 0;
1895 lm_pw = pdb_get_lanman_passwd(sampass);
1896 if (!lm_pw) {
1897 lm_pw_len = 0;
1900 nt_pw = pdb_get_nt_passwd(sampass);
1901 if (!nt_pw) {
1902 nt_pw_len = 0;
1905 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1906 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1907 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1908 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1909 } else {
1910 nt_pw_hist_len = 0;
1913 acct_desc = pdb_get_acct_desc(sampass);
1914 if (acct_desc) {
1915 acct_desc_len = strlen(acct_desc) +1;
1916 } else {
1917 acct_desc_len = 0;
1920 workstations = pdb_get_workstations(sampass);
1921 if (workstations) {
1922 workstations_len = strlen(workstations) +1;
1923 } else {
1924 workstations_len = 0;
1927 comment = pdb_get_comment(sampass);
1928 if (comment) {
1929 comment_len = strlen(comment) +1;
1930 } else {
1931 comment_len = 0;
1934 munged_dial = pdb_get_munged_dial(sampass);
1935 if (munged_dial) {
1936 munged_dial_len = strlen(munged_dial) +1;
1937 } else {
1938 munged_dial_len = 0;
1941 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1943 /* one time to get the size needed */
1944 len = tdb_pack(NULL, 0, SAMU_BUFFER_FORMAT_V3,
1945 logon_time, /* d */
1946 logoff_time, /* d */
1947 kickoff_time, /* d */
1948 bad_password_time, /* d */
1949 pass_last_set_time, /* d */
1950 pass_can_change_time, /* d */
1951 pass_must_change_time, /* d */
1952 username_len, username, /* B */
1953 domain_len, domain, /* B */
1954 nt_username_len, nt_username, /* B */
1955 fullname_len, fullname, /* B */
1956 homedir_len, homedir, /* B */
1957 dir_drive_len, dir_drive, /* B */
1958 logon_script_len, logon_script, /* B */
1959 profile_path_len, profile_path, /* B */
1960 acct_desc_len, acct_desc, /* B */
1961 workstations_len, workstations, /* B */
1962 comment_len, comment, /* B */
1963 munged_dial_len, munged_dial, /* B */
1964 user_rid, /* d */
1965 group_rid, /* d */
1966 lm_pw_len, lm_pw, /* B */
1967 nt_pw_len, nt_pw, /* B */
1968 nt_pw_hist_len, nt_pw_hist, /* B */
1969 pdb_get_acct_ctrl(sampass), /* d */
1970 pdb_get_logon_divs(sampass), /* w */
1971 pdb_get_hours_len(sampass), /* d */
1972 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1973 pdb_get_bad_password_count(sampass), /* w */
1974 pdb_get_logon_count(sampass), /* w */
1975 pdb_get_unknown_6(sampass)); /* d */
1977 if (size_only) {
1978 return buflen;
1981 /* malloc the space needed */
1982 if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
1983 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1984 return (-1);
1987 /* now for the real call to tdb_pack() */
1988 buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
1989 logon_time, /* d */
1990 logoff_time, /* d */
1991 kickoff_time, /* d */
1992 bad_password_time, /* d */
1993 pass_last_set_time, /* d */
1994 pass_can_change_time, /* d */
1995 pass_must_change_time, /* d */
1996 username_len, username, /* B */
1997 domain_len, domain, /* B */
1998 nt_username_len, nt_username, /* B */
1999 fullname_len, fullname, /* B */
2000 homedir_len, homedir, /* B */
2001 dir_drive_len, dir_drive, /* B */
2002 logon_script_len, logon_script, /* B */
2003 profile_path_len, profile_path, /* B */
2004 acct_desc_len, acct_desc, /* B */
2005 workstations_len, workstations, /* B */
2006 comment_len, comment, /* B */
2007 munged_dial_len, munged_dial, /* B */
2008 user_rid, /* d */
2009 group_rid, /* d */
2010 lm_pw_len, lm_pw, /* B */
2011 nt_pw_len, nt_pw, /* B */
2012 nt_pw_hist_len, nt_pw_hist, /* B */
2013 pdb_get_acct_ctrl(sampass), /* d */
2014 pdb_get_logon_divs(sampass), /* w */
2015 pdb_get_hours_len(sampass), /* d */
2016 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2017 pdb_get_bad_password_count(sampass), /* w */
2018 pdb_get_logon_count(sampass), /* w */
2019 pdb_get_unknown_6(sampass)); /* d */
2021 /* check to make sure we got it correct */
2022 if (buflen != len) {
2023 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2024 (unsigned long)buflen, (unsigned long)len));
2025 /* error */
2026 SAFE_FREE (*buf);
2027 return (-1);
2030 return (buflen);
2033 static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2035 /* nothing changed between V3 and V4 */
2036 return init_samu_from_buffer_v3(sampass, buf, buflen);
2039 static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2041 /* nothing changed between V3 and V4 */
2042 return init_buffer_from_samu_v3(buf, sampass, size_only);
2045 /**********************************************************************
2046 Intialize a struct samu struct from a BYTE buffer of size len
2047 *********************************************************************/
2049 bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2050 uint8_t *buf, uint32_t buflen)
2052 switch (level) {
2053 case SAMU_BUFFER_V0:
2054 return init_samu_from_buffer_v0(sampass, buf, buflen);
2055 case SAMU_BUFFER_V1:
2056 return init_samu_from_buffer_v1(sampass, buf, buflen);
2057 case SAMU_BUFFER_V2:
2058 return init_samu_from_buffer_v2(sampass, buf, buflen);
2059 case SAMU_BUFFER_V3:
2060 return init_samu_from_buffer_v3(sampass, buf, buflen);
2061 case SAMU_BUFFER_V4:
2062 return init_samu_from_buffer_v4(sampass, buf, buflen);
2065 return false;
2068 /**********************************************************************
2069 Intialize a BYTE buffer from a struct samu struct
2070 *********************************************************************/
2072 uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2074 return init_buffer_from_samu_v4(buf, sampass, size_only);
2077 /*********************************************************************
2078 *********************************************************************/
2080 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2082 uint8_t *buf = NULL;
2083 int len;
2085 len = init_buffer_from_samu(&buf, src, False);
2086 if (len == -1 || !buf) {
2087 SAFE_FREE(buf);
2088 return False;
2091 if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2092 free(buf);
2093 return False;
2096 dst->methods = src->methods;
2098 if ( src->unix_pw ) {
2099 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2100 if (!dst->unix_pw) {
2101 free(buf);
2102 return False;
2106 if (src->group_sid) {
2107 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2110 free(buf);
2111 return True;
2114 /*********************************************************************
2115 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2116 *********************************************************************/
2118 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2120 time_t LastBadPassword;
2121 uint16_t BadPasswordCount;
2122 uint32_t resettime;
2123 bool res;
2125 BadPasswordCount = pdb_get_bad_password_count(sampass);
2126 if (!BadPasswordCount) {
2127 DEBUG(9, ("No bad password attempts.\n"));
2128 return True;
2131 become_root();
2132 res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2133 unbecome_root();
2135 if (!res) {
2136 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2137 return False;
2140 /* First, check if there is a reset time to compare */
2141 if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2142 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2143 return True;
2146 LastBadPassword = pdb_get_bad_password_time(sampass);
2147 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2148 (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
2149 if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2150 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2151 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2152 if (updated) {
2153 *updated = True;
2157 return True;
2160 /*********************************************************************
2161 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2162 *********************************************************************/
2164 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2166 uint32_t duration;
2167 time_t LastBadPassword;
2168 bool res;
2170 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2171 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2172 pdb_get_username(sampass)));
2173 return True;
2176 become_root();
2177 res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2178 unbecome_root();
2180 if (!res) {
2181 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2182 return False;
2185 /* First, check if there is a duration to compare */
2186 if ((duration == (uint32_t) -1) || (duration == 0)) {
2187 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2188 return True;
2191 LastBadPassword = pdb_get_bad_password_time(sampass);
2192 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2193 pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
2195 if (LastBadPassword == (time_t)0) {
2196 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2197 "administratively locked out with no bad password "
2198 "time. Leaving locked out.\n",
2199 pdb_get_username(sampass) ));
2200 return True;
2203 if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2204 pdb_set_acct_ctrl(sampass,
2205 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2206 PDB_CHANGED);
2207 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2208 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2209 if (updated) {
2210 *updated = True;
2214 return True;
2217 /*********************************************************************
2218 Increment the bad_password_count
2219 *********************************************************************/
2221 bool pdb_increment_bad_password_count(struct samu *sampass)
2223 uint32_t account_policy_lockout;
2224 bool autolock_updated = False, badpw_updated = False;
2225 bool ret;
2227 /* Retrieve the account lockout policy */
2228 become_root();
2229 ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2230 unbecome_root();
2231 if ( !ret ) {
2232 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2233 return False;
2236 /* If there is no policy, we don't need to continue checking */
2237 if (!account_policy_lockout) {
2238 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2239 return True;
2242 /* Check if the autolock needs to be cleared */
2243 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2244 return False;
2246 /* Check if the badpw count needs to be reset */
2247 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2248 return False;
2251 Ok, now we can assume that any resetting that needs to be
2252 done has been done, and just get on with incrementing
2253 and autolocking if necessary
2256 pdb_set_bad_password_count(sampass,
2257 pdb_get_bad_password_count(sampass)+1,
2258 PDB_CHANGED);
2259 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2262 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2263 return True;
2265 if (!pdb_set_acct_ctrl(sampass,
2266 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2267 PDB_CHANGED)) {
2268 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2269 return False;
2272 return True;
2275 bool is_dc_trusted_domain_situation(const char *domain_name)
2277 return IS_DC && !strequal(domain_name, lp_workgroup());
2280 /*******************************************************************
2281 Wrapper around retrieving the clear text trust account password.
2282 appropriate account name is stored in account_name.
2283 Caller must free password, but not account_name.
2284 *******************************************************************/
2286 static bool get_trust_pw_clear2(const char *domain,
2287 const char **account_name,
2288 enum netr_SchannelType *channel,
2289 char **cur_pw,
2290 time_t *_last_set_time,
2291 char **prev_pw)
2293 char *pwd;
2294 time_t last_set_time;
2296 if (cur_pw != NULL) {
2297 *cur_pw = NULL;
2299 if (_last_set_time != NULL) {
2300 *_last_set_time = 0;
2302 if (prev_pw != NULL) {
2303 *prev_pw = NULL;
2306 /* if we are a DC and this is not our domain, then lookup an account
2307 * for the domain trust */
2309 if (is_dc_trusted_domain_situation(domain)) {
2310 if (!lp_allow_trusted_domains()) {
2311 return false;
2314 if (!pdb_get_trusteddom_pw(domain, cur_pw, NULL,
2315 &last_set_time))
2317 DEBUG(0, ("get_trust_pw: could not fetch trust "
2318 "account password for trusted domain %s\n",
2319 domain));
2320 return false;
2323 if (channel != NULL) {
2324 *channel = SEC_CHAN_DOMAIN;
2327 if (account_name != NULL) {
2328 *account_name = lp_workgroup();
2331 if (_last_set_time != NULL) {
2332 *_last_set_time = last_set_time;
2335 return true;
2339 * Since we can only be member of one single domain, we are now
2340 * in a member situation:
2342 * - Either we are a DC (selfjoined) and the domain is our
2343 * own domain.
2344 * - Or we are on a member and the domain is our own or some
2345 * other (potentially trusted) domain.
2347 * In both cases, we can only get the machine account password
2348 * for our own domain to connect to our own dc. (For a member,
2349 * request to trusted domains are performed through our dc.)
2351 * So we simply use our own domain name to retrieve the
2352 * machine account passowrd and ignore the request domain here.
2355 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2357 if (pwd != NULL) {
2358 struct timeval expire;
2360 *cur_pw = pwd;
2362 if (account_name != NULL) {
2363 *account_name = lp_netbios_name();
2366 if (_last_set_time != NULL) {
2367 *_last_set_time = last_set_time;
2370 if (prev_pw == NULL) {
2371 return true;
2374 ZERO_STRUCT(expire);
2375 expire.tv_sec = lp_machine_password_timeout();
2376 expire.tv_sec /= 2;
2377 expire.tv_sec += last_set_time;
2378 if (timeval_expired(&expire)) {
2379 return true;
2382 pwd = secrets_fetch_prev_machine_password(lp_workgroup());
2383 if (pwd != NULL) {
2384 *prev_pw = pwd;
2387 return true;
2390 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2391 "account password for domain %s\n", domain));
2392 return false;
2395 bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2396 const char **account_name,
2397 enum netr_SchannelType *channel)
2399 return get_trust_pw_clear2(domain,
2400 account_name,
2401 channel,
2402 ret_pwd,
2403 NULL,
2404 NULL);
2407 /*******************************************************************
2408 Wrapper around retrieving the trust account password.
2409 appropriate account name is stored in account_name.
2410 *******************************************************************/
2412 static bool get_trust_pw_hash2(const char *domain,
2413 const char **account_name,
2414 enum netr_SchannelType *channel,
2415 struct samr_Password *current_nt_hash,
2416 time_t *last_set_time,
2417 struct samr_Password **_previous_nt_hash)
2419 char *cur_pw = NULL;
2420 char *prev_pw = NULL;
2421 char **_prev_pw = NULL;
2422 bool ok;
2424 if (_previous_nt_hash != NULL) {
2425 *_previous_nt_hash = NULL;
2426 _prev_pw = &prev_pw;
2429 ok = get_trust_pw_clear2(domain, account_name, channel,
2430 &cur_pw, last_set_time, _prev_pw);
2431 if (ok) {
2432 struct samr_Password *previous_nt_hash = NULL;
2434 E_md4hash(cur_pw, current_nt_hash->hash);
2435 SAFE_FREE(cur_pw);
2437 if (prev_pw == NULL) {
2438 return true;
2441 previous_nt_hash = SMB_MALLOC_P(struct samr_Password);
2442 if (previous_nt_hash == NULL) {
2443 return false;
2446 E_md4hash(prev_pw, previous_nt_hash->hash);
2447 SAFE_FREE(prev_pw);
2449 *_previous_nt_hash = previous_nt_hash;
2450 return true;
2451 } else if (is_dc_trusted_domain_situation(domain)) {
2452 return false;
2455 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2457 if (secrets_fetch_trust_account_password_legacy(domain,
2458 current_nt_hash->hash,
2459 last_set_time,
2460 channel))
2462 if (account_name != NULL) {
2463 *account_name = lp_netbios_name();
2466 return true;
2469 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2470 "password for domain %s\n", domain));
2471 return False;
2474 bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2475 const char **account_name,
2476 enum netr_SchannelType *channel)
2478 struct samr_Password current_nt_hash;
2479 bool ok;
2481 ok = get_trust_pw_hash2(domain, account_name, channel,
2482 &current_nt_hash, NULL, NULL);
2483 if (!ok) {
2484 return false;
2487 memcpy(ret_pwd, current_nt_hash.hash, sizeof(current_nt_hash.hash));
2488 return true;
2491 NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
2492 const char *dns_domain, /* optional */
2493 TALLOC_CTX *mem_ctx,
2494 struct cli_credentials **_creds)
2496 TALLOC_CTX *frame = talloc_stackframe();
2497 NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
2498 struct loadparm_context *lp_ctx;
2499 enum netr_SchannelType channel;
2500 time_t last_set_time;
2501 const char *_account_name;
2502 const char *account_name;
2503 char *cur_pw = NULL;
2504 char *prev_pw = NULL;
2505 struct samr_Password cur_nt_hash;
2506 struct cli_credentials *creds = NULL;
2507 bool ok;
2510 * If this is our primary trust relationship, use the common
2511 * code to read the secrets.ldb or secrets.tdb file.
2513 if (strequal(netbios_domain, lp_workgroup())) {
2514 struct db_context *db_ctx = secrets_db_ctx();
2515 if (db_ctx == NULL) {
2516 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2517 netbios_domain));
2518 status = NT_STATUS_INTERNAL_ERROR;
2519 goto fail;
2522 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2523 if (lp_ctx == NULL) {
2524 DEBUG(1, ("loadparm_init_s3 failed\n"));
2525 status = NT_STATUS_INTERNAL_ERROR;
2526 goto fail;
2529 creds = cli_credentials_init(mem_ctx);
2530 if (creds == NULL) {
2531 status = NT_STATUS_NO_MEMORY;
2532 goto fail;
2535 cli_credentials_set_conf(creds, lp_ctx);
2537 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2538 if (!ok) {
2539 status = NT_STATUS_NO_MEMORY;
2540 goto fail;
2543 status = cli_credentials_set_machine_account_db_ctx(creds,
2544 lp_ctx,
2545 db_ctx);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 goto fail;
2549 goto done;
2550 } else if (!IS_DC) {
2551 DEBUG(1, ("Refusing to get trust account info for %s, "
2552 "which is not our primary domain %s, "
2553 "as we are not a DC\n",
2554 netbios_domain, lp_workgroup()));
2555 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2556 goto fail;
2559 status = pdb_get_trusteddom_creds(netbios_domain, mem_ctx, &creds);
2560 if (NT_STATUS_IS_OK(status)) {
2561 goto done;
2563 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
2564 goto fail;
2567 ok = get_trust_pw_clear2(netbios_domain,
2568 &_account_name,
2569 &channel,
2570 &cur_pw,
2571 &last_set_time,
2572 &prev_pw);
2573 if (!ok) {
2574 ok = get_trust_pw_hash2(netbios_domain,
2575 &_account_name,
2576 &channel,
2577 &cur_nt_hash,
2578 &last_set_time,
2579 NULL);
2580 if (!ok) {
2581 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2582 netbios_domain));
2583 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2584 goto fail;
2588 account_name = talloc_asprintf(frame, "%s$", _account_name);
2589 if (account_name == NULL) {
2590 status = NT_STATUS_NO_MEMORY;
2591 goto fail;
2594 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2595 if (lp_ctx == NULL) {
2596 DEBUG(1, ("loadparm_init_s3 failed\n"));
2597 status = NT_STATUS_INTERNAL_ERROR;
2598 goto fail;
2601 creds = cli_credentials_init(mem_ctx);
2602 if (creds == NULL) {
2603 status = NT_STATUS_NO_MEMORY;
2604 goto fail;
2607 cli_credentials_set_conf(creds, lp_ctx);
2609 cli_credentials_set_secure_channel_type(creds, channel);
2610 cli_credentials_set_password_last_changed_time(creds, last_set_time);
2612 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2613 if (!ok) {
2614 status = NT_STATUS_NO_MEMORY;
2615 goto fail;
2618 if (dns_domain != NULL) {
2619 ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
2620 if (!ok) {
2621 status = NT_STATUS_NO_MEMORY;
2622 goto fail;
2626 * It's not possible to use NTLMSSP with a domain trust account.
2628 cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
2629 } else {
2631 * We can't use kerberos against an NT4 domain.
2633 * We should have a mode that also disallows NTLMSSP here,
2634 * as only NETLOGON SCHANNEL is possible.
2636 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
2639 ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
2640 if (!ok) {
2641 status = NT_STATUS_NO_MEMORY;
2642 goto fail;
2645 if (cur_pw == NULL) {
2646 ok = cli_credentials_set_nt_hash(creds, &cur_nt_hash, CRED_SPECIFIED);
2647 if (!ok) {
2648 status = NT_STATUS_NO_MEMORY;
2649 goto fail;
2652 * We currently can't do kerberos just with an NTHASH.
2654 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
2655 goto done;
2658 ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
2659 if (!ok) {
2660 status = NT_STATUS_NO_MEMORY;
2661 goto fail;
2664 if (prev_pw != NULL) {
2665 ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
2666 if (!ok) {
2667 status = NT_STATUS_NO_MEMORY;
2668 goto fail;
2672 done:
2673 *_creds = creds;
2674 creds = NULL;
2675 status = NT_STATUS_OK;
2676 fail:
2677 TALLOC_FREE(creds);
2678 SAFE_FREE(cur_pw);
2679 SAFE_FREE(prev_pw);
2680 TALLOC_FREE(frame);
2681 return status;