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.
34 LEGACY: this function provides the legacy domain mapping used with
35 the lp_map_untrusted_to_domain() parameter
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 /* Default to the DOMAIN name when not specified */
45 return lp_workgroup();
48 /**********************************************************************
49 ***********************************************************************/
51 static int samu_destroy(struct samu
*user
)
53 data_blob_clear_free( &user
->lm_pw
);
54 data_blob_clear_free( &user
->nt_pw
);
56 if ( user
->plaintext_pw
)
57 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
62 /**********************************************************************
63 generate a new struct samuser
64 ***********************************************************************/
66 struct samu
*samu_new( TALLOC_CTX
*ctx
)
70 if ( !(user
= TALLOC_ZERO_P( ctx
, struct samu
)) ) {
71 DEBUG(0,("samuser_new: Talloc failed!\n"));
75 talloc_set_destructor( user
, samu_destroy
);
77 /* no initial methods */
81 /* Don't change these timestamp settings without a good reason.
82 They are important for NT member server compatibility. */
84 user
->logon_time
= (time_t)0;
85 user
->pass_last_set_time
= (time_t)0;
86 user
->pass_can_change_time
= (time_t)0;
87 user
->logoff_time
= get_time_t_max();
88 user
->kickoff_time
= get_time_t_max();
89 user
->pass_must_change_time
= get_time_t_max();
90 user
->fields_present
= 0x00ffffff;
91 user
->logon_divs
= 168; /* hours per week */
92 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
93 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
94 user
->bad_password_count
= 0;
95 user
->logon_count
= 0;
96 user
->unknown_6
= 0x000004ec; /* don't know */
98 /* Some parts of samba strlen their pdb_get...() returns,
99 so this keeps the interface unchanged for now. */
103 user
->nt_username
= "";
104 user
->full_name
= "";
106 user
->logon_script
= "";
107 user
->profile_path
= "";
108 user
->acct_desc
= "";
109 user
->workstations
= "";
111 user
->munged_dial
= "";
113 user
->plaintext_pw
= NULL
;
115 /* Unless we know otherwise have a Account Control Bit
116 value of 'normal user'. This helps User Manager, which
117 asks for a filtered list of users. */
119 user
->acct_ctrl
= ACB_NORMAL
;
124 /*********************************************************************
125 Initialize a struct samu from a struct passwd including the user
126 and group SIDs. The *user structure is filled out with the Unix
127 attributes and a user SID.
128 *********************************************************************/
130 static NTSTATUS
samu_set_unix_internal(struct samu
*user
, const struct passwd
*pwd
, bool create
)
132 const char *guest_account
= lp_guestaccount();
133 const char *domain
= global_myname();
137 return NT_STATUS_NO_SUCH_USER
;
140 /* Basic properties based upon the Unix account information */
142 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
143 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
144 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
146 /* This can lead to a primary group of S-1-22-2-XX which
147 will be rejected by other parts of the Samba code.
148 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
151 gid_to_sid(&group_sid
, pwd
->pw_gid
);
152 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
155 /* save the password structure for later use */
157 user
->unix_pw
= tcopy_passwd( user
, pwd
);
159 /* Special case for the guest account which must have a RID of 501 */
161 if ( strequal( pwd
->pw_name
, guest_account
) ) {
162 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_USER_RID_GUEST
, PDB_DEFAULT
)) {
163 return NT_STATUS_NO_SUCH_USER
;
168 /* Non-guest accounts...Check for a workstation or user account */
170 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
173 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
174 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
176 return NT_STATUS_INVALID_COMPUTER_NAME
;
182 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
183 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
185 return NT_STATUS_INVALID_ACCOUNT_NAME
;
188 /* set some basic attributes */
190 pdb_set_profile_path(user
, talloc_sub_specified(user
,
191 lp_logon_path(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
193 pdb_set_homedir(user
, talloc_sub_specified(user
,
194 lp_logon_home(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
196 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
197 lp_logon_drive(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
199 pdb_set_logon_script(user
, talloc_sub_specified(user
,
200 lp_logon_script(), pwd
->pw_name
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
204 /* Now deal with the user SID. If we have a backend that can generate
205 RIDs, then do so. But sometimes the caller just wanted a structure
206 initialized and will fill in these fields later (such as from a
207 netr_SamInfo3 structure) */
209 if ( create
&& !pdb_rid_algorithm() ) {
213 if ( !pdb_new_rid( &user_rid
) ) {
214 DEBUG(3, ("Could not allocate a new RID\n"));
215 return NT_STATUS_ACCESS_DENIED
;
218 sid_copy( &user_sid
, get_global_sam_sid() );
219 sid_append_rid( &user_sid
, user_rid
);
221 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
222 DEBUG(3, ("pdb_set_user_sid failed\n"));
223 return NT_STATUS_INTERNAL_ERROR
;
229 /* generate a SID for the user with the RID algorithm */
231 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
233 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
234 return NT_STATUS_INTERNAL_ERROR
;
240 /********************************************************************
241 Set the Unix user attributes
242 ********************************************************************/
244 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
246 return samu_set_unix_internal( user
, pwd
, False
);
249 NTSTATUS
samu_alloc_rid_unix(struct samu
*user
, const struct passwd
*pwd
)
251 return samu_set_unix_internal( user
, pwd
, True
);
254 /**********************************************************
255 Encode the account control bits into a string.
256 length = length of string to encode into (including terminating
257 null). length *MUST BE MORE THAN 2* !
258 **********************************************************/
260 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl
, size_t length
)
267 SMB_ASSERT(length
<= sizeof(acct_str
));
271 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
272 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
273 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
274 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
275 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
276 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
277 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
278 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
279 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
280 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
281 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
283 for ( ; i
< length
- 2 ; i
++ )
288 acct_str
[i
++] = '\0';
290 result
= talloc_strdup(talloc_tos(), acct_str
);
291 SMB_ASSERT(result
!= NULL
);
295 /**********************************************************
296 Decode the account control bits from a string.
297 **********************************************************/
299 uint32_t pdb_decode_acct_ctrl(const char *p
)
301 uint32_t acct_ctrl
= 0;
302 bool finished
= false;
305 * Check if the account type bits have been encoded after the
306 * NT password (in the form [NDHTUWSLXI]).
312 for (p
++; *p
&& !finished
; p
++) {
314 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
315 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
316 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
317 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
318 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
319 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
320 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
321 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
322 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
323 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
324 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
330 default: { finished
= true; }
337 /*************************************************************
338 Routine to set 32 hex password characters from a 16 byte array.
339 **************************************************************/
341 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32 acct_ctrl
)
345 for (i
= 0; i
< 16; i
++)
346 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
348 if (acct_ctrl
& ACB_PWNOTREQ
)
349 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
351 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
355 /*************************************************************
356 Routine to get the 32 hex characters and turn them
357 into a 16 byte array.
358 **************************************************************/
360 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
363 unsigned char lonybble
, hinybble
;
364 const char *hexchars
= "0123456789ABCDEF";
370 for (i
= 0; i
< 32; i
+= 2) {
371 hinybble
= toupper_ascii(p
[i
]);
372 lonybble
= toupper_ascii(p
[i
+ 1]);
374 p1
= strchr(hexchars
, hinybble
);
375 p2
= strchr(hexchars
, lonybble
);
380 hinybble
= PTR_DIFF(p1
, hexchars
);
381 lonybble
= PTR_DIFF(p2
, hexchars
);
383 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
388 /*************************************************************
389 Routine to set 42 hex hours characters from a 21 byte array.
390 **************************************************************/
392 void pdb_sethexhours(char *p
, const unsigned char *hours
)
396 for (i
= 0; i
< 21; i
++) {
397 slprintf(&p
[i
*2], 3, "%02X", hours
[i
]);
400 safe_strcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
404 /*************************************************************
405 Routine to get the 42 hex characters and turn them
406 into a 21 byte array.
407 **************************************************************/
409 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
412 unsigned char lonybble
, hinybble
;
413 const char *hexchars
= "0123456789ABCDEF";
420 for (i
= 0; i
< 42; i
+= 2) {
421 hinybble
= toupper_ascii(p
[i
]);
422 lonybble
= toupper_ascii(p
[i
+ 1]);
424 p1
= strchr(hexchars
, hinybble
);
425 p2
= strchr(hexchars
, lonybble
);
431 hinybble
= PTR_DIFF(p1
, hexchars
);
432 lonybble
= PTR_DIFF(p2
, hexchars
);
434 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
439 /********************************************************************
440 ********************************************************************/
442 int algorithmic_rid_base(void)
446 rid_offset
= lp_algorithmic_rid_base();
448 if (rid_offset
< BASE_RID
) {
449 /* Try to prevent admin foot-shooting, we can't put algorithmic
450 rids below 1000, that's the 'well known RIDs' on NT */
451 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
452 rid_offset
= BASE_RID
;
454 if (rid_offset
& 1) {
455 DEBUG(0, ("algorithmic rid base must be even\n"));
461 /*******************************************************************
462 Converts NT user RID to a UNIX uid.
463 ********************************************************************/
465 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
467 int rid_offset
= algorithmic_rid_base();
468 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
471 uid_t
max_algorithmic_uid(void)
473 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
476 /*******************************************************************
477 converts UNIX uid to an NT User RID.
478 ********************************************************************/
480 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
482 int rid_offset
= algorithmic_rid_base();
483 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
486 /*******************************************************************
487 Converts NT group RID to a UNIX gid.
488 ********************************************************************/
490 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
492 int rid_offset
= algorithmic_rid_base();
493 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
496 gid_t
max_algorithmic_gid(void)
498 return pdb_group_rid_to_gid(0xffffffff);
501 /*******************************************************************
502 converts NT Group RID to a UNIX uid.
504 warning: you must not call that function only
505 you must do a call to the group mapping first.
506 there is not anymore a direct link between the gid and the rid.
507 ********************************************************************/
509 uint32
algorithmic_pdb_gid_to_group_rid(gid_t gid
)
511 int rid_offset
= algorithmic_rid_base();
512 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
515 /*******************************************************************
516 Decides if a RID is a well known RID.
517 ********************************************************************/
519 static bool rid_is_well_known(uint32 rid
)
521 /* Not using rid_offset here, because this is the actual
522 NT fixed value (1000) */
524 return (rid
< BASE_RID
);
527 /*******************************************************************
528 Decides if a RID is a user or group RID.
529 ********************************************************************/
531 bool algorithmic_pdb_rid_is_user(uint32 rid
)
533 if ( rid_is_well_known(rid
) ) {
535 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
536 * and DOMAIN_USER_RID_GUEST.
538 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
540 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
546 /*******************************************************************
547 Convert a name into a SID. Used in the lookup name rpc.
548 ********************************************************************/
550 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
551 enum lsa_SidType
*type
)
556 /* Windows treats "MACHINE\None" as a special name for
557 rid 513 on non-DCs. You cannot create a user or group
558 name "None" on Windows. You will get an error that
559 the group already exists. */
561 if ( strequal( name
, "None" ) ) {
562 *rid
= DOMAIN_GROUP_RID_USERS
;
563 *type
= SID_NAME_DOM_GRP
;
568 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
569 * correctly in the case where foo also exists as a user. If the flag
570 * is set, don't look for users at all. */
572 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
573 struct samu
*sam_account
= NULL
;
576 if ( !(sam_account
= samu_new( NULL
)) ) {
581 ret
= pdb_getsampwnam(sam_account
, name
);
585 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
588 TALLOC_FREE(sam_account
);
591 if (!sid_check_is_in_our_domain(&user_sid
)) {
592 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
593 name
, sid_string_dbg(&user_sid
)));
597 sid_peek_rid(&user_sid
, rid
);
598 *type
= SID_NAME_USER
;
604 * Maybe it is a group ?
608 ret
= pdb_getgrnam(&map
, name
);
615 /* BUILTIN groups are looked up elsewhere */
616 if (!sid_check_is_in_our_domain(&map
.sid
)) {
617 DEBUG(10, ("Found group %s (%s) not in our domain -- "
618 "ignoring.", name
, sid_string_dbg(&map
.sid
)));
622 /* yes it's a mapped group */
623 sid_peek_rid(&map
.sid
, rid
);
624 *type
= map
.sid_name_use
;
628 /*************************************************************
629 Change a password entry in the local smbpasswd file.
630 *************************************************************/
632 NTSTATUS
local_password_change(const char *user_name
,
634 const char *new_passwd
,
638 struct samu
*sam_pass
=NULL
;
645 /* Get the smb passwd entry for this user */
647 if ( !(sam_pass
= samu_new( NULL
)) ) {
648 return NT_STATUS_NO_MEMORY
;
652 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
654 TALLOC_FREE(sam_pass
);
656 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
657 int tmp_debug
= DEBUGLEVEL
;
660 /* Might not exist in /etc/passwd. */
666 if ( !(pwd
= getpwnam_alloc(talloc_autofree_context(), user_name
)) ) {
667 return NT_STATUS_NO_SUCH_USER
;
670 /* create the struct samu and initialize the basic Unix properties */
672 if ( !(sam_pass
= samu_new( NULL
)) ) {
673 return NT_STATUS_NO_MEMORY
;
676 result
= samu_set_unix( sam_pass
, pwd
);
678 DEBUGLEVEL
= tmp_debug
;
682 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
686 if (!NT_STATUS_IS_OK(result
)) {
687 if (asprintf(pp_err_str
, "Failed to " "initialize account for user %s: %s\n",
688 user_name
, nt_errstr(result
)) < 0) {
694 if (asprintf(pp_err_str
, "Failed to find entry for user %s.\n", user_name
) < 0) {
697 return NT_STATUS_NO_SUCH_USER
;
701 /* the entry already existed */
702 local_flags
&= ~LOCAL_ADD_USER
;
705 /* the 'other' acb bits not being changed here */
706 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (~(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
707 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
708 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
709 if (asprintf(pp_err_str
, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
) < 0) {
712 TALLOC_FREE(sam_pass
);
713 return NT_STATUS_UNSUCCESSFUL
;
715 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
716 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
717 if (asprintf(pp_err_str
, "Failed to set 'domain trust account' flags for user %s.\n", user_name
) < 0) {
720 TALLOC_FREE(sam_pass
);
721 return NT_STATUS_UNSUCCESSFUL
;
724 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
725 if (asprintf(pp_err_str
, "Failed to set 'normal account' flags for user %s.\n", user_name
) < 0) {
728 TALLOC_FREE(sam_pass
);
729 return NT_STATUS_UNSUCCESSFUL
;
734 * We are root - just write the new password
735 * and the valid last change time.
738 if (local_flags
& LOCAL_DISABLE_USER
) {
739 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
740 if (asprintf(pp_err_str
, "Failed to set 'disabled' flag for user %s.\n", user_name
) < 0) {
743 TALLOC_FREE(sam_pass
);
744 return NT_STATUS_UNSUCCESSFUL
;
746 } else if (local_flags
& LOCAL_ENABLE_USER
) {
747 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
748 if (asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
) < 0) {
751 TALLOC_FREE(sam_pass
);
752 return NT_STATUS_UNSUCCESSFUL
;
756 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
757 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
758 if (asprintf(pp_err_str
, "Failed to set 'no password required' flag for user %s.\n", user_name
) < 0) {
761 TALLOC_FREE(sam_pass
);
762 return NT_STATUS_UNSUCCESSFUL
;
764 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
766 * If we're dealing with setting a completely empty user account
767 * ie. One with a password of 'XXXX', but not set disabled (like
768 * an account created from scratch) then if the old password was
769 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
770 * We remove that as we're giving this user their first password
771 * and the decision hasn't really been made to disable them (ie.
772 * don't create them disabled). JRA.
774 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
775 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
776 if (asprintf(pp_err_str
, "Failed to unset 'disabled' flag for user %s.\n", user_name
) < 0) {
779 TALLOC_FREE(sam_pass
);
780 return NT_STATUS_UNSUCCESSFUL
;
783 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
784 if (asprintf(pp_err_str
, "Failed to unset 'no password required' flag for user %s.\n", user_name
) < 0) {
787 TALLOC_FREE(sam_pass
);
788 return NT_STATUS_UNSUCCESSFUL
;
791 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
792 if (asprintf(pp_err_str
, "Failed to set password for user %s.\n", user_name
) < 0) {
795 TALLOC_FREE(sam_pass
);
796 return NT_STATUS_UNSUCCESSFUL
;
800 if (local_flags
& LOCAL_ADD_USER
) {
801 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
802 if (asprintf(pp_msg_str
, "Added user %s.\n", user_name
) < 0) {
805 TALLOC_FREE(sam_pass
);
808 if (asprintf(pp_err_str
, "Failed to add entry for user %s.\n", user_name
) < 0) {
811 TALLOC_FREE(sam_pass
);
812 return NT_STATUS_UNSUCCESSFUL
;
814 } else if (local_flags
& LOCAL_DELETE_USER
) {
815 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
816 if (asprintf(pp_err_str
, "Failed to delete entry for user %s.\n", user_name
) < 0) {
819 TALLOC_FREE(sam_pass
);
820 return NT_STATUS_UNSUCCESSFUL
;
822 if (asprintf(pp_msg_str
, "Deleted user %s.\n", user_name
) < 0) {
826 result
= pdb_update_sam_account(sam_pass
);
827 if(!NT_STATUS_IS_OK(result
)) {
828 if (asprintf(pp_err_str
, "Failed to modify entry for user %s.\n", user_name
) < 0) {
831 TALLOC_FREE(sam_pass
);
834 if(local_flags
& LOCAL_DISABLE_USER
) {
835 if (asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
) < 0) {
838 } else if (local_flags
& LOCAL_ENABLE_USER
) {
839 if (asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
) < 0) {
842 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
843 if (asprintf(pp_msg_str
, "User %s password set to none.\n", user_name
) < 0) {
849 TALLOC_FREE(sam_pass
);
853 /**********************************************************************
854 Marshall/unmarshall struct samu structs.
855 *********************************************************************/
857 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
858 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
859 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
860 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
861 /* nothing changed between V3 and V4 */
863 /*********************************************************************
864 *********************************************************************/
866 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
869 /* times are stored as 32bit integer
870 take care on system with 64bit wide time_t
876 pass_can_change_time
,
877 pass_must_change_time
;
878 char *username
= NULL
;
880 char *nt_username
= NULL
;
881 char *dir_drive
= NULL
;
882 char *unknown_str
= NULL
;
883 char *munged_dial
= NULL
;
884 char *fullname
= NULL
;
885 char *homedir
= NULL
;
886 char *logon_script
= NULL
;
887 char *profile_path
= NULL
;
888 char *acct_desc
= NULL
;
889 char *workstations
= NULL
;
890 uint32 username_len
, domain_len
, nt_username_len
,
891 dir_drive_len
, unknown_str_len
, munged_dial_len
,
892 fullname_len
, homedir_len
, logon_script_len
,
893 profile_path_len
, acct_desc_len
, workstations_len
;
895 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
896 uint16 acct_ctrl
, logon_divs
;
897 uint16 bad_password_count
, logon_count
;
899 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
901 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
904 if(sampass
== NULL
|| buf
== NULL
) {
905 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
909 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
911 /* unpack the buffer into variables */
912 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
914 &logoff_time
, /* d */
915 &kickoff_time
, /* d */
916 &pass_last_set_time
, /* d */
917 &pass_can_change_time
, /* d */
918 &pass_must_change_time
, /* d */
919 &username_len
, &username
, /* B */
920 &domain_len
, &domain
, /* B */
921 &nt_username_len
, &nt_username
, /* B */
922 &fullname_len
, &fullname
, /* B */
923 &homedir_len
, &homedir
, /* B */
924 &dir_drive_len
, &dir_drive
, /* B */
925 &logon_script_len
, &logon_script
, /* B */
926 &profile_path_len
, &profile_path
, /* B */
927 &acct_desc_len
, &acct_desc
, /* B */
928 &workstations_len
, &workstations
, /* B */
929 &unknown_str_len
, &unknown_str
, /* B */
930 &munged_dial_len
, &munged_dial
, /* B */
933 &lm_pw_len
, &lm_pw_ptr
, /* B */
934 &nt_pw_len
, &nt_pw_ptr
, /* B */
936 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
939 &hourslen
, &hours
, /* B */
940 &bad_password_count
, /* w */
941 &logon_count
, /* w */
944 if (len
== (uint32
) -1) {
949 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
950 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
951 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
952 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
953 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
954 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
956 pdb_set_username(sampass
, username
, PDB_SET
);
957 pdb_set_domain(sampass
, domain
, PDB_SET
);
958 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
959 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
962 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
965 pdb_set_homedir(sampass
,
966 talloc_sub_basic(sampass
, username
, domain
,
972 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
974 pdb_set_dir_drive(sampass
,
975 talloc_sub_basic(sampass
, username
, domain
,
981 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
983 pdb_set_logon_script(sampass
,
984 talloc_sub_basic(sampass
, username
, domain
,
990 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
992 pdb_set_profile_path(sampass
,
993 talloc_sub_basic(sampass
, username
, domain
,
998 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
999 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1000 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1002 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1003 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1009 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1010 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1016 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1017 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1018 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1019 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1020 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1021 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1022 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1023 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1024 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1025 pdb_set_hours(sampass
, hours
, PDB_SET
);
1029 SAFE_FREE(username
);
1031 SAFE_FREE(nt_username
);
1032 SAFE_FREE(fullname
);
1034 SAFE_FREE(dir_drive
);
1035 SAFE_FREE(logon_script
);
1036 SAFE_FREE(profile_path
);
1037 SAFE_FREE(acct_desc
);
1038 SAFE_FREE(workstations
);
1039 SAFE_FREE(munged_dial
);
1040 SAFE_FREE(unknown_str
);
1041 SAFE_FREE(lm_pw_ptr
);
1042 SAFE_FREE(nt_pw_ptr
);
1048 /*********************************************************************
1049 *********************************************************************/
1051 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1054 /* times are stored as 32bit integer
1055 take care on system with 64bit wide time_t
1062 pass_can_change_time
,
1063 pass_must_change_time
;
1064 char *username
= NULL
;
1065 char *domain
= NULL
;
1066 char *nt_username
= NULL
;
1067 char *dir_drive
= NULL
;
1068 char *unknown_str
= NULL
;
1069 char *munged_dial
= NULL
;
1070 char *fullname
= NULL
;
1071 char *homedir
= NULL
;
1072 char *logon_script
= NULL
;
1073 char *profile_path
= NULL
;
1074 char *acct_desc
= NULL
;
1075 char *workstations
= NULL
;
1076 uint32 username_len
, domain_len
, nt_username_len
,
1077 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1078 fullname_len
, homedir_len
, logon_script_len
,
1079 profile_path_len
, acct_desc_len
, workstations_len
;
1081 uint32 user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1082 uint16 acct_ctrl
, logon_divs
;
1083 uint16 bad_password_count
, logon_count
;
1084 uint8
*hours
= NULL
;
1085 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1087 uint32 lm_pw_len
, nt_pw_len
, hourslen
;
1090 if(sampass
== NULL
|| buf
== NULL
) {
1091 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1095 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1097 /* unpack the buffer into variables */
1098 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1099 &logon_time
, /* d */
1100 &logoff_time
, /* d */
1101 &kickoff_time
, /* d */
1102 /* Change from V0 is addition of bad_password_time field. */
1103 &bad_password_time
, /* d */
1104 &pass_last_set_time
, /* d */
1105 &pass_can_change_time
, /* d */
1106 &pass_must_change_time
, /* d */
1107 &username_len
, &username
, /* B */
1108 &domain_len
, &domain
, /* B */
1109 &nt_username_len
, &nt_username
, /* B */
1110 &fullname_len
, &fullname
, /* B */
1111 &homedir_len
, &homedir
, /* B */
1112 &dir_drive_len
, &dir_drive
, /* B */
1113 &logon_script_len
, &logon_script
, /* B */
1114 &profile_path_len
, &profile_path
, /* B */
1115 &acct_desc_len
, &acct_desc
, /* B */
1116 &workstations_len
, &workstations
, /* B */
1117 &unknown_str_len
, &unknown_str
, /* B */
1118 &munged_dial_len
, &munged_dial
, /* B */
1121 &lm_pw_len
, &lm_pw_ptr
, /* B */
1122 &nt_pw_len
, &nt_pw_ptr
, /* B */
1125 &logon_divs
, /* w */
1127 &hourslen
, &hours
, /* B */
1128 &bad_password_count
, /* w */
1129 &logon_count
, /* w */
1130 &unknown_6
); /* d */
1132 if (len
== (uint32
) -1) {
1137 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1138 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1139 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1141 /* Change from V0 is addition of bad_password_time field. */
1142 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1143 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1144 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1145 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1147 pdb_set_username(sampass
, username
, PDB_SET
);
1148 pdb_set_domain(sampass
, domain
, PDB_SET
);
1149 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1150 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1153 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1156 pdb_set_homedir(sampass
,
1157 talloc_sub_basic(sampass
, username
, domain
,
1163 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1165 pdb_set_dir_drive(sampass
,
1166 talloc_sub_basic(sampass
, username
, domain
,
1172 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1174 pdb_set_logon_script(sampass
,
1175 talloc_sub_basic(sampass
, username
, domain
,
1181 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1183 pdb_set_profile_path(sampass
,
1184 talloc_sub_basic(sampass
, username
, domain
,
1189 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1190 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1191 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1193 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1194 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1200 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1201 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1207 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1209 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1210 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1211 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1212 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1213 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1214 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1215 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1216 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1217 pdb_set_hours(sampass
, hours
, PDB_SET
);
1221 SAFE_FREE(username
);
1223 SAFE_FREE(nt_username
);
1224 SAFE_FREE(fullname
);
1226 SAFE_FREE(dir_drive
);
1227 SAFE_FREE(logon_script
);
1228 SAFE_FREE(profile_path
);
1229 SAFE_FREE(acct_desc
);
1230 SAFE_FREE(workstations
);
1231 SAFE_FREE(munged_dial
);
1232 SAFE_FREE(unknown_str
);
1233 SAFE_FREE(lm_pw_ptr
);
1234 SAFE_FREE(nt_pw_ptr
);
1240 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1243 /* times are stored as 32bit integer
1244 take care on system with 64bit wide time_t
1251 pass_can_change_time
,
1252 pass_must_change_time
;
1253 char *username
= NULL
;
1254 char *domain
= NULL
;
1255 char *nt_username
= NULL
;
1256 char *dir_drive
= NULL
;
1257 char *unknown_str
= NULL
;
1258 char *munged_dial
= NULL
;
1259 char *fullname
= NULL
;
1260 char *homedir
= NULL
;
1261 char *logon_script
= NULL
;
1262 char *profile_path
= NULL
;
1263 char *acct_desc
= NULL
;
1264 char *workstations
= NULL
;
1265 uint32 username_len
, domain_len
, nt_username_len
,
1266 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1267 fullname_len
, homedir_len
, logon_script_len
,
1268 profile_path_len
, acct_desc_len
, workstations_len
;
1270 uint32 user_rid
, group_rid
, hours_len
, unknown_6
;
1271 uint16 acct_ctrl
, logon_divs
;
1272 uint16 bad_password_count
, logon_count
;
1273 uint8
*hours
= NULL
;
1274 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1276 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1277 uint32 pwHistLen
= 0;
1280 bool expand_explicit
= lp_passdb_expand_explicit();
1282 if(sampass
== NULL
|| buf
== NULL
) {
1283 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1287 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1289 /* unpack the buffer into variables */
1290 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1291 &logon_time
, /* d */
1292 &logoff_time
, /* d */
1293 &kickoff_time
, /* d */
1294 &bad_password_time
, /* d */
1295 &pass_last_set_time
, /* d */
1296 &pass_can_change_time
, /* d */
1297 &pass_must_change_time
, /* d */
1298 &username_len
, &username
, /* B */
1299 &domain_len
, &domain
, /* B */
1300 &nt_username_len
, &nt_username
, /* B */
1301 &fullname_len
, &fullname
, /* B */
1302 &homedir_len
, &homedir
, /* B */
1303 &dir_drive_len
, &dir_drive
, /* B */
1304 &logon_script_len
, &logon_script
, /* B */
1305 &profile_path_len
, &profile_path
, /* B */
1306 &acct_desc_len
, &acct_desc
, /* B */
1307 &workstations_len
, &workstations
, /* B */
1308 &unknown_str_len
, &unknown_str
, /* B */
1309 &munged_dial_len
, &munged_dial
, /* B */
1312 &lm_pw_len
, &lm_pw_ptr
, /* B */
1313 &nt_pw_len
, &nt_pw_ptr
, /* B */
1314 /* Change from V1 is addition of password history field. */
1315 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1317 /* Also "remove_me" field was removed. */
1318 &logon_divs
, /* w */
1320 &hourslen
, &hours
, /* B */
1321 &bad_password_count
, /* w */
1322 &logon_count
, /* w */
1323 &unknown_6
); /* d */
1325 if (len
== (uint32
) -1) {
1330 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1331 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1332 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1333 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1334 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1335 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1336 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1338 pdb_set_username(sampass
, username
, PDB_SET
);
1339 pdb_set_domain(sampass
, domain
, PDB_SET
);
1340 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1341 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1344 fstrcpy( tmp_string
, homedir
);
1345 if (expand_explicit
) {
1346 standard_sub_basic( username
, domain
, tmp_string
,
1347 sizeof(tmp_string
) );
1349 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1352 pdb_set_homedir(sampass
,
1353 talloc_sub_basic(sampass
, username
, domain
,
1359 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1361 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1364 fstrcpy( tmp_string
, logon_script
);
1365 if (expand_explicit
) {
1366 standard_sub_basic( username
, domain
, tmp_string
,
1367 sizeof(tmp_string
) );
1369 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1372 pdb_set_logon_script(sampass
,
1373 talloc_sub_basic(sampass
, username
, domain
,
1379 fstrcpy( tmp_string
, profile_path
);
1380 if (expand_explicit
) {
1381 standard_sub_basic( username
, domain
, tmp_string
,
1382 sizeof(tmp_string
) );
1384 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1387 pdb_set_profile_path(sampass
,
1388 talloc_sub_basic(sampass
, username
, domain
,
1393 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1394 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1395 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1397 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1398 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1404 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1405 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1411 /* Change from V1 is addition of password history field. */
1412 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1414 uint8
*pw_hist
= SMB_MALLOC_ARRAY(uint8
, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1419 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1420 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1422 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1423 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1424 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1425 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1426 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1427 PW_HISTORY_ENTRY_LEN
);
1430 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1437 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1440 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1441 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1442 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1443 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1444 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1445 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1446 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1447 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1448 pdb_set_hours(sampass
, hours
, PDB_SET
);
1452 SAFE_FREE(username
);
1454 SAFE_FREE(nt_username
);
1455 SAFE_FREE(fullname
);
1457 SAFE_FREE(dir_drive
);
1458 SAFE_FREE(logon_script
);
1459 SAFE_FREE(profile_path
);
1460 SAFE_FREE(acct_desc
);
1461 SAFE_FREE(workstations
);
1462 SAFE_FREE(munged_dial
);
1463 SAFE_FREE(unknown_str
);
1464 SAFE_FREE(lm_pw_ptr
);
1465 SAFE_FREE(nt_pw_ptr
);
1466 SAFE_FREE(nt_pw_hist_ptr
);
1472 /*********************************************************************
1473 *********************************************************************/
1475 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1478 /* times are stored as 32bit integer
1479 take care on system with 64bit wide time_t
1486 pass_can_change_time
,
1487 pass_must_change_time
;
1488 char *username
= NULL
;
1489 char *domain
= NULL
;
1490 char *nt_username
= NULL
;
1491 char *dir_drive
= NULL
;
1492 char *unknown_str
= NULL
;
1493 char *munged_dial
= NULL
;
1494 char *fullname
= NULL
;
1495 char *homedir
= NULL
;
1496 char *logon_script
= NULL
;
1497 char *profile_path
= NULL
;
1498 char *acct_desc
= NULL
;
1499 char *workstations
= NULL
;
1500 uint32 username_len
, domain_len
, nt_username_len
,
1501 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1502 fullname_len
, homedir_len
, logon_script_len
,
1503 profile_path_len
, acct_desc_len
, workstations_len
;
1505 uint32 user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1507 uint16 bad_password_count
, logon_count
;
1508 uint8
*hours
= NULL
;
1509 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1511 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1512 uint32 pwHistLen
= 0;
1515 bool expand_explicit
= lp_passdb_expand_explicit();
1517 if(sampass
== NULL
|| buf
== NULL
) {
1518 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1522 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1524 /* unpack the buffer into variables */
1525 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1526 &logon_time
, /* d */
1527 &logoff_time
, /* d */
1528 &kickoff_time
, /* d */
1529 &bad_password_time
, /* d */
1530 &pass_last_set_time
, /* d */
1531 &pass_can_change_time
, /* d */
1532 &pass_must_change_time
, /* d */
1533 &username_len
, &username
, /* B */
1534 &domain_len
, &domain
, /* B */
1535 &nt_username_len
, &nt_username
, /* B */
1536 &fullname_len
, &fullname
, /* B */
1537 &homedir_len
, &homedir
, /* B */
1538 &dir_drive_len
, &dir_drive
, /* B */
1539 &logon_script_len
, &logon_script
, /* B */
1540 &profile_path_len
, &profile_path
, /* B */
1541 &acct_desc_len
, &acct_desc
, /* B */
1542 &workstations_len
, &workstations
, /* B */
1543 &unknown_str_len
, &unknown_str
, /* B */
1544 &munged_dial_len
, &munged_dial
, /* B */
1547 &lm_pw_len
, &lm_pw_ptr
, /* B */
1548 &nt_pw_len
, &nt_pw_ptr
, /* B */
1549 /* Change from V1 is addition of password history field. */
1550 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1551 /* Change from V2 is the uint32 acb_mask */
1553 /* Also "remove_me" field was removed. */
1554 &logon_divs
, /* w */
1556 &hourslen
, &hours
, /* B */
1557 &bad_password_count
, /* w */
1558 &logon_count
, /* w */
1559 &unknown_6
); /* d */
1561 if (len
== (uint32
) -1) {
1566 pdb_set_logon_time(sampass
, convert_uint32_to_time_t(logon_time
), PDB_SET
);
1567 pdb_set_logoff_time(sampass
, convert_uint32_to_time_t(logoff_time
), PDB_SET
);
1568 pdb_set_kickoff_time(sampass
, convert_uint32_to_time_t(kickoff_time
), PDB_SET
);
1569 pdb_set_bad_password_time(sampass
, convert_uint32_to_time_t(bad_password_time
), PDB_SET
);
1570 pdb_set_pass_can_change_time(sampass
, convert_uint32_to_time_t(pass_can_change_time
), PDB_SET
);
1571 pdb_set_pass_must_change_time(sampass
, convert_uint32_to_time_t(pass_must_change_time
), PDB_SET
);
1572 pdb_set_pass_last_set_time(sampass
, convert_uint32_to_time_t(pass_last_set_time
), PDB_SET
);
1574 pdb_set_username(sampass
, username
, PDB_SET
);
1575 pdb_set_domain(sampass
, domain
, PDB_SET
);
1576 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1577 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1580 fstrcpy( tmp_string
, homedir
);
1581 if (expand_explicit
) {
1582 standard_sub_basic( username
, domain
, tmp_string
,
1583 sizeof(tmp_string
) );
1585 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1588 pdb_set_homedir(sampass
,
1589 talloc_sub_basic(sampass
, username
, domain
,
1595 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1597 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1600 fstrcpy( tmp_string
, logon_script
);
1601 if (expand_explicit
) {
1602 standard_sub_basic( username
, domain
, tmp_string
,
1603 sizeof(tmp_string
) );
1605 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1608 pdb_set_logon_script(sampass
,
1609 talloc_sub_basic(sampass
, username
, domain
,
1615 fstrcpy( tmp_string
, profile_path
);
1616 if (expand_explicit
) {
1617 standard_sub_basic( username
, domain
, tmp_string
,
1618 sizeof(tmp_string
) );
1620 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1623 pdb_set_profile_path(sampass
,
1624 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1628 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1629 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1630 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1632 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1633 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1639 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1640 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1646 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1648 uint8
*pw_hist
= (uint8
*)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1653 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1654 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1656 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1657 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1658 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1659 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1660 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1661 PW_HISTORY_ENTRY_LEN
);
1664 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1671 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1674 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1675 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1676 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1677 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1678 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1679 /* Change from V2 is the uint32 acct_ctrl */
1680 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1681 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1682 pdb_set_hours(sampass
, hours
, PDB_SET
);
1686 SAFE_FREE(username
);
1688 SAFE_FREE(nt_username
);
1689 SAFE_FREE(fullname
);
1691 SAFE_FREE(dir_drive
);
1692 SAFE_FREE(logon_script
);
1693 SAFE_FREE(profile_path
);
1694 SAFE_FREE(acct_desc
);
1695 SAFE_FREE(workstations
);
1696 SAFE_FREE(munged_dial
);
1697 SAFE_FREE(unknown_str
);
1698 SAFE_FREE(lm_pw_ptr
);
1699 SAFE_FREE(nt_pw_ptr
);
1700 SAFE_FREE(nt_pw_hist_ptr
);
1706 /*********************************************************************
1707 *********************************************************************/
1709 static uint32
init_buffer_from_samu_v3 (uint8
**buf
, struct samu
*sampass
, bool size_only
)
1713 /* times are stored as 32bit integer
1714 take care on system with 64bit wide time_t
1721 pass_can_change_time
,
1722 pass_must_change_time
;
1724 uint32 user_rid
, group_rid
;
1726 const char *username
;
1728 const char *nt_username
;
1729 const char *dir_drive
;
1730 const char *unknown_str
;
1731 const char *munged_dial
;
1732 const char *fullname
;
1733 const char *homedir
;
1734 const char *logon_script
;
1735 const char *profile_path
;
1736 const char *acct_desc
;
1737 const char *workstations
;
1738 uint32 username_len
, domain_len
, nt_username_len
,
1739 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1740 fullname_len
, homedir_len
, logon_script_len
,
1741 profile_path_len
, acct_desc_len
, workstations_len
;
1745 const uint8
*nt_pw_hist
;
1746 uint32 lm_pw_len
= 16;
1747 uint32 nt_pw_len
= 16;
1748 uint32 nt_pw_hist_len
;
1749 uint32 pwHistLen
= 0;
1754 logon_time
= convert_time_t_to_uint32(pdb_get_logon_time(sampass
));
1755 logoff_time
= convert_time_t_to_uint32(pdb_get_logoff_time(sampass
));
1756 kickoff_time
= convert_time_t_to_uint32(pdb_get_kickoff_time(sampass
));
1757 bad_password_time
= convert_time_t_to_uint32(pdb_get_bad_password_time(sampass
));
1758 pass_can_change_time
= convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass
));
1759 pass_must_change_time
= convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass
));
1760 pass_last_set_time
= convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass
));
1762 user_rid
= pdb_get_user_rid(sampass
);
1763 group_rid
= pdb_get_group_rid(sampass
);
1765 username
= pdb_get_username(sampass
);
1767 username_len
= strlen(username
) +1;
1772 domain
= pdb_get_domain(sampass
);
1774 domain_len
= strlen(domain
) +1;
1779 nt_username
= pdb_get_nt_username(sampass
);
1781 nt_username_len
= strlen(nt_username
) +1;
1783 nt_username_len
= 0;
1786 fullname
= pdb_get_fullname(sampass
);
1788 fullname_len
= strlen(fullname
) +1;
1794 * Only updates fields which have been set (not defaults from smb.conf)
1797 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1798 dir_drive
= pdb_get_dir_drive(sampass
);
1803 dir_drive_len
= strlen(dir_drive
) +1;
1808 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1809 homedir
= pdb_get_homedir(sampass
);
1814 homedir_len
= strlen(homedir
) +1;
1819 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1820 logon_script
= pdb_get_logon_script(sampass
);
1822 logon_script
= NULL
;
1825 logon_script_len
= strlen(logon_script
) +1;
1827 logon_script_len
= 0;
1830 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1831 profile_path
= pdb_get_profile_path(sampass
);
1833 profile_path
= NULL
;
1836 profile_path_len
= strlen(profile_path
) +1;
1838 profile_path_len
= 0;
1841 lm_pw
= pdb_get_lanman_passwd(sampass
);
1846 nt_pw
= pdb_get_nt_passwd(sampass
);
1851 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1852 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1853 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1854 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1859 acct_desc
= pdb_get_acct_desc(sampass
);
1861 acct_desc_len
= strlen(acct_desc
) +1;
1866 workstations
= pdb_get_workstations(sampass
);
1868 workstations_len
= strlen(workstations
) +1;
1870 workstations_len
= 0;
1874 unknown_str_len
= 0;
1876 munged_dial
= pdb_get_munged_dial(sampass
);
1878 munged_dial_len
= strlen(munged_dial
) +1;
1880 munged_dial_len
= 0;
1883 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1885 /* one time to get the size needed */
1886 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1888 logoff_time
, /* d */
1889 kickoff_time
, /* d */
1890 bad_password_time
, /* d */
1891 pass_last_set_time
, /* d */
1892 pass_can_change_time
, /* d */
1893 pass_must_change_time
, /* d */
1894 username_len
, username
, /* B */
1895 domain_len
, domain
, /* B */
1896 nt_username_len
, nt_username
, /* B */
1897 fullname_len
, fullname
, /* B */
1898 homedir_len
, homedir
, /* B */
1899 dir_drive_len
, dir_drive
, /* B */
1900 logon_script_len
, logon_script
, /* B */
1901 profile_path_len
, profile_path
, /* B */
1902 acct_desc_len
, acct_desc
, /* B */
1903 workstations_len
, workstations
, /* B */
1904 unknown_str_len
, unknown_str
, /* B */
1905 munged_dial_len
, munged_dial
, /* B */
1908 lm_pw_len
, lm_pw
, /* B */
1909 nt_pw_len
, nt_pw
, /* B */
1910 nt_pw_hist_len
, nt_pw_hist
, /* B */
1911 pdb_get_acct_ctrl(sampass
), /* d */
1912 pdb_get_logon_divs(sampass
), /* w */
1913 pdb_get_hours_len(sampass
), /* d */
1914 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1915 pdb_get_bad_password_count(sampass
), /* w */
1916 pdb_get_logon_count(sampass
), /* w */
1917 pdb_get_unknown_6(sampass
)); /* d */
1923 /* malloc the space needed */
1924 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1925 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1929 /* now for the real call to tdb_pack() */
1930 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
1932 logoff_time
, /* d */
1933 kickoff_time
, /* d */
1934 bad_password_time
, /* d */
1935 pass_last_set_time
, /* d */
1936 pass_can_change_time
, /* d */
1937 pass_must_change_time
, /* d */
1938 username_len
, username
, /* B */
1939 domain_len
, domain
, /* B */
1940 nt_username_len
, nt_username
, /* B */
1941 fullname_len
, fullname
, /* B */
1942 homedir_len
, homedir
, /* B */
1943 dir_drive_len
, dir_drive
, /* B */
1944 logon_script_len
, logon_script
, /* B */
1945 profile_path_len
, profile_path
, /* B */
1946 acct_desc_len
, acct_desc
, /* B */
1947 workstations_len
, workstations
, /* B */
1948 unknown_str_len
, unknown_str
, /* B */
1949 munged_dial_len
, munged_dial
, /* B */
1952 lm_pw_len
, lm_pw
, /* B */
1953 nt_pw_len
, nt_pw
, /* B */
1954 nt_pw_hist_len
, nt_pw_hist
, /* B */
1955 pdb_get_acct_ctrl(sampass
), /* d */
1956 pdb_get_logon_divs(sampass
), /* w */
1957 pdb_get_hours_len(sampass
), /* d */
1958 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1959 pdb_get_bad_password_count(sampass
), /* w */
1960 pdb_get_logon_count(sampass
), /* w */
1961 pdb_get_unknown_6(sampass
)); /* d */
1963 /* check to make sure we got it correct */
1964 if (buflen
!= len
) {
1965 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1966 (unsigned long)buflen
, (unsigned long)len
));
1975 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
1977 /* nothing changed between V3 and V4 */
1978 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
1981 static uint32
init_buffer_from_samu_v4(uint8
**buf
, struct samu
*sampass
, bool size_only
)
1983 /* nothing changed between V3 and V4 */
1984 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
1987 /**********************************************************************
1988 Intialize a struct samu struct from a BYTE buffer of size len
1989 *********************************************************************/
1991 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
1992 uint8
*buf
, uint32 buflen
)
1995 case SAMU_BUFFER_V0
:
1996 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
1997 case SAMU_BUFFER_V1
:
1998 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
1999 case SAMU_BUFFER_V2
:
2000 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2001 case SAMU_BUFFER_V3
:
2002 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2003 case SAMU_BUFFER_V4
:
2004 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2010 /**********************************************************************
2011 Intialize a BYTE buffer from a struct samu struct
2012 *********************************************************************/
2014 uint32
init_buffer_from_samu (uint8
**buf
, struct samu
*sampass
, bool size_only
)
2016 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2019 /*********************************************************************
2020 *********************************************************************/
2022 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2027 len
= init_buffer_from_samu(&buf
, src
, False
);
2028 if (len
== -1 || !buf
) {
2033 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2038 dst
->methods
= src
->methods
;
2040 if ( src
->unix_pw
) {
2041 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2042 if (!dst
->unix_pw
) {
2052 /*********************************************************************
2053 Update the bad password count checking the AP_RESET_COUNT_TIME
2054 *********************************************************************/
2056 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2058 time_t LastBadPassword
;
2059 uint16 BadPasswordCount
;
2063 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2064 if (!BadPasswordCount
) {
2065 DEBUG(9, ("No bad password attempts.\n"));
2070 res
= pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
);
2074 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2078 /* First, check if there is a reset time to compare */
2079 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
2080 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2084 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2085 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2086 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
2087 if (time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(resettime
)*60)){
2088 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2089 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2098 /*********************************************************************
2099 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2100 *********************************************************************/
2102 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2105 time_t LastBadPassword
;
2108 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2109 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2110 pdb_get_username(sampass
)));
2115 res
= pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
);
2119 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2123 /* First, check if there is a duration to compare */
2124 if ((duration
== (uint32
) -1) || (duration
== 0)) {
2125 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2129 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2130 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2131 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
2133 if (LastBadPassword
== (time_t)0) {
2134 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2135 "administratively locked out with no bad password "
2136 "time. Leaving locked out.\n",
2137 pdb_get_username(sampass
) ));
2141 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_to_time_t(duration
) * 60))) {
2142 pdb_set_acct_ctrl(sampass
,
2143 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2145 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2146 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2155 /*********************************************************************
2156 Increment the bad_password_count
2157 *********************************************************************/
2159 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2161 uint32 account_policy_lockout
;
2162 bool autolock_updated
= False
, badpw_updated
= False
;
2165 /* Retrieve the account lockout policy */
2167 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2170 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2174 /* If there is no policy, we don't need to continue checking */
2175 if (!account_policy_lockout
) {
2176 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2180 /* Check if the autolock needs to be cleared */
2181 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2184 /* Check if the badpw count needs to be reset */
2185 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2189 Ok, now we can assume that any resetting that needs to be
2190 done has been done, and just get on with incrementing
2191 and autolocking if necessary
2194 pdb_set_bad_password_count(sampass
,
2195 pdb_get_bad_password_count(sampass
)+1,
2197 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2200 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2203 if (!pdb_set_acct_ctrl(sampass
,
2204 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2206 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2213 bool is_dc_trusted_domain_situation(const char *domain_name
)
2215 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2218 /*******************************************************************
2219 Wrapper around retrieving the clear text trust account password.
2220 appropriate account name is stored in account_name.
2221 Caller must free password, but not account_name.
2222 *******************************************************************/
2224 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2225 const char **account_name
, uint32
*channel
)
2228 time_t last_set_time
;
2230 /* if we are a DC and this is not our domain, then lookup an account
2231 * for the domain trust */
2233 if (is_dc_trusted_domain_situation(domain
)) {
2234 if (!lp_allow_trusted_domains()) {
2238 if (!pdb_get_trusteddom_pw(domain
, ret_pwd
, NULL
,
2241 DEBUG(0, ("get_trust_pw: could not fetch trust "
2242 "account password for trusted domain %s\n",
2247 if (channel
!= NULL
) {
2248 *channel
= SEC_CHAN_DOMAIN
;
2251 if (account_name
!= NULL
) {
2252 *account_name
= lp_workgroup();
2259 * Since we can only be member of one single domain, we are now
2260 * in a member situation:
2262 * - Either we are a DC (selfjoined) and the domain is our
2264 * - Or we are on a member and the domain is our own or some
2265 * other (potentially trusted) domain.
2267 * In both cases, we can only get the machine account password
2268 * for our own domain to connect to our own dc. (For a member,
2269 * request to trusted domains are performed through our dc.)
2271 * So we simply use our own domain name to retrieve the
2272 * machine account passowrd and ignore the request domain here.
2275 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2279 if (account_name
!= NULL
) {
2280 *account_name
= global_myname();
2286 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
2287 "account password for domain %s\n", domain
));
2291 /*******************************************************************
2292 Wrapper around retrieving the trust account password.
2293 appropriate account name is stored in account_name.
2294 *******************************************************************/
2296 bool get_trust_pw_hash(const char *domain
, uint8 ret_pwd
[16],
2297 const char **account_name
, uint32
*channel
)
2300 time_t last_set_time
;
2302 if (get_trust_pw_clear(domain
, &pwd
, account_name
, channel
)) {
2303 E_md4hash(pwd
, ret_pwd
);
2306 } else if (is_dc_trusted_domain_situation(domain
)) {
2310 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2312 if (secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
2316 if (account_name
!= NULL
) {
2317 *account_name
= global_myname();
2323 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2324 "password for domain %s\n", domain
));
2328 struct samr_LogonHours
get_logon_hours_from_pdb(TALLOC_CTX
*mem_ctx
,
2331 struct samr_LogonHours hours
;
2332 const int units_per_week
= 168;
2335 hours
.bits
= talloc_array(mem_ctx
, uint8_t, units_per_week
);
2340 hours
.units_per_week
= units_per_week
;
2341 memset(hours
.bits
, 0xFF, units_per_week
);
2343 if (pdb_get_hours(pw
)) {
2344 memcpy(hours
.bits
, pdb_get_hours(pw
),
2345 MIN(pdb_get_hours_len(pw
), units_per_week
));
2351 /****************************************************************
2352 ****************************************************************/
2354 NTSTATUS
smb_create_user(TALLOC_CTX
*mem_ctx
,
2355 uint32_t acct_flags
,
2356 const char *account
,
2357 struct passwd
**passwd_p
)
2359 struct passwd
*passwd
;
2360 char *add_script
= NULL
;
2362 passwd
= Get_Pwnam_alloc(mem_ctx
, account
);
2365 return NT_STATUS_OK
;
2368 /* Create appropriate user */
2369 if (acct_flags
& ACB_NORMAL
) {
2370 add_script
= talloc_strdup(mem_ctx
, lp_adduser_script());
2371 } else if ( (acct_flags
& ACB_WSTRUST
) ||
2372 (acct_flags
& ACB_SVRTRUST
) ||
2373 (acct_flags
& ACB_DOMTRUST
) ) {
2374 add_script
= talloc_strdup(mem_ctx
, lp_addmachine_script());
2376 DEBUG(1, ("Unknown user type: %s\n",
2377 pdb_encode_acct_ctrl(acct_flags
, NEW_PW_FORMAT_SPACE_PADDED_LEN
)));
2378 return NT_STATUS_UNSUCCESSFUL
;
2382 return NT_STATUS_NO_MEMORY
;
2387 add_script
= talloc_all_string_sub(mem_ctx
, add_script
,
2390 return NT_STATUS_NO_MEMORY
;
2392 add_ret
= smbrun(add_script
, NULL
);
2393 DEBUG(add_ret
? 0 : 1,("fetch_account: Running the command `%s' "
2394 "gave %d\n", add_script
, add_ret
));
2396 smb_nscd_flush_user_cache();
2400 /* try and find the possible unix account again */
2401 passwd
= Get_Pwnam_alloc(mem_ctx
, account
);
2403 return NT_STATUS_NO_SUCH_USER
;
2408 return NT_STATUS_OK
;