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"
35 #include "lib/util/string_wrappers.h"
38 #define DBGC_CLASS DBGC_PASSDB
40 /**********************************************************************
41 ***********************************************************************/
43 static int samu_destroy(struct samu
*user
)
45 data_blob_clear_free( &user
->lm_pw
);
46 data_blob_clear_free( &user
->nt_pw
);
48 if ( user
->plaintext_pw
)
49 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
54 /**********************************************************************
55 generate a new struct samuser
56 ***********************************************************************/
58 struct samu
*samu_new( TALLOC_CTX
*ctx
)
62 if ( !(user
= talloc_zero( ctx
, struct samu
)) ) {
63 DEBUG(0,("samuser_new: Talloc failed!\n"));
67 talloc_set_destructor( user
, samu_destroy
);
69 /* no initial methods */
73 /* Don't change these timestamp settings without a good reason.
74 They are important for NT member server compatibility. */
76 user
->logon_time
= (time_t)0;
77 user
->pass_last_set_time
= (time_t)0;
78 user
->pass_can_change_time
= (time_t)0;
79 user
->logoff_time
= get_time_t_max();
80 user
->kickoff_time
= get_time_t_max();
81 user
->fields_present
= 0x00ffffff;
82 user
->logon_divs
= 168; /* hours per week */
83 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
84 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
85 user
->bad_password_count
= 0;
86 user
->logon_count
= 0;
87 user
->unknown_6
= 0x000004ec; /* don't know */
89 /* Some parts of samba strlen their pdb_get...() returns,
90 so this keeps the interface unchanged for now. */
94 user
->nt_username
= "";
97 user
->logon_script
= "";
98 user
->profile_path
= "";
100 user
->workstations
= "";
102 user
->munged_dial
= "";
104 user
->plaintext_pw
= NULL
;
106 /* Unless we know otherwise have a Account Control Bit
107 value of 'normal user'. This helps User Manager, which
108 asks for a filtered list of users. */
110 user
->acct_ctrl
= ACB_NORMAL
;
115 static int count_commas(const char *str
)
118 const char *comma
= str
;
120 while ((comma
= strchr(comma
, ',')) != NULL
) {
127 /*********************************************************************
128 Initialize a struct samu from a struct passwd including the user
129 and group SIDs. The *user structure is filled out with the Unix
130 attributes and a user SID.
131 *********************************************************************/
133 static NTSTATUS
samu_set_unix_internal(struct pdb_methods
*methods
,
134 struct samu
*user
, const struct passwd
*pwd
, bool create
)
136 const char *guest_account
= lp_guest_account();
137 const char *domain
= lp_netbios_name();
143 return NT_STATUS_NO_SUCH_USER
;
146 /* Basic properties based upon the Unix account information */
148 ok
= pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
150 return NT_STATUS_NO_MEMORY
;
155 if (count_commas(pwd
->pw_gecos
) == 3) {
157 * Heuristic: This seems to be a gecos field that has been
158 * edited by chfn(1). Only use the part before the first
159 * comma. Fixes bug 5198.
161 fullname
= talloc_strndup(
162 talloc_tos(), pwd
->pw_gecos
,
163 strchr(pwd
->pw_gecos
, ',') - pwd
->pw_gecos
);
164 if (fullname
== NULL
) {
165 return NT_STATUS_NO_MEMORY
;
169 if (fullname
!= NULL
) {
170 ok
= pdb_set_fullname(user
, fullname
, PDB_SET
);
172 ok
= pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
174 TALLOC_FREE(fullname
);
177 return NT_STATUS_NO_MEMORY
;
180 ok
= pdb_set_domain(user
, get_global_sam_name(), PDB_DEFAULT
);
182 return NT_STATUS_NO_MEMORY
;
185 /* This can lead to a primary group of S-1-22-2-XX which
186 will be rejected by other parts of the Samba code.
187 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
190 gid_to_sid(&group_sid
, pwd
->pw_gid
);
191 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
194 /* save the password structure for later use */
196 user
->unix_pw
= tcopy_passwd( user
, pwd
);
197 if (user
->unix_pw
== NULL
) {
198 return NT_STATUS_NO_MEMORY
;
201 /* Special case for the guest account which must have a RID of 501 */
203 if ( strequal( pwd
->pw_name
, guest_account
) ) {
204 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_RID_GUEST
, PDB_DEFAULT
)) {
205 return NT_STATUS_NO_SUCH_USER
;
210 /* Non-guest accounts...Check for a workstation or user account */
212 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
215 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
216 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
218 return NT_STATUS_INVALID_COMPUTER_NAME
;
224 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
225 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
227 return NT_STATUS_INVALID_ACCOUNT_NAME
;
230 /* set some basic attributes */
232 ok
= pdb_set_profile_path(
234 talloc_sub_specified(
243 ok
&= pdb_set_homedir(
245 talloc_sub_specified(
254 ok
&= pdb_set_dir_drive(
256 talloc_sub_specified(
265 ok
&= pdb_set_logon_script(
267 talloc_sub_specified(
277 return NT_STATUS_NO_MEMORY
;
281 /* Now deal with the user SID. If we have a backend that can generate
282 RIDs, then do so. But sometimes the caller just wanted a structure
283 initialized and will fill in these fields later (such as from a
284 netr_SamInfo3 structure) */
286 if ( create
&& (methods
->capabilities(methods
) & PDB_CAP_STORE_RIDS
)) {
288 struct dom_sid user_sid
;
290 if ( !methods
->new_rid(methods
, &user_rid
) ) {
291 DEBUG(3, ("Could not allocate a new RID\n"));
292 return NT_STATUS_ACCESS_DENIED
;
295 sid_compose(&user_sid
, get_global_sam_sid(), user_rid
);
297 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
298 DEBUG(3, ("pdb_set_user_sid failed\n"));
299 return NT_STATUS_INTERNAL_ERROR
;
305 /* generate a SID for the user with the RID algorithm */
307 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
309 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
310 return NT_STATUS_INTERNAL_ERROR
;
316 /********************************************************************
317 Set the Unix user attributes
318 ********************************************************************/
320 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
322 return samu_set_unix_internal( NULL
, user
, pwd
, False
);
325 NTSTATUS
samu_alloc_rid_unix(struct pdb_methods
*methods
,
326 struct samu
*user
, const struct passwd
*pwd
)
328 return samu_set_unix_internal( methods
, user
, pwd
, True
);
331 /**********************************************************
332 Encode the account control bits into a string.
333 length = length of string to encode into (including terminating
334 null). length *MUST BE MORE THAN 2* !
335 **********************************************************/
337 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl
, size_t length
)
344 SMB_ASSERT(length
<= sizeof(acct_str
));
348 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
349 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
350 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
351 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
352 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
353 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
354 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
355 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
356 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
357 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
358 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
360 for ( ; i
< length
- 2 ; i
++ )
365 acct_str
[i
++] = '\0';
367 result
= talloc_strdup(talloc_tos(), acct_str
);
368 SMB_ASSERT(result
!= NULL
);
372 /**********************************************************
373 Decode the account control bits from a string.
374 **********************************************************/
376 uint32_t pdb_decode_acct_ctrl(const char *p
)
378 uint32_t acct_ctrl
= 0;
379 bool finished
= false;
382 * Check if the account type bits have been encoded after the
383 * NT password (in the form [NDHTUWSLXI]).
389 for (p
++; *p
&& !finished
; p
++) {
391 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
392 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
393 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
394 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
395 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
396 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
397 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
398 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
399 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
400 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
401 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
407 default: { finished
= true; }
414 /*************************************************************
415 Routine to set 32 hex password characters from a 16 byte array.
416 **************************************************************/
418 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32_t acct_ctrl
)
421 hex_encode_buf(p
, pwd
, 16);
423 if (acct_ctrl
& ACB_PWNOTREQ
)
424 strlcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
426 strlcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
430 /*************************************************************
431 Routine to get the 32 hex characters and turn them
432 into a 16 byte array.
433 **************************************************************/
435 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
438 unsigned char lonybble
, hinybble
;
439 const char *hexchars
= "0123456789ABCDEF";
445 for (i
= 0; i
< 32; i
+= 2) {
446 hinybble
= toupper_m(p
[i
]);
447 lonybble
= toupper_m(p
[i
+ 1]);
449 p1
= strchr(hexchars
, hinybble
);
450 p2
= strchr(hexchars
, lonybble
);
455 hinybble
= PTR_DIFF(p1
, hexchars
);
456 lonybble
= PTR_DIFF(p2
, hexchars
);
458 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
463 /*************************************************************
464 Routine to set 42 hex hours characters from a 21 byte array.
465 **************************************************************/
467 void pdb_sethexhours(char *p
, const unsigned char *hours
)
470 hex_encode_buf(p
, hours
, 21);
472 strlcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
476 /*************************************************************
477 Routine to get the 42 hex characters and turn them
478 into a 21 byte array.
479 **************************************************************/
481 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
484 unsigned char lonybble
, hinybble
;
485 const char *hexchars
= "0123456789ABCDEF";
492 for (i
= 0; i
< 42; i
+= 2) {
493 hinybble
= toupper_m(p
[i
]);
494 lonybble
= toupper_m(p
[i
+ 1]);
496 p1
= strchr(hexchars
, hinybble
);
497 p2
= strchr(hexchars
, lonybble
);
503 hinybble
= PTR_DIFF(p1
, hexchars
);
504 lonybble
= PTR_DIFF(p2
, hexchars
);
506 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
511 /********************************************************************
512 ********************************************************************/
514 int algorithmic_rid_base(void)
518 rid_offset
= lp_algorithmic_rid_base();
520 if (rid_offset
< BASE_RID
) {
521 /* Try to prevent admin foot-shooting, we can't put algorithmic
522 rids below 1000, that's the 'well known RIDs' on NT */
523 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
524 rid_offset
= BASE_RID
;
526 if (rid_offset
& 1) {
527 DEBUG(0, ("algorithmic rid base must be even\n"));
533 /*******************************************************************
534 Converts NT user RID to a UNIX uid.
535 ********************************************************************/
537 uid_t
algorithmic_pdb_user_rid_to_uid(uint32_t user_rid
)
539 int rid_offset
= algorithmic_rid_base();
540 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
543 uid_t
max_algorithmic_uid(void)
545 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
548 /*******************************************************************
549 converts UNIX uid to an NT User RID.
550 ********************************************************************/
552 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid
)
554 int rid_offset
= algorithmic_rid_base();
555 return (((((uint32_t)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
558 /*******************************************************************
559 Converts NT group RID to a UNIX gid.
560 ********************************************************************/
562 gid_t
pdb_group_rid_to_gid(uint32_t group_rid
)
564 int rid_offset
= algorithmic_rid_base();
565 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
568 gid_t
max_algorithmic_gid(void)
570 return pdb_group_rid_to_gid(0xffffffff);
573 /*******************************************************************
574 converts NT Group RID to a UNIX uid.
576 warning: you must not call that function only
577 you must do a call to the group mapping first.
578 there is not anymore a direct link between the gid and the rid.
579 ********************************************************************/
581 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid
)
583 int rid_offset
= algorithmic_rid_base();
584 return (((((uint32_t)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
587 /*******************************************************************
588 Decides if a RID is a well known RID.
589 ********************************************************************/
591 static bool rid_is_well_known(uint32_t rid
)
593 /* Not using rid_offset here, because this is the actual
594 NT fixed value (1000) */
596 return (rid
< BASE_RID
);
599 /*******************************************************************
600 Decides if a RID is a user or group RID.
601 ********************************************************************/
603 bool algorithmic_pdb_rid_is_user(uint32_t rid
)
605 if ( rid_is_well_known(rid
) ) {
607 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
608 * and DOMAIN_RID_GUEST.
610 if(rid
== DOMAIN_RID_ADMINISTRATOR
|| rid
== DOMAIN_RID_GUEST
)
612 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
618 /*******************************************************************
619 Convert a name into a SID. Used in the lookup name rpc.
620 ********************************************************************/
622 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
623 enum lsa_SidType
*type
)
628 /* Windows treats "MACHINE\None" as a special name for
629 rid 513 on non-DCs. You cannot create a user or group
630 name "None" on Windows. You will get an error that
631 the group already exists. */
633 if ( strequal( name
, "None" ) ) {
634 *rid
= DOMAIN_RID_USERS
;
635 *type
= SID_NAME_DOM_GRP
;
640 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
641 * correctly in the case where foo also exists as a user. If the flag
642 * is set, don't look for users at all. */
644 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
645 struct samu
*sam_account
= NULL
;
646 struct dom_sid user_sid
;
648 if ( !(sam_account
= samu_new( NULL
)) ) {
653 ret
= pdb_getsampwnam(sam_account
, name
);
657 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
660 TALLOC_FREE(sam_account
);
663 if (!sid_check_is_in_our_sam(&user_sid
)) {
664 struct dom_sid_buf buf
;
665 DBG_ERR("User %s with invalid SID %s"
668 dom_sid_str_buf(&user_sid
, &buf
));
672 sid_peek_rid(&user_sid
, rid
);
673 *type
= SID_NAME_USER
;
679 * Maybe it is a group ?
682 map
= talloc_zero(NULL
, GROUP_MAP
);
688 ret
= pdb_getgrnam(map
, name
);
696 /* BUILTIN groups are looked up elsewhere */
697 if (!sid_check_is_in_our_sam(&map
->sid
)) {
698 struct dom_sid_buf buf
;
699 DEBUG(10, ("Found group %s (%s) not in our domain -- "
702 dom_sid_str_buf(&map
->sid
, &buf
)));
707 /* yes it's a mapped group */
708 sid_peek_rid(&map
->sid
, rid
);
709 *type
= map
->sid_name_use
;
714 /*************************************************************
715 Change a password entry in the local passdb backend.
718 - always called as root
719 - ignores the account type except when adding a new account
720 - will create/delete the unix account if the relative
721 add/delete user script is configured
723 *************************************************************/
725 NTSTATUS
local_password_change(const char *user_name
,
727 const char *new_passwd
,
732 struct samu
*sam_pass
;
742 tosctx
= talloc_tos();
744 sam_pass
= samu_new(tosctx
);
746 result
= NT_STATUS_NO_MEMORY
;
750 /* Get the smb passwd entry for this user */
751 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
753 /* Check delete first, we don't need to do anything else if we
754 * are going to delete the account */
755 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
757 result
= pdb_delete_user(tosctx
, sam_pass
);
758 if (!NT_STATUS_IS_OK(result
)) {
759 ret
= asprintf(pp_err_str
,
760 "Failed to delete entry for user %s.\n",
765 result
= NT_STATUS_UNSUCCESSFUL
;
767 ret
= asprintf(pp_msg_str
,
768 "Deleted user %s.\n",
777 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
778 /* the entry already existed */
779 local_flags
&= ~LOCAL_ADD_USER
;
782 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
783 ret
= asprintf(pp_err_str
,
784 "Failed to find entry for user %s.\n",
789 result
= NT_STATUS_NO_SUCH_USER
;
793 /* First thing add the new user if we are required to do so */
794 if (local_flags
& LOCAL_ADD_USER
) {
796 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
798 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
804 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
805 if (!NT_STATUS_IS_OK(result
)) {
806 ret
= asprintf(pp_err_str
,
807 "Failed to add entry for user %s.\n",
812 result
= NT_STATUS_UNSUCCESSFUL
;
816 sam_pass
= samu_new(tosctx
);
818 result
= NT_STATUS_NO_MEMORY
;
822 /* Now get back the smb passwd entry for this new user */
823 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
825 ret
= asprintf(pp_err_str
,
826 "Failed to add entry for user %s.\n",
831 result
= NT_STATUS_UNSUCCESSFUL
;
836 acb
= pdb_get_acct_ctrl(sam_pass
);
839 * We are root - just write the new password
840 * and the valid last change time.
842 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
844 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
845 ret
= asprintf(pp_err_str
,
846 "Failed to set 'no password required' "
847 "flag for user %s.\n", user_name
);
851 result
= NT_STATUS_UNSUCCESSFUL
;
856 if (local_flags
& LOCAL_SET_PASSWORD
) {
858 * If we're dealing with setting a completely empty user account
859 * ie. One with a password of 'XXXX', but not set disabled (like
860 * an account created from scratch) then if the old password was
861 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
862 * We remove that as we're giving this user their first password
863 * and the decision hasn't really been made to disable them (ie.
864 * don't create them disabled). JRA.
866 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
867 (acb
& ACB_DISABLED
)) {
868 acb
&= (~ACB_DISABLED
);
869 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
870 ret
= asprintf(pp_err_str
,
871 "Failed to unset 'disabled' "
872 "flag for user %s.\n",
877 result
= NT_STATUS_UNSUCCESSFUL
;
882 acb
&= (~ACB_PWNOTREQ
);
883 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
884 ret
= asprintf(pp_err_str
,
885 "Failed to unset 'no password required'"
886 " flag for user %s.\n", user_name
);
890 result
= NT_STATUS_UNSUCCESSFUL
;
894 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
895 ret
= asprintf(pp_err_str
,
896 "Failed to set password for "
897 "user %s.\n", user_name
);
901 result
= NT_STATUS_UNSUCCESSFUL
;
906 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
908 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
909 ret
= asprintf(pp_err_str
,
910 "Failed to set 'disabled' flag for "
911 "user %s.\n", user_name
);
915 result
= NT_STATUS_UNSUCCESSFUL
;
920 if ((local_flags
& LOCAL_ENABLE_USER
) && (acb
& ACB_DISABLED
)) {
921 acb
&= (~ACB_DISABLED
);
922 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
923 ret
= asprintf(pp_err_str
,
924 "Failed to unset 'disabled' flag for "
925 "user %s.\n", user_name
);
929 result
= NT_STATUS_UNSUCCESSFUL
;
934 /* now commit changes if any */
935 result
= pdb_update_sam_account(sam_pass
);
936 if (!NT_STATUS_IS_OK(result
)) {
937 ret
= asprintf(pp_err_str
,
938 "Failed to modify entry for user %s.\n",
946 if (local_flags
& LOCAL_ADD_USER
) {
947 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
948 } else if (local_flags
& LOCAL_DISABLE_USER
) {
949 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
950 } else if (local_flags
& LOCAL_ENABLE_USER
) {
951 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
952 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
953 ret
= asprintf(pp_msg_str
,
954 "User %s password set to none.\n", user_name
);
961 result
= NT_STATUS_OK
;
964 TALLOC_FREE(sam_pass
);
968 /**********************************************************************
969 Marshall/unmarshall struct samu structs.
970 *********************************************************************/
972 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
973 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
974 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
975 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
976 /* nothing changed between V3 and V4 */
978 /*********************************************************************
979 *********************************************************************/
981 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
984 /* times are stored as 32bit integer
985 take care on system with 64bit wide time_t
991 pass_can_change_time
,
992 pass_must_change_time
;
993 char *username
= NULL
;
995 char *nt_username
= NULL
;
996 char *dir_drive
= NULL
;
997 char *unknown_str
= NULL
;
998 char *munged_dial
= NULL
;
999 char *fullname
= NULL
;
1000 char *homedir
= NULL
;
1001 char *logon_script
= NULL
;
1002 char *profile_path
= NULL
;
1003 char *acct_desc
= NULL
;
1004 char *workstations
= NULL
;
1005 uint32_t username_len
, domain_len
, nt_username_len
,
1006 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1007 fullname_len
, homedir_len
, logon_script_len
,
1008 profile_path_len
, acct_desc_len
, workstations_len
;
1010 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1011 uint16_t acct_ctrl
, logon_divs
;
1012 uint16_t bad_password_count
, logon_count
;
1013 uint8_t *hours
= NULL
;
1014 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1016 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1019 if(sampass
== NULL
|| buf
== NULL
) {
1020 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
1024 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1026 /* unpack the buffer into variables */
1027 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
1028 &logon_time
, /* d */
1029 &logoff_time
, /* d */
1030 &kickoff_time
, /* d */
1031 &pass_last_set_time
, /* d */
1032 &pass_can_change_time
, /* d */
1033 &pass_must_change_time
, /* d */
1034 &username_len
, &username
, /* B */
1035 &domain_len
, &domain
, /* B */
1036 &nt_username_len
, &nt_username
, /* B */
1037 &fullname_len
, &fullname
, /* B */
1038 &homedir_len
, &homedir
, /* B */
1039 &dir_drive_len
, &dir_drive
, /* B */
1040 &logon_script_len
, &logon_script
, /* B */
1041 &profile_path_len
, &profile_path
, /* B */
1042 &acct_desc_len
, &acct_desc
, /* B */
1043 &workstations_len
, &workstations
, /* B */
1044 &unknown_str_len
, &unknown_str
, /* B */
1045 &munged_dial_len
, &munged_dial
, /* B */
1048 &lm_pw_len
, &lm_pw_ptr
, /* B */
1049 &nt_pw_len
, &nt_pw_ptr
, /* B */
1051 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
1052 &logon_divs
, /* w */
1054 &hourslen
, &hours
, /* B */
1055 &bad_password_count
, /* w */
1056 &logon_count
, /* w */
1057 &unknown_6
); /* d */
1059 if (len
== (uint32_t) -1) {
1064 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1065 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1066 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1067 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1068 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1070 pdb_set_username(sampass
, username
, PDB_SET
);
1071 pdb_set_domain(sampass
, domain
, PDB_SET
);
1072 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1073 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1076 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1079 pdb_set_homedir(sampass
,
1080 talloc_sub_basic(sampass
, username
, domain
,
1086 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1088 pdb_set_dir_drive(sampass
,
1089 talloc_sub_basic(sampass
, username
, domain
,
1095 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1097 pdb_set_logon_script(sampass
,
1098 talloc_sub_basic(sampass
, username
, domain
,
1104 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1106 pdb_set_profile_path(sampass
,
1107 talloc_sub_basic(sampass
, username
, domain
,
1112 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1113 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1114 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1116 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1117 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1123 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1124 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1130 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1131 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1132 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1133 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1134 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1135 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1136 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1137 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1138 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1139 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1143 SAFE_FREE(username
);
1145 SAFE_FREE(nt_username
);
1146 SAFE_FREE(fullname
);
1148 SAFE_FREE(dir_drive
);
1149 SAFE_FREE(logon_script
);
1150 SAFE_FREE(profile_path
);
1151 SAFE_FREE(acct_desc
);
1152 SAFE_FREE(workstations
);
1153 SAFE_FREE(munged_dial
);
1154 SAFE_FREE(unknown_str
);
1155 SAFE_FREE(lm_pw_ptr
);
1156 SAFE_FREE(nt_pw_ptr
);
1162 /*********************************************************************
1163 *********************************************************************/
1165 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1168 /* times are stored as 32bit integer
1169 take care on system with 64bit wide time_t
1171 uint32_t logon_time
,
1176 pass_can_change_time
,
1177 pass_must_change_time
;
1178 char *username
= NULL
;
1179 char *domain
= NULL
;
1180 char *nt_username
= NULL
;
1181 char *dir_drive
= NULL
;
1182 char *unknown_str
= NULL
;
1183 char *munged_dial
= NULL
;
1184 char *fullname
= NULL
;
1185 char *homedir
= NULL
;
1186 char *logon_script
= NULL
;
1187 char *profile_path
= NULL
;
1188 char *acct_desc
= NULL
;
1189 char *workstations
= NULL
;
1190 uint32_t username_len
, domain_len
, nt_username_len
,
1191 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1192 fullname_len
, homedir_len
, logon_script_len
,
1193 profile_path_len
, acct_desc_len
, workstations_len
;
1195 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1196 uint16_t acct_ctrl
, logon_divs
;
1197 uint16_t bad_password_count
, logon_count
;
1198 uint8_t *hours
= NULL
;
1199 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1201 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1204 if(sampass
== NULL
|| buf
== NULL
) {
1205 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1209 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1211 /* unpack the buffer into variables */
1212 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1213 &logon_time
, /* d */
1214 &logoff_time
, /* d */
1215 &kickoff_time
, /* d */
1216 /* Change from V0 is addition of bad_password_time field. */
1217 &bad_password_time
, /* d */
1218 &pass_last_set_time
, /* d */
1219 &pass_can_change_time
, /* d */
1220 &pass_must_change_time
, /* d */
1221 &username_len
, &username
, /* B */
1222 &domain_len
, &domain
, /* B */
1223 &nt_username_len
, &nt_username
, /* B */
1224 &fullname_len
, &fullname
, /* B */
1225 &homedir_len
, &homedir
, /* B */
1226 &dir_drive_len
, &dir_drive
, /* B */
1227 &logon_script_len
, &logon_script
, /* B */
1228 &profile_path_len
, &profile_path
, /* B */
1229 &acct_desc_len
, &acct_desc
, /* B */
1230 &workstations_len
, &workstations
, /* B */
1231 &unknown_str_len
, &unknown_str
, /* B */
1232 &munged_dial_len
, &munged_dial
, /* B */
1235 &lm_pw_len
, &lm_pw_ptr
, /* B */
1236 &nt_pw_len
, &nt_pw_ptr
, /* B */
1239 &logon_divs
, /* w */
1241 &hourslen
, &hours
, /* B */
1242 &bad_password_count
, /* w */
1243 &logon_count
, /* w */
1244 &unknown_6
); /* d */
1246 if (len
== (uint32_t) -1) {
1251 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1252 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1253 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1255 /* Change from V0 is addition of bad_password_time field. */
1256 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1257 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1258 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1260 pdb_set_username(sampass
, username
, PDB_SET
);
1261 pdb_set_domain(sampass
, domain
, PDB_SET
);
1262 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1263 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1266 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1269 pdb_set_homedir(sampass
,
1270 talloc_sub_basic(sampass
, username
, domain
,
1276 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1278 pdb_set_dir_drive(sampass
,
1279 talloc_sub_basic(sampass
, username
, domain
,
1285 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1287 pdb_set_logon_script(sampass
,
1288 talloc_sub_basic(sampass
, username
, domain
,
1294 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1296 pdb_set_profile_path(sampass
,
1297 talloc_sub_basic(sampass
, username
, domain
,
1302 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1303 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1304 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1306 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1307 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1313 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1314 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1320 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1322 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1323 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1324 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1325 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1326 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1327 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1328 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1329 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1330 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1334 SAFE_FREE(username
);
1336 SAFE_FREE(nt_username
);
1337 SAFE_FREE(fullname
);
1339 SAFE_FREE(dir_drive
);
1340 SAFE_FREE(logon_script
);
1341 SAFE_FREE(profile_path
);
1342 SAFE_FREE(acct_desc
);
1343 SAFE_FREE(workstations
);
1344 SAFE_FREE(munged_dial
);
1345 SAFE_FREE(unknown_str
);
1346 SAFE_FREE(lm_pw_ptr
);
1347 SAFE_FREE(nt_pw_ptr
);
1353 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1356 /* times are stored as 32bit integer
1357 take care on system with 64bit wide time_t
1359 uint32_t logon_time
,
1364 pass_can_change_time
,
1365 pass_must_change_time
;
1366 char *username
= NULL
;
1367 char *domain
= NULL
;
1368 char *nt_username
= NULL
;
1369 char *dir_drive
= NULL
;
1370 char *unknown_str
= NULL
;
1371 char *munged_dial
= NULL
;
1372 char *fullname
= NULL
;
1373 char *homedir
= NULL
;
1374 char *logon_script
= NULL
;
1375 char *profile_path
= NULL
;
1376 char *acct_desc
= NULL
;
1377 char *workstations
= NULL
;
1378 uint32_t username_len
, domain_len
, nt_username_len
,
1379 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1380 fullname_len
, homedir_len
, logon_script_len
,
1381 profile_path_len
, acct_desc_len
, workstations_len
;
1383 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
;
1384 uint16_t acct_ctrl
, logon_divs
;
1385 uint16_t bad_password_count
, logon_count
;
1386 uint8_t *hours
= NULL
;
1387 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1389 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1390 uint32_t pwHistLen
= 0;
1393 bool expand_explicit
= lp_passdb_expand_explicit();
1395 if(sampass
== NULL
|| buf
== NULL
) {
1396 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1400 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1402 /* unpack the buffer into variables */
1403 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1404 &logon_time
, /* d */
1405 &logoff_time
, /* d */
1406 &kickoff_time
, /* d */
1407 &bad_password_time
, /* d */
1408 &pass_last_set_time
, /* d */
1409 &pass_can_change_time
, /* d */
1410 &pass_must_change_time
, /* d */
1411 &username_len
, &username
, /* B */
1412 &domain_len
, &domain
, /* B */
1413 &nt_username_len
, &nt_username
, /* B */
1414 &fullname_len
, &fullname
, /* B */
1415 &homedir_len
, &homedir
, /* B */
1416 &dir_drive_len
, &dir_drive
, /* B */
1417 &logon_script_len
, &logon_script
, /* B */
1418 &profile_path_len
, &profile_path
, /* B */
1419 &acct_desc_len
, &acct_desc
, /* B */
1420 &workstations_len
, &workstations
, /* B */
1421 &unknown_str_len
, &unknown_str
, /* B */
1422 &munged_dial_len
, &munged_dial
, /* B */
1425 &lm_pw_len
, &lm_pw_ptr
, /* B */
1426 &nt_pw_len
, &nt_pw_ptr
, /* B */
1427 /* Change from V1 is addition of password history field. */
1428 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1430 /* Also "remove_me" field was removed. */
1431 &logon_divs
, /* w */
1433 &hourslen
, &hours
, /* B */
1434 &bad_password_count
, /* w */
1435 &logon_count
, /* w */
1436 &unknown_6
); /* d */
1438 if (len
== (uint32_t) -1) {
1443 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1444 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1445 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1446 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1447 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1448 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1450 pdb_set_username(sampass
, username
, PDB_SET
);
1451 pdb_set_domain(sampass
, domain
, PDB_SET
);
1452 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1453 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1456 fstrcpy( tmp_string
, homedir
);
1457 if (expand_explicit
) {
1458 standard_sub_basic( username
, domain
, tmp_string
,
1459 sizeof(tmp_string
) );
1461 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1464 pdb_set_homedir(sampass
,
1465 talloc_sub_basic(sampass
, username
, domain
,
1471 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1473 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1476 fstrcpy( tmp_string
, logon_script
);
1477 if (expand_explicit
) {
1478 standard_sub_basic( username
, domain
, tmp_string
,
1479 sizeof(tmp_string
) );
1481 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1484 pdb_set_logon_script(sampass
,
1485 talloc_sub_basic(sampass
, username
, domain
,
1491 fstrcpy( tmp_string
, profile_path
);
1492 if (expand_explicit
) {
1493 standard_sub_basic( username
, domain
, tmp_string
,
1494 sizeof(tmp_string
) );
1496 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1499 pdb_set_profile_path(sampass
,
1500 talloc_sub_basic(sampass
, username
, domain
,
1505 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1506 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1507 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1509 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1510 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1516 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1517 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1523 /* Change from V1 is addition of password history field. */
1524 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1526 uint8_t *pw_hist
= SMB_MALLOC_ARRAY(uint8_t, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1531 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1532 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1534 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1535 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1536 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1537 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1538 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1539 PW_HISTORY_ENTRY_LEN
);
1542 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1549 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1552 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1553 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1554 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1555 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1556 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1557 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1558 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1559 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1560 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1564 SAFE_FREE(username
);
1566 SAFE_FREE(nt_username
);
1567 SAFE_FREE(fullname
);
1569 SAFE_FREE(dir_drive
);
1570 SAFE_FREE(logon_script
);
1571 SAFE_FREE(profile_path
);
1572 SAFE_FREE(acct_desc
);
1573 SAFE_FREE(workstations
);
1574 SAFE_FREE(munged_dial
);
1575 SAFE_FREE(unknown_str
);
1576 SAFE_FREE(lm_pw_ptr
);
1577 SAFE_FREE(nt_pw_ptr
);
1578 SAFE_FREE(nt_pw_hist_ptr
);
1584 /*********************************************************************
1585 *********************************************************************/
1587 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1590 /* times are stored as 32bit integer
1591 take care on system with 64bit wide time_t
1593 uint32_t logon_time
,
1598 pass_can_change_time
,
1599 pass_must_change_time
;
1600 char *username
= NULL
;
1601 char *domain
= NULL
;
1602 char *nt_username
= NULL
;
1603 char *dir_drive
= NULL
;
1604 char *comment
= NULL
;
1605 char *munged_dial
= NULL
;
1606 char *fullname
= NULL
;
1607 char *homedir
= NULL
;
1608 char *logon_script
= NULL
;
1609 char *profile_path
= NULL
;
1610 char *acct_desc
= NULL
;
1611 char *workstations
= NULL
;
1612 uint32_t username_len
, domain_len
, nt_username_len
,
1613 dir_drive_len
, comment_len
, munged_dial_len
,
1614 fullname_len
, homedir_len
, logon_script_len
,
1615 profile_path_len
, acct_desc_len
, workstations_len
;
1617 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1618 uint16_t logon_divs
;
1619 uint16_t bad_password_count
, logon_count
;
1620 uint8_t *hours
= NULL
;
1621 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1623 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1624 uint32_t pwHistLen
= 0;
1627 bool expand_explicit
= lp_passdb_expand_explicit();
1629 if(sampass
== NULL
|| buf
== NULL
) {
1630 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1634 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1636 /* unpack the buffer into variables */
1637 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1638 &logon_time
, /* d */
1639 &logoff_time
, /* d */
1640 &kickoff_time
, /* d */
1641 &bad_password_time
, /* d */
1642 &pass_last_set_time
, /* d */
1643 &pass_can_change_time
, /* d */
1644 &pass_must_change_time
, /* d */
1645 &username_len
, &username
, /* B */
1646 &domain_len
, &domain
, /* B */
1647 &nt_username_len
, &nt_username
, /* B */
1648 &fullname_len
, &fullname
, /* B */
1649 &homedir_len
, &homedir
, /* B */
1650 &dir_drive_len
, &dir_drive
, /* B */
1651 &logon_script_len
, &logon_script
, /* B */
1652 &profile_path_len
, &profile_path
, /* B */
1653 &acct_desc_len
, &acct_desc
, /* B */
1654 &workstations_len
, &workstations
, /* B */
1655 &comment_len
, &comment
, /* B */
1656 &munged_dial_len
, &munged_dial
, /* B */
1659 &lm_pw_len
, &lm_pw_ptr
, /* B */
1660 &nt_pw_len
, &nt_pw_ptr
, /* B */
1661 /* Change from V1 is addition of password history field. */
1662 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1663 /* Change from V2 is the uint32_t acb_mask */
1665 /* Also "remove_me" field was removed. */
1666 &logon_divs
, /* w */
1668 &hourslen
, &hours
, /* B */
1669 &bad_password_count
, /* w */
1670 &logon_count
, /* w */
1671 &unknown_6
); /* d */
1673 if (len
== (uint32_t) -1) {
1678 pdb_set_logon_time(sampass
, convert_uint32_t_to_time_t(logon_time
), PDB_SET
);
1679 pdb_set_logoff_time(sampass
, convert_uint32_t_to_time_t(logoff_time
), PDB_SET
);
1680 pdb_set_kickoff_time(sampass
, convert_uint32_t_to_time_t(kickoff_time
), PDB_SET
);
1681 pdb_set_bad_password_time(sampass
, convert_uint32_t_to_time_t(bad_password_time
), PDB_SET
);
1682 pdb_set_pass_can_change_time(sampass
, convert_uint32_t_to_time_t(pass_can_change_time
), PDB_SET
);
1683 pdb_set_pass_last_set_time(sampass
, convert_uint32_t_to_time_t(pass_last_set_time
), PDB_SET
);
1685 pdb_set_username(sampass
, username
, PDB_SET
);
1686 pdb_set_domain(sampass
, domain
, PDB_SET
);
1687 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1688 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1691 fstrcpy( tmp_string
, homedir
);
1692 if (expand_explicit
) {
1693 standard_sub_basic( username
, domain
, tmp_string
,
1694 sizeof(tmp_string
) );
1696 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1699 pdb_set_homedir(sampass
,
1700 talloc_sub_basic(sampass
, username
, domain
,
1706 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1708 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1711 fstrcpy( tmp_string
, logon_script
);
1712 if (expand_explicit
) {
1713 standard_sub_basic( username
, domain
, tmp_string
,
1714 sizeof(tmp_string
) );
1716 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1719 pdb_set_logon_script(sampass
,
1720 talloc_sub_basic(sampass
, username
, domain
,
1726 fstrcpy( tmp_string
, profile_path
);
1727 if (expand_explicit
) {
1728 standard_sub_basic( username
, domain
, tmp_string
,
1729 sizeof(tmp_string
) );
1731 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1734 pdb_set_profile_path(sampass
,
1735 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1739 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1740 pdb_set_comment(sampass
, comment
, PDB_SET
);
1741 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1742 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1744 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1745 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1751 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1752 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1758 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1760 uint8_t *pw_hist
= (uint8_t *)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1765 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1766 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1768 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1769 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1770 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1771 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1772 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1773 PW_HISTORY_ENTRY_LEN
);
1776 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1783 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1786 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1787 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1788 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1789 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1790 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1791 /* Change from V2 is the uint32_t acct_ctrl */
1792 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1793 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1794 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1798 SAFE_FREE(username
);
1800 SAFE_FREE(nt_username
);
1801 SAFE_FREE(fullname
);
1803 SAFE_FREE(dir_drive
);
1804 SAFE_FREE(logon_script
);
1805 SAFE_FREE(profile_path
);
1806 SAFE_FREE(acct_desc
);
1807 SAFE_FREE(workstations
);
1808 SAFE_FREE(munged_dial
);
1810 SAFE_FREE(lm_pw_ptr
);
1811 SAFE_FREE(nt_pw_ptr
);
1812 SAFE_FREE(nt_pw_hist_ptr
);
1818 /*********************************************************************
1819 *********************************************************************/
1821 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
1825 /* times are stored as 32bit integer
1826 take care on system with 64bit wide time_t
1828 uint32_t logon_time
,
1833 pass_can_change_time
,
1834 pass_must_change_time
;
1836 uint32_t user_rid
, group_rid
;
1838 const char *username
;
1840 const char *nt_username
;
1841 const char *dir_drive
;
1842 const char *comment
;
1843 const char *munged_dial
;
1844 const char *fullname
;
1845 const char *homedir
;
1846 const char *logon_script
;
1847 const char *profile_path
;
1848 const char *acct_desc
;
1849 const char *workstations
;
1850 uint32_t username_len
, domain_len
, nt_username_len
,
1851 dir_drive_len
, comment_len
, munged_dial_len
,
1852 fullname_len
, homedir_len
, logon_script_len
,
1853 profile_path_len
, acct_desc_len
, workstations_len
;
1855 const uint8_t *lm_pw
;
1856 const uint8_t *nt_pw
;
1857 const uint8_t *nt_pw_hist
;
1858 uint32_t lm_pw_len
= 16;
1859 uint32_t nt_pw_len
= 16;
1860 uint32_t nt_pw_hist_len
;
1861 uint32_t pwHistLen
= 0;
1866 logon_time
= convert_time_t_to_uint32_t(pdb_get_logon_time(sampass
));
1867 logoff_time
= convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass
));
1868 kickoff_time
= convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass
));
1869 bad_password_time
= convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass
));
1870 pass_can_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass
));
1871 pass_must_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass
));
1872 pass_last_set_time
= convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass
));
1874 user_rid
= pdb_get_user_rid(sampass
);
1875 group_rid
= pdb_get_group_rid(sampass
);
1877 username
= pdb_get_username(sampass
);
1879 username_len
= strlen(username
) +1;
1884 domain
= pdb_get_domain(sampass
);
1886 domain_len
= strlen(domain
) +1;
1891 nt_username
= pdb_get_nt_username(sampass
);
1893 nt_username_len
= strlen(nt_username
) +1;
1895 nt_username_len
= 0;
1898 fullname
= pdb_get_fullname(sampass
);
1900 fullname_len
= strlen(fullname
) +1;
1906 * Only updates fields which have been set (not defaults from smb.conf)
1909 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1910 dir_drive
= pdb_get_dir_drive(sampass
);
1915 dir_drive_len
= strlen(dir_drive
) +1;
1920 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1921 homedir
= pdb_get_homedir(sampass
);
1926 homedir_len
= strlen(homedir
) +1;
1931 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1932 logon_script
= pdb_get_logon_script(sampass
);
1934 logon_script
= NULL
;
1937 logon_script_len
= strlen(logon_script
) +1;
1939 logon_script_len
= 0;
1942 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1943 profile_path
= pdb_get_profile_path(sampass
);
1945 profile_path
= NULL
;
1948 profile_path_len
= strlen(profile_path
) +1;
1950 profile_path_len
= 0;
1953 lm_pw
= pdb_get_lanman_passwd(sampass
);
1958 nt_pw
= pdb_get_nt_passwd(sampass
);
1963 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1964 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1965 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1966 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1971 acct_desc
= pdb_get_acct_desc(sampass
);
1973 acct_desc_len
= strlen(acct_desc
) +1;
1978 workstations
= pdb_get_workstations(sampass
);
1980 workstations_len
= strlen(workstations
) +1;
1982 workstations_len
= 0;
1985 comment
= pdb_get_comment(sampass
);
1987 comment_len
= strlen(comment
) +1;
1992 munged_dial
= pdb_get_munged_dial(sampass
);
1994 munged_dial_len
= strlen(munged_dial
) +1;
1996 munged_dial_len
= 0;
1999 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
2001 /* one time to get the size needed */
2002 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
2004 logoff_time
, /* d */
2005 kickoff_time
, /* d */
2006 bad_password_time
, /* d */
2007 pass_last_set_time
, /* d */
2008 pass_can_change_time
, /* d */
2009 pass_must_change_time
, /* d */
2010 username_len
, username
, /* B */
2011 domain_len
, domain
, /* B */
2012 nt_username_len
, nt_username
, /* B */
2013 fullname_len
, fullname
, /* B */
2014 homedir_len
, homedir
, /* B */
2015 dir_drive_len
, dir_drive
, /* B */
2016 logon_script_len
, logon_script
, /* B */
2017 profile_path_len
, profile_path
, /* B */
2018 acct_desc_len
, acct_desc
, /* B */
2019 workstations_len
, workstations
, /* B */
2020 comment_len
, comment
, /* B */
2021 munged_dial_len
, munged_dial
, /* B */
2024 lm_pw_len
, lm_pw
, /* B */
2025 nt_pw_len
, nt_pw
, /* B */
2026 nt_pw_hist_len
, nt_pw_hist
, /* B */
2027 pdb_get_acct_ctrl(sampass
), /* d */
2028 pdb_get_logon_divs(sampass
), /* w */
2029 pdb_get_hours_len(sampass
), /* d */
2030 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2031 pdb_get_bad_password_count(sampass
), /* w */
2032 pdb_get_logon_count(sampass
), /* w */
2033 pdb_get_unknown_6(sampass
)); /* d */
2039 /* malloc the space needed */
2040 if ( (*buf
=(uint8_t*)SMB_MALLOC(len
)) == NULL
) {
2041 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2045 /* now for the real call to tdb_pack() */
2046 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
2048 logoff_time
, /* d */
2049 kickoff_time
, /* d */
2050 bad_password_time
, /* d */
2051 pass_last_set_time
, /* d */
2052 pass_can_change_time
, /* d */
2053 pass_must_change_time
, /* d */
2054 username_len
, username
, /* B */
2055 domain_len
, domain
, /* B */
2056 nt_username_len
, nt_username
, /* B */
2057 fullname_len
, fullname
, /* B */
2058 homedir_len
, homedir
, /* B */
2059 dir_drive_len
, dir_drive
, /* B */
2060 logon_script_len
, logon_script
, /* B */
2061 profile_path_len
, profile_path
, /* B */
2062 acct_desc_len
, acct_desc
, /* B */
2063 workstations_len
, workstations
, /* B */
2064 comment_len
, comment
, /* B */
2065 munged_dial_len
, munged_dial
, /* B */
2068 lm_pw_len
, lm_pw
, /* B */
2069 nt_pw_len
, nt_pw
, /* B */
2070 nt_pw_hist_len
, nt_pw_hist
, /* B */
2071 pdb_get_acct_ctrl(sampass
), /* d */
2072 pdb_get_logon_divs(sampass
), /* w */
2073 pdb_get_hours_len(sampass
), /* d */
2074 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2075 pdb_get_bad_password_count(sampass
), /* w */
2076 pdb_get_logon_count(sampass
), /* w */
2077 pdb_get_unknown_6(sampass
)); /* d */
2079 /* check to make sure we got it correct */
2080 if (buflen
!= len
) {
2081 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2082 (unsigned long)buflen
, (unsigned long)len
));
2091 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
2093 /* nothing changed between V3 and V4 */
2094 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2097 static uint32_t init_buffer_from_samu_v4(uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2099 /* nothing changed between V3 and V4 */
2100 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2103 /**********************************************************************
2104 Intialize a struct samu struct from a BYTE buffer of size len
2105 *********************************************************************/
2107 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2108 uint8_t *buf
, uint32_t buflen
)
2111 case SAMU_BUFFER_V0
:
2112 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2113 case SAMU_BUFFER_V1
:
2114 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2115 case SAMU_BUFFER_V2
:
2116 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2117 case SAMU_BUFFER_V3
:
2118 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2119 case SAMU_BUFFER_V4
:
2120 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2126 /**********************************************************************
2127 Intialize a BYTE buffer from a struct samu struct
2128 *********************************************************************/
2130 uint32_t init_buffer_from_samu (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2132 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2135 /*********************************************************************
2136 *********************************************************************/
2138 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2140 uint8_t *buf
= NULL
;
2143 len
= init_buffer_from_samu(&buf
, src
, False
);
2144 if (len
== -1 || !buf
) {
2149 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2154 dst
->methods
= src
->methods
;
2156 if ( src
->unix_pw
) {
2157 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2158 if (!dst
->unix_pw
) {
2164 if (src
->group_sid
) {
2165 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2172 /*********************************************************************
2173 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2174 *********************************************************************/
2176 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2178 time_t LastBadPassword
;
2179 uint16_t BadPasswordCount
;
2183 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2184 if (!BadPasswordCount
) {
2185 DEBUG(9, ("No bad password attempts.\n"));
2190 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2194 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2198 /* First, check if there is a reset time to compare */
2199 if ((resettime
== (uint32_t) -1) || (resettime
== 0)) {
2200 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2204 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2205 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2206 (uint32_t) LastBadPassword
, resettime
, (uint32_t)time(NULL
)));
2207 if (time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(resettime
)*60)){
2208 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2209 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2218 /*********************************************************************
2219 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2220 *********************************************************************/
2222 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2225 time_t LastBadPassword
;
2228 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2229 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2230 pdb_get_username(sampass
)));
2235 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2239 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2243 /* First, check if there is a duration to compare */
2244 if ((duration
== (uint32_t) -1) || (duration
== 0)) {
2245 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2249 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2250 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2251 pdb_get_username(sampass
), (uint32_t)LastBadPassword
, duration
*60, (uint32_t)time(NULL
)));
2253 if (LastBadPassword
== (time_t)0) {
2254 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2255 "administratively locked out with no bad password "
2256 "time. Leaving locked out.\n",
2257 pdb_get_username(sampass
) ));
2261 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(duration
) * 60))) {
2262 pdb_set_acct_ctrl(sampass
,
2263 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2265 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2266 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2275 /*********************************************************************
2276 Increment the bad_password_count
2277 *********************************************************************/
2279 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2281 uint32_t account_policy_lockout
;
2282 bool autolock_updated
= False
, badpw_updated
= False
;
2285 /* Retrieve the account lockout policy */
2287 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2290 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2294 /* If there is no policy, we don't need to continue checking */
2295 if (!account_policy_lockout
) {
2296 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2300 /* Check if the autolock needs to be cleared */
2301 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2304 /* Check if the badpw count needs to be reset */
2305 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2309 Ok, now we can assume that any resetting that needs to be
2310 done has been done, and just get on with incrementing
2311 and autolocking if necessary
2314 pdb_set_bad_password_count(sampass
,
2315 pdb_get_bad_password_count(sampass
)+1,
2317 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2320 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2323 if (!pdb_set_acct_ctrl(sampass
,
2324 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2326 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2333 bool is_dc_trusted_domain_situation(const char *domain_name
)
2335 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2338 /*******************************************************************
2339 Wrapper around retrieving the clear text trust account password.
2340 appropriate account name is stored in account_name.
2341 Caller must free password, but not account_name.
2342 *******************************************************************/
2344 static bool get_trust_pw_clear2(const char *domain
,
2345 const char **account_name
,
2346 enum netr_SchannelType
*channel
,
2348 time_t *_last_set_time
,
2352 time_t last_set_time
;
2354 if (cur_pw
!= NULL
) {
2357 if (_last_set_time
!= NULL
) {
2358 *_last_set_time
= 0;
2360 if (prev_pw
!= NULL
) {
2364 /* if we are a DC and this is not our domain, then lookup an account
2365 * for the domain trust */
2367 if (is_dc_trusted_domain_situation(domain
)) {
2368 if (!lp_allow_trusted_domains()) {
2372 if (!pdb_get_trusteddom_pw(domain
, cur_pw
, NULL
,
2375 DEBUG(0, ("get_trust_pw: could not fetch trust "
2376 "account password for trusted domain %s\n",
2381 if (channel
!= NULL
) {
2382 *channel
= SEC_CHAN_DOMAIN
;
2385 if (account_name
!= NULL
) {
2386 *account_name
= lp_workgroup();
2389 if (_last_set_time
!= NULL
) {
2390 *_last_set_time
= last_set_time
;
2397 * Since we can only be member of one single domain, we are now
2398 * in a member situation:
2400 * - Either we are a DC (selfjoined) and the domain is our
2402 * - Or we are on a member and the domain is our own or some
2403 * other (potentially trusted) domain.
2405 * In both cases, we can only get the machine account password
2406 * for our own domain to connect to our own dc. (For a member,
2407 * request to trusted domains are performed through our dc.)
2409 * So we simply use our own domain name to retrieve the
2410 * machine account passowrd and ignore the request domain here.
2413 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2416 struct timeval expire
;
2420 if (account_name
!= NULL
) {
2421 *account_name
= lp_netbios_name();
2424 if (_last_set_time
!= NULL
) {
2425 *_last_set_time
= last_set_time
;
2428 if (prev_pw
== NULL
) {
2432 ZERO_STRUCT(expire
);
2433 expire
.tv_sec
= lp_machine_password_timeout();
2435 expire
.tv_sec
+= last_set_time
;
2436 if (timeval_expired(&expire
)) {
2440 pwd
= secrets_fetch_prev_machine_password(lp_workgroup());
2448 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2449 "account password for domain %s\n", domain
));
2453 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2454 const char **account_name
,
2455 enum netr_SchannelType
*channel
)
2457 return get_trust_pw_clear2(domain
,
2465 /*******************************************************************
2466 Wrapper around retrieving the trust account password.
2467 appropriate account name is stored in account_name.
2468 *******************************************************************/
2470 static bool get_trust_pw_hash2(const char *domain
,
2471 const char **account_name
,
2472 enum netr_SchannelType
*channel
,
2473 struct samr_Password
*current_nt_hash
,
2474 time_t *last_set_time
,
2475 struct samr_Password
**_previous_nt_hash
)
2477 char *cur_pw
= NULL
;
2478 char *prev_pw
= NULL
;
2479 char **_prev_pw
= NULL
;
2482 if (_previous_nt_hash
!= NULL
) {
2483 *_previous_nt_hash
= NULL
;
2484 _prev_pw
= &prev_pw
;
2487 ok
= get_trust_pw_clear2(domain
, account_name
, channel
,
2488 &cur_pw
, last_set_time
, _prev_pw
);
2490 struct samr_Password
*previous_nt_hash
= NULL
;
2492 E_md4hash(cur_pw
, current_nt_hash
->hash
);
2495 if (prev_pw
== NULL
) {
2499 previous_nt_hash
= SMB_MALLOC_P(struct samr_Password
);
2500 if (previous_nt_hash
== NULL
) {
2504 E_md4hash(prev_pw
, previous_nt_hash
->hash
);
2507 *_previous_nt_hash
= previous_nt_hash
;
2509 } else if (is_dc_trusted_domain_situation(domain
)) {
2513 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2515 if (secrets_fetch_trust_account_password_legacy(domain
,
2516 current_nt_hash
->hash
,
2520 if (account_name
!= NULL
) {
2521 *account_name
= lp_netbios_name();
2527 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2528 "password for domain %s\n", domain
));
2532 bool get_trust_pw_hash(const char *domain
, uint8_t ret_pwd
[16],
2533 const char **account_name
,
2534 enum netr_SchannelType
*channel
)
2536 struct samr_Password current_nt_hash
;
2539 ok
= get_trust_pw_hash2(domain
, account_name
, channel
,
2540 ¤t_nt_hash
, NULL
, NULL
);
2545 memcpy(ret_pwd
, current_nt_hash
.hash
, sizeof(current_nt_hash
.hash
));
2549 NTSTATUS
pdb_get_trust_credentials(const char *netbios_domain
,
2550 const char *dns_domain
, /* optional */
2551 TALLOC_CTX
*mem_ctx
,
2552 struct cli_credentials
**_creds
)
2554 TALLOC_CTX
*frame
= talloc_stackframe();
2556 struct loadparm_context
*lp_ctx
;
2557 enum netr_SchannelType channel
;
2558 time_t last_set_time
;
2559 const char *_account_name
;
2560 const char *account_name
;
2561 char *cur_pw
= NULL
;
2562 char *prev_pw
= NULL
;
2563 struct samr_Password cur_nt_hash
;
2564 struct cli_credentials
*creds
= NULL
;
2568 * If this is our primary trust relationship, use the common
2569 * code to read the secrets.ldb or secrets.tdb file.
2571 if (strequal(netbios_domain
, lp_workgroup())) {
2572 struct db_context
*db_ctx
= secrets_db_ctx();
2573 if (db_ctx
== NULL
) {
2574 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2576 status
= NT_STATUS_INTERNAL_ERROR
;
2580 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2581 if (lp_ctx
== NULL
) {
2582 DEBUG(1, ("loadparm_init_s3 failed\n"));
2583 status
= NT_STATUS_INTERNAL_ERROR
;
2587 creds
= cli_credentials_init(mem_ctx
);
2588 if (creds
== NULL
) {
2589 status
= NT_STATUS_NO_MEMORY
;
2593 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2595 status
= NT_STATUS_INTERNAL_ERROR
;
2599 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2601 status
= NT_STATUS_NO_MEMORY
;
2605 status
= cli_credentials_set_machine_account_db_ctx(creds
,
2608 if (!NT_STATUS_IS_OK(status
)) {
2612 } else if (!IS_DC
) {
2613 DEBUG(1, ("Refusing to get trust account info for %s, "
2614 "which is not our primary domain %s, "
2615 "as we are not a DC\n",
2616 netbios_domain
, lp_workgroup()));
2617 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2621 status
= pdb_get_trusteddom_creds(netbios_domain
, mem_ctx
, &creds
);
2622 if (NT_STATUS_IS_OK(status
)) {
2625 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
2629 ok
= get_trust_pw_clear2(netbios_domain
,
2636 ok
= get_trust_pw_hash2(netbios_domain
,
2643 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2645 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2650 account_name
= talloc_asprintf(frame
, "%s$", _account_name
);
2651 if (account_name
== NULL
) {
2652 status
= NT_STATUS_NO_MEMORY
;
2656 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2657 if (lp_ctx
== NULL
) {
2658 DEBUG(1, ("loadparm_init_s3 failed\n"));
2659 status
= NT_STATUS_INTERNAL_ERROR
;
2663 creds
= cli_credentials_init(mem_ctx
);
2664 if (creds
== NULL
) {
2665 status
= NT_STATUS_NO_MEMORY
;
2669 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2671 status
= NT_STATUS_INTERNAL_ERROR
;
2675 cli_credentials_set_secure_channel_type(creds
, channel
);
2676 cli_credentials_set_password_last_changed_time(creds
, last_set_time
);
2678 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2680 status
= NT_STATUS_NO_MEMORY
;
2684 if (dns_domain
!= NULL
) {
2685 ok
= cli_credentials_set_realm(creds
, dns_domain
, CRED_SPECIFIED
);
2687 status
= NT_STATUS_NO_MEMORY
;
2692 * It's not possible to use NTLMSSP with a domain trust account.
2694 cli_credentials_set_kerberos_state(creds
,
2695 CRED_USE_KERBEROS_REQUIRED
,
2699 * We can't use kerberos against an NT4 domain.
2701 * We should have a mode that also disallows NTLMSSP here,
2702 * as only NETLOGON SCHANNEL is possible.
2704 cli_credentials_set_kerberos_state(creds
,
2705 CRED_USE_KERBEROS_DISABLED
,
2709 ok
= cli_credentials_set_username(creds
, account_name
, CRED_SPECIFIED
);
2711 status
= NT_STATUS_NO_MEMORY
;
2715 if (cur_pw
== NULL
) {
2716 ok
= cli_credentials_set_nt_hash(creds
, &cur_nt_hash
, CRED_SPECIFIED
);
2718 status
= NT_STATUS_NO_MEMORY
;
2722 * We currently can't do kerberos just with an NTHASH.
2724 cli_credentials_set_kerberos_state(creds
,
2725 CRED_USE_KERBEROS_DISABLED
,
2730 ok
= cli_credentials_set_password(creds
, cur_pw
, CRED_SPECIFIED
);
2732 status
= NT_STATUS_NO_MEMORY
;
2736 if (prev_pw
!= NULL
) {
2737 ok
= cli_credentials_set_old_password(creds
, prev_pw
, CRED_SPECIFIED
);
2739 status
= NT_STATUS_NO_MEMORY
;
2747 status
= NT_STATUS_OK
;