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", 32);
351 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
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 *user
, 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( user
, "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
, user
);
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 user
, 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
, user
);
618 /* BUILTIN groups are looked up elsewhere */
619 if (!sid_check_is_in_our_domain(&map
.sid
)) {
620 DEBUG(10, ("Found group %s (%s) not in our domain -- "
622 sid_string_static(&map
.sid
)));
626 /* yes it's a mapped group */
627 sid_peek_rid(&map
.sid
, rid
);
628 *type
= map
.sid_name_use
;
632 /*************************************************************
633 Change a password entry in the local smbpasswd file.
634 *************************************************************/
636 NTSTATUS
local_password_change(const char *user_name
, int local_flags
,
637 const char *new_passwd
,
638 char *err_str
, size_t err_str_len
,
639 char *msg_str
, size_t msg_str_len
)
641 struct samu
*sam_pass
=NULL
;
648 /* Get the smb passwd entry for this user */
650 if ( !(sam_pass
= samu_new( NULL
)) ) {
651 return NT_STATUS_NO_MEMORY
;
655 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
657 TALLOC_FREE(sam_pass
);
659 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
660 int tmp_debug
= DEBUGLEVEL
;
663 /* Might not exist in /etc/passwd. */
669 if ( !(pwd
= getpwnam_alloc( NULL
, user_name
)) ) {
670 return NT_STATUS_NO_SUCH_USER
;
673 /* create the struct samu and initialize the basic Unix properties */
675 if ( !(sam_pass
= samu_new( NULL
)) ) {
676 return NT_STATUS_NO_MEMORY
;
679 result
= samu_set_unix( sam_pass
, pwd
);
681 DEBUGLEVEL
= tmp_debug
;
685 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
689 if (!NT_STATUS_IS_OK(result
)) {
690 slprintf(err_str
, err_str_len
-1, "Failed to " "initialize account for user %s: %s\n",
691 user_name
, nt_errstr(result
));
695 slprintf(err_str
, err_str_len
-1,"Failed to find entry for user %s.\n", user_name
);
696 return NT_STATUS_NO_SUCH_USER
;
700 /* the entry already existed */
701 local_flags
&= ~LOCAL_ADD_USER
;
704 /* the 'other' acb bits not being changed here */
705 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (~(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
706 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
707 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
708 slprintf(err_str
, err_str_len
- 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
);
709 TALLOC_FREE(sam_pass
);
710 return NT_STATUS_UNSUCCESSFUL
;
712 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
713 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
714 slprintf(err_str
, err_str_len
- 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name
);
715 TALLOC_FREE(sam_pass
);
716 return NT_STATUS_UNSUCCESSFUL
;
719 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
720 slprintf(err_str
, err_str_len
- 1, "Failed to set 'normal account' flags for user %s.\n", user_name
);
721 TALLOC_FREE(sam_pass
);
722 return NT_STATUS_UNSUCCESSFUL
;
727 * We are root - just write the new password
728 * and the valid last change time.
731 if (local_flags
& LOCAL_DISABLE_USER
) {
732 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
733 slprintf(err_str
, err_str_len
-1, "Failed to set 'disabled' flag for user %s.\n", user_name
);
734 TALLOC_FREE(sam_pass
);
735 return NT_STATUS_UNSUCCESSFUL
;
737 } else if (local_flags
& LOCAL_ENABLE_USER
) {
738 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
739 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
740 TALLOC_FREE(sam_pass
);
741 return NT_STATUS_UNSUCCESSFUL
;
745 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
746 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
747 slprintf(err_str
, err_str_len
-1, "Failed to set 'no password required' flag for user %s.\n", user_name
);
748 TALLOC_FREE(sam_pass
);
749 return NT_STATUS_UNSUCCESSFUL
;
751 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
753 * If we're dealing with setting a completely empty user account
754 * ie. One with a password of 'XXXX', but not set disabled (like
755 * an account created from scratch) then if the old password was
756 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
757 * We remove that as we're giving this user their first password
758 * and the decision hasn't really been made to disable them (ie.
759 * don't create them disabled). JRA.
761 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
762 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
763 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
764 TALLOC_FREE(sam_pass
);
765 return NT_STATUS_UNSUCCESSFUL
;
768 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
769 slprintf(err_str
, err_str_len
-1, "Failed to unset 'no password required' flag for user %s.\n", user_name
);
770 TALLOC_FREE(sam_pass
);
771 return NT_STATUS_UNSUCCESSFUL
;
774 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
775 slprintf(err_str
, err_str_len
-1, "Failed to set password for user %s.\n", user_name
);
776 TALLOC_FREE(sam_pass
);
777 return NT_STATUS_UNSUCCESSFUL
;
781 if (local_flags
& LOCAL_ADD_USER
) {
782 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
783 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
784 TALLOC_FREE(sam_pass
);
787 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
788 TALLOC_FREE(sam_pass
);
789 return NT_STATUS_UNSUCCESSFUL
;
791 } else if (local_flags
& LOCAL_DELETE_USER
) {
792 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
793 slprintf(err_str
,err_str_len
-1, "Failed to delete entry for user %s.\n", user_name
);
794 TALLOC_FREE(sam_pass
);
795 return NT_STATUS_UNSUCCESSFUL
;
797 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
799 result
= pdb_update_sam_account(sam_pass
);
800 if(!NT_STATUS_IS_OK(result
)) {
801 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n", user_name
);
802 TALLOC_FREE(sam_pass
);
805 if(local_flags
& LOCAL_DISABLE_USER
)
806 slprintf(msg_str
, msg_str_len
-1, "Disabled user %s.\n", user_name
);
807 else if (local_flags
& LOCAL_ENABLE_USER
)
808 slprintf(msg_str
, msg_str_len
-1, "Enabled user %s.\n", user_name
);
809 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
810 slprintf(msg_str
, msg_str_len
-1, "User %s password set to none.\n", user_name
);
813 TALLOC_FREE(sam_pass
);
817 /**********************************************************************
818 Marshall/unmarshall struct samu structs.
819 *********************************************************************/
821 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
823 /*********************************************************************
824 *********************************************************************/
826 BOOL
init_sam_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
829 /* times are stored as 32bit integer
830 take care on system with 64bit wide time_t
837 pass_can_change_time
,
838 pass_must_change_time
;
839 char *username
= NULL
;
841 char *nt_username
= NULL
;
842 char *dir_drive
= NULL
;
843 char *unknown_str
= NULL
;
844 char *munged_dial
= NULL
;
845 char *fullname
= NULL
;
846 char *homedir
= NULL
;
847 char *logon_script
= NULL
;
848 char *profile_path
= NULL
;
849 char *acct_desc
= NULL
;
850 char *workstations
= NULL
;
851 uint32 username_len
, domain_len
, nt_username_len
,
852 dir_drive_len
, unknown_str_len
, munged_dial_len
,
853 fullname_len
, homedir_len
, logon_script_len
,
854 profile_path_len
, acct_desc_len
, workstations_len
;
856 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
858 uint16 bad_password_count
, logon_count
;
860 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
862 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
863 uint32 pwHistLen
= 0;
866 BOOL expand_explicit
= lp_passdb_expand_explicit();
868 if(sampass
== NULL
|| buf
== NULL
) {
869 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
873 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
875 /* unpack the buffer into variables */
876 len
= tdb_unpack ((char *)buf
, buflen
, TDB_FORMAT_STRING_V3
,
878 &logoff_time
, /* d */
879 &kickoff_time
, /* d */
880 &bad_password_time
, /* d */
881 &pass_last_set_time
, /* d */
882 &pass_can_change_time
, /* d */
883 &pass_must_change_time
, /* d */
884 &username_len
, &username
, /* B */
885 &domain_len
, &domain
, /* B */
886 &nt_username_len
, &nt_username
, /* B */
887 &fullname_len
, &fullname
, /* B */
888 &homedir_len
, &homedir
, /* B */
889 &dir_drive_len
, &dir_drive
, /* B */
890 &logon_script_len
, &logon_script
, /* B */
891 &profile_path_len
, &profile_path
, /* B */
892 &acct_desc_len
, &acct_desc
, /* B */
893 &workstations_len
, &workstations
, /* B */
894 &unknown_str_len
, &unknown_str
, /* B */
895 &munged_dial_len
, &munged_dial
, /* B */
898 &lm_pw_len
, &lm_pw_ptr
, /* B */
899 &nt_pw_len
, &nt_pw_ptr
, /* B */
900 /* Change from V1 is addition of password history field. */
901 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
902 /* Change from V2 is the uint32 acb_mask */
904 /* Also "remove_me" field was removed. */
907 &hourslen
, &hours
, /* B */
908 &bad_password_count
, /* w */
909 &logon_count
, /* w */
912 if (len
== (uint32
) -1) {
917 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
918 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
919 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
920 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
921 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
922 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
923 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
925 pdb_set_username(sampass
, username
, PDB_SET
);
926 pdb_set_domain(sampass
, domain
, PDB_SET
);
927 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
928 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
931 fstrcpy( tmpstring
, homedir
);
932 if (expand_explicit
) {
933 standard_sub_basic( username
, domain
, tmpstring
,
936 pdb_set_homedir(sampass
, tmpstring
, PDB_SET
);
939 pdb_set_homedir(sampass
,
940 talloc_sub_basic(sampass
, username
, domain
,
946 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
948 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
951 fstrcpy( tmpstring
, logon_script
);
952 if (expand_explicit
) {
953 standard_sub_basic( username
, domain
, tmpstring
,
956 pdb_set_logon_script(sampass
, tmpstring
, PDB_SET
);
959 pdb_set_logon_script(sampass
,
960 talloc_sub_basic(sampass
, username
, domain
,
966 fstrcpy( tmpstring
, profile_path
);
967 if (expand_explicit
) {
968 standard_sub_basic( username
, domain
, tmpstring
,
971 pdb_set_profile_path(sampass
, tmpstring
, PDB_SET
);
974 pdb_set_profile_path(sampass
,
975 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
979 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
980 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
981 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
983 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
984 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
990 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
991 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
997 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
999 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1004 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1005 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1007 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1008 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1009 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1010 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1011 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1012 PW_HISTORY_ENTRY_LEN
);
1015 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1022 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1025 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1026 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1027 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1028 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1029 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1030 /* Change from V2 is the uint32 acct_ctrl */
1031 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1032 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1033 pdb_set_hours(sampass
, hours
, PDB_SET
);
1037 SAFE_FREE(username
);
1039 SAFE_FREE(nt_username
);
1040 SAFE_FREE(fullname
);
1042 SAFE_FREE(dir_drive
);
1043 SAFE_FREE(logon_script
);
1044 SAFE_FREE(profile_path
);
1045 SAFE_FREE(acct_desc
);
1046 SAFE_FREE(workstations
);
1047 SAFE_FREE(munged_dial
);
1048 SAFE_FREE(unknown_str
);
1049 SAFE_FREE(lm_pw_ptr
);
1050 SAFE_FREE(nt_pw_ptr
);
1051 SAFE_FREE(nt_pw_hist_ptr
);
1057 /*********************************************************************
1058 *********************************************************************/
1060 uint32
init_buffer_from_sam_v3 (uint8
**buf
, struct samu
*sampass
, BOOL size_only
)
1064 /* times are stored as 32bit integer
1065 take care on system with 64bit wide time_t
1072 pass_can_change_time
,
1073 pass_must_change_time
;
1075 uint32 user_rid
, group_rid
;
1077 const char *username
;
1079 const char *nt_username
;
1080 const char *dir_drive
;
1081 const char *unknown_str
;
1082 const char *munged_dial
;
1083 const char *fullname
;
1084 const char *homedir
;
1085 const char *logon_script
;
1086 const char *profile_path
;
1087 const char *acct_desc
;
1088 const char *workstations
;
1089 uint32 username_len
, domain_len
, nt_username_len
,
1090 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1091 fullname_len
, homedir_len
, logon_script_len
,
1092 profile_path_len
, acct_desc_len
, workstations_len
;
1096 const uint8
*nt_pw_hist
;
1097 uint32 lm_pw_len
= 16;
1098 uint32 nt_pw_len
= 16;
1099 uint32 nt_pw_hist_len
;
1100 uint32 pwHistLen
= 0;
1105 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1106 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1107 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1108 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1109 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1110 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1111 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1113 user_rid
= pdb_get_user_rid(sampass
);
1114 group_rid
= pdb_get_group_rid(sampass
);
1116 username
= pdb_get_username(sampass
);
1118 username_len
= strlen(username
) +1;
1123 domain
= pdb_get_domain(sampass
);
1125 domain_len
= strlen(domain
) +1;
1130 nt_username
= pdb_get_nt_username(sampass
);
1132 nt_username_len
= strlen(nt_username
) +1;
1134 nt_username_len
= 0;
1137 fullname
= pdb_get_fullname(sampass
);
1139 fullname_len
= strlen(fullname
) +1;
1145 * Only updates fields which have been set (not defaults from smb.conf)
1148 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1149 dir_drive
= pdb_get_dir_drive(sampass
);
1154 dir_drive_len
= strlen(dir_drive
) +1;
1159 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1160 homedir
= pdb_get_homedir(sampass
);
1165 homedir_len
= strlen(homedir
) +1;
1170 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1171 logon_script
= pdb_get_logon_script(sampass
);
1173 logon_script
= NULL
;
1176 logon_script_len
= strlen(logon_script
) +1;
1178 logon_script_len
= 0;
1181 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1182 profile_path
= pdb_get_profile_path(sampass
);
1184 profile_path
= NULL
;
1187 profile_path_len
= strlen(profile_path
) +1;
1189 profile_path_len
= 0;
1192 lm_pw
= pdb_get_lanman_passwd(sampass
);
1197 nt_pw
= pdb_get_nt_passwd(sampass
);
1202 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1203 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1204 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1205 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1210 acct_desc
= pdb_get_acct_desc(sampass
);
1212 acct_desc_len
= strlen(acct_desc
) +1;
1217 workstations
= pdb_get_workstations(sampass
);
1219 workstations_len
= strlen(workstations
) +1;
1221 workstations_len
= 0;
1225 unknown_str_len
= 0;
1227 munged_dial
= pdb_get_munged_dial(sampass
);
1229 munged_dial_len
= strlen(munged_dial
) +1;
1231 munged_dial_len
= 0;
1234 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1236 /* one time to get the size needed */
1237 len
= tdb_pack(NULL
, 0, TDB_FORMAT_STRING_V3
,
1239 logoff_time
, /* d */
1240 kickoff_time
, /* d */
1241 bad_password_time
, /* d */
1242 pass_last_set_time
, /* d */
1243 pass_can_change_time
, /* d */
1244 pass_must_change_time
, /* d */
1245 username_len
, username
, /* B */
1246 domain_len
, domain
, /* B */
1247 nt_username_len
, nt_username
, /* B */
1248 fullname_len
, fullname
, /* B */
1249 homedir_len
, homedir
, /* B */
1250 dir_drive_len
, dir_drive
, /* B */
1251 logon_script_len
, logon_script
, /* B */
1252 profile_path_len
, profile_path
, /* B */
1253 acct_desc_len
, acct_desc
, /* B */
1254 workstations_len
, workstations
, /* B */
1255 unknown_str_len
, unknown_str
, /* B */
1256 munged_dial_len
, munged_dial
, /* B */
1259 lm_pw_len
, lm_pw
, /* B */
1260 nt_pw_len
, nt_pw
, /* B */
1261 nt_pw_hist_len
, nt_pw_hist
, /* B */
1262 pdb_get_acct_ctrl(sampass
), /* d */
1263 pdb_get_logon_divs(sampass
), /* w */
1264 pdb_get_hours_len(sampass
), /* d */
1265 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1266 pdb_get_bad_password_count(sampass
), /* w */
1267 pdb_get_logon_count(sampass
), /* w */
1268 pdb_get_unknown_6(sampass
)); /* d */
1274 /* malloc the space needed */
1275 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1276 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1280 /* now for the real call to tdb_pack() */
1281 buflen
= tdb_pack((char *)*buf
, len
, TDB_FORMAT_STRING_V3
,
1283 logoff_time
, /* d */
1284 kickoff_time
, /* d */
1285 bad_password_time
, /* d */
1286 pass_last_set_time
, /* d */
1287 pass_can_change_time
, /* d */
1288 pass_must_change_time
, /* d */
1289 username_len
, username
, /* B */
1290 domain_len
, domain
, /* B */
1291 nt_username_len
, nt_username
, /* B */
1292 fullname_len
, fullname
, /* B */
1293 homedir_len
, homedir
, /* B */
1294 dir_drive_len
, dir_drive
, /* B */
1295 logon_script_len
, logon_script
, /* B */
1296 profile_path_len
, profile_path
, /* B */
1297 acct_desc_len
, acct_desc
, /* B */
1298 workstations_len
, workstations
, /* B */
1299 unknown_str_len
, unknown_str
, /* B */
1300 munged_dial_len
, munged_dial
, /* B */
1303 lm_pw_len
, lm_pw
, /* B */
1304 nt_pw_len
, nt_pw
, /* B */
1305 nt_pw_hist_len
, nt_pw_hist
, /* B */
1306 pdb_get_acct_ctrl(sampass
), /* d */
1307 pdb_get_logon_divs(sampass
), /* w */
1308 pdb_get_hours_len(sampass
), /* d */
1309 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1310 pdb_get_bad_password_count(sampass
), /* w */
1311 pdb_get_logon_count(sampass
), /* w */
1312 pdb_get_unknown_6(sampass
)); /* d */
1314 /* check to make sure we got it correct */
1315 if (buflen
!= len
) {
1316 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1317 (unsigned long)buflen
, (unsigned long)len
));
1327 /*********************************************************************
1328 *********************************************************************/
1330 BOOL
pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
1335 len
= init_buffer_from_sam_v3(&buf
, src
, False
);
1336 if (len
== -1 || !buf
) {
1341 if (!init_sam_from_buffer_v3( dst
, buf
, len
)) {
1346 dst
->methods
= src
->methods
;
1348 if ( src
->unix_pw
) {
1349 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
1350 if (!dst
->unix_pw
) {
1360 /*********************************************************************
1361 Update the bad password count checking the AP_RESET_COUNT_TIME
1362 *********************************************************************/
1364 BOOL
pdb_update_bad_password_count(struct samu
*sampass
, BOOL
*updated
)
1366 time_t LastBadPassword
;
1367 uint16 BadPasswordCount
;
1371 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
1372 if (!BadPasswordCount
) {
1373 DEBUG(9, ("No bad password attempts.\n"));
1378 res
= pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
);
1382 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1386 /* First, check if there is a reset time to compare */
1387 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
1388 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1392 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1393 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1394 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
1395 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
1396 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1397 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1406 /*********************************************************************
1407 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1408 *********************************************************************/
1410 BOOL
pdb_update_autolock_flag(struct samu
*sampass
, BOOL
*updated
)
1413 time_t LastBadPassword
;
1416 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
1417 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1418 pdb_get_username(sampass
)));
1423 res
= pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
);
1427 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1431 /* First, check if there is a duration to compare */
1432 if ((duration
== (uint32
) -1) || (duration
== 0)) {
1433 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1437 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1438 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1439 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
1441 if (LastBadPassword
== (time_t)0) {
1442 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
1443 bad password time. Leaving locked out.\n",
1444 pdb_get_username(sampass
) ));
1448 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(duration
) * 60))) {
1449 pdb_set_acct_ctrl(sampass
,
1450 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
1452 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1453 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1462 /*********************************************************************
1463 Increment the bad_password_count
1464 *********************************************************************/
1466 BOOL
pdb_increment_bad_password_count(struct samu
*sampass
)
1468 uint32 account_policy_lockout
;
1469 BOOL autolock_updated
= False
, badpw_updated
= False
;
1472 /* Retrieve the account lockout policy */
1474 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
1477 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1481 /* If there is no policy, we don't need to continue checking */
1482 if (!account_policy_lockout
) {
1483 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1487 /* Check if the autolock needs to be cleared */
1488 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
1491 /* Check if the badpw count needs to be reset */
1492 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
1496 Ok, now we can assume that any resetting that needs to be
1497 done has been done, and just get on with incrementing
1498 and autolocking if necessary
1501 pdb_set_bad_password_count(sampass
,
1502 pdb_get_bad_password_count(sampass
)+1,
1504 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
1507 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
1510 if (!pdb_set_acct_ctrl(sampass
,
1511 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
1513 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));