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/>.
27 #include "system/passwd.h"
28 #include "../libcli/auth/libcli_auth.h"
30 #include "../libcli/security/security.h"
31 #include "../lib/util/util_pw.h"
33 #include "auth/credentials/credentials.h"
34 #include "lib/param/param.h"
37 #define DBGC_CLASS DBGC_PASSDB
39 /**********************************************************************
40 ***********************************************************************/
42 static int samu_destroy(struct samu
*user
)
44 data_blob_clear_free( &user
->lm_pw
);
45 data_blob_clear_free( &user
->nt_pw
);
47 if ( user
->plaintext_pw
)
48 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
53 /**********************************************************************
54 generate a new struct samuser
55 ***********************************************************************/
57 struct samu
*samu_new( TALLOC_CTX
*ctx
)
61 if ( !(user
= talloc_zero( ctx
, struct samu
)) ) {
62 DEBUG(0,("samuser_new: Talloc failed!\n"));
66 talloc_set_destructor( user
, samu_destroy
);
68 /* no initial methods */
72 /* Don't change these timestamp settings without a good reason.
73 They are important for NT member server compatibility. */
75 user
->logon_time
= (time_t)0;
76 user
->pass_last_set_time
= (time_t)0;
77 user
->pass_can_change_time
= (time_t)0;
78 user
->logoff_time
= get_time_t_max();
79 user
->kickoff_time
= get_time_t_max();
80 user
->fields_present
= 0x00ffffff;
81 user
->logon_divs
= 168; /* hours per week */
82 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
83 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
84 user
->bad_password_count
= 0;
85 user
->logon_count
= 0;
86 user
->unknown_6
= 0x000004ec; /* don't know */
88 /* Some parts of samba strlen their pdb_get...() returns,
89 so this keeps the interface unchanged for now. */
93 user
->nt_username
= "";
96 user
->logon_script
= "";
97 user
->profile_path
= "";
99 user
->workstations
= "";
101 user
->munged_dial
= "";
103 user
->plaintext_pw
= NULL
;
105 /* Unless we know otherwise have a Account Control Bit
106 value of 'normal user'. This helps User Manager, which
107 asks for a filtered list of users. */
109 user
->acct_ctrl
= ACB_NORMAL
;
114 static int count_commas(const char *str
)
117 const char *comma
= str
;
119 while ((comma
= strchr(comma
, ',')) != NULL
) {
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 pdb_methods
*methods
,
133 struct samu
*user
, const struct passwd
*pwd
, bool create
)
135 const char *guest_account
= lp_guest_account();
136 const char *domain
= lp_netbios_name();
141 return NT_STATUS_NO_SUCH_USER
;
144 /* Basic properties based upon the Unix account information */
146 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
150 if (count_commas(pwd
->pw_gecos
) == 3) {
152 * Heuristic: This seems to be a gecos field that has been
153 * edited by chfn(1). Only use the part before the first
154 * comma. Fixes bug 5198.
156 fullname
= talloc_strndup(
157 talloc_tos(), pwd
->pw_gecos
,
158 strchr(pwd
->pw_gecos
, ',') - pwd
->pw_gecos
);
161 if (fullname
!= NULL
) {
162 pdb_set_fullname(user
, fullname
, PDB_SET
);
164 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
166 TALLOC_FREE(fullname
);
168 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
170 /* This can lead to a primary group of S-1-22-2-XX which
171 will be rejected by other parts of the Samba code.
172 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
175 gid_to_sid(&group_sid
, pwd
->pw_gid
);
176 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
179 /* save the password structure for later use */
181 user
->unix_pw
= tcopy_passwd( user
, pwd
);
183 /* Special case for the guest account which must have a RID of 501 */
185 if ( strequal( pwd
->pw_name
, guest_account
) ) {
186 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_RID_GUEST
, PDB_DEFAULT
)) {
187 return NT_STATUS_NO_SUCH_USER
;
192 /* Non-guest accounts...Check for a workstation or user account */
194 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
197 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
198 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
200 return NT_STATUS_INVALID_COMPUTER_NAME
;
206 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
207 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
209 return NT_STATUS_INVALID_ACCOUNT_NAME
;
212 /* set some basic attributes */
214 pdb_set_profile_path(user
, talloc_sub_specified(user
,
215 lp_logon_path(), pwd
->pw_name
, NULL
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
217 pdb_set_homedir(user
, talloc_sub_specified(user
,
218 lp_logon_home(), pwd
->pw_name
, NULL
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
220 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
221 lp_logon_drive(), pwd
->pw_name
, NULL
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
223 pdb_set_logon_script(user
, talloc_sub_specified(user
,
224 lp_logon_script(), pwd
->pw_name
, NULL
, domain
, pwd
->pw_uid
, pwd
->pw_gid
),
228 /* Now deal with the user SID. If we have a backend that can generate
229 RIDs, then do so. But sometimes the caller just wanted a structure
230 initialized and will fill in these fields later (such as from a
231 netr_SamInfo3 structure) */
233 if ( create
&& (methods
->capabilities(methods
) & PDB_CAP_STORE_RIDS
)) {
235 struct dom_sid user_sid
;
237 if ( !methods
->new_rid(methods
, &user_rid
) ) {
238 DEBUG(3, ("Could not allocate a new RID\n"));
239 return NT_STATUS_ACCESS_DENIED
;
242 sid_compose(&user_sid
, get_global_sam_sid(), user_rid
);
244 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
245 DEBUG(3, ("pdb_set_user_sid failed\n"));
246 return NT_STATUS_INTERNAL_ERROR
;
252 /* generate a SID for the user with the RID algorithm */
254 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
256 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
257 return NT_STATUS_INTERNAL_ERROR
;
263 /********************************************************************
264 Set the Unix user attributes
265 ********************************************************************/
267 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
269 return samu_set_unix_internal( NULL
, user
, pwd
, False
);
272 NTSTATUS
samu_alloc_rid_unix(struct pdb_methods
*methods
,
273 struct samu
*user
, const struct passwd
*pwd
)
275 return samu_set_unix_internal( methods
, user
, pwd
, True
);
278 /**********************************************************
279 Encode the account control bits into a string.
280 length = length of string to encode into (including terminating
281 null). length *MUST BE MORE THAN 2* !
282 **********************************************************/
284 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl
, size_t length
)
291 SMB_ASSERT(length
<= sizeof(acct_str
));
295 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
296 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
297 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
298 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
299 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
300 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
301 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
302 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
303 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
304 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
305 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
307 for ( ; i
< length
- 2 ; i
++ )
312 acct_str
[i
++] = '\0';
314 result
= talloc_strdup(talloc_tos(), acct_str
);
315 SMB_ASSERT(result
!= NULL
);
319 /**********************************************************
320 Decode the account control bits from a string.
321 **********************************************************/
323 uint32_t pdb_decode_acct_ctrl(const char *p
)
325 uint32_t acct_ctrl
= 0;
326 bool finished
= false;
329 * Check if the account type bits have been encoded after the
330 * NT password (in the form [NDHTUWSLXI]).
336 for (p
++; *p
&& !finished
; p
++) {
338 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
339 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
340 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
341 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
342 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
343 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
344 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
345 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
346 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
347 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
348 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
354 default: { finished
= true; }
361 /*************************************************************
362 Routine to set 32 hex password characters from a 16 byte array.
363 **************************************************************/
365 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32_t acct_ctrl
)
368 hex_encode_buf(p
, pwd
, 16);
370 if (acct_ctrl
& ACB_PWNOTREQ
)
371 strlcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
373 strlcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
377 /*************************************************************
378 Routine to get the 32 hex characters and turn them
379 into a 16 byte array.
380 **************************************************************/
382 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
385 unsigned char lonybble
, hinybble
;
386 const char *hexchars
= "0123456789ABCDEF";
392 for (i
= 0; i
< 32; i
+= 2) {
393 hinybble
= toupper_m(p
[i
]);
394 lonybble
= toupper_m(p
[i
+ 1]);
396 p1
= strchr(hexchars
, hinybble
);
397 p2
= strchr(hexchars
, lonybble
);
402 hinybble
= PTR_DIFF(p1
, hexchars
);
403 lonybble
= PTR_DIFF(p2
, hexchars
);
405 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
410 /*************************************************************
411 Routine to set 42 hex hours characters from a 21 byte array.
412 **************************************************************/
414 void pdb_sethexhours(char *p
, const unsigned char *hours
)
417 hex_encode_buf(p
, hours
, 21);
419 strlcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
423 /*************************************************************
424 Routine to get the 42 hex characters and turn them
425 into a 21 byte array.
426 **************************************************************/
428 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
431 unsigned char lonybble
, hinybble
;
432 const char *hexchars
= "0123456789ABCDEF";
439 for (i
= 0; i
< 42; i
+= 2) {
440 hinybble
= toupper_m(p
[i
]);
441 lonybble
= toupper_m(p
[i
+ 1]);
443 p1
= strchr(hexchars
, hinybble
);
444 p2
= strchr(hexchars
, lonybble
);
450 hinybble
= PTR_DIFF(p1
, hexchars
);
451 lonybble
= PTR_DIFF(p2
, hexchars
);
453 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
458 /********************************************************************
459 ********************************************************************/
461 int algorithmic_rid_base(void)
465 rid_offset
= lp_algorithmic_rid_base();
467 if (rid_offset
< BASE_RID
) {
468 /* Try to prevent admin foot-shooting, we can't put algorithmic
469 rids below 1000, that's the 'well known RIDs' on NT */
470 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
471 rid_offset
= BASE_RID
;
473 if (rid_offset
& 1) {
474 DEBUG(0, ("algorithmic rid base must be even\n"));
480 /*******************************************************************
481 Converts NT user RID to a UNIX uid.
482 ********************************************************************/
484 uid_t
algorithmic_pdb_user_rid_to_uid(uint32_t user_rid
)
486 int rid_offset
= algorithmic_rid_base();
487 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
490 uid_t
max_algorithmic_uid(void)
492 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
495 /*******************************************************************
496 converts UNIX uid to an NT User RID.
497 ********************************************************************/
499 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid
)
501 int rid_offset
= algorithmic_rid_base();
502 return (((((uint32_t)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
505 /*******************************************************************
506 Converts NT group RID to a UNIX gid.
507 ********************************************************************/
509 gid_t
pdb_group_rid_to_gid(uint32_t group_rid
)
511 int rid_offset
= algorithmic_rid_base();
512 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
515 gid_t
max_algorithmic_gid(void)
517 return pdb_group_rid_to_gid(0xffffffff);
520 /*******************************************************************
521 converts NT Group RID to a UNIX uid.
523 warning: you must not call that function only
524 you must do a call to the group mapping first.
525 there is not anymore a direct link between the gid and the rid.
526 ********************************************************************/
528 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid
)
530 int rid_offset
= algorithmic_rid_base();
531 return (((((uint32_t)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
534 /*******************************************************************
535 Decides if a RID is a well known RID.
536 ********************************************************************/
538 static bool rid_is_well_known(uint32_t rid
)
540 /* Not using rid_offset here, because this is the actual
541 NT fixed value (1000) */
543 return (rid
< BASE_RID
);
546 /*******************************************************************
547 Decides if a RID is a user or group RID.
548 ********************************************************************/
550 bool algorithmic_pdb_rid_is_user(uint32_t rid
)
552 if ( rid_is_well_known(rid
) ) {
554 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
555 * and DOMAIN_RID_GUEST.
557 if(rid
== DOMAIN_RID_ADMINISTRATOR
|| rid
== DOMAIN_RID_GUEST
)
559 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
565 /*******************************************************************
566 Convert a name into a SID. Used in the lookup name rpc.
567 ********************************************************************/
569 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
570 enum lsa_SidType
*type
)
575 /* Windows treats "MACHINE\None" as a special name for
576 rid 513 on non-DCs. You cannot create a user or group
577 name "None" on Windows. You will get an error that
578 the group already exists. */
580 if ( strequal( name
, "None" ) ) {
581 *rid
= DOMAIN_RID_USERS
;
582 *type
= SID_NAME_DOM_GRP
;
587 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
588 * correctly in the case where foo also exists as a user. If the flag
589 * is set, don't look for users at all. */
591 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
592 struct samu
*sam_account
= NULL
;
593 struct dom_sid user_sid
;
595 if ( !(sam_account
= samu_new( NULL
)) ) {
600 ret
= pdb_getsampwnam(sam_account
, name
);
604 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
607 TALLOC_FREE(sam_account
);
610 if (!sid_check_is_in_our_sam(&user_sid
)) {
611 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
612 name
, sid_string_dbg(&user_sid
)));
616 sid_peek_rid(&user_sid
, rid
);
617 *type
= SID_NAME_USER
;
623 * Maybe it is a group ?
626 map
= talloc_zero(NULL
, GROUP_MAP
);
632 ret
= pdb_getgrnam(map
, name
);
640 /* BUILTIN groups are looked up elsewhere */
641 if (!sid_check_is_in_our_sam(&map
->sid
)) {
642 DEBUG(10, ("Found group %s (%s) not in our domain -- "
644 name
, sid_string_dbg(&map
->sid
)));
649 /* yes it's a mapped group */
650 sid_peek_rid(&map
->sid
, rid
);
651 *type
= map
->sid_name_use
;
656 /*************************************************************
657 Change a password entry in the local passdb backend.
660 - always called as root
661 - ignores the account type except when adding a new account
662 - will create/delete the unix account if the relative
663 add/delete user script is configured
665 *************************************************************/
667 NTSTATUS
local_password_change(const char *user_name
,
669 const char *new_passwd
,
674 struct samu
*sam_pass
;
684 tosctx
= talloc_tos();
686 sam_pass
= samu_new(tosctx
);
688 result
= NT_STATUS_NO_MEMORY
;
692 /* Get the smb passwd entry for this user */
693 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
695 /* Check delete first, we don't need to do anything else if we
696 * are going to delete the acocunt */
697 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
699 result
= pdb_delete_user(tosctx
, sam_pass
);
700 if (!NT_STATUS_IS_OK(result
)) {
701 ret
= asprintf(pp_err_str
,
702 "Failed to delete entry for user %s.\n",
707 result
= NT_STATUS_UNSUCCESSFUL
;
709 ret
= asprintf(pp_msg_str
,
710 "Deleted user %s.\n",
719 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
720 /* the entry already existed */
721 local_flags
&= ~LOCAL_ADD_USER
;
724 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
725 ret
= asprintf(pp_err_str
,
726 "Failed to find entry for user %s.\n",
731 result
= NT_STATUS_NO_SUCH_USER
;
735 /* First thing add the new user if we are required to do so */
736 if (local_flags
& LOCAL_ADD_USER
) {
738 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
740 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
746 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
747 if (!NT_STATUS_IS_OK(result
)) {
748 ret
= asprintf(pp_err_str
,
749 "Failed to add entry for user %s.\n",
754 result
= NT_STATUS_UNSUCCESSFUL
;
758 sam_pass
= samu_new(tosctx
);
760 result
= NT_STATUS_NO_MEMORY
;
764 /* Now get back the smb passwd entry for this new user */
765 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
767 ret
= asprintf(pp_err_str
,
768 "Failed to add entry for user %s.\n",
773 result
= NT_STATUS_UNSUCCESSFUL
;
778 acb
= pdb_get_acct_ctrl(sam_pass
);
781 * We are root - just write the new password
782 * and the valid last change time.
784 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
786 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
787 ret
= asprintf(pp_err_str
,
788 "Failed to set 'no password required' "
789 "flag for user %s.\n", user_name
);
793 result
= NT_STATUS_UNSUCCESSFUL
;
798 if (local_flags
& LOCAL_SET_PASSWORD
) {
800 * If we're dealing with setting a completely empty user account
801 * ie. One with a password of 'XXXX', but not set disabled (like
802 * an account created from scratch) then if the old password was
803 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
804 * We remove that as we're giving this user their first password
805 * and the decision hasn't really been made to disable them (ie.
806 * don't create them disabled). JRA.
808 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
809 (acb
& ACB_DISABLED
)) {
810 acb
&= (~ACB_DISABLED
);
811 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
812 ret
= asprintf(pp_err_str
,
813 "Failed to unset 'disabled' "
814 "flag for user %s.\n",
819 result
= NT_STATUS_UNSUCCESSFUL
;
824 acb
&= (~ACB_PWNOTREQ
);
825 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
826 ret
= asprintf(pp_err_str
,
827 "Failed to unset 'no password required'"
828 " flag for user %s.\n", user_name
);
832 result
= NT_STATUS_UNSUCCESSFUL
;
836 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
837 ret
= asprintf(pp_err_str
,
838 "Failed to set password for "
839 "user %s.\n", user_name
);
843 result
= NT_STATUS_UNSUCCESSFUL
;
848 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
850 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
851 ret
= asprintf(pp_err_str
,
852 "Failed to set 'disabled' flag for "
853 "user %s.\n", user_name
);
857 result
= NT_STATUS_UNSUCCESSFUL
;
862 if ((local_flags
& LOCAL_ENABLE_USER
) && (acb
& ACB_DISABLED
)) {
863 acb
&= (~ACB_DISABLED
);
864 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
865 ret
= asprintf(pp_err_str
,
866 "Failed to unset 'disabled' flag for "
867 "user %s.\n", user_name
);
871 result
= NT_STATUS_UNSUCCESSFUL
;
876 /* now commit changes if any */
877 result
= pdb_update_sam_account(sam_pass
);
878 if (!NT_STATUS_IS_OK(result
)) {
879 ret
= asprintf(pp_err_str
,
880 "Failed to modify entry for user %s.\n",
888 if (local_flags
& LOCAL_ADD_USER
) {
889 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
890 } else if (local_flags
& LOCAL_DISABLE_USER
) {
891 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
892 } else if (local_flags
& LOCAL_ENABLE_USER
) {
893 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
894 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
895 ret
= asprintf(pp_msg_str
,
896 "User %s password set to none.\n", user_name
);
903 result
= NT_STATUS_OK
;
906 TALLOC_FREE(sam_pass
);
910 /**********************************************************************
911 Marshall/unmarshall struct samu structs.
912 *********************************************************************/
914 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
915 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
916 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
917 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
918 /* nothing changed between V3 and V4 */
920 /*********************************************************************
921 *********************************************************************/
923 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
926 /* times are stored as 32bit integer
927 take care on system with 64bit wide time_t
933 pass_can_change_time
,
934 pass_must_change_time
;
935 char *username
= NULL
;
937 char *nt_username
= NULL
;
938 char *dir_drive
= NULL
;
939 char *unknown_str
= NULL
;
940 char *munged_dial
= NULL
;
941 char *fullname
= NULL
;
942 char *homedir
= NULL
;
943 char *logon_script
= NULL
;
944 char *profile_path
= NULL
;
945 char *acct_desc
= NULL
;
946 char *workstations
= NULL
;
947 uint32_t username_len
, domain_len
, nt_username_len
,
948 dir_drive_len
, unknown_str_len
, munged_dial_len
,
949 fullname_len
, homedir_len
, logon_script_len
,
950 profile_path_len
, acct_desc_len
, workstations_len
;
952 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
953 uint16_t acct_ctrl
, logon_divs
;
954 uint16_t bad_password_count
, logon_count
;
955 uint8_t *hours
= NULL
;
956 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
958 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
961 if(sampass
== NULL
|| buf
== NULL
) {
962 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
966 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
968 /* unpack the buffer into variables */
969 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
971 &logoff_time
, /* d */
972 &kickoff_time
, /* d */
973 &pass_last_set_time
, /* d */
974 &pass_can_change_time
, /* d */
975 &pass_must_change_time
, /* d */
976 &username_len
, &username
, /* B */
977 &domain_len
, &domain
, /* B */
978 &nt_username_len
, &nt_username
, /* B */
979 &fullname_len
, &fullname
, /* B */
980 &homedir_len
, &homedir
, /* B */
981 &dir_drive_len
, &dir_drive
, /* B */
982 &logon_script_len
, &logon_script
, /* B */
983 &profile_path_len
, &profile_path
, /* B */
984 &acct_desc_len
, &acct_desc
, /* B */
985 &workstations_len
, &workstations
, /* B */
986 &unknown_str_len
, &unknown_str
, /* B */
987 &munged_dial_len
, &munged_dial
, /* B */
990 &lm_pw_len
, &lm_pw_ptr
, /* B */
991 &nt_pw_len
, &nt_pw_ptr
, /* B */
993 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
996 &hourslen
, &hours
, /* B */
997 &bad_password_count
, /* w */
998 &logon_count
, /* w */
1001 if (len
== (uint32_t) -1) {
1006 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1007 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1008 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1009 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1010 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1012 pdb_set_username(sampass
, username
, PDB_SET
);
1013 pdb_set_domain(sampass
, domain
, PDB_SET
);
1014 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1015 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1018 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1021 pdb_set_homedir(sampass
,
1022 talloc_sub_basic(sampass
, username
, domain
,
1028 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1030 pdb_set_dir_drive(sampass
,
1031 talloc_sub_basic(sampass
, username
, domain
,
1037 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1039 pdb_set_logon_script(sampass
,
1040 talloc_sub_basic(sampass
, username
, domain
,
1046 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1048 pdb_set_profile_path(sampass
,
1049 talloc_sub_basic(sampass
, username
, domain
,
1054 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1055 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1056 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1058 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1059 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1065 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1066 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1072 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1073 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1074 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1075 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1076 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1077 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1078 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1079 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1080 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1081 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1085 SAFE_FREE(username
);
1087 SAFE_FREE(nt_username
);
1088 SAFE_FREE(fullname
);
1090 SAFE_FREE(dir_drive
);
1091 SAFE_FREE(logon_script
);
1092 SAFE_FREE(profile_path
);
1093 SAFE_FREE(acct_desc
);
1094 SAFE_FREE(workstations
);
1095 SAFE_FREE(munged_dial
);
1096 SAFE_FREE(unknown_str
);
1097 SAFE_FREE(lm_pw_ptr
);
1098 SAFE_FREE(nt_pw_ptr
);
1104 /*********************************************************************
1105 *********************************************************************/
1107 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1110 /* times are stored as 32bit integer
1111 take care on system with 64bit wide time_t
1113 uint32_t logon_time
,
1118 pass_can_change_time
,
1119 pass_must_change_time
;
1120 char *username
= NULL
;
1121 char *domain
= NULL
;
1122 char *nt_username
= NULL
;
1123 char *dir_drive
= NULL
;
1124 char *unknown_str
= NULL
;
1125 char *munged_dial
= NULL
;
1126 char *fullname
= NULL
;
1127 char *homedir
= NULL
;
1128 char *logon_script
= NULL
;
1129 char *profile_path
= NULL
;
1130 char *acct_desc
= NULL
;
1131 char *workstations
= NULL
;
1132 uint32_t username_len
, domain_len
, nt_username_len
,
1133 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1134 fullname_len
, homedir_len
, logon_script_len
,
1135 profile_path_len
, acct_desc_len
, workstations_len
;
1137 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1138 uint16_t acct_ctrl
, logon_divs
;
1139 uint16_t bad_password_count
, logon_count
;
1140 uint8_t *hours
= NULL
;
1141 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1143 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1146 if(sampass
== NULL
|| buf
== NULL
) {
1147 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1151 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1153 /* unpack the buffer into variables */
1154 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1155 &logon_time
, /* d */
1156 &logoff_time
, /* d */
1157 &kickoff_time
, /* d */
1158 /* Change from V0 is addition of bad_password_time field. */
1159 &bad_password_time
, /* d */
1160 &pass_last_set_time
, /* d */
1161 &pass_can_change_time
, /* d */
1162 &pass_must_change_time
, /* d */
1163 &username_len
, &username
, /* B */
1164 &domain_len
, &domain
, /* B */
1165 &nt_username_len
, &nt_username
, /* B */
1166 &fullname_len
, &fullname
, /* B */
1167 &homedir_len
, &homedir
, /* B */
1168 &dir_drive_len
, &dir_drive
, /* B */
1169 &logon_script_len
, &logon_script
, /* B */
1170 &profile_path_len
, &profile_path
, /* B */
1171 &acct_desc_len
, &acct_desc
, /* B */
1172 &workstations_len
, &workstations
, /* B */
1173 &unknown_str_len
, &unknown_str
, /* B */
1174 &munged_dial_len
, &munged_dial
, /* B */
1177 &lm_pw_len
, &lm_pw_ptr
, /* B */
1178 &nt_pw_len
, &nt_pw_ptr
, /* B */
1181 &logon_divs
, /* w */
1183 &hourslen
, &hours
, /* B */
1184 &bad_password_count
, /* w */
1185 &logon_count
, /* w */
1186 &unknown_6
); /* d */
1188 if (len
== (uint32_t) -1) {
1193 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1194 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1195 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1197 /* Change from V0 is addition of bad_password_time field. */
1198 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1199 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1200 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1202 pdb_set_username(sampass
, username
, PDB_SET
);
1203 pdb_set_domain(sampass
, domain
, PDB_SET
);
1204 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1205 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1208 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1211 pdb_set_homedir(sampass
,
1212 talloc_sub_basic(sampass
, username
, domain
,
1218 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1220 pdb_set_dir_drive(sampass
,
1221 talloc_sub_basic(sampass
, username
, domain
,
1227 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1229 pdb_set_logon_script(sampass
,
1230 talloc_sub_basic(sampass
, username
, domain
,
1236 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1238 pdb_set_profile_path(sampass
,
1239 talloc_sub_basic(sampass
, username
, domain
,
1244 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1245 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1246 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1248 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1249 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1255 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1256 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1262 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1264 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1265 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1266 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1267 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1268 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1269 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1270 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1271 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1272 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1276 SAFE_FREE(username
);
1278 SAFE_FREE(nt_username
);
1279 SAFE_FREE(fullname
);
1281 SAFE_FREE(dir_drive
);
1282 SAFE_FREE(logon_script
);
1283 SAFE_FREE(profile_path
);
1284 SAFE_FREE(acct_desc
);
1285 SAFE_FREE(workstations
);
1286 SAFE_FREE(munged_dial
);
1287 SAFE_FREE(unknown_str
);
1288 SAFE_FREE(lm_pw_ptr
);
1289 SAFE_FREE(nt_pw_ptr
);
1295 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1298 /* times are stored as 32bit integer
1299 take care on system with 64bit wide time_t
1301 uint32_t logon_time
,
1306 pass_can_change_time
,
1307 pass_must_change_time
;
1308 char *username
= NULL
;
1309 char *domain
= NULL
;
1310 char *nt_username
= NULL
;
1311 char *dir_drive
= NULL
;
1312 char *unknown_str
= NULL
;
1313 char *munged_dial
= NULL
;
1314 char *fullname
= NULL
;
1315 char *homedir
= NULL
;
1316 char *logon_script
= NULL
;
1317 char *profile_path
= NULL
;
1318 char *acct_desc
= NULL
;
1319 char *workstations
= NULL
;
1320 uint32_t username_len
, domain_len
, nt_username_len
,
1321 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1322 fullname_len
, homedir_len
, logon_script_len
,
1323 profile_path_len
, acct_desc_len
, workstations_len
;
1325 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
;
1326 uint16_t acct_ctrl
, logon_divs
;
1327 uint16_t bad_password_count
, logon_count
;
1328 uint8_t *hours
= NULL
;
1329 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1331 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1332 uint32_t pwHistLen
= 0;
1335 bool expand_explicit
= lp_passdb_expand_explicit();
1337 if(sampass
== NULL
|| buf
== NULL
) {
1338 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1342 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1344 /* unpack the buffer into variables */
1345 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1346 &logon_time
, /* d */
1347 &logoff_time
, /* d */
1348 &kickoff_time
, /* d */
1349 &bad_password_time
, /* d */
1350 &pass_last_set_time
, /* d */
1351 &pass_can_change_time
, /* d */
1352 &pass_must_change_time
, /* d */
1353 &username_len
, &username
, /* B */
1354 &domain_len
, &domain
, /* B */
1355 &nt_username_len
, &nt_username
, /* B */
1356 &fullname_len
, &fullname
, /* B */
1357 &homedir_len
, &homedir
, /* B */
1358 &dir_drive_len
, &dir_drive
, /* B */
1359 &logon_script_len
, &logon_script
, /* B */
1360 &profile_path_len
, &profile_path
, /* B */
1361 &acct_desc_len
, &acct_desc
, /* B */
1362 &workstations_len
, &workstations
, /* B */
1363 &unknown_str_len
, &unknown_str
, /* B */
1364 &munged_dial_len
, &munged_dial
, /* B */
1367 &lm_pw_len
, &lm_pw_ptr
, /* B */
1368 &nt_pw_len
, &nt_pw_ptr
, /* B */
1369 /* Change from V1 is addition of password history field. */
1370 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1372 /* Also "remove_me" field was removed. */
1373 &logon_divs
, /* w */
1375 &hourslen
, &hours
, /* B */
1376 &bad_password_count
, /* w */
1377 &logon_count
, /* w */
1378 &unknown_6
); /* d */
1380 if (len
== (uint32_t) -1) {
1385 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1386 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1387 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1388 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1389 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1390 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1392 pdb_set_username(sampass
, username
, PDB_SET
);
1393 pdb_set_domain(sampass
, domain
, PDB_SET
);
1394 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1395 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1398 fstrcpy( tmp_string
, homedir
);
1399 if (expand_explicit
) {
1400 standard_sub_basic( username
, domain
, tmp_string
,
1401 sizeof(tmp_string
) );
1403 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1406 pdb_set_homedir(sampass
,
1407 talloc_sub_basic(sampass
, username
, domain
,
1413 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1415 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1418 fstrcpy( tmp_string
, logon_script
);
1419 if (expand_explicit
) {
1420 standard_sub_basic( username
, domain
, tmp_string
,
1421 sizeof(tmp_string
) );
1423 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1426 pdb_set_logon_script(sampass
,
1427 talloc_sub_basic(sampass
, username
, domain
,
1433 fstrcpy( tmp_string
, profile_path
);
1434 if (expand_explicit
) {
1435 standard_sub_basic( username
, domain
, tmp_string
,
1436 sizeof(tmp_string
) );
1438 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1441 pdb_set_profile_path(sampass
,
1442 talloc_sub_basic(sampass
, username
, domain
,
1447 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1448 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1449 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1451 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1452 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1458 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1459 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1465 /* Change from V1 is addition of password history field. */
1466 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1468 uint8_t *pw_hist
= SMB_MALLOC_ARRAY(uint8_t, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1473 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1474 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1476 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1477 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1478 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1479 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1480 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1481 PW_HISTORY_ENTRY_LEN
);
1484 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1491 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1494 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1495 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1496 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1497 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1498 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1499 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1500 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1501 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1502 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1506 SAFE_FREE(username
);
1508 SAFE_FREE(nt_username
);
1509 SAFE_FREE(fullname
);
1511 SAFE_FREE(dir_drive
);
1512 SAFE_FREE(logon_script
);
1513 SAFE_FREE(profile_path
);
1514 SAFE_FREE(acct_desc
);
1515 SAFE_FREE(workstations
);
1516 SAFE_FREE(munged_dial
);
1517 SAFE_FREE(unknown_str
);
1518 SAFE_FREE(lm_pw_ptr
);
1519 SAFE_FREE(nt_pw_ptr
);
1520 SAFE_FREE(nt_pw_hist_ptr
);
1526 /*********************************************************************
1527 *********************************************************************/
1529 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1532 /* times are stored as 32bit integer
1533 take care on system with 64bit wide time_t
1535 uint32_t logon_time
,
1540 pass_can_change_time
,
1541 pass_must_change_time
;
1542 char *username
= NULL
;
1543 char *domain
= NULL
;
1544 char *nt_username
= NULL
;
1545 char *dir_drive
= NULL
;
1546 char *comment
= NULL
;
1547 char *munged_dial
= NULL
;
1548 char *fullname
= NULL
;
1549 char *homedir
= NULL
;
1550 char *logon_script
= NULL
;
1551 char *profile_path
= NULL
;
1552 char *acct_desc
= NULL
;
1553 char *workstations
= NULL
;
1554 uint32_t username_len
, domain_len
, nt_username_len
,
1555 dir_drive_len
, comment_len
, munged_dial_len
,
1556 fullname_len
, homedir_len
, logon_script_len
,
1557 profile_path_len
, acct_desc_len
, workstations_len
;
1559 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1560 uint16_t logon_divs
;
1561 uint16_t bad_password_count
, logon_count
;
1562 uint8_t *hours
= NULL
;
1563 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1565 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1566 uint32_t pwHistLen
= 0;
1569 bool expand_explicit
= lp_passdb_expand_explicit();
1571 if(sampass
== NULL
|| buf
== NULL
) {
1572 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1576 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1578 /* unpack the buffer into variables */
1579 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1580 &logon_time
, /* d */
1581 &logoff_time
, /* d */
1582 &kickoff_time
, /* d */
1583 &bad_password_time
, /* d */
1584 &pass_last_set_time
, /* d */
1585 &pass_can_change_time
, /* d */
1586 &pass_must_change_time
, /* d */
1587 &username_len
, &username
, /* B */
1588 &domain_len
, &domain
, /* B */
1589 &nt_username_len
, &nt_username
, /* B */
1590 &fullname_len
, &fullname
, /* B */
1591 &homedir_len
, &homedir
, /* B */
1592 &dir_drive_len
, &dir_drive
, /* B */
1593 &logon_script_len
, &logon_script
, /* B */
1594 &profile_path_len
, &profile_path
, /* B */
1595 &acct_desc_len
, &acct_desc
, /* B */
1596 &workstations_len
, &workstations
, /* B */
1597 &comment_len
, &comment
, /* B */
1598 &munged_dial_len
, &munged_dial
, /* B */
1601 &lm_pw_len
, &lm_pw_ptr
, /* B */
1602 &nt_pw_len
, &nt_pw_ptr
, /* B */
1603 /* Change from V1 is addition of password history field. */
1604 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1605 /* Change from V2 is the uint32_t acb_mask */
1607 /* Also "remove_me" field was removed. */
1608 &logon_divs
, /* w */
1610 &hourslen
, &hours
, /* B */
1611 &bad_password_count
, /* w */
1612 &logon_count
, /* w */
1613 &unknown_6
); /* d */
1615 if (len
== (uint32_t) -1) {
1620 pdb_set_logon_time(sampass
, convert_uint32_t_to_time_t(logon_time
), PDB_SET
);
1621 pdb_set_logoff_time(sampass
, convert_uint32_t_to_time_t(logoff_time
), PDB_SET
);
1622 pdb_set_kickoff_time(sampass
, convert_uint32_t_to_time_t(kickoff_time
), PDB_SET
);
1623 pdb_set_bad_password_time(sampass
, convert_uint32_t_to_time_t(bad_password_time
), PDB_SET
);
1624 pdb_set_pass_can_change_time(sampass
, convert_uint32_t_to_time_t(pass_can_change_time
), PDB_SET
);
1625 pdb_set_pass_last_set_time(sampass
, convert_uint32_t_to_time_t(pass_last_set_time
), PDB_SET
);
1627 pdb_set_username(sampass
, username
, PDB_SET
);
1628 pdb_set_domain(sampass
, domain
, PDB_SET
);
1629 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1630 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1633 fstrcpy( tmp_string
, homedir
);
1634 if (expand_explicit
) {
1635 standard_sub_basic( username
, domain
, tmp_string
,
1636 sizeof(tmp_string
) );
1638 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1641 pdb_set_homedir(sampass
,
1642 talloc_sub_basic(sampass
, username
, domain
,
1648 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1650 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1653 fstrcpy( tmp_string
, logon_script
);
1654 if (expand_explicit
) {
1655 standard_sub_basic( username
, domain
, tmp_string
,
1656 sizeof(tmp_string
) );
1658 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1661 pdb_set_logon_script(sampass
,
1662 talloc_sub_basic(sampass
, username
, domain
,
1668 fstrcpy( tmp_string
, profile_path
);
1669 if (expand_explicit
) {
1670 standard_sub_basic( username
, domain
, tmp_string
,
1671 sizeof(tmp_string
) );
1673 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1676 pdb_set_profile_path(sampass
,
1677 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1681 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1682 pdb_set_comment(sampass
, comment
, PDB_SET
);
1683 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1684 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1686 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1687 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1693 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1694 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1700 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1702 uint8_t *pw_hist
= (uint8_t *)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1707 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1708 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1710 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1711 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1712 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1713 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1714 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1715 PW_HISTORY_ENTRY_LEN
);
1718 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1725 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1728 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1729 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1730 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1731 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1732 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1733 /* Change from V2 is the uint32_t acct_ctrl */
1734 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1735 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1736 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1740 SAFE_FREE(username
);
1742 SAFE_FREE(nt_username
);
1743 SAFE_FREE(fullname
);
1745 SAFE_FREE(dir_drive
);
1746 SAFE_FREE(logon_script
);
1747 SAFE_FREE(profile_path
);
1748 SAFE_FREE(acct_desc
);
1749 SAFE_FREE(workstations
);
1750 SAFE_FREE(munged_dial
);
1752 SAFE_FREE(lm_pw_ptr
);
1753 SAFE_FREE(nt_pw_ptr
);
1754 SAFE_FREE(nt_pw_hist_ptr
);
1760 /*********************************************************************
1761 *********************************************************************/
1763 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
1767 /* times are stored as 32bit integer
1768 take care on system with 64bit wide time_t
1770 uint32_t logon_time
,
1775 pass_can_change_time
,
1776 pass_must_change_time
;
1778 uint32_t user_rid
, group_rid
;
1780 const char *username
;
1782 const char *nt_username
;
1783 const char *dir_drive
;
1784 const char *comment
;
1785 const char *munged_dial
;
1786 const char *fullname
;
1787 const char *homedir
;
1788 const char *logon_script
;
1789 const char *profile_path
;
1790 const char *acct_desc
;
1791 const char *workstations
;
1792 uint32_t username_len
, domain_len
, nt_username_len
,
1793 dir_drive_len
, comment_len
, munged_dial_len
,
1794 fullname_len
, homedir_len
, logon_script_len
,
1795 profile_path_len
, acct_desc_len
, workstations_len
;
1797 const uint8_t *lm_pw
;
1798 const uint8_t *nt_pw
;
1799 const uint8_t *nt_pw_hist
;
1800 uint32_t lm_pw_len
= 16;
1801 uint32_t nt_pw_len
= 16;
1802 uint32_t nt_pw_hist_len
;
1803 uint32_t pwHistLen
= 0;
1808 logon_time
= convert_time_t_to_uint32_t(pdb_get_logon_time(sampass
));
1809 logoff_time
= convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass
));
1810 kickoff_time
= convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass
));
1811 bad_password_time
= convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass
));
1812 pass_can_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass
));
1813 pass_must_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass
));
1814 pass_last_set_time
= convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass
));
1816 user_rid
= pdb_get_user_rid(sampass
);
1817 group_rid
= pdb_get_group_rid(sampass
);
1819 username
= pdb_get_username(sampass
);
1821 username_len
= strlen(username
) +1;
1826 domain
= pdb_get_domain(sampass
);
1828 domain_len
= strlen(domain
) +1;
1833 nt_username
= pdb_get_nt_username(sampass
);
1835 nt_username_len
= strlen(nt_username
) +1;
1837 nt_username_len
= 0;
1840 fullname
= pdb_get_fullname(sampass
);
1842 fullname_len
= strlen(fullname
) +1;
1848 * Only updates fields which have been set (not defaults from smb.conf)
1851 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1852 dir_drive
= pdb_get_dir_drive(sampass
);
1857 dir_drive_len
= strlen(dir_drive
) +1;
1862 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1863 homedir
= pdb_get_homedir(sampass
);
1868 homedir_len
= strlen(homedir
) +1;
1873 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1874 logon_script
= pdb_get_logon_script(sampass
);
1876 logon_script
= NULL
;
1879 logon_script_len
= strlen(logon_script
) +1;
1881 logon_script_len
= 0;
1884 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1885 profile_path
= pdb_get_profile_path(sampass
);
1887 profile_path
= NULL
;
1890 profile_path_len
= strlen(profile_path
) +1;
1892 profile_path_len
= 0;
1895 lm_pw
= pdb_get_lanman_passwd(sampass
);
1900 nt_pw
= pdb_get_nt_passwd(sampass
);
1905 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1906 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1907 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1908 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1913 acct_desc
= pdb_get_acct_desc(sampass
);
1915 acct_desc_len
= strlen(acct_desc
) +1;
1920 workstations
= pdb_get_workstations(sampass
);
1922 workstations_len
= strlen(workstations
) +1;
1924 workstations_len
= 0;
1927 comment
= pdb_get_comment(sampass
);
1929 comment_len
= strlen(comment
) +1;
1934 munged_dial
= pdb_get_munged_dial(sampass
);
1936 munged_dial_len
= strlen(munged_dial
) +1;
1938 munged_dial_len
= 0;
1941 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1943 /* one time to get the size needed */
1944 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1946 logoff_time
, /* d */
1947 kickoff_time
, /* d */
1948 bad_password_time
, /* d */
1949 pass_last_set_time
, /* d */
1950 pass_can_change_time
, /* d */
1951 pass_must_change_time
, /* d */
1952 username_len
, username
, /* B */
1953 domain_len
, domain
, /* B */
1954 nt_username_len
, nt_username
, /* B */
1955 fullname_len
, fullname
, /* B */
1956 homedir_len
, homedir
, /* B */
1957 dir_drive_len
, dir_drive
, /* B */
1958 logon_script_len
, logon_script
, /* B */
1959 profile_path_len
, profile_path
, /* B */
1960 acct_desc_len
, acct_desc
, /* B */
1961 workstations_len
, workstations
, /* B */
1962 comment_len
, comment
, /* B */
1963 munged_dial_len
, munged_dial
, /* B */
1966 lm_pw_len
, lm_pw
, /* B */
1967 nt_pw_len
, nt_pw
, /* B */
1968 nt_pw_hist_len
, nt_pw_hist
, /* B */
1969 pdb_get_acct_ctrl(sampass
), /* d */
1970 pdb_get_logon_divs(sampass
), /* w */
1971 pdb_get_hours_len(sampass
), /* d */
1972 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1973 pdb_get_bad_password_count(sampass
), /* w */
1974 pdb_get_logon_count(sampass
), /* w */
1975 pdb_get_unknown_6(sampass
)); /* d */
1981 /* malloc the space needed */
1982 if ( (*buf
=(uint8_t*)SMB_MALLOC(len
)) == NULL
) {
1983 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1987 /* now for the real call to tdb_pack() */
1988 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
1990 logoff_time
, /* d */
1991 kickoff_time
, /* d */
1992 bad_password_time
, /* d */
1993 pass_last_set_time
, /* d */
1994 pass_can_change_time
, /* d */
1995 pass_must_change_time
, /* d */
1996 username_len
, username
, /* B */
1997 domain_len
, domain
, /* B */
1998 nt_username_len
, nt_username
, /* B */
1999 fullname_len
, fullname
, /* B */
2000 homedir_len
, homedir
, /* B */
2001 dir_drive_len
, dir_drive
, /* B */
2002 logon_script_len
, logon_script
, /* B */
2003 profile_path_len
, profile_path
, /* B */
2004 acct_desc_len
, acct_desc
, /* B */
2005 workstations_len
, workstations
, /* B */
2006 comment_len
, comment
, /* B */
2007 munged_dial_len
, munged_dial
, /* B */
2010 lm_pw_len
, lm_pw
, /* B */
2011 nt_pw_len
, nt_pw
, /* B */
2012 nt_pw_hist_len
, nt_pw_hist
, /* B */
2013 pdb_get_acct_ctrl(sampass
), /* d */
2014 pdb_get_logon_divs(sampass
), /* w */
2015 pdb_get_hours_len(sampass
), /* d */
2016 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2017 pdb_get_bad_password_count(sampass
), /* w */
2018 pdb_get_logon_count(sampass
), /* w */
2019 pdb_get_unknown_6(sampass
)); /* d */
2021 /* check to make sure we got it correct */
2022 if (buflen
!= len
) {
2023 DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2024 (unsigned long)buflen
, (unsigned long)len
));
2033 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
2035 /* nothing changed between V3 and V4 */
2036 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2039 static uint32_t init_buffer_from_samu_v4(uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2041 /* nothing changed between V3 and V4 */
2042 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2045 /**********************************************************************
2046 Intialize a struct samu struct from a BYTE buffer of size len
2047 *********************************************************************/
2049 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2050 uint8_t *buf
, uint32_t buflen
)
2053 case SAMU_BUFFER_V0
:
2054 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2055 case SAMU_BUFFER_V1
:
2056 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2057 case SAMU_BUFFER_V2
:
2058 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2059 case SAMU_BUFFER_V3
:
2060 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2061 case SAMU_BUFFER_V4
:
2062 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2068 /**********************************************************************
2069 Intialize a BYTE buffer from a struct samu struct
2070 *********************************************************************/
2072 uint32_t init_buffer_from_samu (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2074 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2077 /*********************************************************************
2078 *********************************************************************/
2080 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2082 uint8_t *buf
= NULL
;
2085 len
= init_buffer_from_samu(&buf
, src
, False
);
2086 if (len
== -1 || !buf
) {
2091 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2096 dst
->methods
= src
->methods
;
2098 if ( src
->unix_pw
) {
2099 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2100 if (!dst
->unix_pw
) {
2106 if (src
->group_sid
) {
2107 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2114 /*********************************************************************
2115 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2116 *********************************************************************/
2118 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2120 time_t LastBadPassword
;
2121 uint16_t BadPasswordCount
;
2125 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2126 if (!BadPasswordCount
) {
2127 DEBUG(9, ("No bad password attempts.\n"));
2132 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2136 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2140 /* First, check if there is a reset time to compare */
2141 if ((resettime
== (uint32_t) -1) || (resettime
== 0)) {
2142 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2146 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2147 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2148 (uint32_t) LastBadPassword
, resettime
, (uint32_t)time(NULL
)));
2149 if (time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(resettime
)*60)){
2150 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2151 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2160 /*********************************************************************
2161 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2162 *********************************************************************/
2164 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2167 time_t LastBadPassword
;
2170 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2171 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2172 pdb_get_username(sampass
)));
2177 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2181 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2185 /* First, check if there is a duration to compare */
2186 if ((duration
== (uint32_t) -1) || (duration
== 0)) {
2187 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2191 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2192 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2193 pdb_get_username(sampass
), (uint32_t)LastBadPassword
, duration
*60, (uint32_t)time(NULL
)));
2195 if (LastBadPassword
== (time_t)0) {
2196 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2197 "administratively locked out with no bad password "
2198 "time. Leaving locked out.\n",
2199 pdb_get_username(sampass
) ));
2203 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(duration
) * 60))) {
2204 pdb_set_acct_ctrl(sampass
,
2205 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2207 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2208 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2217 /*********************************************************************
2218 Increment the bad_password_count
2219 *********************************************************************/
2221 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2223 uint32_t account_policy_lockout
;
2224 bool autolock_updated
= False
, badpw_updated
= False
;
2227 /* Retrieve the account lockout policy */
2229 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2232 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2236 /* If there is no policy, we don't need to continue checking */
2237 if (!account_policy_lockout
) {
2238 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2242 /* Check if the autolock needs to be cleared */
2243 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2246 /* Check if the badpw count needs to be reset */
2247 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2251 Ok, now we can assume that any resetting that needs to be
2252 done has been done, and just get on with incrementing
2253 and autolocking if necessary
2256 pdb_set_bad_password_count(sampass
,
2257 pdb_get_bad_password_count(sampass
)+1,
2259 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2262 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2265 if (!pdb_set_acct_ctrl(sampass
,
2266 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2268 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2275 bool is_dc_trusted_domain_situation(const char *domain_name
)
2277 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2280 /*******************************************************************
2281 Wrapper around retrieving the clear text trust account password.
2282 appropriate account name is stored in account_name.
2283 Caller must free password, but not account_name.
2284 *******************************************************************/
2286 static bool get_trust_pw_clear2(const char *domain
,
2287 const char **account_name
,
2288 enum netr_SchannelType
*channel
,
2290 time_t *_last_set_time
,
2294 time_t last_set_time
;
2296 if (cur_pw
!= NULL
) {
2299 if (_last_set_time
!= NULL
) {
2300 *_last_set_time
= 0;
2302 if (prev_pw
!= NULL
) {
2306 /* if we are a DC and this is not our domain, then lookup an account
2307 * for the domain trust */
2309 if (is_dc_trusted_domain_situation(domain
)) {
2310 if (!lp_allow_trusted_domains()) {
2314 if (!pdb_get_trusteddom_pw(domain
, cur_pw
, NULL
,
2317 DEBUG(0, ("get_trust_pw: could not fetch trust "
2318 "account password for trusted domain %s\n",
2323 if (channel
!= NULL
) {
2324 *channel
= SEC_CHAN_DOMAIN
;
2327 if (account_name
!= NULL
) {
2328 *account_name
= lp_workgroup();
2331 if (_last_set_time
!= NULL
) {
2332 *_last_set_time
= last_set_time
;
2339 * Since we can only be member of one single domain, we are now
2340 * in a member situation:
2342 * - Either we are a DC (selfjoined) and the domain is our
2344 * - Or we are on a member and the domain is our own or some
2345 * other (potentially trusted) domain.
2347 * In both cases, we can only get the machine account password
2348 * for our own domain to connect to our own dc. (For a member,
2349 * request to trusted domains are performed through our dc.)
2351 * So we simply use our own domain name to retrieve the
2352 * machine account passowrd and ignore the request domain here.
2355 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2358 struct timeval expire
;
2362 if (account_name
!= NULL
) {
2363 *account_name
= lp_netbios_name();
2366 if (_last_set_time
!= NULL
) {
2367 *_last_set_time
= last_set_time
;
2370 if (prev_pw
== NULL
) {
2374 ZERO_STRUCT(expire
);
2375 expire
.tv_sec
= lp_machine_password_timeout();
2377 expire
.tv_sec
+= last_set_time
;
2378 if (timeval_expired(&expire
)) {
2382 pwd
= secrets_fetch_prev_machine_password(lp_workgroup());
2390 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2391 "account password for domain %s\n", domain
));
2395 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2396 const char **account_name
,
2397 enum netr_SchannelType
*channel
)
2399 return get_trust_pw_clear2(domain
,
2407 /*******************************************************************
2408 Wrapper around retrieving the trust account password.
2409 appropriate account name is stored in account_name.
2410 *******************************************************************/
2412 static bool get_trust_pw_hash2(const char *domain
,
2413 const char **account_name
,
2414 enum netr_SchannelType
*channel
,
2415 struct samr_Password
*current_nt_hash
,
2416 time_t *last_set_time
,
2417 struct samr_Password
**_previous_nt_hash
)
2419 char *cur_pw
= NULL
;
2420 char *prev_pw
= NULL
;
2421 char **_prev_pw
= NULL
;
2424 if (_previous_nt_hash
!= NULL
) {
2425 *_previous_nt_hash
= NULL
;
2426 _prev_pw
= &prev_pw
;
2429 ok
= get_trust_pw_clear2(domain
, account_name
, channel
,
2430 &cur_pw
, last_set_time
, _prev_pw
);
2432 struct samr_Password
*previous_nt_hash
= NULL
;
2434 E_md4hash(cur_pw
, current_nt_hash
->hash
);
2437 if (prev_pw
== NULL
) {
2441 previous_nt_hash
= SMB_MALLOC_P(struct samr_Password
);
2442 if (previous_nt_hash
== NULL
) {
2446 E_md4hash(prev_pw
, previous_nt_hash
->hash
);
2449 *_previous_nt_hash
= previous_nt_hash
;
2451 } else if (is_dc_trusted_domain_situation(domain
)) {
2455 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2457 if (secrets_fetch_trust_account_password_legacy(domain
,
2458 current_nt_hash
->hash
,
2462 if (account_name
!= NULL
) {
2463 *account_name
= lp_netbios_name();
2469 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2470 "password for domain %s\n", domain
));
2474 bool get_trust_pw_hash(const char *domain
, uint8_t ret_pwd
[16],
2475 const char **account_name
,
2476 enum netr_SchannelType
*channel
)
2478 struct samr_Password current_nt_hash
;
2481 ok
= get_trust_pw_hash2(domain
, account_name
, channel
,
2482 ¤t_nt_hash
, NULL
, NULL
);
2487 memcpy(ret_pwd
, current_nt_hash
.hash
, sizeof(current_nt_hash
.hash
));
2491 NTSTATUS
pdb_get_trust_credentials(const char *netbios_domain
,
2492 const char *dns_domain
, /* optional */
2493 TALLOC_CTX
*mem_ctx
,
2494 struct cli_credentials
**_creds
)
2496 TALLOC_CTX
*frame
= talloc_stackframe();
2497 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
2498 struct loadparm_context
*lp_ctx
;
2499 enum netr_SchannelType channel
;
2500 time_t last_set_time
;
2501 const char *_account_name
;
2502 const char *account_name
;
2503 char *cur_pw
= NULL
;
2504 char *prev_pw
= NULL
;
2505 struct samr_Password cur_nt_hash
;
2506 struct cli_credentials
*creds
= NULL
;
2510 * If this is our primary trust relationship, use the common
2511 * code to read the secrets.ldb or secrets.tdb file.
2513 if (strequal(netbios_domain
, lp_workgroup())) {
2514 struct db_context
*db_ctx
= secrets_db_ctx();
2515 if (db_ctx
== NULL
) {
2516 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2518 status
= NT_STATUS_INTERNAL_ERROR
;
2522 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2523 if (lp_ctx
== NULL
) {
2524 DEBUG(1, ("loadparm_init_s3 failed\n"));
2525 status
= NT_STATUS_INTERNAL_ERROR
;
2529 creds
= cli_credentials_init(mem_ctx
);
2530 if (creds
== NULL
) {
2531 status
= NT_STATUS_NO_MEMORY
;
2535 cli_credentials_set_conf(creds
, lp_ctx
);
2537 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2539 status
= NT_STATUS_NO_MEMORY
;
2543 status
= cli_credentials_set_machine_account_db_ctx(creds
,
2546 if (!NT_STATUS_IS_OK(status
)) {
2550 } else if (!IS_DC
) {
2551 DEBUG(1, ("Refusing to get trust account info for %s, "
2552 "which is not our primary domain %s, "
2553 "as we are not a DC\n",
2554 netbios_domain
, lp_workgroup()));
2555 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2559 status
= pdb_get_trusteddom_creds(netbios_domain
, mem_ctx
, &creds
);
2560 if (NT_STATUS_IS_OK(status
)) {
2563 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
2567 ok
= get_trust_pw_clear2(netbios_domain
,
2574 ok
= get_trust_pw_hash2(netbios_domain
,
2581 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2583 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2588 account_name
= talloc_asprintf(frame
, "%s$", _account_name
);
2589 if (account_name
== NULL
) {
2590 status
= NT_STATUS_NO_MEMORY
;
2594 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2595 if (lp_ctx
== NULL
) {
2596 DEBUG(1, ("loadparm_init_s3 failed\n"));
2597 status
= NT_STATUS_INTERNAL_ERROR
;
2601 creds
= cli_credentials_init(mem_ctx
);
2602 if (creds
== NULL
) {
2603 status
= NT_STATUS_NO_MEMORY
;
2607 cli_credentials_set_conf(creds
, lp_ctx
);
2609 cli_credentials_set_secure_channel_type(creds
, channel
);
2610 cli_credentials_set_password_last_changed_time(creds
, last_set_time
);
2612 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2614 status
= NT_STATUS_NO_MEMORY
;
2618 if (dns_domain
!= NULL
) {
2619 ok
= cli_credentials_set_realm(creds
, dns_domain
, CRED_SPECIFIED
);
2621 status
= NT_STATUS_NO_MEMORY
;
2626 ok
= cli_credentials_set_username(creds
, account_name
, CRED_SPECIFIED
);
2628 status
= NT_STATUS_NO_MEMORY
;
2632 if (cur_pw
== NULL
) {
2633 ok
= cli_credentials_set_nt_hash(creds
, &cur_nt_hash
, CRED_SPECIFIED
);
2635 status
= NT_STATUS_NO_MEMORY
;
2641 ok
= cli_credentials_set_password(creds
, cur_pw
, CRED_SPECIFIED
);
2643 status
= NT_STATUS_NO_MEMORY
;
2647 if (prev_pw
!= NULL
) {
2648 ok
= cli_credentials_set_old_password(creds
, prev_pw
, CRED_SPECIFIED
);
2650 status
= NT_STATUS_NO_MEMORY
;
2658 status
= NT_STATUS_OK
;