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(struct samu
*user
)
55 data_blob_clear_free( &user
->lm_pw
);
56 data_blob_clear_free( &user
->nt_pw
);
58 if ( user
->plaintext_pw
)
59 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
64 /**********************************************************************
65 generate a new struct samuser
66 ***********************************************************************/
68 struct samu
*samu_new( TALLOC_CTX
*ctx
)
72 if ( !(user
= TALLOC_ZERO_P( ctx
, struct samu
)) ) {
73 DEBUG(0,("samuser_new: Talloc failed!\n"));
77 talloc_set_destructor( user
, samu_destroy
);
79 /* no initial methods */
83 /* Don't change these timestamp settings without a good reason.
84 They are important for NT member server compatibility. */
86 user
->logon_time
= (time_t)0;
87 user
->pass_last_set_time
= (time_t)0;
88 user
->pass_can_change_time
= (time_t)0;
89 user
->logoff_time
= get_time_t_max();
90 user
->kickoff_time
= get_time_t_max();
91 user
->pass_must_change_time
= get_time_t_max();
92 user
->fields_present
= 0x00ffffff;
93 user
->logon_divs
= 168; /* hours per week */
94 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
95 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
96 user
->bad_password_count
= 0;
97 user
->logon_count
= 0;
98 user
->unknown_6
= 0x000004ec; /* don't know */
100 /* Some parts of samba strlen their pdb_get...() returns,
101 so this keeps the interface unchanged for now. */
105 user
->nt_username
= "";
106 user
->full_name
= "";
108 user
->logon_script
= "";
109 user
->profile_path
= "";
110 user
->acct_desc
= "";
111 user
->workstations
= "";
113 user
->munged_dial
= "";
115 user
->plaintext_pw
= NULL
;
117 /* Unless we know otherwise have a Account Control Bit
118 value of 'normal user'. This helps User Manager, which
119 asks for a filtered list of users. */
121 user
->acct_ctrl
= ACB_NORMAL
;
127 /*********************************************************************
128 Initialize a struct samu from a struct passwd including the user
129 and group SIDs. The *user structure is filled out with the Unix
130 attributes and a user SID.
131 *********************************************************************/
133 static NTSTATUS
samu_set_unix_internal(struct samu
*user
, const struct passwd
*pwd
, BOOL create
)
135 const char *guest_account
= lp_guestaccount();
136 const char *domain
= global_myname();
140 return NT_STATUS_NO_SUCH_USER
;
143 /* Basic properties based upon the Unix account information */
145 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
146 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
147 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
149 /* This can lead to a primary group of S-1-22-2-XX which
150 will be rejected by other parts of the Samba code.
151 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
154 gid_to_sid(&group_sid
, pwd
->pw_gid
);
155 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
158 /* save the password structure for later use */
160 user
->unix_pw
= tcopy_passwd( user
, pwd
);
162 /* Special case for the guest account which must have a RID of 501 */
164 if ( strequal( pwd
->pw_name
, guest_account
) ) {
165 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_USER_RID_GUEST
, PDB_DEFAULT
)) {
166 return NT_STATUS_NO_SUCH_USER
;
171 /* Non-guest accounts...Check for a workstation or user account */
173 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
176 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
177 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
179 return NT_STATUS_INVALID_COMPUTER_NAME
;
185 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
186 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
188 return NT_STATUS_INVALID_ACCOUNT_NAME
;
191 /* set some basic attributes */
193 pdb_set_profile_path(user
, talloc_sub_specified(user
,
194 lp_logon_path(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
196 pdb_set_homedir(user
, talloc_sub_specified(user
,
197 lp_logon_home(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
199 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
200 lp_logon_drive(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
202 pdb_set_logon_script(user
, talloc_sub_specified(user
,
203 lp_logon_script(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
207 /* Now deal with the user SID. If we have a backend that can generate
208 RIDs, then do so. But sometimes the caller just wanted a structure
209 initialized and will fill in these fields later (such as from a
210 NET_USER_INFO_3 structure) */
212 if ( create
&& !pdb_rid_algorithm() ) {
216 if ( !pdb_new_rid( &user_rid
) ) {
217 DEBUG(3, ("Could not allocate a new RID\n"));
218 return NT_STATUS_ACCESS_DENIED
;
221 sid_copy( &user_sid
, get_global_sam_sid() );
222 sid_append_rid( &user_sid
, user_rid
);
224 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
225 DEBUG(3, ("pdb_set_user_sid failed\n"));
226 return NT_STATUS_INTERNAL_ERROR
;
232 /* generate a SID for the user with the RID algorithm */
234 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
236 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
237 return NT_STATUS_INTERNAL_ERROR
;
243 /********************************************************************
244 Set the Unix user attributes
245 ********************************************************************/
247 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
249 return samu_set_unix_internal( user
, pwd
, False
);
252 NTSTATUS
samu_alloc_rid_unix(struct samu
*user
, const struct passwd
*pwd
)
254 return samu_set_unix_internal( user
, pwd
, True
);
257 /**********************************************************
258 Encode the account control bits into a string.
259 length = length of string to encode into (including terminating
260 null). length *MUST BE MORE THAN 2* !
261 **********************************************************/
263 char *pdb_encode_acct_ctrl(uint32 acct_ctrl
, size_t length
)
265 static fstring acct_str
;
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';
295 /**********************************************************
296 Decode the account control bits from a string.
297 **********************************************************/
299 uint32
pdb_decode_acct_ctrl(const char *p
)
301 uint32 acct_ctrl
= 0;
302 BOOL finished
= False
;
305 * Check if the account type bits have been encoded after the
306 * NT password (in the form [NDHTUWSLXI]).
312 for (p
++; *p
&& !finished
; p
++) {
314 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
315 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
316 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
317 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
318 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
319 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
320 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
321 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
322 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
323 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
324 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
330 default: { finished
= True
; }
337 /*************************************************************
338 Routine to set 32 hex password characters from a 16 byte array.
339 **************************************************************/
341 void pdb_sethexpwd(char *p
, const unsigned char *pwd
, uint32 acct_ctrl
)
345 for (i
= 0; i
< 16; i
++)
346 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
348 if (acct_ctrl
& ACB_PWNOTREQ
)
349 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
351 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
355 /*************************************************************
356 Routine to get the 32 hex characters and turn them
357 into a 16 byte array.
358 **************************************************************/
360 BOOL
pdb_gethexpwd(const char *p
, unsigned char *pwd
)
363 unsigned char lonybble
, hinybble
;
364 const char *hexchars
= "0123456789ABCDEF";
370 for (i
= 0; i
< 32; i
+= 2) {
371 hinybble
= toupper_ascii(p
[i
]);
372 lonybble
= toupper_ascii(p
[i
+ 1]);
374 p1
= strchr(hexchars
, hinybble
);
375 p2
= strchr(hexchars
, lonybble
);
380 hinybble
= PTR_DIFF(p1
, hexchars
);
381 lonybble
= PTR_DIFF(p2
, hexchars
);
383 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
388 /*************************************************************
389 Routine to set 42 hex hours characters from a 21 byte array.
390 **************************************************************/
392 void pdb_sethexhours(char *p
, const unsigned char *hours
)
396 for (i
= 0; i
< 21; i
++) {
397 slprintf(&p
[i
*2], 3, "%02X", hours
[i
]);
400 safe_strcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
404 /*************************************************************
405 Routine to get the 42 hex characters and turn them
406 into a 21 byte array.
407 **************************************************************/
409 BOOL
pdb_gethexhours(const char *p
, unsigned char *hours
)
412 unsigned char lonybble
, hinybble
;
413 const char *hexchars
= "0123456789ABCDEF";
420 for (i
= 0; i
< 42; i
+= 2) {
421 hinybble
= toupper_ascii(p
[i
]);
422 lonybble
= toupper_ascii(p
[i
+ 1]);
424 p1
= strchr(hexchars
, hinybble
);
425 p2
= strchr(hexchars
, lonybble
);
431 hinybble
= PTR_DIFF(p1
, hexchars
);
432 lonybble
= PTR_DIFF(p2
, hexchars
);
434 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
439 /********************************************************************
440 ********************************************************************/
442 int algorithmic_rid_base(void)
444 static int rid_offset
= 0;
449 rid_offset
= lp_algorithmic_rid_base();
451 if (rid_offset
< BASE_RID
) {
452 /* Try to prevent admin foot-shooting, we can't put algorithmic
453 rids below 1000, that's the 'well known RIDs' on NT */
454 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
455 rid_offset
= BASE_RID
;
457 if (rid_offset
& 1) {
458 DEBUG(0, ("algorithmic rid base must be even\n"));
464 /*******************************************************************
465 Converts NT user RID to a UNIX uid.
466 ********************************************************************/
468 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
470 int rid_offset
= algorithmic_rid_base();
471 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
474 uid_t
max_algorithmic_uid(void)
476 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
479 /*******************************************************************
480 converts UNIX uid to an NT User RID.
481 ********************************************************************/
483 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
485 int rid_offset
= algorithmic_rid_base();
486 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
489 /*******************************************************************
490 Converts NT group RID to a UNIX gid.
491 ********************************************************************/
493 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
495 int rid_offset
= algorithmic_rid_base();
496 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
499 gid_t
max_algorithmic_gid(void)
501 return pdb_group_rid_to_gid(0xffffffff);
504 /*******************************************************************
505 converts NT Group RID to a UNIX uid.
507 warning: you must not call that function only
508 you must do a call to the group mapping first.
509 there is not anymore a direct link between the gid and the rid.
510 ********************************************************************/
512 uint32
algorithmic_pdb_gid_to_group_rid(gid_t gid
)
514 int rid_offset
= algorithmic_rid_base();
515 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
518 /*******************************************************************
519 Decides if a RID is a well known RID.
520 ********************************************************************/
522 static BOOL
rid_is_well_known(uint32 rid
)
524 /* Not using rid_offset here, because this is the actual
525 NT fixed value (1000) */
527 return (rid
< BASE_RID
);
530 /*******************************************************************
531 Decides if a RID is a user or group RID.
532 ********************************************************************/
534 BOOL
algorithmic_pdb_rid_is_user(uint32 rid
)
536 if ( rid_is_well_known(rid
) ) {
538 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
539 * and DOMAIN_USER_RID_GUEST.
541 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
543 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
549 /*******************************************************************
550 Convert a name into a SID. Used in the lookup name rpc.
551 ********************************************************************/
553 BOOL
lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
554 enum lsa_SidType
*type
)
559 /* Windows treats "MACHINE\None" as a special name for
560 rid 513 on non-DCs. You cannot create a user or group
561 name "None" on Windows. You will get an error that
562 the group already exists. */
564 if ( strequal( name
, "None" ) ) {
565 *rid
= DOMAIN_GROUP_RID_USERS
;
566 *type
= SID_NAME_DOM_GRP
;
571 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
572 * correctly in the case where foo also exists as a user. If the flag
573 * is set, don't look for users at all. */
575 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
576 struct samu
*sam_account
= NULL
;
579 if ( !(sam_account
= samu_new( NULL
)) ) {
584 ret
= pdb_getsampwnam(sam_account
, name
);
588 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
591 TALLOC_FREE(sam_account
);
594 if (!sid_check_is_in_our_domain(&user_sid
)) {
595 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
596 name
, sid_string_static(&user_sid
)));
600 sid_peek_rid(&user_sid
, rid
);
601 *type
= SID_NAME_USER
;
607 * Maybe it is a group ?
611 ret
= pdb_getgrnam(&map
, name
);
615 /* try to see if we can lookup a mapped
616 * group with the unix group name */
620 grp
= getgrnam(name
);
626 ret
= pdb_getgrgid(&map
, grp
->gr_gid
);
634 /* BUILTIN groups are looked up elsewhere */
635 if (!sid_check_is_in_our_domain(&map
.sid
)) {
636 DEBUG(10, ("Found group %s (%s) not in our domain -- "
638 sid_string_static(&map
.sid
)));
642 /* yes it's a mapped group */
643 sid_peek_rid(&map
.sid
, rid
);
644 *type
= map
.sid_name_use
;
648 /*************************************************************
649 Change a password entry in the local smbpasswd file.
650 *************************************************************/
652 NTSTATUS
local_password_change(const char *user_name
, int local_flags
,
653 const char *new_passwd
,
654 char *err_str
, size_t err_str_len
,
655 char *msg_str
, size_t msg_str_len
)
657 struct samu
*sam_pass
=NULL
;
664 /* Get the smb passwd entry for this user */
666 if ( !(sam_pass
= samu_new( NULL
)) ) {
667 return NT_STATUS_NO_MEMORY
;
671 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
673 TALLOC_FREE(sam_pass
);
675 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
676 int tmp_debug
= DEBUGLEVEL
;
679 /* Might not exist in /etc/passwd. */
685 if ( !(pwd
= getpwnam_alloc( NULL
, user_name
)) ) {
686 return NT_STATUS_NO_SUCH_USER
;
689 /* create the struct samu and initialize the basic Unix properties */
691 if ( !(sam_pass
= samu_new( NULL
)) ) {
692 return NT_STATUS_NO_MEMORY
;
695 result
= samu_set_unix( sam_pass
, pwd
);
697 DEBUGLEVEL
= tmp_debug
;
701 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
705 if (!NT_STATUS_IS_OK(result
)) {
706 slprintf(err_str
, err_str_len
-1, "Failed to " "initialize account for user %s: %s\n",
707 user_name
, nt_errstr(result
));
711 slprintf(err_str
, err_str_len
-1,"Failed to find entry for user %s.\n", user_name
);
712 return NT_STATUS_NO_SUCH_USER
;
716 /* the entry already existed */
717 local_flags
&= ~LOCAL_ADD_USER
;
720 /* the 'other' acb bits not being changed here */
721 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (!(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
722 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
723 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
724 slprintf(err_str
, err_str_len
- 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
);
725 TALLOC_FREE(sam_pass
);
726 return NT_STATUS_UNSUCCESSFUL
;
728 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
729 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
730 slprintf(err_str
, err_str_len
- 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name
);
731 TALLOC_FREE(sam_pass
);
732 return NT_STATUS_UNSUCCESSFUL
;
735 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
736 slprintf(err_str
, err_str_len
- 1, "Failed to set 'normal account' flags for user %s.\n", user_name
);
737 TALLOC_FREE(sam_pass
);
738 return NT_STATUS_UNSUCCESSFUL
;
743 * We are root - just write the new password
744 * and the valid last change time.
747 if (local_flags
& LOCAL_DISABLE_USER
) {
748 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
749 slprintf(err_str
, err_str_len
-1, "Failed to set 'disabled' flag for user %s.\n", user_name
);
750 TALLOC_FREE(sam_pass
);
751 return NT_STATUS_UNSUCCESSFUL
;
753 } else if (local_flags
& LOCAL_ENABLE_USER
) {
754 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
755 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
756 TALLOC_FREE(sam_pass
);
757 return NT_STATUS_UNSUCCESSFUL
;
761 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
762 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
763 slprintf(err_str
, err_str_len
-1, "Failed to set 'no password required' flag for user %s.\n", user_name
);
764 TALLOC_FREE(sam_pass
);
765 return NT_STATUS_UNSUCCESSFUL
;
767 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
769 * If we're dealing with setting a completely empty user account
770 * ie. One with a password of 'XXXX', but not set disabled (like
771 * an account created from scratch) then if the old password was
772 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
773 * We remove that as we're giving this user their first password
774 * and the decision hasn't really been made to disable them (ie.
775 * don't create them disabled). JRA.
777 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
778 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
779 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
780 TALLOC_FREE(sam_pass
);
781 return NT_STATUS_UNSUCCESSFUL
;
784 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
785 slprintf(err_str
, err_str_len
-1, "Failed to unset 'no password required' flag for user %s.\n", user_name
);
786 TALLOC_FREE(sam_pass
);
787 return NT_STATUS_UNSUCCESSFUL
;
790 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
791 slprintf(err_str
, err_str_len
-1, "Failed to set password for user %s.\n", user_name
);
792 TALLOC_FREE(sam_pass
);
793 return NT_STATUS_UNSUCCESSFUL
;
797 if (local_flags
& LOCAL_ADD_USER
) {
798 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
799 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
800 TALLOC_FREE(sam_pass
);
803 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
804 TALLOC_FREE(sam_pass
);
805 return NT_STATUS_UNSUCCESSFUL
;
807 } else if (local_flags
& LOCAL_DELETE_USER
) {
808 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
809 slprintf(err_str
,err_str_len
-1, "Failed to delete entry for user %s.\n", user_name
);
810 TALLOC_FREE(sam_pass
);
811 return NT_STATUS_UNSUCCESSFUL
;
813 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
815 result
= pdb_update_sam_account(sam_pass
);
816 if(!NT_STATUS_IS_OK(result
)) {
817 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n", user_name
);
818 TALLOC_FREE(sam_pass
);
821 if(local_flags
& LOCAL_DISABLE_USER
)
822 slprintf(msg_str
, msg_str_len
-1, "Disabled user %s.\n", user_name
);
823 else if (local_flags
& LOCAL_ENABLE_USER
)
824 slprintf(msg_str
, msg_str_len
-1, "Enabled user %s.\n", user_name
);
825 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
826 slprintf(msg_str
, msg_str_len
-1, "User %s password set to none.\n", user_name
);
829 TALLOC_FREE(sam_pass
);
833 /**********************************************************************
834 Marshall/unmarshall struct samu structs.
835 *********************************************************************/
837 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
839 /*********************************************************************
840 *********************************************************************/
842 BOOL
init_sam_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
845 /* times are stored as 32bit integer
846 take care on system with 64bit wide time_t
853 pass_can_change_time
,
854 pass_must_change_time
;
855 char *username
= NULL
;
857 char *nt_username
= NULL
;
858 char *dir_drive
= NULL
;
859 char *unknown_str
= NULL
;
860 char *munged_dial
= NULL
;
861 char *fullname
= NULL
;
862 char *homedir
= NULL
;
863 char *logon_script
= NULL
;
864 char *profile_path
= NULL
;
865 char *acct_desc
= NULL
;
866 char *workstations
= NULL
;
867 uint32 username_len
, domain_len
, nt_username_len
,
868 dir_drive_len
, unknown_str_len
, munged_dial_len
,
869 fullname_len
, homedir_len
, logon_script_len
,
870 profile_path_len
, acct_desc_len
, workstations_len
;
872 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
874 uint16 bad_password_count
, logon_count
;
876 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
878 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
879 uint32 pwHistLen
= 0;
882 BOOL expand_explicit
= lp_passdb_expand_explicit();
884 if(sampass
== NULL
|| buf
== NULL
) {
885 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
889 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
891 /* unpack the buffer into variables */
892 len
= tdb_unpack ((char *)buf
, buflen
, TDB_FORMAT_STRING_V3
,
894 &logoff_time
, /* d */
895 &kickoff_time
, /* d */
896 &bad_password_time
, /* d */
897 &pass_last_set_time
, /* d */
898 &pass_can_change_time
, /* d */
899 &pass_must_change_time
, /* d */
900 &username_len
, &username
, /* B */
901 &domain_len
, &domain
, /* B */
902 &nt_username_len
, &nt_username
, /* B */
903 &fullname_len
, &fullname
, /* B */
904 &homedir_len
, &homedir
, /* B */
905 &dir_drive_len
, &dir_drive
, /* B */
906 &logon_script_len
, &logon_script
, /* B */
907 &profile_path_len
, &profile_path
, /* B */
908 &acct_desc_len
, &acct_desc
, /* B */
909 &workstations_len
, &workstations
, /* B */
910 &unknown_str_len
, &unknown_str
, /* B */
911 &munged_dial_len
, &munged_dial
, /* B */
914 &lm_pw_len
, &lm_pw_ptr
, /* B */
915 &nt_pw_len
, &nt_pw_ptr
, /* B */
916 /* Change from V1 is addition of password history field. */
917 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
918 /* Change from V2 is the uint32 acb_mask */
920 /* Also "remove_me" field was removed. */
923 &hourslen
, &hours
, /* B */
924 &bad_password_count
, /* w */
925 &logon_count
, /* w */
928 if (len
== (uint32
) -1) {
933 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
934 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
935 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
936 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
937 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
938 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
939 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
941 pdb_set_username(sampass
, username
, PDB_SET
);
942 pdb_set_domain(sampass
, domain
, PDB_SET
);
943 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
944 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
947 fstrcpy( tmpstring
, homedir
);
948 if (expand_explicit
) {
949 standard_sub_basic( username
, domain
, tmpstring
,
952 pdb_set_homedir(sampass
, tmpstring
, PDB_SET
);
955 pdb_set_homedir(sampass
,
956 talloc_sub_basic(sampass
, username
, domain
,
962 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
964 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
967 fstrcpy( tmpstring
, logon_script
);
968 if (expand_explicit
) {
969 standard_sub_basic( username
, domain
, tmpstring
,
972 pdb_set_logon_script(sampass
, tmpstring
, PDB_SET
);
975 pdb_set_logon_script(sampass
,
976 talloc_sub_basic(sampass
, username
, domain
,
982 fstrcpy( tmpstring
, profile_path
);
983 if (expand_explicit
) {
984 standard_sub_basic( username
, domain
, tmpstring
,
987 pdb_set_profile_path(sampass
, tmpstring
, PDB_SET
);
990 pdb_set_profile_path(sampass
,
991 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
995 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
996 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
997 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
999 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1000 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1006 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1007 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1013 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1015 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1020 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1021 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1023 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1024 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1025 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1026 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1027 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1028 PW_HISTORY_ENTRY_LEN
);
1031 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1038 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1041 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1042 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1043 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1044 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1045 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1046 /* Change from V2 is the uint32 acct_ctrl */
1047 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1048 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1049 pdb_set_hours(sampass
, hours
, PDB_SET
);
1053 SAFE_FREE(username
);
1055 SAFE_FREE(nt_username
);
1056 SAFE_FREE(fullname
);
1058 SAFE_FREE(dir_drive
);
1059 SAFE_FREE(logon_script
);
1060 SAFE_FREE(profile_path
);
1061 SAFE_FREE(acct_desc
);
1062 SAFE_FREE(workstations
);
1063 SAFE_FREE(munged_dial
);
1064 SAFE_FREE(unknown_str
);
1065 SAFE_FREE(lm_pw_ptr
);
1066 SAFE_FREE(nt_pw_ptr
);
1067 SAFE_FREE(nt_pw_hist_ptr
);
1073 /*********************************************************************
1074 *********************************************************************/
1076 uint32
init_buffer_from_sam_v3 (uint8
**buf
, struct samu
*sampass
, BOOL size_only
)
1080 /* times are stored as 32bit integer
1081 take care on system with 64bit wide time_t
1088 pass_can_change_time
,
1089 pass_must_change_time
;
1091 uint32 user_rid
, group_rid
;
1093 const char *username
;
1095 const char *nt_username
;
1096 const char *dir_drive
;
1097 const char *unknown_str
;
1098 const char *munged_dial
;
1099 const char *fullname
;
1100 const char *homedir
;
1101 const char *logon_script
;
1102 const char *profile_path
;
1103 const char *acct_desc
;
1104 const char *workstations
;
1105 uint32 username_len
, domain_len
, nt_username_len
,
1106 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1107 fullname_len
, homedir_len
, logon_script_len
,
1108 profile_path_len
, acct_desc_len
, workstations_len
;
1112 const uint8
*nt_pw_hist
;
1113 uint32 lm_pw_len
= 16;
1114 uint32 nt_pw_len
= 16;
1115 uint32 nt_pw_hist_len
;
1116 uint32 pwHistLen
= 0;
1121 logon_time
= (uint32
)pdb_get_logon_time(sampass
);
1122 logoff_time
= (uint32
)pdb_get_logoff_time(sampass
);
1123 kickoff_time
= (uint32
)pdb_get_kickoff_time(sampass
);
1124 bad_password_time
= (uint32
)pdb_get_bad_password_time(sampass
);
1125 pass_can_change_time
= (uint32
)pdb_get_pass_can_change_time_noncalc(sampass
);
1126 pass_must_change_time
= (uint32
)pdb_get_pass_must_change_time(sampass
);
1127 pass_last_set_time
= (uint32
)pdb_get_pass_last_set_time(sampass
);
1129 user_rid
= pdb_get_user_rid(sampass
);
1130 group_rid
= pdb_get_group_rid(sampass
);
1132 username
= pdb_get_username(sampass
);
1134 username_len
= strlen(username
) +1;
1139 domain
= pdb_get_domain(sampass
);
1141 domain_len
= strlen(domain
) +1;
1146 nt_username
= pdb_get_nt_username(sampass
);
1148 nt_username_len
= strlen(nt_username
) +1;
1150 nt_username_len
= 0;
1153 fullname
= pdb_get_fullname(sampass
);
1155 fullname_len
= strlen(fullname
) +1;
1161 * Only updates fields which have been set (not defaults from smb.conf)
1164 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1165 dir_drive
= pdb_get_dir_drive(sampass
);
1170 dir_drive_len
= strlen(dir_drive
) +1;
1175 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1176 homedir
= pdb_get_homedir(sampass
);
1181 homedir_len
= strlen(homedir
) +1;
1186 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1187 logon_script
= pdb_get_logon_script(sampass
);
1189 logon_script
= NULL
;
1192 logon_script_len
= strlen(logon_script
) +1;
1194 logon_script_len
= 0;
1197 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1198 profile_path
= pdb_get_profile_path(sampass
);
1200 profile_path
= NULL
;
1203 profile_path_len
= strlen(profile_path
) +1;
1205 profile_path_len
= 0;
1208 lm_pw
= pdb_get_lanman_passwd(sampass
);
1213 nt_pw
= pdb_get_nt_passwd(sampass
);
1218 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1219 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1220 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1221 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1226 acct_desc
= pdb_get_acct_desc(sampass
);
1228 acct_desc_len
= strlen(acct_desc
) +1;
1233 workstations
= pdb_get_workstations(sampass
);
1235 workstations_len
= strlen(workstations
) +1;
1237 workstations_len
= 0;
1241 unknown_str_len
= 0;
1243 munged_dial
= pdb_get_munged_dial(sampass
);
1245 munged_dial_len
= strlen(munged_dial
) +1;
1247 munged_dial_len
= 0;
1250 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1252 /* one time to get the size needed */
1253 len
= tdb_pack(NULL
, 0, TDB_FORMAT_STRING_V3
,
1255 logoff_time
, /* d */
1256 kickoff_time
, /* d */
1257 bad_password_time
, /* d */
1258 pass_last_set_time
, /* d */
1259 pass_can_change_time
, /* d */
1260 pass_must_change_time
, /* d */
1261 username_len
, username
, /* B */
1262 domain_len
, domain
, /* B */
1263 nt_username_len
, nt_username
, /* B */
1264 fullname_len
, fullname
, /* B */
1265 homedir_len
, homedir
, /* B */
1266 dir_drive_len
, dir_drive
, /* B */
1267 logon_script_len
, logon_script
, /* B */
1268 profile_path_len
, profile_path
, /* B */
1269 acct_desc_len
, acct_desc
, /* B */
1270 workstations_len
, workstations
, /* B */
1271 unknown_str_len
, unknown_str
, /* B */
1272 munged_dial_len
, munged_dial
, /* B */
1275 lm_pw_len
, lm_pw
, /* B */
1276 nt_pw_len
, nt_pw
, /* B */
1277 nt_pw_hist_len
, nt_pw_hist
, /* B */
1278 pdb_get_acct_ctrl(sampass
), /* d */
1279 pdb_get_logon_divs(sampass
), /* w */
1280 pdb_get_hours_len(sampass
), /* d */
1281 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1282 pdb_get_bad_password_count(sampass
), /* w */
1283 pdb_get_logon_count(sampass
), /* w */
1284 pdb_get_unknown_6(sampass
)); /* d */
1290 /* malloc the space needed */
1291 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1292 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1296 /* now for the real call to tdb_pack() */
1297 buflen
= tdb_pack((char *)*buf
, len
, TDB_FORMAT_STRING_V3
,
1299 logoff_time
, /* d */
1300 kickoff_time
, /* d */
1301 bad_password_time
, /* d */
1302 pass_last_set_time
, /* d */
1303 pass_can_change_time
, /* d */
1304 pass_must_change_time
, /* d */
1305 username_len
, username
, /* B */
1306 domain_len
, domain
, /* B */
1307 nt_username_len
, nt_username
, /* B */
1308 fullname_len
, fullname
, /* B */
1309 homedir_len
, homedir
, /* B */
1310 dir_drive_len
, dir_drive
, /* B */
1311 logon_script_len
, logon_script
, /* B */
1312 profile_path_len
, profile_path
, /* B */
1313 acct_desc_len
, acct_desc
, /* B */
1314 workstations_len
, workstations
, /* B */
1315 unknown_str_len
, unknown_str
, /* B */
1316 munged_dial_len
, munged_dial
, /* B */
1319 lm_pw_len
, lm_pw
, /* B */
1320 nt_pw_len
, nt_pw
, /* B */
1321 nt_pw_hist_len
, nt_pw_hist
, /* B */
1322 pdb_get_acct_ctrl(sampass
), /* d */
1323 pdb_get_logon_divs(sampass
), /* w */
1324 pdb_get_hours_len(sampass
), /* d */
1325 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1326 pdb_get_bad_password_count(sampass
), /* w */
1327 pdb_get_logon_count(sampass
), /* w */
1328 pdb_get_unknown_6(sampass
)); /* d */
1330 /* check to make sure we got it correct */
1331 if (buflen
!= len
) {
1332 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1333 (unsigned long)buflen
, (unsigned long)len
));
1343 /*********************************************************************
1344 *********************************************************************/
1346 BOOL
pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
1351 len
= init_buffer_from_sam_v3(&buf
, src
, False
);
1352 if (len
== -1 || !buf
) {
1357 if (!init_sam_from_buffer_v3( dst
, buf
, len
)) {
1362 dst
->methods
= src
->methods
;
1364 if ( src
->unix_pw
) {
1365 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
1366 if (!dst
->unix_pw
) {
1376 /*********************************************************************
1377 Update the bad password count checking the AP_RESET_COUNT_TIME
1378 *********************************************************************/
1380 BOOL
pdb_update_bad_password_count(struct samu
*sampass
, BOOL
*updated
)
1382 time_t LastBadPassword
;
1383 uint16 BadPasswordCount
;
1386 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
1387 if (!BadPasswordCount
) {
1388 DEBUG(9, ("No bad password attempts.\n"));
1392 if (!pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
)) {
1393 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1397 /* First, check if there is a reset time to compare */
1398 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
1399 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1403 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1404 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1405 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
1406 if (time(NULL
) > (LastBadPassword
+ (time_t)resettime
*60)){
1407 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1408 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1417 /*********************************************************************
1418 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1419 *********************************************************************/
1421 BOOL
pdb_update_autolock_flag(struct samu
*sampass
, BOOL
*updated
)
1424 time_t LastBadPassword
;
1426 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
1427 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1428 pdb_get_username(sampass
)));
1432 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
)) {
1433 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1437 /* First, check if there is a duration to compare */
1438 if ((duration
== (uint32
) -1) || (duration
== 0)) {
1439 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1443 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1444 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1445 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
1447 if (LastBadPassword
== (time_t)0) {
1448 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
1449 bad password time. Leaving locked out.\n",
1450 pdb_get_username(sampass
) ));
1454 if ((time(NULL
) > (LastBadPassword
+ (time_t) duration
* 60))) {
1455 pdb_set_acct_ctrl(sampass
,
1456 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
1458 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1459 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1468 /*********************************************************************
1469 Increment the bad_password_count
1470 *********************************************************************/
1472 BOOL
pdb_increment_bad_password_count(struct samu
*sampass
)
1474 uint32 account_policy_lockout
;
1475 BOOL autolock_updated
= False
, badpw_updated
= False
;
1478 /* Retrieve the account lockout policy */
1480 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
1483 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1487 /* If there is no policy, we don't need to continue checking */
1488 if (!account_policy_lockout
) {
1489 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1493 /* Check if the autolock needs to be cleared */
1494 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
1497 /* Check if the badpw count needs to be reset */
1498 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
1502 Ok, now we can assume that any resetting that needs to be
1503 done has been done, and just get on with incrementing
1504 and autolocking if necessary
1507 pdb_set_bad_password_count(sampass
,
1508 pdb_get_bad_password_count(sampass
)+1,
1510 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
1513 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
1516 if (!pdb_set_acct_ctrl(sampass
,
1517 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
1519 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));