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/>.
28 #define DBGC_CLASS DBGC_PASSDB
30 /******************************************************************
31 get the default domain/netbios name to be used when
32 testing authentication. For example, if you connect
33 to a Windows member server using a bogus domain name, the
34 Windows box will map the BOGUS\user to DOMAIN\user. A
35 standalone box will map to WKS\user.
36 ******************************************************************/
38 const char *my_sam_name(void)
40 /* standalone servers can only use the local netbios name */
41 if ( lp_server_role() == ROLE_STANDALONE
)
42 return global_myname();
44 /* Windows domain members default to the DOMAIN
45 name when not specified */
46 return lp_workgroup();
49 /**********************************************************************
50 ***********************************************************************/
52 static int samu_destroy(struct samu
*user
)
54 data_blob_clear_free( &user
->lm_pw
);
55 data_blob_clear_free( &user
->nt_pw
);
57 if ( user
->plaintext_pw
)
58 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
63 /**********************************************************************
64 generate a new struct samuser
65 ***********************************************************************/
67 struct samu
*samu_new( TALLOC_CTX
*ctx
)
71 if ( !(user
= TALLOC_ZERO_P( ctx
, struct samu
)) ) {
72 DEBUG(0,("samuser_new: Talloc failed!\n"));
76 talloc_set_destructor( user
, samu_destroy
);
78 /* no initial methods */
82 /* Don't change these timestamp settings without a good reason.
83 They are important for NT member server compatibility. */
85 user
->logon_time
= (time_t)0;
86 user
->pass_last_set_time
= (time_t)0;
87 user
->pass_can_change_time
= (time_t)0;
88 user
->logoff_time
= get_time_t_max();
89 user
->kickoff_time
= get_time_t_max();
90 user
->pass_must_change_time
= get_time_t_max();
91 user
->fields_present
= 0x00ffffff;
92 user
->logon_divs
= 168; /* hours per week */
93 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
94 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
95 user
->bad_password_count
= 0;
96 user
->logon_count
= 0;
97 user
->unknown_6
= 0x000004ec; /* don't know */
99 /* Some parts of samba strlen their pdb_get...() returns,
100 so this keeps the interface unchanged for now. */
104 user
->nt_username
= "";
105 user
->full_name
= "";
107 user
->logon_script
= "";
108 user
->profile_path
= "";
109 user
->acct_desc
= "";
110 user
->workstations
= "";
112 user
->munged_dial
= "";
114 user
->plaintext_pw
= NULL
;
116 /* Unless we know otherwise have a Account Control Bit
117 value of 'normal user'. This helps User Manager, which
118 asks for a filtered list of users. */
120 user
->acct_ctrl
= ACB_NORMAL
;
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 samu
*user
, const struct passwd
*pwd
, bool create
)
134 const char *guest_account
= lp_guestaccount();
135 const char *domain
= global_myname();
139 return NT_STATUS_NO_SUCH_USER
;
142 /* Basic properties based upon the Unix account information */
144 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
145 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
146 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
148 /* This can lead to a primary group of S-1-22-2-XX which
149 will be rejected by other parts of the Samba code.
150 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
153 gid_to_sid(&group_sid
, pwd
->pw_gid
);
154 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
157 /* save the password structure for later use */
159 user
->unix_pw
= tcopy_passwd( user
, pwd
);
161 /* Special case for the guest account which must have a RID of 501 */
163 if ( strequal( pwd
->pw_name
, guest_account
) ) {
164 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_USER_RID_GUEST
, PDB_DEFAULT
)) {
165 return NT_STATUS_NO_SUCH_USER
;
170 /* Non-guest accounts...Check for a workstation or user account */
172 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
175 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
176 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
178 return NT_STATUS_INVALID_COMPUTER_NAME
;
184 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
185 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
187 return NT_STATUS_INVALID_ACCOUNT_NAME
;
190 /* set some basic attributes */
192 pdb_set_profile_path(user
, talloc_sub_specified(user
,
193 lp_logon_path(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
195 pdb_set_homedir(user
, talloc_sub_specified(user
,
196 lp_logon_home(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
198 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
199 lp_logon_drive(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
201 pdb_set_logon_script(user
, talloc_sub_specified(user
,
202 lp_logon_script(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
206 /* Now deal with the user SID. If we have a backend that can generate
207 RIDs, then do so. But sometimes the caller just wanted a structure
208 initialized and will fill in these fields later (such as from a
209 NET_USER_INFO_3 structure) */
211 if ( create
&& !pdb_rid_algorithm() ) {
215 if ( !pdb_new_rid( &user_rid
) ) {
216 DEBUG(3, ("Could not allocate a new RID\n"));
217 return NT_STATUS_ACCESS_DENIED
;
220 sid_copy( &user_sid
, get_global_sam_sid() );
221 sid_append_rid( &user_sid
, user_rid
);
223 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
224 DEBUG(3, ("pdb_set_user_sid failed\n"));
225 return NT_STATUS_INTERNAL_ERROR
;
231 /* generate a SID for the user with the RID algorithm */
233 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
235 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
236 return NT_STATUS_INTERNAL_ERROR
;
242 /********************************************************************
243 Set the Unix user attributes
244 ********************************************************************/
246 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
248 return samu_set_unix_internal( user
, pwd
, False
);
251 NTSTATUS
samu_alloc_rid_unix(struct samu
*user
, const struct passwd
*pwd
)
253 return samu_set_unix_internal( user
, pwd
, True
);
256 /**********************************************************
257 Encode the account control bits into a string.
258 length = length of string to encode into (including terminating
259 null). length *MUST BE MORE THAN 2* !
260 **********************************************************/
262 char *pdb_encode_acct_ctrl(uint32 acct_ctrl
, size_t length
)
269 SMB_ASSERT(length
<= sizeof(acct_str
));
273 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
274 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
275 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
276 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
277 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
278 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
279 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
280 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
281 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
282 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
283 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
285 for ( ; i
< length
- 2 ; i
++ )
290 acct_str
[i
++] = '\0';
292 result
= talloc_strdup(talloc_tos(), acct_str
);
293 SMB_ASSERT(result
!= NULL
);
297 /**********************************************************
298 Decode the account control bits from a string.
299 **********************************************************/
301 uint32
pdb_decode_acct_ctrl(const char *p
)
303 uint32 acct_ctrl
= 0;
304 bool finished
= False
;
307 * Check if the account type bits have been encoded after the
308 * NT password (in the form [NDHTUWSLXI]).
314 for (p
++; *p
&& !finished
; p
++) {
316 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
317 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
318 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
319 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
320 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
321 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
322 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
323 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
324 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
325 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
326 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
332 default: { finished
= True
; }
339 /*************************************************************
340 Routine to set 32 hex password characters from a 16 byte array.
341 **************************************************************/
343 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32 acct_ctrl
)
347 for (i
= 0; i
< 16; i
++)
348 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
350 if (acct_ctrl
& ACB_PWNOTREQ
)
351 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
353 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
357 /*************************************************************
358 Routine to get the 32 hex characters and turn them
359 into a 16 byte array.
360 **************************************************************/
362 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
365 unsigned char lonybble
, hinybble
;
366 const char *hexchars
= "0123456789ABCDEF";
372 for (i
= 0; i
< 32; i
+= 2) {
373 hinybble
= toupper_ascii(p
[i
]);
374 lonybble
= toupper_ascii(p
[i
+ 1]);
376 p1
= strchr(hexchars
, hinybble
);
377 p2
= strchr(hexchars
, lonybble
);
382 hinybble
= PTR_DIFF(p1
, hexchars
);
383 lonybble
= PTR_DIFF(p2
, hexchars
);
385 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
390 /*************************************************************
391 Routine to set 42 hex hours characters from a 21 byte array.
392 **************************************************************/
394 void pdb_sethexhours(char *p
, const unsigned char *hours
)
398 for (i
= 0; i
< 21; i
++) {
399 slprintf(&p
[i
*2], 3, "%02X", hours
[i
]);
402 safe_strcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
406 /*************************************************************
407 Routine to get the 42 hex characters and turn them
408 into a 21 byte array.
409 **************************************************************/
411 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
414 unsigned char lonybble
, hinybble
;
415 const char *hexchars
= "0123456789ABCDEF";
422 for (i
= 0; i
< 42; i
+= 2) {
423 hinybble
= toupper_ascii(p
[i
]);
424 lonybble
= toupper_ascii(p
[i
+ 1]);
426 p1
= strchr(hexchars
, hinybble
);
427 p2
= strchr(hexchars
, lonybble
);
433 hinybble
= PTR_DIFF(p1
, hexchars
);
434 lonybble
= PTR_DIFF(p2
, hexchars
);
436 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
441 /********************************************************************
442 ********************************************************************/
444 int algorithmic_rid_base(void)
446 static int rid_offset
= 0;
451 rid_offset
= lp_algorithmic_rid_base();
453 if (rid_offset
< BASE_RID
) {
454 /* Try to prevent admin foot-shooting, we can't put algorithmic
455 rids below 1000, that's the 'well known RIDs' on NT */
456 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
457 rid_offset
= BASE_RID
;
459 if (rid_offset
& 1) {
460 DEBUG(0, ("algorithmic rid base must be even\n"));
466 /*******************************************************************
467 Converts NT user RID to a UNIX uid.
468 ********************************************************************/
470 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
472 int rid_offset
= algorithmic_rid_base();
473 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
476 uid_t
max_algorithmic_uid(void)
478 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
481 /*******************************************************************
482 converts UNIX uid to an NT User RID.
483 ********************************************************************/
485 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
487 int rid_offset
= algorithmic_rid_base();
488 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
491 /*******************************************************************
492 Converts NT group RID to a UNIX gid.
493 ********************************************************************/
495 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
497 int rid_offset
= algorithmic_rid_base();
498 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
501 gid_t
max_algorithmic_gid(void)
503 return pdb_group_rid_to_gid(0xffffffff);
506 /*******************************************************************
507 converts NT Group RID to a UNIX uid.
509 warning: you must not call that function only
510 you must do a call to the group mapping first.
511 there is not anymore a direct link between the gid and the rid.
512 ********************************************************************/
514 uint32
algorithmic_pdb_gid_to_group_rid(gid_t gid
)
516 int rid_offset
= algorithmic_rid_base();
517 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
520 /*******************************************************************
521 Decides if a RID is a well known RID.
522 ********************************************************************/
524 static bool rid_is_well_known(uint32 rid
)
526 /* Not using rid_offset here, because this is the actual
527 NT fixed value (1000) */
529 return (rid
< BASE_RID
);
532 /*******************************************************************
533 Decides if a RID is a user or group RID.
534 ********************************************************************/
536 bool algorithmic_pdb_rid_is_user(uint32 rid
)
538 if ( rid_is_well_known(rid
) ) {
540 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
541 * and DOMAIN_USER_RID_GUEST.
543 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
545 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
551 /*******************************************************************
552 Convert a name into a SID. Used in the lookup name rpc.
553 ********************************************************************/
555 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
556 enum lsa_SidType
*type
)
561 /* Windows treats "MACHINE\None" as a special name for
562 rid 513 on non-DCs. You cannot create a user or group
563 name "None" on Windows. You will get an error that
564 the group already exists. */
566 if ( strequal( name
, "None" ) ) {
567 *rid
= DOMAIN_GROUP_RID_USERS
;
568 *type
= SID_NAME_DOM_GRP
;
573 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
574 * correctly in the case where foo also exists as a user. If the flag
575 * is set, don't look for users at all. */
577 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
578 struct samu
*sam_account
= NULL
;
581 if ( !(sam_account
= samu_new( NULL
)) ) {
586 ret
= pdb_getsampwnam(sam_account
, name
);
590 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
593 TALLOC_FREE(sam_account
);
596 if (!sid_check_is_in_our_domain(&user_sid
)) {
597 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
598 name
, sid_string_dbg(&user_sid
)));
602 sid_peek_rid(&user_sid
, rid
);
603 *type
= SID_NAME_USER
;
609 * Maybe it is a group ?
613 ret
= pdb_getgrnam(&map
, name
);
620 /* BUILTIN groups are looked up elsewhere */
621 if (!sid_check_is_in_our_domain(&map
.sid
)) {
622 DEBUG(10, ("Found group %s (%s) not in our domain -- "
623 "ignoring.", name
, sid_string_dbg(&map
.sid
)));
627 /* yes it's a mapped group */
628 sid_peek_rid(&map
.sid
, rid
);
629 *type
= map
.sid_name_use
;
633 /*************************************************************
634 Change a password entry in the local smbpasswd file.
635 *************************************************************/
637 NTSTATUS
local_password_change(const char *user_name
,
639 const char *new_passwd
,
643 struct samu
*sam_pass
=NULL
;
650 /* Get the smb passwd entry for this user */
652 if ( !(sam_pass
= samu_new( NULL
)) ) {
653 return NT_STATUS_NO_MEMORY
;
657 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
659 TALLOC_FREE(sam_pass
);
661 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
662 int tmp_debug
= DEBUGLEVEL
;
665 /* Might not exist in /etc/passwd. */
671 if ( !(pwd
= getpwnam_alloc( NULL
, user_name
)) ) {
672 return NT_STATUS_NO_SUCH_USER
;
675 /* create the struct samu and initialize the basic Unix properties */
677 if ( !(sam_pass
= samu_new( NULL
)) ) {
678 return NT_STATUS_NO_MEMORY
;
681 result
= samu_set_unix( sam_pass
, pwd
);
683 DEBUGLEVEL
= tmp_debug
;
687 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
691 if (!NT_STATUS_IS_OK(result
)) {
692 asprintf(pp_err_str
, "Failed to " "initialize account for user %s: %s\n",
693 user_name
, nt_errstr(result
));
697 asprintf(pp_err_str
, "Failed to find entry for user %s.\n", user_name
);
698 return NT_STATUS_NO_SUCH_USER
;
702 /* the entry already existed */
703 local_flags
&= ~LOCAL_ADD_USER
;
706 /* the 'other' acb bits not being changed here */
707 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (~(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
708 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
709 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
710 asprintf(pp_err_str
, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
);
711 TALLOC_FREE(sam_pass
);
712 return NT_STATUS_UNSUCCESSFUL
;
714 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
715 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
716 asprintf(pp_err_str
, "Failed to set 'domain trust account' flags for user %s.\n", user_name
);
717 TALLOC_FREE(sam_pass
);
718 return NT_STATUS_UNSUCCESSFUL
;
721 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
722 asprintf(pp_err_str
, "Failed to set 'normal account' flags for user %s.\n", user_name
);
723 TALLOC_FREE(sam_pass
);
724 return NT_STATUS_UNSUCCESSFUL
;
729 * We are root - just write the new password
730 * and the valid last change time.
733 if (local_flags
& LOCAL_DISABLE_USER
) {
734 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
735 asprintf(pp_err_str
, "Failed to set 'disabled' flag for user %s.\n", user_name
);
736 TALLOC_FREE(sam_pass
);
737 return NT_STATUS_UNSUCCESSFUL
;
739 } else if (local_flags
& LOCAL_ENABLE_USER
) {
740 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
741 asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
742 TALLOC_FREE(sam_pass
);
743 return NT_STATUS_UNSUCCESSFUL
;
747 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
748 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
749 asprintf(pp_err_str
, "Failed to set 'no password required' flag for user %s.\n", user_name
);
750 TALLOC_FREE(sam_pass
);
751 return NT_STATUS_UNSUCCESSFUL
;
753 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
755 * If we're dealing with setting a completely empty user account
756 * ie. One with a password of 'XXXX', but not set disabled (like
757 * an account created from scratch) then if the old password was
758 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
759 * We remove that as we're giving this user their first password
760 * and the decision hasn't really been made to disable them (ie.
761 * don't create them disabled). JRA.
763 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
764 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
765 asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
766 TALLOC_FREE(sam_pass
);
767 return NT_STATUS_UNSUCCESSFUL
;
770 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
771 asprintf(pp_err_str
, "Failed to unset 'no password required' flag for user %s.\n", user_name
);
772 TALLOC_FREE(sam_pass
);
773 return NT_STATUS_UNSUCCESSFUL
;
776 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
777 asprintf(pp_err_str
, "Failed to set password for user %s.\n", user_name
);
778 TALLOC_FREE(sam_pass
);
779 return NT_STATUS_UNSUCCESSFUL
;
783 if (local_flags
& LOCAL_ADD_USER
) {
784 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
785 asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
786 TALLOC_FREE(sam_pass
);
789 asprintf(pp_err_str
, "Failed to add entry for user %s.\n", user_name
);
790 TALLOC_FREE(sam_pass
);
791 return NT_STATUS_UNSUCCESSFUL
;
793 } else if (local_flags
& LOCAL_DELETE_USER
) {
794 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
795 asprintf(pp_err_str
, "Failed to delete entry for user %s.\n", user_name
);
796 TALLOC_FREE(sam_pass
);
797 return NT_STATUS_UNSUCCESSFUL
;
799 asprintf(pp_msg_str
, "Deleted user %s.\n", user_name
);
801 result
= pdb_update_sam_account(sam_pass
);
802 if(!NT_STATUS_IS_OK(result
)) {
803 asprintf(pp_err_str
, "Failed to modify entry for user %s.\n", user_name
);
804 TALLOC_FREE(sam_pass
);
807 if(local_flags
& LOCAL_DISABLE_USER
)
808 asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
809 else if (local_flags
& LOCAL_ENABLE_USER
)
810 asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
811 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
812 asprintf(pp_msg_str
, "User %s password set to none.\n", user_name
);
815 TALLOC_FREE(sam_pass
);
819 /**********************************************************************
820 Marshall/unmarshall struct samu structs.
821 *********************************************************************/
823 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
825 /*********************************************************************
826 *********************************************************************/
828 bool init_sam_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
831 /* times are stored as 32bit integer
832 take care on system with 64bit wide time_t
839 pass_can_change_time
,
840 pass_must_change_time
;
841 char *username
= NULL
;
843 char *nt_username
= NULL
;
844 char *dir_drive
= NULL
;
845 char *unknown_str
= NULL
;
846 char *munged_dial
= NULL
;
847 char *fullname
= NULL
;
848 char *homedir
= NULL
;
849 char *logon_script
= NULL
;
850 char *profile_path
= NULL
;
851 char *acct_desc
= NULL
;
852 char *workstations
= NULL
;
853 uint32 username_len
, domain_len
, nt_username_len
,
854 dir_drive_len
, unknown_str_len
, munged_dial_len
,
855 fullname_len
, homedir_len
, logon_script_len
,
856 profile_path_len
, acct_desc_len
, workstations_len
;
858 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
860 uint16 bad_password_count
, logon_count
;
862 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
864 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
865 uint32 pwHistLen
= 0;
868 bool expand_explicit
= lp_passdb_expand_explicit();
870 if(sampass
== NULL
|| buf
== NULL
) {
871 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
875 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
877 /* unpack the buffer into variables */
878 len
= tdb_unpack (buf
, buflen
, TDB_FORMAT_STRING_V3
,
880 &logoff_time
, /* d */
881 &kickoff_time
, /* d */
882 &bad_password_time
, /* d */
883 &pass_last_set_time
, /* d */
884 &pass_can_change_time
, /* d */
885 &pass_must_change_time
, /* d */
886 &username_len
, &username
, /* B */
887 &domain_len
, &domain
, /* B */
888 &nt_username_len
, &nt_username
, /* B */
889 &fullname_len
, &fullname
, /* B */
890 &homedir_len
, &homedir
, /* B */
891 &dir_drive_len
, &dir_drive
, /* B */
892 &logon_script_len
, &logon_script
, /* B */
893 &profile_path_len
, &profile_path
, /* B */
894 &acct_desc_len
, &acct_desc
, /* B */
895 &workstations_len
, &workstations
, /* B */
896 &unknown_str_len
, &unknown_str
, /* B */
897 &munged_dial_len
, &munged_dial
, /* B */
900 &lm_pw_len
, &lm_pw_ptr
, /* B */
901 &nt_pw_len
, &nt_pw_ptr
, /* B */
902 /* Change from V1 is addition of password history field. */
903 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
904 /* Change from V2 is the uint32 acb_mask */
906 /* Also "remove_me" field was removed. */
909 &hourslen
, &hours
, /* B */
910 &bad_password_count
, /* w */
911 &logon_count
, /* w */
914 if (len
== (uint32
) -1) {
919 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
920 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
921 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
922 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
923 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
924 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
925 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
927 pdb_set_username(sampass
, username
, PDB_SET
);
928 pdb_set_domain(sampass
, domain
, PDB_SET
);
929 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
930 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
933 fstrcpy( tmp_string
, homedir
);
934 if (expand_explicit
) {
935 standard_sub_basic( username
, domain
, tmp_string
,
936 sizeof(tmp_string
) );
938 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
941 pdb_set_homedir(sampass
,
942 talloc_sub_basic(sampass
, username
, domain
,
948 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
950 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
953 fstrcpy( tmp_string
, logon_script
);
954 if (expand_explicit
) {
955 standard_sub_basic( username
, domain
, tmp_string
,
956 sizeof(tmp_string
) );
958 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
961 pdb_set_logon_script(sampass
,
962 talloc_sub_basic(sampass
, username
, domain
,
968 fstrcpy( tmp_string
, profile_path
);
969 if (expand_explicit
) {
970 standard_sub_basic( username
, domain
, tmp_string
,
971 sizeof(tmp_string
) );
973 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
976 pdb_set_profile_path(sampass
,
977 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
981 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
982 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
983 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
985 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
986 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
992 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
993 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
999 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1001 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1006 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1007 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1009 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1010 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1011 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1012 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1013 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1014 PW_HISTORY_ENTRY_LEN
);
1017 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1024 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1027 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1028 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1029 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1030 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1031 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1032 /* Change from V2 is the uint32 acct_ctrl */
1033 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1034 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1035 pdb_set_hours(sampass
, hours
, PDB_SET
);
1039 SAFE_FREE(username
);
1041 SAFE_FREE(nt_username
);
1042 SAFE_FREE(fullname
);
1044 SAFE_FREE(dir_drive
);
1045 SAFE_FREE(logon_script
);
1046 SAFE_FREE(profile_path
);
1047 SAFE_FREE(acct_desc
);
1048 SAFE_FREE(workstations
);
1049 SAFE_FREE(munged_dial
);
1050 SAFE_FREE(unknown_str
);
1051 SAFE_FREE(lm_pw_ptr
);
1052 SAFE_FREE(nt_pw_ptr
);
1053 SAFE_FREE(nt_pw_hist_ptr
);
1059 /*********************************************************************
1060 *********************************************************************/
1062 uint32
init_buffer_from_sam_v3 (uint8
**buf
, struct samu
*sampass
, bool size_only
)
1066 /* times are stored as 32bit integer
1067 take care on system with 64bit wide time_t
1074 pass_can_change_time
,
1075 pass_must_change_time
;
1077 uint32 user_rid
, group_rid
;
1079 const char *username
;
1081 const char *nt_username
;
1082 const char *dir_drive
;
1083 const char *unknown_str
;
1084 const char *munged_dial
;
1085 const char *fullname
;
1086 const char *homedir
;
1087 const char *logon_script
;
1088 const char *profile_path
;
1089 const char *acct_desc
;
1090 const char *workstations
;
1091 uint32 username_len
, domain_len
, nt_username_len
,
1092 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1093 fullname_len
, homedir_len
, logon_script_len
,
1094 profile_path_len
, acct_desc_len
, workstations_len
;
1098 const uint8
*nt_pw_hist
;
1099 uint32 lm_pw_len
= 16;
1100 uint32 nt_pw_len
= 16;
1101 uint32 nt_pw_hist_len
;
1102 uint32 pwHistLen
= 0;
1107 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1108 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1109 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1110 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1111 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1112 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1113 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1115 user_rid
= pdb_get_user_rid(sampass
);
1116 group_rid
= pdb_get_group_rid(sampass
);
1118 username
= pdb_get_username(sampass
);
1120 username_len
= strlen(username
) +1;
1125 domain
= pdb_get_domain(sampass
);
1127 domain_len
= strlen(domain
) +1;
1132 nt_username
= pdb_get_nt_username(sampass
);
1134 nt_username_len
= strlen(nt_username
) +1;
1136 nt_username_len
= 0;
1139 fullname
= pdb_get_fullname(sampass
);
1141 fullname_len
= strlen(fullname
) +1;
1147 * Only updates fields which have been set (not defaults from smb.conf)
1150 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1151 dir_drive
= pdb_get_dir_drive(sampass
);
1156 dir_drive_len
= strlen(dir_drive
) +1;
1161 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1162 homedir
= pdb_get_homedir(sampass
);
1167 homedir_len
= strlen(homedir
) +1;
1172 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1173 logon_script
= pdb_get_logon_script(sampass
);
1175 logon_script
= NULL
;
1178 logon_script_len
= strlen(logon_script
) +1;
1180 logon_script_len
= 0;
1183 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1184 profile_path
= pdb_get_profile_path(sampass
);
1186 profile_path
= NULL
;
1189 profile_path_len
= strlen(profile_path
) +1;
1191 profile_path_len
= 0;
1194 lm_pw
= pdb_get_lanman_passwd(sampass
);
1199 nt_pw
= pdb_get_nt_passwd(sampass
);
1204 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1205 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1206 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1207 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1212 acct_desc
= pdb_get_acct_desc(sampass
);
1214 acct_desc_len
= strlen(acct_desc
) +1;
1219 workstations
= pdb_get_workstations(sampass
);
1221 workstations_len
= strlen(workstations
) +1;
1223 workstations_len
= 0;
1227 unknown_str_len
= 0;
1229 munged_dial
= pdb_get_munged_dial(sampass
);
1231 munged_dial_len
= strlen(munged_dial
) +1;
1233 munged_dial_len
= 0;
1236 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1238 /* one time to get the size needed */
1239 len
= tdb_pack(NULL
, 0, TDB_FORMAT_STRING_V3
,
1241 logoff_time
, /* d */
1242 kickoff_time
, /* d */
1243 bad_password_time
, /* d */
1244 pass_last_set_time
, /* d */
1245 pass_can_change_time
, /* d */
1246 pass_must_change_time
, /* d */
1247 username_len
, username
, /* B */
1248 domain_len
, domain
, /* B */
1249 nt_username_len
, nt_username
, /* B */
1250 fullname_len
, fullname
, /* B */
1251 homedir_len
, homedir
, /* B */
1252 dir_drive_len
, dir_drive
, /* B */
1253 logon_script_len
, logon_script
, /* B */
1254 profile_path_len
, profile_path
, /* B */
1255 acct_desc_len
, acct_desc
, /* B */
1256 workstations_len
, workstations
, /* B */
1257 unknown_str_len
, unknown_str
, /* B */
1258 munged_dial_len
, munged_dial
, /* B */
1261 lm_pw_len
, lm_pw
, /* B */
1262 nt_pw_len
, nt_pw
, /* B */
1263 nt_pw_hist_len
, nt_pw_hist
, /* B */
1264 pdb_get_acct_ctrl(sampass
), /* d */
1265 pdb_get_logon_divs(sampass
), /* w */
1266 pdb_get_hours_len(sampass
), /* d */
1267 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1268 pdb_get_bad_password_count(sampass
), /* w */
1269 pdb_get_logon_count(sampass
), /* w */
1270 pdb_get_unknown_6(sampass
)); /* d */
1276 /* malloc the space needed */
1277 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1278 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1282 /* now for the real call to tdb_pack() */
1283 buflen
= tdb_pack(*buf
, len
, TDB_FORMAT_STRING_V3
,
1285 logoff_time
, /* d */
1286 kickoff_time
, /* d */
1287 bad_password_time
, /* d */
1288 pass_last_set_time
, /* d */
1289 pass_can_change_time
, /* d */
1290 pass_must_change_time
, /* d */
1291 username_len
, username
, /* B */
1292 domain_len
, domain
, /* B */
1293 nt_username_len
, nt_username
, /* B */
1294 fullname_len
, fullname
, /* B */
1295 homedir_len
, homedir
, /* B */
1296 dir_drive_len
, dir_drive
, /* B */
1297 logon_script_len
, logon_script
, /* B */
1298 profile_path_len
, profile_path
, /* B */
1299 acct_desc_len
, acct_desc
, /* B */
1300 workstations_len
, workstations
, /* B */
1301 unknown_str_len
, unknown_str
, /* B */
1302 munged_dial_len
, munged_dial
, /* B */
1305 lm_pw_len
, lm_pw
, /* B */
1306 nt_pw_len
, nt_pw
, /* B */
1307 nt_pw_hist_len
, nt_pw_hist
, /* B */
1308 pdb_get_acct_ctrl(sampass
), /* d */
1309 pdb_get_logon_divs(sampass
), /* w */
1310 pdb_get_hours_len(sampass
), /* d */
1311 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1312 pdb_get_bad_password_count(sampass
), /* w */
1313 pdb_get_logon_count(sampass
), /* w */
1314 pdb_get_unknown_6(sampass
)); /* d */
1316 /* check to make sure we got it correct */
1317 if (buflen
!= len
) {
1318 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1319 (unsigned long)buflen
, (unsigned long)len
));
1329 /*********************************************************************
1330 *********************************************************************/
1332 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
1337 len
= init_buffer_from_sam_v3(&buf
, src
, False
);
1338 if (len
== -1 || !buf
) {
1343 if (!init_sam_from_buffer_v3( dst
, buf
, len
)) {
1348 dst
->methods
= src
->methods
;
1350 if ( src
->unix_pw
) {
1351 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
1352 if (!dst
->unix_pw
) {
1362 /*********************************************************************
1363 Update the bad password count checking the AP_RESET_COUNT_TIME
1364 *********************************************************************/
1366 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
1368 time_t LastBadPassword
;
1369 uint16 BadPasswordCount
;
1373 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
1374 if (!BadPasswordCount
) {
1375 DEBUG(9, ("No bad password attempts.\n"));
1380 res
= pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
);
1384 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1388 /* First, check if there is a reset time to compare */
1389 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
1390 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1394 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1395 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1396 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
1397 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
1398 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1399 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1408 /*********************************************************************
1409 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1410 *********************************************************************/
1412 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
1415 time_t LastBadPassword
;
1418 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
1419 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1420 pdb_get_username(sampass
)));
1425 res
= pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
);
1429 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1433 /* First, check if there is a duration to compare */
1434 if ((duration
== (uint32
) -1) || (duration
== 0)) {
1435 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1439 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1440 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1441 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
1443 if (LastBadPassword
== (time_t)0) {
1444 DEBUG(1,("pdb_update_autolock_flag: Account %s "
1445 "administratively locked out with no bad password "
1446 "time. Leaving locked out.\n",
1447 pdb_get_username(sampass
) ));
1451 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(duration
) * 60))) {
1452 pdb_set_acct_ctrl(sampass
,
1453 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
1455 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1456 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1465 /*********************************************************************
1466 Increment the bad_password_count
1467 *********************************************************************/
1469 bool pdb_increment_bad_password_count(struct samu
*sampass
)
1471 uint32 account_policy_lockout
;
1472 bool autolock_updated
= False
, badpw_updated
= False
;
1475 /* Retrieve the account lockout policy */
1477 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
1480 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1484 /* If there is no policy, we don't need to continue checking */
1485 if (!account_policy_lockout
) {
1486 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1490 /* Check if the autolock needs to be cleared */
1491 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
1494 /* Check if the badpw count needs to be reset */
1495 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
1499 Ok, now we can assume that any resetting that needs to be
1500 done has been done, and just get on with incrementing
1501 and autolocking if necessary
1504 pdb_set_bad_password_count(sampass
,
1505 pdb_get_bad_password_count(sampass
)+1,
1507 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
1510 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
1513 if (!pdb_set_acct_ctrl(sampass
,
1514 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
1516 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
1523 bool is_trusted_domain_situation(const char *domain_name
)
1526 lp_allow_trusted_domains() &&
1527 !strequal(domain_name
, lp_workgroup());
1530 /*******************************************************************
1531 Wrapper around retrieving the clear text trust account password.
1532 appropriate account name is stored in account_name.
1533 Caller must free password, but not account_name.
1534 *******************************************************************/
1536 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
1537 const char **account_name
, uint32
*channel
)
1540 time_t last_set_time
;
1542 /* if we are a DC and this is not our domain, then lookup an account
1543 * for the domain trust */
1545 if (is_trusted_domain_situation(domain
)) {
1546 if (!pdb_get_trusteddom_pw(domain
, ret_pwd
, NULL
,
1549 DEBUG(0, ("get_trust_pw: could not fetch trust "
1550 "account password for trusted domain %s\n",
1555 if (channel
!= NULL
) {
1556 *channel
= SEC_CHAN_DOMAIN
;
1559 if (account_name
!= NULL
) {
1560 *account_name
= lp_workgroup();
1566 /* Just get the account for the requested domain. In the future this
1567 * might also cover to be member of more than one domain. */
1569 pwd
= secrets_fetch_machine_password(domain
, &last_set_time
, channel
);
1573 if (account_name
!= NULL
) {
1574 *account_name
= global_myname();
1580 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
1581 "account password for domain %s\n", domain
));
1585 /*******************************************************************
1586 Wrapper around retrieving the trust account password.
1587 appropriate account name is stored in account_name.
1588 *******************************************************************/
1590 bool get_trust_pw_hash(const char *domain
, uint8 ret_pwd
[16],
1591 const char **account_name
, uint32
*channel
)
1594 time_t last_set_time
;
1596 if (get_trust_pw_clear(domain
, &pwd
, account_name
, channel
)) {
1597 E_md4hash(pwd
, ret_pwd
);
1600 } else if (is_trusted_domain_situation(domain
)) {
1604 /* as a fallback, try to get the hashed pwd directly from the tdb... */
1606 if (secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
1610 if (account_name
!= NULL
) {
1611 *account_name
= global_myname();
1617 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
1618 "password for domain %s\n", domain
));