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(talloc_autofree_context(), 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 if (asprintf(pp_err_str
, "Failed to " "initialize account for user %s: %s\n",
690 user_name
, nt_errstr(result
)) < 0) {
696 if (asprintf(pp_err_str
, "Failed to find entry for user %s.\n", user_name
) < 0) {
699 return NT_STATUS_NO_SUCH_USER
;
703 /* the entry already existed */
704 local_flags
&= ~LOCAL_ADD_USER
;
707 /* the 'other' acb bits not being changed here */
708 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (~(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
709 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
710 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
711 if (asprintf(pp_err_str
, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
) < 0) {
714 TALLOC_FREE(sam_pass
);
715 return NT_STATUS_UNSUCCESSFUL
;
717 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
718 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
719 if (asprintf(pp_err_str
, "Failed to set 'domain trust account' flags for user %s.\n", user_name
) < 0) {
722 TALLOC_FREE(sam_pass
);
723 return NT_STATUS_UNSUCCESSFUL
;
726 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
727 if (asprintf(pp_err_str
, "Failed to set 'normal account' flags for user %s.\n", user_name
) < 0) {
730 TALLOC_FREE(sam_pass
);
731 return NT_STATUS_UNSUCCESSFUL
;
736 * We are root - just write the new password
737 * and the valid last change time.
740 if (local_flags
& LOCAL_DISABLE_USER
) {
741 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
742 if (asprintf(pp_err_str
, "Failed to set 'disabled' flag for user %s.\n", user_name
) < 0) {
745 TALLOC_FREE(sam_pass
);
746 return NT_STATUS_UNSUCCESSFUL
;
748 } else if (local_flags
& LOCAL_ENABLE_USER
) {
749 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
750 if (asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
) < 0) {
753 TALLOC_FREE(sam_pass
);
754 return NT_STATUS_UNSUCCESSFUL
;
758 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
759 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
760 if (asprintf(pp_err_str
, "Failed to set 'no password required' flag for user %s.\n", user_name
) < 0) {
763 TALLOC_FREE(sam_pass
);
764 return NT_STATUS_UNSUCCESSFUL
;
766 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
768 * If we're dealing with setting a completely empty user account
769 * ie. One with a password of 'XXXX', but not set disabled (like
770 * an account created from scratch) then if the old password was
771 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
772 * We remove that as we're giving this user their first password
773 * and the decision hasn't really been made to disable them (ie.
774 * don't create them disabled). JRA.
776 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
777 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
778 if (asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
) < 0) {
781 TALLOC_FREE(sam_pass
);
782 return NT_STATUS_UNSUCCESSFUL
;
785 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
786 if (asprintf(pp_err_str
, "Failed to unset 'no password required' flag for user %s.\n", user_name
) < 0) {
789 TALLOC_FREE(sam_pass
);
790 return NT_STATUS_UNSUCCESSFUL
;
793 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
794 if (asprintf(pp_err_str
, "Failed to set password for user %s.\n", user_name
) < 0) {
797 TALLOC_FREE(sam_pass
);
798 return NT_STATUS_UNSUCCESSFUL
;
802 if (local_flags
& LOCAL_ADD_USER
) {
803 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
804 if (asprintf(pp_msg_str
, "Added user %s.\n", user_name
) < 0) {
807 TALLOC_FREE(sam_pass
);
810 if (asprintf(pp_err_str
, "Failed to add entry for user %s.\n", user_name
) < 0) {
813 TALLOC_FREE(sam_pass
);
814 return NT_STATUS_UNSUCCESSFUL
;
816 } else if (local_flags
& LOCAL_DELETE_USER
) {
817 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
818 if (asprintf(pp_err_str
, "Failed to delete entry for user %s.\n", user_name
) < 0) {
821 TALLOC_FREE(sam_pass
);
822 return NT_STATUS_UNSUCCESSFUL
;
824 if (asprintf(pp_msg_str
, "Deleted user %s.\n", user_name
) < 0) {
828 result
= pdb_update_sam_account(sam_pass
);
829 if(!NT_STATUS_IS_OK(result
)) {
830 if (asprintf(pp_err_str
, "Failed to modify entry for user %s.\n", user_name
) < 0) {
833 TALLOC_FREE(sam_pass
);
836 if(local_flags
& LOCAL_DISABLE_USER
) {
837 if (asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
) < 0) {
840 } else if (local_flags
& LOCAL_ENABLE_USER
) {
841 if (asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
) < 0) {
844 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
845 if (asprintf(pp_msg_str
, "User %s password set to none.\n", user_name
) < 0) {
851 TALLOC_FREE(sam_pass
);
855 /**********************************************************************
856 Marshall/unmarshall struct samu structs.
857 *********************************************************************/
859 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
860 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
861 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
862 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
863 /* nothing changed between V3 and V4 */
865 /*********************************************************************
866 *********************************************************************/
868 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
871 /* times are stored as 32bit integer
872 take care on system with 64bit wide time_t
878 pass_can_change_time
,
879 pass_must_change_time
;
880 char *username
= NULL
;
882 char *nt_username
= NULL
;
883 char *dir_drive
= NULL
;
884 char *unknown_str
= NULL
;
885 char *munged_dial
= NULL
;
886 char *fullname
= NULL
;
887 char *homedir
= NULL
;
888 char *logon_script
= NULL
;
889 char *profile_path
= NULL
;
890 char *acct_desc
= NULL
;
891 char *workstations
= NULL
;
892 uint32 username_len
, domain_len
, nt_username_len
,
893 dir_drive_len
, unknown_str_len
, munged_dial_len
,
894 fullname_len
, homedir_len
, logon_script_len
,
895 profile_path_len
, acct_desc_len
, workstations_len
;
897 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
898 uint16 acct_ctrl
, logon_divs
;
899 uint16 bad_password_count
, logon_count
;
901 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
903 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
906 if(sampass
== NULL
|| buf
== NULL
) {
907 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
911 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
913 /* unpack the buffer into variables */
914 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
916 &logoff_time
, /* d */
917 &kickoff_time
, /* d */
918 &pass_last_set_time
, /* d */
919 &pass_can_change_time
, /* d */
920 &pass_must_change_time
, /* d */
921 &username_len
, &username
, /* B */
922 &domain_len
, &domain
, /* B */
923 &nt_username_len
, &nt_username
, /* B */
924 &fullname_len
, &fullname
, /* B */
925 &homedir_len
, &homedir
, /* B */
926 &dir_drive_len
, &dir_drive
, /* B */
927 &logon_script_len
, &logon_script
, /* B */
928 &profile_path_len
, &profile_path
, /* B */
929 &acct_desc_len
, &acct_desc
, /* B */
930 &workstations_len
, &workstations
, /* B */
931 &unknown_str_len
, &unknown_str
, /* B */
932 &munged_dial_len
, &munged_dial
, /* B */
935 &lm_pw_len
, &lm_pw_ptr
, /* B */
936 &nt_pw_len
, &nt_pw_ptr
, /* B */
938 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
941 &hourslen
, &hours
, /* B */
942 &bad_password_count
, /* w */
943 &logon_count
, /* w */
946 if (len
== (uint32
) -1) {
951 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
952 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
953 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
954 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
955 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
956 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
958 pdb_set_username(sampass
, username
, PDB_SET
);
959 pdb_set_domain(sampass
, domain
, PDB_SET
);
960 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
961 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
964 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
967 pdb_set_homedir(sampass
,
968 talloc_sub_basic(sampass
, username
, domain
,
974 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
976 pdb_set_dir_drive(sampass
,
977 talloc_sub_basic(sampass
, username
, domain
,
983 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
985 pdb_set_logon_script(sampass
,
986 talloc_sub_basic(sampass
, username
, domain
,
992 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
994 pdb_set_profile_path(sampass
,
995 talloc_sub_basic(sampass
, username
, domain
,
1000 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1001 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1002 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1004 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1005 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1011 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1012 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1018 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1019 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1020 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1021 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1022 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1023 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1024 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1025 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1026 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1027 pdb_set_hours(sampass
, hours
, PDB_SET
);
1031 SAFE_FREE(username
);
1033 SAFE_FREE(nt_username
);
1034 SAFE_FREE(fullname
);
1036 SAFE_FREE(dir_drive
);
1037 SAFE_FREE(logon_script
);
1038 SAFE_FREE(profile_path
);
1039 SAFE_FREE(acct_desc
);
1040 SAFE_FREE(workstations
);
1041 SAFE_FREE(munged_dial
);
1042 SAFE_FREE(unknown_str
);
1043 SAFE_FREE(lm_pw_ptr
);
1044 SAFE_FREE(nt_pw_ptr
);
1050 /*********************************************************************
1051 *********************************************************************/
1053 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1056 /* times are stored as 32bit integer
1057 take care on system with 64bit wide time_t
1064 pass_can_change_time
,
1065 pass_must_change_time
;
1066 char *username
= NULL
;
1067 char *domain
= NULL
;
1068 char *nt_username
= NULL
;
1069 char *dir_drive
= NULL
;
1070 char *unknown_str
= NULL
;
1071 char *munged_dial
= NULL
;
1072 char *fullname
= NULL
;
1073 char *homedir
= NULL
;
1074 char *logon_script
= NULL
;
1075 char *profile_path
= NULL
;
1076 char *acct_desc
= NULL
;
1077 char *workstations
= NULL
;
1078 uint32 username_len
, domain_len
, nt_username_len
,
1079 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1080 fullname_len
, homedir_len
, logon_script_len
,
1081 profile_path_len
, acct_desc_len
, workstations_len
;
1083 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1084 uint16 acct_ctrl
, logon_divs
;
1085 uint16 bad_password_count
, logon_count
;
1086 uint8
*hours
= NULL
;
1087 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1089 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
1092 if(sampass
== NULL
|| buf
== NULL
) {
1093 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1097 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1099 /* unpack the buffer into variables */
1100 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1101 &logon_time
, /* d */
1102 &logoff_time
, /* d */
1103 &kickoff_time
, /* d */
1104 /* Change from V0 is addition of bad_password_time field. */
1105 &bad_password_time
, /* d */
1106 &pass_last_set_time
, /* d */
1107 &pass_can_change_time
, /* d */
1108 &pass_must_change_time
, /* d */
1109 &username_len
, &username
, /* B */
1110 &domain_len
, &domain
, /* B */
1111 &nt_username_len
, &nt_username
, /* B */
1112 &fullname_len
, &fullname
, /* B */
1113 &homedir_len
, &homedir
, /* B */
1114 &dir_drive_len
, &dir_drive
, /* B */
1115 &logon_script_len
, &logon_script
, /* B */
1116 &profile_path_len
, &profile_path
, /* B */
1117 &acct_desc_len
, &acct_desc
, /* B */
1118 &workstations_len
, &workstations
, /* B */
1119 &unknown_str_len
, &unknown_str
, /* B */
1120 &munged_dial_len
, &munged_dial
, /* B */
1123 &lm_pw_len
, &lm_pw_ptr
, /* B */
1124 &nt_pw_len
, &nt_pw_ptr
, /* B */
1127 &logon_divs
, /* w */
1129 &hourslen
, &hours
, /* B */
1130 &bad_password_count
, /* w */
1131 &logon_count
, /* w */
1132 &unknown_6
); /* d */
1134 if (len
== (uint32
) -1) {
1139 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1140 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1141 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1143 /* Change from V0 is addition of bad_password_time field. */
1144 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1145 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1146 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1147 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1149 pdb_set_username(sampass
, username
, PDB_SET
);
1150 pdb_set_domain(sampass
, domain
, PDB_SET
);
1151 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1152 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1155 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1158 pdb_set_homedir(sampass
,
1159 talloc_sub_basic(sampass
, username
, domain
,
1165 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1167 pdb_set_dir_drive(sampass
,
1168 talloc_sub_basic(sampass
, username
, domain
,
1174 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1176 pdb_set_logon_script(sampass
,
1177 talloc_sub_basic(sampass
, username
, domain
,
1183 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1185 pdb_set_profile_path(sampass
,
1186 talloc_sub_basic(sampass
, username
, domain
,
1191 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1192 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1193 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1195 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1196 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1202 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1203 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1209 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1211 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1212 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1213 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1214 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1215 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1216 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1217 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1218 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1219 pdb_set_hours(sampass
, hours
, PDB_SET
);
1223 SAFE_FREE(username
);
1225 SAFE_FREE(nt_username
);
1226 SAFE_FREE(fullname
);
1228 SAFE_FREE(dir_drive
);
1229 SAFE_FREE(logon_script
);
1230 SAFE_FREE(profile_path
);
1231 SAFE_FREE(acct_desc
);
1232 SAFE_FREE(workstations
);
1233 SAFE_FREE(munged_dial
);
1234 SAFE_FREE(unknown_str
);
1235 SAFE_FREE(lm_pw_ptr
);
1236 SAFE_FREE(nt_pw_ptr
);
1242 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1245 /* times are stored as 32bit integer
1246 take care on system with 64bit wide time_t
1253 pass_can_change_time
,
1254 pass_must_change_time
;
1255 char *username
= NULL
;
1256 char *domain
= NULL
;
1257 char *nt_username
= NULL
;
1258 char *dir_drive
= NULL
;
1259 char *unknown_str
= NULL
;
1260 char *munged_dial
= NULL
;
1261 char *fullname
= NULL
;
1262 char *homedir
= NULL
;
1263 char *logon_script
= NULL
;
1264 char *profile_path
= NULL
;
1265 char *acct_desc
= NULL
;
1266 char *workstations
= NULL
;
1267 uint32 username_len
, domain_len
, nt_username_len
,
1268 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1269 fullname_len
, homedir_len
, logon_script_len
,
1270 profile_path_len
, acct_desc_len
, workstations_len
;
1272 uint32 user_rid
, group_rid
, hours_len
, unknown_6
;
1273 uint16 acct_ctrl
, logon_divs
;
1274 uint16 bad_password_count
, logon_count
;
1275 uint8
*hours
= NULL
;
1276 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1278 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1279 uint32 pwHistLen
= 0;
1282 bool expand_explicit
= lp_passdb_expand_explicit();
1284 if(sampass
== NULL
|| buf
== NULL
) {
1285 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1289 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1291 /* unpack the buffer into variables */
1292 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1293 &logon_time
, /* d */
1294 &logoff_time
, /* d */
1295 &kickoff_time
, /* d */
1296 &bad_password_time
, /* d */
1297 &pass_last_set_time
, /* d */
1298 &pass_can_change_time
, /* d */
1299 &pass_must_change_time
, /* d */
1300 &username_len
, &username
, /* B */
1301 &domain_len
, &domain
, /* B */
1302 &nt_username_len
, &nt_username
, /* B */
1303 &fullname_len
, &fullname
, /* B */
1304 &homedir_len
, &homedir
, /* B */
1305 &dir_drive_len
, &dir_drive
, /* B */
1306 &logon_script_len
, &logon_script
, /* B */
1307 &profile_path_len
, &profile_path
, /* B */
1308 &acct_desc_len
, &acct_desc
, /* B */
1309 &workstations_len
, &workstations
, /* B */
1310 &unknown_str_len
, &unknown_str
, /* B */
1311 &munged_dial_len
, &munged_dial
, /* B */
1314 &lm_pw_len
, &lm_pw_ptr
, /* B */
1315 &nt_pw_len
, &nt_pw_ptr
, /* B */
1316 /* Change from V1 is addition of password history field. */
1317 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1319 /* Also "remove_me" field was removed. */
1320 &logon_divs
, /* w */
1322 &hourslen
, &hours
, /* B */
1323 &bad_password_count
, /* w */
1324 &logon_count
, /* w */
1325 &unknown_6
); /* d */
1327 if (len
== (uint32
) -1) {
1332 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1333 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1334 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1335 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1336 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1337 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1338 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1340 pdb_set_username(sampass
, username
, PDB_SET
);
1341 pdb_set_domain(sampass
, domain
, PDB_SET
);
1342 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1343 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1346 fstrcpy( tmp_string
, homedir
);
1347 if (expand_explicit
) {
1348 standard_sub_basic( username
, domain
, tmp_string
,
1349 sizeof(tmp_string
) );
1351 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1354 pdb_set_homedir(sampass
,
1355 talloc_sub_basic(sampass
, username
, domain
,
1361 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1363 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1366 fstrcpy( tmp_string
, logon_script
);
1367 if (expand_explicit
) {
1368 standard_sub_basic( username
, domain
, tmp_string
,
1369 sizeof(tmp_string
) );
1371 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1374 pdb_set_logon_script(sampass
,
1375 talloc_sub_basic(sampass
, username
, domain
,
1381 fstrcpy( tmp_string
, profile_path
);
1382 if (expand_explicit
) {
1383 standard_sub_basic( username
, domain
, tmp_string
,
1384 sizeof(tmp_string
) );
1386 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1389 pdb_set_profile_path(sampass
,
1390 talloc_sub_basic(sampass
, username
, domain
,
1395 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1396 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1397 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1399 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1400 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1406 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1407 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1413 /* Change from V1 is addition of password history field. */
1414 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1416 uint8
*pw_hist
= SMB_MALLOC_ARRAY(uint8
, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1421 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1422 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1424 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1425 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1426 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1427 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1428 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1429 PW_HISTORY_ENTRY_LEN
);
1432 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1439 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1442 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1443 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1444 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1445 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1446 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1447 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1448 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1449 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1450 pdb_set_hours(sampass
, hours
, PDB_SET
);
1454 SAFE_FREE(username
);
1456 SAFE_FREE(nt_username
);
1457 SAFE_FREE(fullname
);
1459 SAFE_FREE(dir_drive
);
1460 SAFE_FREE(logon_script
);
1461 SAFE_FREE(profile_path
);
1462 SAFE_FREE(acct_desc
);
1463 SAFE_FREE(workstations
);
1464 SAFE_FREE(munged_dial
);
1465 SAFE_FREE(unknown_str
);
1466 SAFE_FREE(lm_pw_ptr
);
1467 SAFE_FREE(nt_pw_ptr
);
1468 SAFE_FREE(nt_pw_hist_ptr
);
1474 /*********************************************************************
1475 *********************************************************************/
1477 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1480 /* times are stored as 32bit integer
1481 take care on system with 64bit wide time_t
1488 pass_can_change_time
,
1489 pass_must_change_time
;
1490 char *username
= NULL
;
1491 char *domain
= NULL
;
1492 char *nt_username
= NULL
;
1493 char *dir_drive
= NULL
;
1494 char *unknown_str
= NULL
;
1495 char *munged_dial
= NULL
;
1496 char *fullname
= NULL
;
1497 char *homedir
= NULL
;
1498 char *logon_script
= NULL
;
1499 char *profile_path
= NULL
;
1500 char *acct_desc
= NULL
;
1501 char *workstations
= NULL
;
1502 uint32 username_len
, domain_len
, nt_username_len
,
1503 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1504 fullname_len
, homedir_len
, logon_script_len
,
1505 profile_path_len
, acct_desc_len
, workstations_len
;
1507 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1509 uint16 bad_password_count
, logon_count
;
1510 uint8
*hours
= NULL
;
1511 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1513 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1514 uint32 pwHistLen
= 0;
1517 bool expand_explicit
= lp_passdb_expand_explicit();
1519 if(sampass
== NULL
|| buf
== NULL
) {
1520 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1524 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1526 /* unpack the buffer into variables */
1527 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1528 &logon_time
, /* d */
1529 &logoff_time
, /* d */
1530 &kickoff_time
, /* d */
1531 &bad_password_time
, /* d */
1532 &pass_last_set_time
, /* d */
1533 &pass_can_change_time
, /* d */
1534 &pass_must_change_time
, /* d */
1535 &username_len
, &username
, /* B */
1536 &domain_len
, &domain
, /* B */
1537 &nt_username_len
, &nt_username
, /* B */
1538 &fullname_len
, &fullname
, /* B */
1539 &homedir_len
, &homedir
, /* B */
1540 &dir_drive_len
, &dir_drive
, /* B */
1541 &logon_script_len
, &logon_script
, /* B */
1542 &profile_path_len
, &profile_path
, /* B */
1543 &acct_desc_len
, &acct_desc
, /* B */
1544 &workstations_len
, &workstations
, /* B */
1545 &unknown_str_len
, &unknown_str
, /* B */
1546 &munged_dial_len
, &munged_dial
, /* B */
1549 &lm_pw_len
, &lm_pw_ptr
, /* B */
1550 &nt_pw_len
, &nt_pw_ptr
, /* B */
1551 /* Change from V1 is addition of password history field. */
1552 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1553 /* Change from V2 is the uint32 acb_mask */
1555 /* Also "remove_me" field was removed. */
1556 &logon_divs
, /* w */
1558 &hourslen
, &hours
, /* B */
1559 &bad_password_count
, /* w */
1560 &logon_count
, /* w */
1561 &unknown_6
); /* d */
1563 if (len
== (uint32
) -1) {
1568 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
1569 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
1570 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
1571 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
1572 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
1573 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
1574 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
1576 pdb_set_username(sampass
, username
, PDB_SET
);
1577 pdb_set_domain(sampass
, domain
, PDB_SET
);
1578 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1579 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1582 fstrcpy( tmp_string
, homedir
);
1583 if (expand_explicit
) {
1584 standard_sub_basic( username
, domain
, tmp_string
,
1585 sizeof(tmp_string
) );
1587 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1590 pdb_set_homedir(sampass
,
1591 talloc_sub_basic(sampass
, username
, domain
,
1597 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1599 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1602 fstrcpy( tmp_string
, logon_script
);
1603 if (expand_explicit
) {
1604 standard_sub_basic( username
, domain
, tmp_string
,
1605 sizeof(tmp_string
) );
1607 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1610 pdb_set_logon_script(sampass
,
1611 talloc_sub_basic(sampass
, username
, domain
,
1617 fstrcpy( tmp_string
, profile_path
);
1618 if (expand_explicit
) {
1619 standard_sub_basic( username
, domain
, tmp_string
,
1620 sizeof(tmp_string
) );
1622 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1625 pdb_set_profile_path(sampass
,
1626 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1630 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1631 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1632 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1634 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1635 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1641 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1642 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1648 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1650 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1655 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1656 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1658 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1659 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1660 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1661 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1662 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1663 PW_HISTORY_ENTRY_LEN
);
1666 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1673 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1676 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1677 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1678 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1679 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1680 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1681 /* Change from V2 is the uint32 acct_ctrl */
1682 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1683 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1684 pdb_set_hours(sampass
, hours
, PDB_SET
);
1688 SAFE_FREE(username
);
1690 SAFE_FREE(nt_username
);
1691 SAFE_FREE(fullname
);
1693 SAFE_FREE(dir_drive
);
1694 SAFE_FREE(logon_script
);
1695 SAFE_FREE(profile_path
);
1696 SAFE_FREE(acct_desc
);
1697 SAFE_FREE(workstations
);
1698 SAFE_FREE(munged_dial
);
1699 SAFE_FREE(unknown_str
);
1700 SAFE_FREE(lm_pw_ptr
);
1701 SAFE_FREE(nt_pw_ptr
);
1702 SAFE_FREE(nt_pw_hist_ptr
);
1708 /*********************************************************************
1709 *********************************************************************/
1711 static uint32
init_buffer_from_samu_v3 (uint8
**buf
, struct samu
*sampass
, bool size_only
)
1715 /* times are stored as 32bit integer
1716 take care on system with 64bit wide time_t
1723 pass_can_change_time
,
1724 pass_must_change_time
;
1726 uint32 user_rid
, group_rid
;
1728 const char *username
;
1730 const char *nt_username
;
1731 const char *dir_drive
;
1732 const char *unknown_str
;
1733 const char *munged_dial
;
1734 const char *fullname
;
1735 const char *homedir
;
1736 const char *logon_script
;
1737 const char *profile_path
;
1738 const char *acct_desc
;
1739 const char *workstations
;
1740 uint32 username_len
, domain_len
, nt_username_len
,
1741 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1742 fullname_len
, homedir_len
, logon_script_len
,
1743 profile_path_len
, acct_desc_len
, workstations_len
;
1747 const uint8
*nt_pw_hist
;
1748 uint32 lm_pw_len
= 16;
1749 uint32 nt_pw_len
= 16;
1750 uint32 nt_pw_hist_len
;
1751 uint32 pwHistLen
= 0;
1756 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1757 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1758 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1759 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1760 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1761 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1762 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1764 user_rid
= pdb_get_user_rid(sampass
);
1765 group_rid
= pdb_get_group_rid(sampass
);
1767 username
= pdb_get_username(sampass
);
1769 username_len
= strlen(username
) +1;
1774 domain
= pdb_get_domain(sampass
);
1776 domain_len
= strlen(domain
) +1;
1781 nt_username
= pdb_get_nt_username(sampass
);
1783 nt_username_len
= strlen(nt_username
) +1;
1785 nt_username_len
= 0;
1788 fullname
= pdb_get_fullname(sampass
);
1790 fullname_len
= strlen(fullname
) +1;
1796 * Only updates fields which have been set (not defaults from smb.conf)
1799 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1800 dir_drive
= pdb_get_dir_drive(sampass
);
1805 dir_drive_len
= strlen(dir_drive
) +1;
1810 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1811 homedir
= pdb_get_homedir(sampass
);
1816 homedir_len
= strlen(homedir
) +1;
1821 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1822 logon_script
= pdb_get_logon_script(sampass
);
1824 logon_script
= NULL
;
1827 logon_script_len
= strlen(logon_script
) +1;
1829 logon_script_len
= 0;
1832 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1833 profile_path
= pdb_get_profile_path(sampass
);
1835 profile_path
= NULL
;
1838 profile_path_len
= strlen(profile_path
) +1;
1840 profile_path_len
= 0;
1843 lm_pw
= pdb_get_lanman_passwd(sampass
);
1848 nt_pw
= pdb_get_nt_passwd(sampass
);
1853 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1854 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1855 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1856 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1861 acct_desc
= pdb_get_acct_desc(sampass
);
1863 acct_desc_len
= strlen(acct_desc
) +1;
1868 workstations
= pdb_get_workstations(sampass
);
1870 workstations_len
= strlen(workstations
) +1;
1872 workstations_len
= 0;
1876 unknown_str_len
= 0;
1878 munged_dial
= pdb_get_munged_dial(sampass
);
1880 munged_dial_len
= strlen(munged_dial
) +1;
1882 munged_dial_len
= 0;
1885 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1887 /* one time to get the size needed */
1888 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1890 logoff_time
, /* d */
1891 kickoff_time
, /* d */
1892 bad_password_time
, /* d */
1893 pass_last_set_time
, /* d */
1894 pass_can_change_time
, /* d */
1895 pass_must_change_time
, /* d */
1896 username_len
, username
, /* B */
1897 domain_len
, domain
, /* B */
1898 nt_username_len
, nt_username
, /* B */
1899 fullname_len
, fullname
, /* B */
1900 homedir_len
, homedir
, /* B */
1901 dir_drive_len
, dir_drive
, /* B */
1902 logon_script_len
, logon_script
, /* B */
1903 profile_path_len
, profile_path
, /* B */
1904 acct_desc_len
, acct_desc
, /* B */
1905 workstations_len
, workstations
, /* B */
1906 unknown_str_len
, unknown_str
, /* B */
1907 munged_dial_len
, munged_dial
, /* B */
1910 lm_pw_len
, lm_pw
, /* B */
1911 nt_pw_len
, nt_pw
, /* B */
1912 nt_pw_hist_len
, nt_pw_hist
, /* B */
1913 pdb_get_acct_ctrl(sampass
), /* d */
1914 pdb_get_logon_divs(sampass
), /* w */
1915 pdb_get_hours_len(sampass
), /* d */
1916 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1917 pdb_get_bad_password_count(sampass
), /* w */
1918 pdb_get_logon_count(sampass
), /* w */
1919 pdb_get_unknown_6(sampass
)); /* d */
1925 /* malloc the space needed */
1926 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1927 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1931 /* now for the real call to tdb_pack() */
1932 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
1934 logoff_time
, /* d */
1935 kickoff_time
, /* d */
1936 bad_password_time
, /* d */
1937 pass_last_set_time
, /* d */
1938 pass_can_change_time
, /* d */
1939 pass_must_change_time
, /* d */
1940 username_len
, username
, /* B */
1941 domain_len
, domain
, /* B */
1942 nt_username_len
, nt_username
, /* B */
1943 fullname_len
, fullname
, /* B */
1944 homedir_len
, homedir
, /* B */
1945 dir_drive_len
, dir_drive
, /* B */
1946 logon_script_len
, logon_script
, /* B */
1947 profile_path_len
, profile_path
, /* B */
1948 acct_desc_len
, acct_desc
, /* B */
1949 workstations_len
, workstations
, /* B */
1950 unknown_str_len
, unknown_str
, /* B */
1951 munged_dial_len
, munged_dial
, /* B */
1954 lm_pw_len
, lm_pw
, /* B */
1955 nt_pw_len
, nt_pw
, /* B */
1956 nt_pw_hist_len
, nt_pw_hist
, /* B */
1957 pdb_get_acct_ctrl(sampass
), /* d */
1958 pdb_get_logon_divs(sampass
), /* w */
1959 pdb_get_hours_len(sampass
), /* d */
1960 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1961 pdb_get_bad_password_count(sampass
), /* w */
1962 pdb_get_logon_count(sampass
), /* w */
1963 pdb_get_unknown_6(sampass
)); /* d */
1965 /* check to make sure we got it correct */
1966 if (buflen
!= len
) {
1967 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1968 (unsigned long)buflen
, (unsigned long)len
));
1977 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1979 /* nothing changed between V3 and V4 */
1980 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
1983 static uint32
init_buffer_from_samu_v4(uint8
**buf
, struct samu
*sampass
, bool size_only
)
1985 /* nothing changed between V3 and V4 */
1986 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
1989 /**********************************************************************
1990 Intialize a struct samu struct from a BYTE buffer of size len
1991 *********************************************************************/
1993 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
1994 uint8
*buf
, uint32 buflen
)
1997 case SAMU_BUFFER_V0
:
1998 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
1999 case SAMU_BUFFER_V1
:
2000 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2001 case SAMU_BUFFER_V2
:
2002 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2003 case SAMU_BUFFER_V3
:
2004 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2005 case SAMU_BUFFER_V4
:
2006 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2012 /**********************************************************************
2013 Intialize a BYTE buffer from a struct samu struct
2014 *********************************************************************/
2016 uint32
init_buffer_from_samu (uint8
**buf
, struct samu
*sampass
, bool size_only
)
2018 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2021 /*********************************************************************
2022 *********************************************************************/
2024 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2029 len
= init_buffer_from_samu(&buf
, src
, False
);
2030 if (len
== -1 || !buf
) {
2035 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2040 dst
->methods
= src
->methods
;
2042 if ( src
->unix_pw
) {
2043 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2044 if (!dst
->unix_pw
) {
2054 /*********************************************************************
2055 Update the bad password count checking the AP_RESET_COUNT_TIME
2056 *********************************************************************/
2058 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2060 time_t LastBadPassword
;
2061 uint16 BadPasswordCount
;
2065 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2066 if (!BadPasswordCount
) {
2067 DEBUG(9, ("No bad password attempts.\n"));
2072 res
= pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
);
2076 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2080 /* First, check if there is a reset time to compare */
2081 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
2082 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2086 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2087 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2088 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
2089 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
2090 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2091 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2100 /*********************************************************************
2101 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2102 *********************************************************************/
2104 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2107 time_t LastBadPassword
;
2110 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2111 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2112 pdb_get_username(sampass
)));
2117 res
= pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
);
2121 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2125 /* First, check if there is a duration to compare */
2126 if ((duration
== (uint32
) -1) || (duration
== 0)) {
2127 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2131 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2132 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2133 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
2135 if (LastBadPassword
== (time_t)0) {
2136 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2137 "administratively locked out with no bad password "
2138 "time. Leaving locked out.\n",
2139 pdb_get_username(sampass
) ));
2143 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(duration
) * 60))) {
2144 pdb_set_acct_ctrl(sampass
,
2145 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2147 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2148 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2157 /*********************************************************************
2158 Increment the bad_password_count
2159 *********************************************************************/
2161 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2163 uint32 account_policy_lockout
;
2164 bool autolock_updated
= False
, badpw_updated
= False
;
2167 /* Retrieve the account lockout policy */
2169 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2172 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2176 /* If there is no policy, we don't need to continue checking */
2177 if (!account_policy_lockout
) {
2178 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2182 /* Check if the autolock needs to be cleared */
2183 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2186 /* Check if the badpw count needs to be reset */
2187 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2191 Ok, now we can assume that any resetting that needs to be
2192 done has been done, and just get on with incrementing
2193 and autolocking if necessary
2196 pdb_set_bad_password_count(sampass
,
2197 pdb_get_bad_password_count(sampass
)+1,
2199 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2202 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2205 if (!pdb_set_acct_ctrl(sampass
,
2206 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2208 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2215 bool is_dc_trusted_domain_situation(const char *domain_name
)
2217 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2220 /*******************************************************************
2221 Wrapper around retrieving the clear text trust account password.
2222 appropriate account name is stored in account_name.
2223 Caller must free password, but not account_name.
2224 *******************************************************************/
2226 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2227 const char **account_name
, uint32
*channel
)
2230 time_t last_set_time
;
2232 /* if we are a DC and this is not our domain, then lookup an account
2233 * for the domain trust */
2235 if (is_dc_trusted_domain_situation(domain
)) {
2236 if (!lp_allow_trusted_domains()) {
2240 if (!pdb_get_trusteddom_pw(domain
, ret_pwd
, NULL
,
2243 DEBUG(0, ("get_trust_pw: could not fetch trust "
2244 "account password for trusted domain %s\n",
2249 if (channel
!= NULL
) {
2250 *channel
= SEC_CHAN_DOMAIN
;
2253 if (account_name
!= NULL
) {
2254 *account_name
= lp_workgroup();
2261 * Since we can only be member of one single domain, we are now
2262 * in a member situation:
2264 * - Either we are a DC (selfjoined) and the domain is our
2266 * - Or we are on a member and the domain is our own or some
2267 * other (potentially trusted) domain.
2269 * In both cases, we can only get the machine account password
2270 * for our own domain to connect to our own dc. (For a member,
2271 * request to trusted domains are performed through our dc.)
2273 * So we simply use our own domain name to retrieve the
2274 * machine account passowrd and ignore the request domain here.
2277 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2281 if (account_name
!= NULL
) {
2282 *account_name
= global_myname();
2288 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2289 "account password for domain %s\n", domain
));
2293 /*******************************************************************
2294 Wrapper around retrieving the trust account password.
2295 appropriate account name is stored in account_name.
2296 *******************************************************************/
2298 bool get_trust_pw_hash(const char *domain
, uint8 ret_pwd
[16],
2299 const char **account_name
, uint32
*channel
)
2302 time_t last_set_time
;
2304 if (get_trust_pw_clear(domain
, &pwd
, account_name
, channel
)) {
2305 E_md4hash(pwd
, ret_pwd
);
2308 } else if (is_dc_trusted_domain_situation(domain
)) {
2312 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2314 if (secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
2318 if (account_name
!= NULL
) {
2319 *account_name
= global_myname();
2325 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2326 "password for domain %s\n", domain
));
2330 struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
2333 struct samr_LogonHours hours
;
2334 const int units_per_week
= 168;
2337 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
2342 hours
.units_per_week
= units_per_week
;
2343 memset(hours
.bits
, 0xFF, units_per_week
);
2345 if (pdb_get_hours(pw
)) {
2346 memcpy(hours
.bits
, pdb_get_hours(pw
),
2347 MIN(pdb_get_hours_len(pw
), units_per_week
));