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 2 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, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DBGC_CLASS DBGC_PASSDB
31 /******************************************************************
32 get the default domain/netbios name to be used when
33 testing authentication. For example, if you connect
34 to a Windows member server using a bogus domain name, the
35 Windows box will map the BOGUS\user to DOMAIN\user. A
36 standalone box will map to WKS\user.
37 ******************************************************************/
39 const char *my_sam_name(void)
41 /* standalone servers can only use the local netbios name */
42 if ( lp_server_role() == ROLE_STANDALONE )
43 return global_myname();
45 /* Windows domain members default to the DOMAIN
46 name when not specified */
47 return lp_workgroup();
50 /**********************************************************************
51 ***********************************************************************/
53 static int samu_destroy(void *p)
55 struct samu *user = p;
57 data_blob_clear_free( &user->lm_pw );
58 data_blob_clear_free( &user->nt_pw );
60 if ( user->plaintext_pw )
61 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
66 /**********************************************************************
67 generate a new struct samuser
68 ***********************************************************************/
70 struct samu* samu_new( TALLOC_CTX *ctx )
74 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
75 DEBUG(0,("samuser_new: Talloc failed!\n"));
79 talloc_set_destructor( user, samu_destroy );
81 /* no initial methods */
85 /* Don't change these timestamp settings without a good reason.
86 They are important for NT member server compatibility. */
88 user->logon_time = (time_t)0;
89 user->pass_last_set_time = (time_t)0;
90 user->pass_can_change_time = (time_t)0;
91 user->logoff_time = get_time_t_max();
92 user->kickoff_time = get_time_t_max();
93 user->pass_must_change_time = get_time_t_max();
94 user->fields_present = 0x00ffffff;
95 user->logon_divs = 168; /* hours per week */
96 user->hours_len = 21; /* 21 times 8 bits = 168 */
97 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
98 user->bad_password_count = 0;
99 user->logon_count = 0;
100 user->unknown_6 = 0x000004ec; /* don't know */
102 /* Some parts of samba strlen their pdb_get...() returns,
103 so this keeps the interface unchanged for now. */
107 user->nt_username = "";
108 user->full_name = "";
110 user->logon_script = "";
111 user->profile_path = "";
112 user->acct_desc = "";
113 user->workstations = "";
114 user->unknown_str = "";
115 user->munged_dial = "";
117 user->plaintext_pw = NULL;
119 /* Unless we know otherwise have a Account Control Bit
120 value of 'normal user'. This helps User Manager, which
121 asks for a filtered list of users. */
123 user->acct_ctrl = ACB_NORMAL;
129 /*********************************************************************
130 Initialize a struct samu from a struct passwd including the user
131 and group SIDs. The *user structure is filled out with the Unix
132 attributes and a user SID.
133 *********************************************************************/
135 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, BOOL create)
137 const char *guest_account = lp_guestaccount();
138 const char *domain = global_myname();
142 return NT_STATUS_NO_SUCH_USER;
145 /* Basic properties based upon the Unix account information */
147 pdb_set_username(user, pwd->pw_name, PDB_SET);
148 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
149 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
151 /* save the password structure for later use */
153 user->unix_pw = tcopy_passwd( user, pwd );
155 /* Special case for the guest account which must have a RID of 501 */
157 if ( strequal( pwd->pw_name, guest_account ) ) {
158 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
159 return NT_STATUS_NO_SUCH_USER;
164 /* Non-guest accounts...Check for a workstation or user account */
166 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
169 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
170 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
172 return NT_STATUS_INVALID_COMPUTER_NAME;
178 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
179 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
181 return NT_STATUS_INVALID_ACCOUNT_NAME;
184 /* set some basic attributes */
186 pdb_set_profile_path(user, talloc_sub_specified(user,
187 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
189 pdb_set_homedir(user, talloc_sub_specified(user,
190 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
192 pdb_set_dir_drive(user, talloc_sub_specified(user,
193 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
195 pdb_set_logon_script(user, talloc_sub_specified(user,
196 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
200 /* Now deal with the user SID. If we have a backend that can generate
201 RIDs, then do so. But sometimes the caller just wanted a structure
202 initialized and will fill in these fields later (such as from a
203 NET_USER_INFO_3 structure) */
205 if ( create && !pdb_rid_algorithm() ) {
209 if ( !pdb_new_rid( &user_rid ) ) {
210 DEBUG(3, ("Could not allocate a new RID\n"));
211 return NT_STATUS_ACCESS_DENIED;
214 sid_copy( &user_sid, get_global_sam_sid() );
215 sid_append_rid( &user_sid, user_rid );
217 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
218 DEBUG(3, ("pdb_set_user_sid failed\n"));
219 return NT_STATUS_INTERNAL_ERROR;
225 /* generate a SID for the user with the RID algorithm */
227 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
229 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
230 return NT_STATUS_INTERNAL_ERROR;
236 /********************************************************************
237 Set the Unix user attributes
238 ********************************************************************/
240 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
242 return samu_set_unix_internal( user, pwd, False );
245 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
247 return samu_set_unix_internal( user, pwd, True );
250 /**********************************************************
251 Encode the account control bits into a string.
252 length = length of string to encode into (including terminating
253 null). length *MUST BE MORE THAN 2* !
254 **********************************************************/
256 char *pdb_encode_acct_ctrl(uint32 acct_ctrl, size_t length)
258 static fstring acct_str;
262 SMB_ASSERT(length <= sizeof(acct_str));
266 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
267 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
268 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
269 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
270 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
271 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
272 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
273 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
274 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
275 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
276 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
278 for ( ; i < length - 2 ; i++ )
283 acct_str[i++] = '\0';
288 /**********************************************************
289 Decode the account control bits from a string.
290 **********************************************************/
292 uint32 pdb_decode_acct_ctrl(const char *p)
294 uint32 acct_ctrl = 0;
295 BOOL finished = False;
298 * Check if the account type bits have been encoded after the
299 * NT password (in the form [NDHTUWSLXI]).
305 for (p++; *p && !finished; p++) {
307 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
308 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
309 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
310 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
311 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
312 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
313 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
314 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
315 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
316 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
317 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
323 default: { finished = True; }
330 /*************************************************************
331 Routine to set 32 hex password characters from a 16 byte array.
332 **************************************************************/
334 void pdb_sethexpwd(char *p, const unsigned char *pwd, uint32 acct_ctrl)
338 for (i = 0; i < 16; i++)
339 slprintf(&p[i*2], 3, "%02X", pwd[i]);
341 if (acct_ctrl & ACB_PWNOTREQ)
342 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
344 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
348 /*************************************************************
349 Routine to get the 32 hex characters and turn them
350 into a 16 byte array.
351 **************************************************************/
353 BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
356 unsigned char lonybble, hinybble;
357 const char *hexchars = "0123456789ABCDEF";
363 for (i = 0; i < 32; i += 2) {
364 hinybble = toupper_ascii(p[i]);
365 lonybble = toupper_ascii(p[i + 1]);
367 p1 = strchr(hexchars, hinybble);
368 p2 = strchr(hexchars, lonybble);
373 hinybble = PTR_DIFF(p1, hexchars);
374 lonybble = PTR_DIFF(p2, hexchars);
376 pwd[i / 2] = (hinybble << 4) | lonybble;
381 /*************************************************************
382 Routine to set 42 hex hours characters from a 21 byte array.
383 **************************************************************/
385 void pdb_sethexhours(char *p, const unsigned char *hours)
389 for (i = 0; i < 21; i++) {
390 slprintf(&p[i*2], 3, "%02X", hours[i]);
393 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
397 /*************************************************************
398 Routine to get the 42 hex characters and turn them
399 into a 21 byte array.
400 **************************************************************/
402 BOOL pdb_gethexhours(const char *p, unsigned char *hours)
405 unsigned char lonybble, hinybble;
406 const char *hexchars = "0123456789ABCDEF";
413 for (i = 0; i < 42; i += 2) {
414 hinybble = toupper_ascii(p[i]);
415 lonybble = toupper_ascii(p[i + 1]);
417 p1 = strchr(hexchars, hinybble);
418 p2 = strchr(hexchars, lonybble);
424 hinybble = PTR_DIFF(p1, hexchars);
425 lonybble = PTR_DIFF(p2, hexchars);
427 hours[i / 2] = (hinybble << 4) | lonybble;
432 /********************************************************************
433 ********************************************************************/
435 int algorithmic_rid_base(void)
437 static int rid_offset = 0;
442 rid_offset = lp_algorithmic_rid_base();
444 if (rid_offset < BASE_RID) {
445 /* Try to prevent admin foot-shooting, we can't put algorithmic
446 rids below 1000, that's the 'well known RIDs' on NT */
447 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
448 rid_offset = BASE_RID;
450 if (rid_offset & 1) {
451 DEBUG(0, ("algorithmic rid base must be even\n"));
457 /*******************************************************************
458 Converts NT user RID to a UNIX uid.
459 ********************************************************************/
461 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
463 int rid_offset = algorithmic_rid_base();
464 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
467 uid_t max_algorithmic_uid(void)
469 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
472 /*******************************************************************
473 converts UNIX uid to an NT User RID.
474 ********************************************************************/
476 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
478 int rid_offset = algorithmic_rid_base();
479 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
482 /*******************************************************************
483 Converts NT group RID to a UNIX gid.
484 ********************************************************************/
486 gid_t pdb_group_rid_to_gid(uint32 group_rid)
488 int rid_offset = algorithmic_rid_base();
489 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
492 gid_t max_algorithmic_gid(void)
494 return pdb_group_rid_to_gid(0xffffffff);
497 /*******************************************************************
498 converts NT Group RID to a UNIX uid.
500 warning: you must not call that function only
501 you must do a call to the group mapping first.
502 there is not anymore a direct link between the gid and the rid.
503 ********************************************************************/
505 uint32 pdb_gid_to_group_rid(gid_t gid)
507 int rid_offset = algorithmic_rid_base();
508 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
511 /*******************************************************************
512 Decides if a RID is a well known RID.
513 ********************************************************************/
515 static BOOL rid_is_well_known(uint32 rid)
517 /* Not using rid_offset here, because this is the actual
518 NT fixed value (1000) */
520 return (rid < BASE_RID);
523 /*******************************************************************
524 Decides if a RID is a user or group RID.
525 ********************************************************************/
527 BOOL algorithmic_pdb_rid_is_user(uint32 rid)
529 if ( rid_is_well_known(rid) ) {
531 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
532 * and DOMAIN_USER_RID_GUEST.
534 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
536 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
542 /*******************************************************************
543 Convert a name into a SID. Used in the lookup name rpc.
544 ********************************************************************/
546 BOOL lookup_global_sam_name(const char *user, int flags, uint32_t *rid,
547 enum SID_NAME_USE *type)
552 /* Windows treats "MACHINE\None" as a special name for
553 rid 513 on non-DCs. You cannot create a user or group
554 name "None" on Windows. You will get an error that
555 the group already exists. */
557 if ( strequal( user, "None" ) ) {
558 *rid = DOMAIN_GROUP_RID_USERS;
559 *type = SID_NAME_DOM_GRP;
564 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
565 * correctly in the case where foo also exists as a user. If the flag
566 * is set, don't look for users at all. */
568 if ((flags & LOOKUP_NAME_GROUP) == 0) {
569 struct samu *sam_account = NULL;
572 if ( !(sam_account = samu_new( NULL )) ) {
577 ret = pdb_getsampwnam(sam_account, user);
581 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
584 TALLOC_FREE(sam_account);
587 if (!sid_check_is_in_our_domain(&user_sid)) {
588 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
589 user, sid_string_static(&user_sid)));
593 sid_peek_rid(&user_sid, rid);
594 *type = SID_NAME_USER;
600 * Maybe it is a group ?
604 ret = pdb_getgrnam(&map, user);
611 /* BUILTIN groups are looked up elsewhere */
612 if (!sid_check_is_in_our_domain(&map.sid)) {
613 DEBUG(10, ("Found group %s (%s) not in our domain -- "
615 sid_string_static(&map.sid)));
619 /* yes it's a mapped group */
620 sid_peek_rid(&map.sid, rid);
621 *type = map.sid_name_use;
625 /*************************************************************
626 Change a password entry in the local smbpasswd file.
627 *************************************************************/
629 NTSTATUS local_password_change(const char *user_name, int local_flags,
630 const char *new_passwd,
631 char *err_str, size_t err_str_len,
632 char *msg_str, size_t msg_str_len)
634 struct samu *sam_pass=NULL;
641 /* Get the smb passwd entry for this user */
643 if ( !(sam_pass = samu_new( NULL )) ) {
644 return NT_STATUS_NO_MEMORY;
648 if(!pdb_getsampwnam(sam_pass, user_name)) {
650 TALLOC_FREE(sam_pass);
652 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
653 int tmp_debug = DEBUGLEVEL;
656 /* Might not exist in /etc/passwd. */
662 if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) {
663 return NT_STATUS_NO_SUCH_USER;
666 /* create the struct samu and initialize the basic Unix properties */
668 if ( !(sam_pass = samu_new( NULL )) ) {
669 return NT_STATUS_NO_MEMORY;
672 result = samu_set_unix( sam_pass, pwd );
674 DEBUGLEVEL = tmp_debug;
678 if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) {
682 if (!NT_STATUS_IS_OK(result)) {
683 slprintf(err_str, err_str_len-1, "Failed to " "initialize account for user %s: %s\n",
684 user_name, nt_errstr(result));
688 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
689 return NT_STATUS_NO_SUCH_USER;
693 /* the entry already existed */
694 local_flags &= ~LOCAL_ADD_USER;
697 /* the 'other' acb bits not being changed here */
698 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
699 if (local_flags & LOCAL_TRUST_ACCOUNT) {
700 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
701 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
702 TALLOC_FREE(sam_pass);
703 return NT_STATUS_UNSUCCESSFUL;
705 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
706 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
707 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
708 TALLOC_FREE(sam_pass);
709 return NT_STATUS_UNSUCCESSFUL;
712 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
713 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
714 TALLOC_FREE(sam_pass);
715 return NT_STATUS_UNSUCCESSFUL;
720 * We are root - just write the new password
721 * and the valid last change time.
724 if (local_flags & LOCAL_DISABLE_USER) {
725 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
726 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
727 TALLOC_FREE(sam_pass);
728 return NT_STATUS_UNSUCCESSFUL;
730 } else if (local_flags & LOCAL_ENABLE_USER) {
731 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
732 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
733 TALLOC_FREE(sam_pass);
734 return NT_STATUS_UNSUCCESSFUL;
738 if (local_flags & LOCAL_SET_NO_PASSWORD) {
739 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
740 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
741 TALLOC_FREE(sam_pass);
742 return NT_STATUS_UNSUCCESSFUL;
744 } else if (local_flags & LOCAL_SET_PASSWORD) {
746 * If we're dealing with setting a completely empty user account
747 * ie. One with a password of 'XXXX', but not set disabled (like
748 * an account created from scratch) then if the old password was
749 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
750 * We remove that as we're giving this user their first password
751 * and the decision hasn't really been made to disable them (ie.
752 * don't create them disabled). JRA.
754 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
755 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
756 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
757 TALLOC_FREE(sam_pass);
758 return NT_STATUS_UNSUCCESSFUL;
761 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
762 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
763 TALLOC_FREE(sam_pass);
764 return NT_STATUS_UNSUCCESSFUL;
767 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
768 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
769 TALLOC_FREE(sam_pass);
770 return NT_STATUS_UNSUCCESSFUL;
774 if (local_flags & LOCAL_ADD_USER) {
775 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
776 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
777 TALLOC_FREE(sam_pass);
780 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
781 TALLOC_FREE(sam_pass);
782 return NT_STATUS_UNSUCCESSFUL;
784 } else if (local_flags & LOCAL_DELETE_USER) {
785 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
786 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
787 TALLOC_FREE(sam_pass);
788 return NT_STATUS_UNSUCCESSFUL;
790 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
792 result = pdb_update_sam_account(sam_pass);
793 if(!NT_STATUS_IS_OK(result)) {
794 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
795 TALLOC_FREE(sam_pass);
798 if(local_flags & LOCAL_DISABLE_USER)
799 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
800 else if (local_flags & LOCAL_ENABLE_USER)
801 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
802 else if (local_flags & LOCAL_SET_NO_PASSWORD)
803 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
806 TALLOC_FREE(sam_pass);
810 /**********************************************************************
811 Marshall/unmarshall struct samu structs.
812 *********************************************************************/
814 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
816 /*********************************************************************
817 *********************************************************************/
819 BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
822 /* times are stored as 32bit integer
823 take care on system with 64bit wide time_t
830 pass_can_change_time,
831 pass_must_change_time;
832 char *username = NULL;
834 char *nt_username = NULL;
835 char *dir_drive = NULL;
836 char *unknown_str = NULL;
837 char *munged_dial = NULL;
838 char *fullname = NULL;
839 char *homedir = NULL;
840 char *logon_script = NULL;
841 char *profile_path = NULL;
842 char *acct_desc = NULL;
843 char *workstations = NULL;
844 uint32 username_len, domain_len, nt_username_len,
845 dir_drive_len, unknown_str_len, munged_dial_len,
846 fullname_len, homedir_len, logon_script_len,
847 profile_path_len, acct_desc_len, workstations_len;
849 uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
851 uint16 bad_password_count, logon_count;
853 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
855 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
856 uint32 pwHistLen = 0;
859 BOOL expand_explicit = lp_passdb_expand_explicit();
861 if(sampass == NULL || buf == NULL) {
862 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
866 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
868 /* unpack the buffer into variables */
869 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V3,
871 &logoff_time, /* d */
872 &kickoff_time, /* d */
873 &bad_password_time, /* d */
874 &pass_last_set_time, /* d */
875 &pass_can_change_time, /* d */
876 &pass_must_change_time, /* d */
877 &username_len, &username, /* B */
878 &domain_len, &domain, /* B */
879 &nt_username_len, &nt_username, /* B */
880 &fullname_len, &fullname, /* B */
881 &homedir_len, &homedir, /* B */
882 &dir_drive_len, &dir_drive, /* B */
883 &logon_script_len, &logon_script, /* B */
884 &profile_path_len, &profile_path, /* B */
885 &acct_desc_len, &acct_desc, /* B */
886 &workstations_len, &workstations, /* B */
887 &unknown_str_len, &unknown_str, /* B */
888 &munged_dial_len, &munged_dial, /* B */
891 &lm_pw_len, &lm_pw_ptr, /* B */
892 &nt_pw_len, &nt_pw_ptr, /* B */
893 /* Change from V1 is addition of password history field. */
894 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
895 /* Change from V2 is the uint32 acb_mask */
897 /* Also "remove_me" field was removed. */
900 &hourslen, &hours, /* B */
901 &bad_password_count, /* w */
902 &logon_count, /* w */
905 if (len == (uint32) -1) {
910 pdb_set_logon_time(sampass, logon_time, PDB_SET);
911 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
912 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
913 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
914 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
915 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
916 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
918 pdb_set_username(sampass, username, PDB_SET);
919 pdb_set_domain(sampass, domain, PDB_SET);
920 pdb_set_nt_username(sampass, nt_username, PDB_SET);
921 pdb_set_fullname(sampass, fullname, PDB_SET);
924 fstrcpy( tmpstring, homedir );
925 if (expand_explicit) {
926 standard_sub_basic( username, tmpstring,
929 pdb_set_homedir(sampass, tmpstring, PDB_SET);
932 pdb_set_homedir(sampass,
933 talloc_sub_basic(sampass, username, lp_logon_home()),
938 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
940 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
943 fstrcpy( tmpstring, logon_script );
944 if (expand_explicit) {
945 standard_sub_basic( username, tmpstring,
948 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
951 pdb_set_logon_script(sampass,
952 talloc_sub_basic(sampass, username, lp_logon_script()),
957 fstrcpy( tmpstring, profile_path );
958 if (expand_explicit) {
959 standard_sub_basic( username, tmpstring,
962 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
965 pdb_set_profile_path(sampass,
966 talloc_sub_basic(sampass, username, lp_logon_path()),
970 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
971 pdb_set_workstations(sampass, workstations, PDB_SET);
972 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
974 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
975 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
981 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
982 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
988 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
990 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
995 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
996 if (nt_pw_hist_ptr && nt_pw_hist_len) {
998 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
999 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1000 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1001 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1002 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1003 PW_HISTORY_ENTRY_LEN);
1006 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1013 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1016 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1017 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1018 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1019 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1020 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1021 /* Change from V2 is the uint32 acct_ctrl */
1022 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1023 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1024 pdb_set_hours(sampass, hours, PDB_SET);
1028 SAFE_FREE(username);
1030 SAFE_FREE(nt_username);
1031 SAFE_FREE(fullname);
1033 SAFE_FREE(dir_drive);
1034 SAFE_FREE(logon_script);
1035 SAFE_FREE(profile_path);
1036 SAFE_FREE(acct_desc);
1037 SAFE_FREE(workstations);
1038 SAFE_FREE(munged_dial);
1039 SAFE_FREE(unknown_str);
1040 SAFE_FREE(lm_pw_ptr);
1041 SAFE_FREE(nt_pw_ptr);
1042 SAFE_FREE(nt_pw_hist_ptr);
1048 /*********************************************************************
1049 *********************************************************************/
1051 uint32 init_buffer_from_sam_v3 (uint8 **buf, struct samu *sampass, BOOL size_only)
1055 /* times are stored as 32bit integer
1056 take care on system with 64bit wide time_t
1063 pass_can_change_time,
1064 pass_must_change_time;
1066 uint32 user_rid, group_rid;
1068 const char *username;
1070 const char *nt_username;
1071 const char *dir_drive;
1072 const char *unknown_str;
1073 const char *munged_dial;
1074 const char *fullname;
1075 const char *homedir;
1076 const char *logon_script;
1077 const char *profile_path;
1078 const char *acct_desc;
1079 const char *workstations;
1080 uint32 username_len, domain_len, nt_username_len,
1081 dir_drive_len, unknown_str_len, munged_dial_len,
1082 fullname_len, homedir_len, logon_script_len,
1083 profile_path_len, acct_desc_len, workstations_len;
1087 const uint8 *nt_pw_hist;
1088 uint32 lm_pw_len = 16;
1089 uint32 nt_pw_len = 16;
1090 uint32 nt_pw_hist_len;
1091 uint32 pwHistLen = 0;
1093 /* do we have a valid struct samu pointer? */
1094 if (sampass == NULL) {
1095 DEBUG(0, ("init_buffer_from_sam: struct samu is NULL!\n"));
1102 logon_time = (uint32)pdb_get_logon_time(sampass);
1103 logoff_time = (uint32)pdb_get_logoff_time(sampass);
1104 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
1105 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
1106 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
1107 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
1108 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
1110 user_rid = pdb_get_user_rid(sampass);
1111 group_rid = pdb_get_group_rid(sampass);
1113 username = pdb_get_username(sampass);
1115 username_len = strlen(username) +1;
1120 domain = pdb_get_domain(sampass);
1122 domain_len = strlen(domain) +1;
1127 nt_username = pdb_get_nt_username(sampass);
1129 nt_username_len = strlen(nt_username) +1;
1131 nt_username_len = 0;
1134 fullname = pdb_get_fullname(sampass);
1136 fullname_len = strlen(fullname) +1;
1142 * Only updates fields which have been set (not defaults from smb.conf)
1145 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1146 dir_drive = pdb_get_dir_drive(sampass);
1151 dir_drive_len = strlen(dir_drive) +1;
1156 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1157 homedir = pdb_get_homedir(sampass);
1162 homedir_len = strlen(homedir) +1;
1167 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1168 logon_script = pdb_get_logon_script(sampass);
1170 logon_script = NULL;
1173 logon_script_len = strlen(logon_script) +1;
1175 logon_script_len = 0;
1178 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1179 profile_path = pdb_get_profile_path(sampass);
1181 profile_path = NULL;
1184 profile_path_len = strlen(profile_path) +1;
1186 profile_path_len = 0;
1189 lm_pw = pdb_get_lanman_passwd(sampass);
1194 nt_pw = pdb_get_nt_passwd(sampass);
1199 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1200 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1201 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1202 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1207 acct_desc = pdb_get_acct_desc(sampass);
1209 acct_desc_len = strlen(acct_desc) +1;
1214 workstations = pdb_get_workstations(sampass);
1216 workstations_len = strlen(workstations) +1;
1218 workstations_len = 0;
1222 unknown_str_len = 0;
1224 munged_dial = pdb_get_munged_dial(sampass);
1226 munged_dial_len = strlen(munged_dial) +1;
1228 munged_dial_len = 0;
1231 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1233 /* one time to get the size needed */
1234 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V3,
1236 logoff_time, /* d */
1237 kickoff_time, /* d */
1238 bad_password_time, /* d */
1239 pass_last_set_time, /* d */
1240 pass_can_change_time, /* d */
1241 pass_must_change_time, /* d */
1242 username_len, username, /* B */
1243 domain_len, domain, /* B */
1244 nt_username_len, nt_username, /* B */
1245 fullname_len, fullname, /* B */
1246 homedir_len, homedir, /* B */
1247 dir_drive_len, dir_drive, /* B */
1248 logon_script_len, logon_script, /* B */
1249 profile_path_len, profile_path, /* B */
1250 acct_desc_len, acct_desc, /* B */
1251 workstations_len, workstations, /* B */
1252 unknown_str_len, unknown_str, /* B */
1253 munged_dial_len, munged_dial, /* B */
1256 lm_pw_len, lm_pw, /* B */
1257 nt_pw_len, nt_pw, /* B */
1258 nt_pw_hist_len, nt_pw_hist, /* B */
1259 pdb_get_acct_ctrl(sampass), /* d */
1260 pdb_get_logon_divs(sampass), /* w */
1261 pdb_get_hours_len(sampass), /* d */
1262 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1263 pdb_get_bad_password_count(sampass), /* w */
1264 pdb_get_logon_count(sampass), /* w */
1265 pdb_get_unknown_6(sampass)); /* d */
1271 /* malloc the space needed */
1272 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1273 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1277 /* now for the real call to tdb_pack() */
1278 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V3,
1280 logoff_time, /* d */
1281 kickoff_time, /* d */
1282 bad_password_time, /* d */
1283 pass_last_set_time, /* d */
1284 pass_can_change_time, /* d */
1285 pass_must_change_time, /* d */
1286 username_len, username, /* B */
1287 domain_len, domain, /* B */
1288 nt_username_len, nt_username, /* B */
1289 fullname_len, fullname, /* B */
1290 homedir_len, homedir, /* B */
1291 dir_drive_len, dir_drive, /* B */
1292 logon_script_len, logon_script, /* B */
1293 profile_path_len, profile_path, /* B */
1294 acct_desc_len, acct_desc, /* B */
1295 workstations_len, workstations, /* B */
1296 unknown_str_len, unknown_str, /* B */
1297 munged_dial_len, munged_dial, /* B */
1300 lm_pw_len, lm_pw, /* B */
1301 nt_pw_len, nt_pw, /* B */
1302 nt_pw_hist_len, nt_pw_hist, /* B */
1303 pdb_get_acct_ctrl(sampass), /* d */
1304 pdb_get_logon_divs(sampass), /* w */
1305 pdb_get_hours_len(sampass), /* d */
1306 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1307 pdb_get_bad_password_count(sampass), /* w */
1308 pdb_get_logon_count(sampass), /* w */
1309 pdb_get_unknown_6(sampass)); /* d */
1311 /* check to make sure we got it correct */
1312 if (buflen != len) {
1313 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1314 (unsigned long)buflen, (unsigned long)len));
1324 /*********************************************************************
1325 *********************************************************************/
1327 BOOL pdb_copy_sam_account(struct samu *dst, struct samu *src )
1336 len = init_buffer_from_sam_v3(&buf, src, False);
1341 result = init_sam_from_buffer_v3( dst, buf, len );
1342 dst->methods = src->methods;
1345 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
1352 /*********************************************************************
1353 Update the bad password count checking the AP_RESET_COUNT_TIME
1354 *********************************************************************/
1356 BOOL pdb_update_bad_password_count(struct samu *sampass, BOOL *updated)
1358 time_t LastBadPassword;
1359 uint16 BadPasswordCount;
1362 if (!sampass) return False;
1364 BadPasswordCount = pdb_get_bad_password_count(sampass);
1365 if (!BadPasswordCount) {
1366 DEBUG(9, ("No bad password attempts.\n"));
1370 if (!pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime)) {
1371 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1375 /* First, check if there is a reset time to compare */
1376 if ((resettime == (uint32) -1) || (resettime == 0)) {
1377 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1381 LastBadPassword = pdb_get_bad_password_time(sampass);
1382 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1383 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
1384 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
1385 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1386 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1395 /*********************************************************************
1396 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1397 *********************************************************************/
1399 BOOL pdb_update_autolock_flag(struct samu *sampass, BOOL *updated)
1402 time_t LastBadPassword;
1404 if (!sampass) return False;
1406 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
1407 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1408 pdb_get_username(sampass)));
1412 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
1413 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1417 /* First, check if there is a duration to compare */
1418 if ((duration == (uint32) -1) || (duration == 0)) {
1419 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1423 LastBadPassword = pdb_get_bad_password_time(sampass);
1424 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1425 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
1427 if (LastBadPassword == (time_t)0) {
1428 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
1429 bad password time. Leaving locked out.\n",
1430 pdb_get_username(sampass) ));
1434 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
1435 pdb_set_acct_ctrl(sampass,
1436 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
1438 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1439 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1448 /*********************************************************************
1449 Increment the bad_password_count
1450 *********************************************************************/
1452 BOOL pdb_increment_bad_password_count(struct samu *sampass)
1454 uint32 account_policy_lockout;
1455 BOOL autolock_updated = False, badpw_updated = False;
1461 /* Retrieve the account lockout policy */
1463 ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
1466 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1470 /* If there is no policy, we don't need to continue checking */
1471 if (!account_policy_lockout) {
1472 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1476 /* Check if the autolock needs to be cleared */
1477 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
1480 /* Check if the badpw count needs to be reset */
1481 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
1485 Ok, now we can assume that any resetting that needs to be
1486 done has been done, and just get on with incrementing
1487 and autolocking if necessary
1490 pdb_set_bad_password_count(sampass,
1491 pdb_get_bad_password_count(sampass)+1,
1493 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
1496 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
1499 if (!pdb_set_acct_ctrl(sampass,
1500 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
1502 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));