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 netr_SamInfo3 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)
448 rid_offset
= lp_algorithmic_rid_base();
450 if (rid_offset
< BASE_RID
) {
451 /* Try to prevent admin foot-shooting, we can't put algorithmic
452 rids below 1000, that's the 'well known RIDs' on NT */
453 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
454 rid_offset
= BASE_RID
;
456 if (rid_offset
& 1) {
457 DEBUG(0, ("algorithmic rid base must be even\n"));
463 /*******************************************************************
464 Converts NT user RID to a UNIX uid.
465 ********************************************************************/
467 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
469 int rid_offset
= algorithmic_rid_base();
470 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
473 uid_t
max_algorithmic_uid(void)
475 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
478 /*******************************************************************
479 converts UNIX uid to an NT User RID.
480 ********************************************************************/
482 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
484 int rid_offset
= algorithmic_rid_base();
485 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
488 /*******************************************************************
489 Converts NT group RID to a UNIX gid.
490 ********************************************************************/
492 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
494 int rid_offset
= algorithmic_rid_base();
495 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
498 gid_t
max_algorithmic_gid(void)
500 return pdb_group_rid_to_gid(0xffffffff);
503 /*******************************************************************
504 converts NT Group RID to a UNIX uid.
506 warning: you must not call that function only
507 you must do a call to the group mapping first.
508 there is not anymore a direct link between the gid and the rid.
509 ********************************************************************/
511 uint32
algorithmic_pdb_gid_to_group_rid(gid_t gid
)
513 int rid_offset
= algorithmic_rid_base();
514 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
517 /*******************************************************************
518 Decides if a RID is a well known RID.
519 ********************************************************************/
521 static bool rid_is_well_known(uint32 rid
)
523 /* Not using rid_offset here, because this is the actual
524 NT fixed value (1000) */
526 return (rid
< BASE_RID
);
529 /*******************************************************************
530 Decides if a RID is a user or group RID.
531 ********************************************************************/
533 bool algorithmic_pdb_rid_is_user(uint32 rid
)
535 if ( rid_is_well_known(rid
) ) {
537 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
538 * and DOMAIN_USER_RID_GUEST.
540 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
542 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
548 /*******************************************************************
549 Convert a name into a SID. Used in the lookup name rpc.
550 ********************************************************************/
552 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
553 enum lsa_SidType
*type
)
558 /* Windows treats "MACHINE\None" as a special name for
559 rid 513 on non-DCs. You cannot create a user or group
560 name "None" on Windows. You will get an error that
561 the group already exists. */
563 if ( strequal( name
, "None" ) ) {
564 *rid
= DOMAIN_GROUP_RID_USERS
;
565 *type
= SID_NAME_DOM_GRP
;
570 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
571 * correctly in the case where foo also exists as a user. If the flag
572 * is set, don't look for users at all. */
574 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
575 struct samu
*sam_account
= NULL
;
578 if ( !(sam_account
= samu_new( NULL
)) ) {
583 ret
= pdb_getsampwnam(sam_account
, name
);
587 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
590 TALLOC_FREE(sam_account
);
593 if (!sid_check_is_in_our_domain(&user_sid
)) {
594 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
595 name
, sid_string_dbg(&user_sid
)));
599 sid_peek_rid(&user_sid
, rid
);
600 *type
= SID_NAME_USER
;
606 * Maybe it is a group ?
610 ret
= pdb_getgrnam(&map
, name
);
617 /* BUILTIN groups are looked up elsewhere */
618 if (!sid_check_is_in_our_domain(&map
.sid
)) {
619 DEBUG(10, ("Found group %s (%s) not in our domain -- "
620 "ignoring.", name
, sid_string_dbg(&map
.sid
)));
624 /* yes it's a mapped group */
625 sid_peek_rid(&map
.sid
, rid
);
626 *type
= map
.sid_name_use
;
630 /*************************************************************
631 Change a password entry in the local smbpasswd file.
632 *************************************************************/
634 NTSTATUS
local_password_change(const char *user_name
,
636 const char *new_passwd
,
640 struct samu
*sam_pass
=NULL
;
647 /* Get the smb passwd entry for this user */
649 if ( !(sam_pass
= samu_new( NULL
)) ) {
650 return NT_STATUS_NO_MEMORY
;
654 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
656 TALLOC_FREE(sam_pass
);
658 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
659 int tmp_debug
= DEBUGLEVEL
;
662 /* Might not exist in /etc/passwd. */
668 if ( !(pwd
= getpwnam_alloc( NULL
, user_name
)) ) {
669 return NT_STATUS_NO_SUCH_USER
;
672 /* create the struct samu and initialize the basic Unix properties */
674 if ( !(sam_pass
= samu_new( NULL
)) ) {
675 return NT_STATUS_NO_MEMORY
;
678 result
= samu_alloc_rid_unix( sam_pass
, pwd
);
680 DEBUGLEVEL
= tmp_debug
;
684 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
688 if (!NT_STATUS_IS_OK(result
)) {
689 asprintf(pp_err_str
, "Failed to " "initialize account for user %s: %s\n",
690 user_name
, nt_errstr(result
));
694 asprintf(pp_err_str
, "Failed to find entry for user %s.\n", user_name
);
695 return NT_STATUS_NO_SUCH_USER
;
699 /* the entry already existed */
700 local_flags
&= ~LOCAL_ADD_USER
;
703 /* the 'other' acb bits not being changed here */
704 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (~(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
705 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
706 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
707 asprintf(pp_err_str
, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
);
708 TALLOC_FREE(sam_pass
);
709 return NT_STATUS_UNSUCCESSFUL
;
711 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
712 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
713 asprintf(pp_err_str
, "Failed to set 'domain trust account' flags for user %s.\n", user_name
);
714 TALLOC_FREE(sam_pass
);
715 return NT_STATUS_UNSUCCESSFUL
;
718 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
719 asprintf(pp_err_str
, "Failed to set 'normal account' flags for user %s.\n", user_name
);
720 TALLOC_FREE(sam_pass
);
721 return NT_STATUS_UNSUCCESSFUL
;
726 * We are root - just write the new password
727 * and the valid last change time.
730 if (local_flags
& LOCAL_DISABLE_USER
) {
731 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
732 asprintf(pp_err_str
, "Failed to set 'disabled' flag for user %s.\n", user_name
);
733 TALLOC_FREE(sam_pass
);
734 return NT_STATUS_UNSUCCESSFUL
;
736 } else if (local_flags
& LOCAL_ENABLE_USER
) {
737 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
738 asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
739 TALLOC_FREE(sam_pass
);
740 return NT_STATUS_UNSUCCESSFUL
;
744 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
745 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
746 asprintf(pp_err_str
, "Failed to set 'no password required' flag for user %s.\n", user_name
);
747 TALLOC_FREE(sam_pass
);
748 return NT_STATUS_UNSUCCESSFUL
;
750 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
752 * If we're dealing with setting a completely empty user account
753 * ie. One with a password of 'XXXX', but not set disabled (like
754 * an account created from scratch) then if the old password was
755 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
756 * We remove that as we're giving this user their first password
757 * and the decision hasn't really been made to disable them (ie.
758 * don't create them disabled). JRA.
760 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
761 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
762 asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
763 TALLOC_FREE(sam_pass
);
764 return NT_STATUS_UNSUCCESSFUL
;
767 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
768 asprintf(pp_err_str
, "Failed to unset 'no password required' flag for user %s.\n", user_name
);
769 TALLOC_FREE(sam_pass
);
770 return NT_STATUS_UNSUCCESSFUL
;
773 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
774 asprintf(pp_err_str
, "Failed to set password for user %s.\n", user_name
);
775 TALLOC_FREE(sam_pass
);
776 return NT_STATUS_UNSUCCESSFUL
;
780 if (local_flags
& LOCAL_ADD_USER
) {
781 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
782 asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
783 TALLOC_FREE(sam_pass
);
786 asprintf(pp_err_str
, "Failed to add entry for user %s.\n", user_name
);
787 TALLOC_FREE(sam_pass
);
788 return NT_STATUS_UNSUCCESSFUL
;
790 } else if (local_flags
& LOCAL_DELETE_USER
) {
791 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
792 asprintf(pp_err_str
, "Failed to delete entry for user %s.\n", user_name
);
793 TALLOC_FREE(sam_pass
);
794 return NT_STATUS_UNSUCCESSFUL
;
796 asprintf(pp_msg_str
, "Deleted user %s.\n", user_name
);
798 result
= pdb_update_sam_account(sam_pass
);
799 if(!NT_STATUS_IS_OK(result
)) {
800 asprintf(pp_err_str
, "Failed to modify entry for user %s.\n", user_name
);
801 TALLOC_FREE(sam_pass
);
804 if(local_flags
& LOCAL_DISABLE_USER
)
805 asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
806 else if (local_flags
& LOCAL_ENABLE_USER
)
807 asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
808 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
809 asprintf(pp_msg_str
, "User %s password set to none.\n", user_name
);
812 TALLOC_FREE(sam_pass
);
816 /**********************************************************************
817 Marshall/unmarshall struct samu structs.
818 *********************************************************************/
820 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
822 /*********************************************************************
823 *********************************************************************/
825 bool init_sam_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
828 /* times are stored as 32bit integer
829 take care on system with 64bit wide time_t
836 pass_can_change_time
,
837 pass_must_change_time
;
838 char *username
= NULL
;
840 char *nt_username
= NULL
;
841 char *dir_drive
= NULL
;
842 char *unknown_str
= NULL
;
843 char *munged_dial
= NULL
;
844 char *fullname
= NULL
;
845 char *homedir
= NULL
;
846 char *logon_script
= NULL
;
847 char *profile_path
= NULL
;
848 char *acct_desc
= NULL
;
849 char *workstations
= NULL
;
850 uint32 username_len
, domain_len
, nt_username_len
,
851 dir_drive_len
, unknown_str_len
, munged_dial_len
,
852 fullname_len
, homedir_len
, logon_script_len
,
853 profile_path_len
, acct_desc_len
, workstations_len
;
855 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
857 uint16 bad_password_count
, logon_count
;
859 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
861 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
862 uint32 pwHistLen
= 0;
865 bool expand_explicit
= lp_passdb_expand_explicit();
867 if(sampass
== NULL
|| buf
== NULL
) {
868 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
872 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
874 /* unpack the buffer into variables */
875 len
= tdb_unpack (buf
, buflen
, TDB_FORMAT_STRING_V3
,
877 &logoff_time
, /* d */
878 &kickoff_time
, /* d */
879 &bad_password_time
, /* d */
880 &pass_last_set_time
, /* d */
881 &pass_can_change_time
, /* d */
882 &pass_must_change_time
, /* d */
883 &username_len
, &username
, /* B */
884 &domain_len
, &domain
, /* B */
885 &nt_username_len
, &nt_username
, /* B */
886 &fullname_len
, &fullname
, /* B */
887 &homedir_len
, &homedir
, /* B */
888 &dir_drive_len
, &dir_drive
, /* B */
889 &logon_script_len
, &logon_script
, /* B */
890 &profile_path_len
, &profile_path
, /* B */
891 &acct_desc_len
, &acct_desc
, /* B */
892 &workstations_len
, &workstations
, /* B */
893 &unknown_str_len
, &unknown_str
, /* B */
894 &munged_dial_len
, &munged_dial
, /* B */
897 &lm_pw_len
, &lm_pw_ptr
, /* B */
898 &nt_pw_len
, &nt_pw_ptr
, /* B */
899 /* Change from V1 is addition of password history field. */
900 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
901 /* Change from V2 is the uint32 acb_mask */
903 /* Also "remove_me" field was removed. */
906 &hourslen
, &hours
, /* B */
907 &bad_password_count
, /* w */
908 &logon_count
, /* w */
911 if (len
== (uint32
) -1) {
916 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
917 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
918 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
919 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
920 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
921 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
922 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
924 pdb_set_username(sampass
, username
, PDB_SET
);
925 pdb_set_domain(sampass
, domain
, PDB_SET
);
926 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
927 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
930 fstrcpy( tmp_string
, homedir
);
931 if (expand_explicit
) {
932 standard_sub_basic( username
, domain
, tmp_string
,
933 sizeof(tmp_string
) );
935 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
938 pdb_set_homedir(sampass
,
939 talloc_sub_basic(sampass
, username
, domain
,
945 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
947 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
950 fstrcpy( tmp_string
, logon_script
);
951 if (expand_explicit
) {
952 standard_sub_basic( username
, domain
, tmp_string
,
953 sizeof(tmp_string
) );
955 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
958 pdb_set_logon_script(sampass
,
959 talloc_sub_basic(sampass
, username
, domain
,
965 fstrcpy( tmp_string
, profile_path
);
966 if (expand_explicit
) {
967 standard_sub_basic( username
, domain
, tmp_string
,
968 sizeof(tmp_string
) );
970 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
973 pdb_set_profile_path(sampass
,
974 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
978 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
979 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
980 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
982 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
983 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
989 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
990 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
996 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
998 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1003 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1004 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1006 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1007 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1008 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1009 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1010 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1011 PW_HISTORY_ENTRY_LEN
);
1014 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1021 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1024 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1025 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1026 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1027 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1028 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1029 /* Change from V2 is the uint32 acct_ctrl */
1030 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1031 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1032 pdb_set_hours(sampass
, hours
, PDB_SET
);
1036 SAFE_FREE(username
);
1038 SAFE_FREE(nt_username
);
1039 SAFE_FREE(fullname
);
1041 SAFE_FREE(dir_drive
);
1042 SAFE_FREE(logon_script
);
1043 SAFE_FREE(profile_path
);
1044 SAFE_FREE(acct_desc
);
1045 SAFE_FREE(workstations
);
1046 SAFE_FREE(munged_dial
);
1047 SAFE_FREE(unknown_str
);
1048 SAFE_FREE(lm_pw_ptr
);
1049 SAFE_FREE(nt_pw_ptr
);
1050 SAFE_FREE(nt_pw_hist_ptr
);
1056 /*********************************************************************
1057 *********************************************************************/
1059 uint32
init_buffer_from_sam_v3 (uint8
**buf
, struct samu
*sampass
, bool size_only
)
1063 /* times are stored as 32bit integer
1064 take care on system with 64bit wide time_t
1071 pass_can_change_time
,
1072 pass_must_change_time
;
1074 uint32 user_rid
, group_rid
;
1076 const char *username
;
1078 const char *nt_username
;
1079 const char *dir_drive
;
1080 const char *unknown_str
;
1081 const char *munged_dial
;
1082 const char *fullname
;
1083 const char *homedir
;
1084 const char *logon_script
;
1085 const char *profile_path
;
1086 const char *acct_desc
;
1087 const char *workstations
;
1088 uint32 username_len
, domain_len
, nt_username_len
,
1089 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1090 fullname_len
, homedir_len
, logon_script_len
,
1091 profile_path_len
, acct_desc_len
, workstations_len
;
1095 const uint8
*nt_pw_hist
;
1096 uint32 lm_pw_len
= 16;
1097 uint32 nt_pw_len
= 16;
1098 uint32 nt_pw_hist_len
;
1099 uint32 pwHistLen
= 0;
1104 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1105 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1106 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1107 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1108 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1109 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1110 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1112 user_rid
= pdb_get_user_rid(sampass
);
1113 group_rid
= pdb_get_group_rid(sampass
);
1115 username
= pdb_get_username(sampass
);
1117 username_len
= strlen(username
) +1;
1122 domain
= pdb_get_domain(sampass
);
1124 domain_len
= strlen(domain
) +1;
1129 nt_username
= pdb_get_nt_username(sampass
);
1131 nt_username_len
= strlen(nt_username
) +1;
1133 nt_username_len
= 0;
1136 fullname
= pdb_get_fullname(sampass
);
1138 fullname_len
= strlen(fullname
) +1;
1144 * Only updates fields which have been set (not defaults from smb.conf)
1147 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1148 dir_drive
= pdb_get_dir_drive(sampass
);
1153 dir_drive_len
= strlen(dir_drive
) +1;
1158 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1159 homedir
= pdb_get_homedir(sampass
);
1164 homedir_len
= strlen(homedir
) +1;
1169 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1170 logon_script
= pdb_get_logon_script(sampass
);
1172 logon_script
= NULL
;
1175 logon_script_len
= strlen(logon_script
) +1;
1177 logon_script_len
= 0;
1180 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1181 profile_path
= pdb_get_profile_path(sampass
);
1183 profile_path
= NULL
;
1186 profile_path_len
= strlen(profile_path
) +1;
1188 profile_path_len
= 0;
1191 lm_pw
= pdb_get_lanman_passwd(sampass
);
1196 nt_pw
= pdb_get_nt_passwd(sampass
);
1201 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1202 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1203 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1204 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1209 acct_desc
= pdb_get_acct_desc(sampass
);
1211 acct_desc_len
= strlen(acct_desc
) +1;
1216 workstations
= pdb_get_workstations(sampass
);
1218 workstations_len
= strlen(workstations
) +1;
1220 workstations_len
= 0;
1224 unknown_str_len
= 0;
1226 munged_dial
= pdb_get_munged_dial(sampass
);
1228 munged_dial_len
= strlen(munged_dial
) +1;
1230 munged_dial_len
= 0;
1233 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1235 /* one time to get the size needed */
1236 len
= tdb_pack(NULL
, 0, TDB_FORMAT_STRING_V3
,
1238 logoff_time
, /* d */
1239 kickoff_time
, /* d */
1240 bad_password_time
, /* d */
1241 pass_last_set_time
, /* d */
1242 pass_can_change_time
, /* d */
1243 pass_must_change_time
, /* d */
1244 username_len
, username
, /* B */
1245 domain_len
, domain
, /* B */
1246 nt_username_len
, nt_username
, /* B */
1247 fullname_len
, fullname
, /* B */
1248 homedir_len
, homedir
, /* B */
1249 dir_drive_len
, dir_drive
, /* B */
1250 logon_script_len
, logon_script
, /* B */
1251 profile_path_len
, profile_path
, /* B */
1252 acct_desc_len
, acct_desc
, /* B */
1253 workstations_len
, workstations
, /* B */
1254 unknown_str_len
, unknown_str
, /* B */
1255 munged_dial_len
, munged_dial
, /* B */
1258 lm_pw_len
, lm_pw
, /* B */
1259 nt_pw_len
, nt_pw
, /* B */
1260 nt_pw_hist_len
, nt_pw_hist
, /* B */
1261 pdb_get_acct_ctrl(sampass
), /* d */
1262 pdb_get_logon_divs(sampass
), /* w */
1263 pdb_get_hours_len(sampass
), /* d */
1264 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1265 pdb_get_bad_password_count(sampass
), /* w */
1266 pdb_get_logon_count(sampass
), /* w */
1267 pdb_get_unknown_6(sampass
)); /* d */
1273 /* malloc the space needed */
1274 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1275 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1279 /* now for the real call to tdb_pack() */
1280 buflen
= tdb_pack(*buf
, len
, TDB_FORMAT_STRING_V3
,
1282 logoff_time
, /* d */
1283 kickoff_time
, /* d */
1284 bad_password_time
, /* d */
1285 pass_last_set_time
, /* d */
1286 pass_can_change_time
, /* d */
1287 pass_must_change_time
, /* d */
1288 username_len
, username
, /* B */
1289 domain_len
, domain
, /* B */
1290 nt_username_len
, nt_username
, /* B */
1291 fullname_len
, fullname
, /* B */
1292 homedir_len
, homedir
, /* B */
1293 dir_drive_len
, dir_drive
, /* B */
1294 logon_script_len
, logon_script
, /* B */
1295 profile_path_len
, profile_path
, /* B */
1296 acct_desc_len
, acct_desc
, /* B */
1297 workstations_len
, workstations
, /* B */
1298 unknown_str_len
, unknown_str
, /* B */
1299 munged_dial_len
, munged_dial
, /* B */
1302 lm_pw_len
, lm_pw
, /* B */
1303 nt_pw_len
, nt_pw
, /* B */
1304 nt_pw_hist_len
, nt_pw_hist
, /* B */
1305 pdb_get_acct_ctrl(sampass
), /* d */
1306 pdb_get_logon_divs(sampass
), /* w */
1307 pdb_get_hours_len(sampass
), /* d */
1308 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1309 pdb_get_bad_password_count(sampass
), /* w */
1310 pdb_get_logon_count(sampass
), /* w */
1311 pdb_get_unknown_6(sampass
)); /* d */
1313 /* check to make sure we got it correct */
1314 if (buflen
!= len
) {
1315 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1316 (unsigned long)buflen
, (unsigned long)len
));
1326 /*********************************************************************
1327 *********************************************************************/
1329 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
1334 len
= init_buffer_from_sam_v3(&buf
, src
, False
);
1335 if (len
== -1 || !buf
) {
1340 if (!init_sam_from_buffer_v3( dst
, buf
, len
)) {
1345 dst
->methods
= src
->methods
;
1347 if ( src
->unix_pw
) {
1348 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
1349 if (!dst
->unix_pw
) {
1359 /*********************************************************************
1360 Update the bad password count checking the AP_RESET_COUNT_TIME
1361 *********************************************************************/
1363 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
1365 time_t LastBadPassword
;
1366 uint16 BadPasswordCount
;
1370 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
1371 if (!BadPasswordCount
) {
1372 DEBUG(9, ("No bad password attempts.\n"));
1377 res
= pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
);
1381 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1385 /* First, check if there is a reset time to compare */
1386 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
1387 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1391 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1392 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1393 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
1394 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
1395 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1396 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1405 /*********************************************************************
1406 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1407 *********************************************************************/
1409 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
1412 time_t LastBadPassword
;
1415 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
1416 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1417 pdb_get_username(sampass
)));
1422 res
= pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
);
1426 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1430 /* First, check if there is a duration to compare */
1431 if ((duration
== (uint32
) -1) || (duration
== 0)) {
1432 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1436 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1437 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1438 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
1440 if (LastBadPassword
== (time_t)0) {
1441 DEBUG(1,("pdb_update_autolock_flag: Account %s "
1442 "administratively locked out with no bad password "
1443 "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"));
1520 bool is_dc_trusted_domain_situation(const char *domain_name
)
1522 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
1525 /*******************************************************************
1526 Wrapper around retrieving the clear text trust account password.
1527 appropriate account name is stored in account_name.
1528 Caller must free password, but not account_name.
1529 *******************************************************************/
1531 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
1532 const char **account_name
, uint32
*channel
)
1535 time_t last_set_time
;
1537 /* if we are a DC and this is not our domain, then lookup an account
1538 * for the domain trust */
1540 if (is_dc_trusted_domain_situation(domain
)) {
1541 if (!lp_allow_trusted_domains()) {
1545 if (!pdb_get_trusteddom_pw(domain
, ret_pwd
, NULL
,
1548 DEBUG(0, ("get_trust_pw: could not fetch trust "
1549 "account password for trusted domain %s\n",
1554 if (channel
!= NULL
) {
1555 *channel
= SEC_CHAN_DOMAIN
;
1558 if (account_name
!= NULL
) {
1559 *account_name
= lp_workgroup();
1566 * Since we can only be member of one single domain, we are now
1567 * in a member situation:
1569 * - Either we are a DC (selfjoined) and the domain is our
1571 * - Or we are on a member and the domain is our own or some
1572 * other (potentially trusted) domain.
1574 * In both cases, we can only get the machine account password
1575 * for our own domain to connect to our own dc. (For a member,
1576 * request to trusted domains are performed through our dc.)
1578 * So we simply use our own domain name to retrieve the
1579 * machine account passowrd and ignore the request domain here.
1582 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
1586 if (account_name
!= NULL
) {
1587 *account_name
= global_myname();
1593 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
1594 "account password for domain %s\n", domain
));
1598 /*******************************************************************
1599 Wrapper around retrieving the trust account password.
1600 appropriate account name is stored in account_name.
1601 *******************************************************************/
1603 bool get_trust_pw_hash(const char *domain
, uint8 ret_pwd
[16],
1604 const char **account_name
, uint32
*channel
)
1607 time_t last_set_time
;
1609 if (get_trust_pw_clear(domain
, &pwd
, account_name
, channel
)) {
1610 E_md4hash(pwd
, ret_pwd
);
1613 } else if (is_dc_trusted_domain_situation(domain
)) {
1617 /* as a fallback, try to get the hashed pwd directly from the tdb... */
1619 if (secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
1623 if (account_name
!= NULL
) {
1624 *account_name
= global_myname();
1630 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
1631 "password for domain %s\n", domain
));
1635 struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
1638 struct samr_LogonHours hours
;
1639 const int units_per_week
= 168;
1642 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
1647 hours
.units_per_week
= units_per_week
;
1648 memset(hours
.bits
, 0xFF, units_per_week
);
1650 if (pdb_get_hours(pw
)) {
1651 memcpy(hours
.bits
, pdb_get_hours(pw
),
1652 MIN(pdb_get_hours_len(pw
), units_per_week
));