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 struct dom_sid_buf buf
;
612 DBG_ERR("User %s with invalid SID %s"
615 dom_sid_str_buf(&user_sid
, &buf
));
619 sid_peek_rid(&user_sid
, rid
);
620 *type
= SID_NAME_USER
;
626 * Maybe it is a group ?
629 map
= talloc_zero(NULL
, GROUP_MAP
);
635 ret
= pdb_getgrnam(map
, name
);
643 /* BUILTIN groups are looked up elsewhere */
644 if (!sid_check_is_in_our_sam(&map
->sid
)) {
645 struct dom_sid_buf buf
;
646 DEBUG(10, ("Found group %s (%s) not in our domain -- "
649 dom_sid_str_buf(&map
->sid
, &buf
)));
654 /* yes it's a mapped group */
655 sid_peek_rid(&map
->sid
, rid
);
656 *type
= map
->sid_name_use
;
661 /*************************************************************
662 Change a password entry in the local passdb backend.
665 - always called as root
666 - ignores the account type except when adding a new account
667 - will create/delete the unix account if the relative
668 add/delete user script is configured
670 *************************************************************/
672 NTSTATUS
local_password_change(const char *user_name
,
674 const char *new_passwd
,
679 struct samu
*sam_pass
;
689 tosctx
= talloc_tos();
691 sam_pass
= samu_new(tosctx
);
693 result
= NT_STATUS_NO_MEMORY
;
697 /* Get the smb passwd entry for this user */
698 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
700 /* Check delete first, we don't need to do anything else if we
701 * are going to delete the acocunt */
702 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
704 result
= pdb_delete_user(tosctx
, sam_pass
);
705 if (!NT_STATUS_IS_OK(result
)) {
706 ret
= asprintf(pp_err_str
,
707 "Failed to delete entry for user %s.\n",
712 result
= NT_STATUS_UNSUCCESSFUL
;
714 ret
= asprintf(pp_msg_str
,
715 "Deleted user %s.\n",
724 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
725 /* the entry already existed */
726 local_flags
&= ~LOCAL_ADD_USER
;
729 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
730 ret
= asprintf(pp_err_str
,
731 "Failed to find entry for user %s.\n",
736 result
= NT_STATUS_NO_SUCH_USER
;
740 /* First thing add the new user if we are required to do so */
741 if (local_flags
& LOCAL_ADD_USER
) {
743 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
745 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
751 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
752 if (!NT_STATUS_IS_OK(result
)) {
753 ret
= asprintf(pp_err_str
,
754 "Failed to add entry for user %s.\n",
759 result
= NT_STATUS_UNSUCCESSFUL
;
763 sam_pass
= samu_new(tosctx
);
765 result
= NT_STATUS_NO_MEMORY
;
769 /* Now get back the smb passwd entry for this new user */
770 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
772 ret
= asprintf(pp_err_str
,
773 "Failed to add entry for user %s.\n",
778 result
= NT_STATUS_UNSUCCESSFUL
;
783 acb
= pdb_get_acct_ctrl(sam_pass
);
786 * We are root - just write the new password
787 * and the valid last change time.
789 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
791 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
792 ret
= asprintf(pp_err_str
,
793 "Failed to set 'no password required' "
794 "flag for user %s.\n", user_name
);
798 result
= NT_STATUS_UNSUCCESSFUL
;
803 if (local_flags
& LOCAL_SET_PASSWORD
) {
805 * If we're dealing with setting a completely empty user account
806 * ie. One with a password of 'XXXX', but not set disabled (like
807 * an account created from scratch) then if the old password was
808 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
809 * We remove that as we're giving this user their first password
810 * and the decision hasn't really been made to disable them (ie.
811 * don't create them disabled). JRA.
813 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
814 (acb
& ACB_DISABLED
)) {
815 acb
&= (~ACB_DISABLED
);
816 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
817 ret
= asprintf(pp_err_str
,
818 "Failed to unset 'disabled' "
819 "flag for user %s.\n",
824 result
= NT_STATUS_UNSUCCESSFUL
;
829 acb
&= (~ACB_PWNOTREQ
);
830 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
831 ret
= asprintf(pp_err_str
,
832 "Failed to unset 'no password required'"
833 " flag for user %s.\n", user_name
);
837 result
= NT_STATUS_UNSUCCESSFUL
;
841 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
842 ret
= asprintf(pp_err_str
,
843 "Failed to set password for "
844 "user %s.\n", user_name
);
848 result
= NT_STATUS_UNSUCCESSFUL
;
853 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
855 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
856 ret
= asprintf(pp_err_str
,
857 "Failed to set 'disabled' flag for "
858 "user %s.\n", user_name
);
862 result
= NT_STATUS_UNSUCCESSFUL
;
867 if ((local_flags
& LOCAL_ENABLE_USER
) && (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' flag for "
872 "user %s.\n", user_name
);
876 result
= NT_STATUS_UNSUCCESSFUL
;
881 /* now commit changes if any */
882 result
= pdb_update_sam_account(sam_pass
);
883 if (!NT_STATUS_IS_OK(result
)) {
884 ret
= asprintf(pp_err_str
,
885 "Failed to modify entry for user %s.\n",
893 if (local_flags
& LOCAL_ADD_USER
) {
894 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
895 } else if (local_flags
& LOCAL_DISABLE_USER
) {
896 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
897 } else if (local_flags
& LOCAL_ENABLE_USER
) {
898 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
899 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
900 ret
= asprintf(pp_msg_str
,
901 "User %s password set to none.\n", user_name
);
908 result
= NT_STATUS_OK
;
911 TALLOC_FREE(sam_pass
);
915 /**********************************************************************
916 Marshall/unmarshall struct samu structs.
917 *********************************************************************/
919 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
920 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
921 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
922 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
923 /* nothing changed between V3 and V4 */
925 /*********************************************************************
926 *********************************************************************/
928 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
931 /* times are stored as 32bit integer
932 take care on system with 64bit wide time_t
938 pass_can_change_time
,
939 pass_must_change_time
;
940 char *username
= NULL
;
942 char *nt_username
= NULL
;
943 char *dir_drive
= NULL
;
944 char *unknown_str
= NULL
;
945 char *munged_dial
= NULL
;
946 char *fullname
= NULL
;
947 char *homedir
= NULL
;
948 char *logon_script
= NULL
;
949 char *profile_path
= NULL
;
950 char *acct_desc
= NULL
;
951 char *workstations
= NULL
;
952 uint32_t username_len
, domain_len
, nt_username_len
,
953 dir_drive_len
, unknown_str_len
, munged_dial_len
,
954 fullname_len
, homedir_len
, logon_script_len
,
955 profile_path_len
, acct_desc_len
, workstations_len
;
957 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
958 uint16_t acct_ctrl
, logon_divs
;
959 uint16_t bad_password_count
, logon_count
;
960 uint8_t *hours
= NULL
;
961 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
963 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
966 if(sampass
== NULL
|| buf
== NULL
) {
967 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
971 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
973 /* unpack the buffer into variables */
974 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
976 &logoff_time
, /* d */
977 &kickoff_time
, /* d */
978 &pass_last_set_time
, /* d */
979 &pass_can_change_time
, /* d */
980 &pass_must_change_time
, /* d */
981 &username_len
, &username
, /* B */
982 &domain_len
, &domain
, /* B */
983 &nt_username_len
, &nt_username
, /* B */
984 &fullname_len
, &fullname
, /* B */
985 &homedir_len
, &homedir
, /* B */
986 &dir_drive_len
, &dir_drive
, /* B */
987 &logon_script_len
, &logon_script
, /* B */
988 &profile_path_len
, &profile_path
, /* B */
989 &acct_desc_len
, &acct_desc
, /* B */
990 &workstations_len
, &workstations
, /* B */
991 &unknown_str_len
, &unknown_str
, /* B */
992 &munged_dial_len
, &munged_dial
, /* B */
995 &lm_pw_len
, &lm_pw_ptr
, /* B */
996 &nt_pw_len
, &nt_pw_ptr
, /* B */
998 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
1001 &hourslen
, &hours
, /* B */
1002 &bad_password_count
, /* w */
1003 &logon_count
, /* w */
1004 &unknown_6
); /* d */
1006 if (len
== (uint32_t) -1) {
1011 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1012 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1013 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1014 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1015 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1017 pdb_set_username(sampass
, username
, PDB_SET
);
1018 pdb_set_domain(sampass
, domain
, PDB_SET
);
1019 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1020 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1023 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1026 pdb_set_homedir(sampass
,
1027 talloc_sub_basic(sampass
, username
, domain
,
1033 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1035 pdb_set_dir_drive(sampass
,
1036 talloc_sub_basic(sampass
, username
, domain
,
1042 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1044 pdb_set_logon_script(sampass
,
1045 talloc_sub_basic(sampass
, username
, domain
,
1051 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1053 pdb_set_profile_path(sampass
,
1054 talloc_sub_basic(sampass
, username
, domain
,
1059 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1060 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1061 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1063 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1064 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1070 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1071 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1077 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1078 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1079 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1080 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1081 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1082 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1083 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1084 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1085 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1086 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1090 SAFE_FREE(username
);
1092 SAFE_FREE(nt_username
);
1093 SAFE_FREE(fullname
);
1095 SAFE_FREE(dir_drive
);
1096 SAFE_FREE(logon_script
);
1097 SAFE_FREE(profile_path
);
1098 SAFE_FREE(acct_desc
);
1099 SAFE_FREE(workstations
);
1100 SAFE_FREE(munged_dial
);
1101 SAFE_FREE(unknown_str
);
1102 SAFE_FREE(lm_pw_ptr
);
1103 SAFE_FREE(nt_pw_ptr
);
1109 /*********************************************************************
1110 *********************************************************************/
1112 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1115 /* times are stored as 32bit integer
1116 take care on system with 64bit wide time_t
1118 uint32_t logon_time
,
1123 pass_can_change_time
,
1124 pass_must_change_time
;
1125 char *username
= NULL
;
1126 char *domain
= NULL
;
1127 char *nt_username
= NULL
;
1128 char *dir_drive
= NULL
;
1129 char *unknown_str
= NULL
;
1130 char *munged_dial
= NULL
;
1131 char *fullname
= NULL
;
1132 char *homedir
= NULL
;
1133 char *logon_script
= NULL
;
1134 char *profile_path
= NULL
;
1135 char *acct_desc
= NULL
;
1136 char *workstations
= NULL
;
1137 uint32_t username_len
, domain_len
, nt_username_len
,
1138 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1139 fullname_len
, homedir_len
, logon_script_len
,
1140 profile_path_len
, acct_desc_len
, workstations_len
;
1142 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1143 uint16_t acct_ctrl
, logon_divs
;
1144 uint16_t bad_password_count
, logon_count
;
1145 uint8_t *hours
= NULL
;
1146 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1148 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1151 if(sampass
== NULL
|| buf
== NULL
) {
1152 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1156 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1158 /* unpack the buffer into variables */
1159 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1160 &logon_time
, /* d */
1161 &logoff_time
, /* d */
1162 &kickoff_time
, /* d */
1163 /* Change from V0 is addition of bad_password_time field. */
1164 &bad_password_time
, /* d */
1165 &pass_last_set_time
, /* d */
1166 &pass_can_change_time
, /* d */
1167 &pass_must_change_time
, /* d */
1168 &username_len
, &username
, /* B */
1169 &domain_len
, &domain
, /* B */
1170 &nt_username_len
, &nt_username
, /* B */
1171 &fullname_len
, &fullname
, /* B */
1172 &homedir_len
, &homedir
, /* B */
1173 &dir_drive_len
, &dir_drive
, /* B */
1174 &logon_script_len
, &logon_script
, /* B */
1175 &profile_path_len
, &profile_path
, /* B */
1176 &acct_desc_len
, &acct_desc
, /* B */
1177 &workstations_len
, &workstations
, /* B */
1178 &unknown_str_len
, &unknown_str
, /* B */
1179 &munged_dial_len
, &munged_dial
, /* B */
1182 &lm_pw_len
, &lm_pw_ptr
, /* B */
1183 &nt_pw_len
, &nt_pw_ptr
, /* B */
1186 &logon_divs
, /* w */
1188 &hourslen
, &hours
, /* B */
1189 &bad_password_count
, /* w */
1190 &logon_count
, /* w */
1191 &unknown_6
); /* d */
1193 if (len
== (uint32_t) -1) {
1198 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1199 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1200 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1202 /* Change from V0 is addition of bad_password_time field. */
1203 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1204 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1205 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1207 pdb_set_username(sampass
, username
, PDB_SET
);
1208 pdb_set_domain(sampass
, domain
, PDB_SET
);
1209 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1210 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1213 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1216 pdb_set_homedir(sampass
,
1217 talloc_sub_basic(sampass
, username
, domain
,
1223 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1225 pdb_set_dir_drive(sampass
,
1226 talloc_sub_basic(sampass
, username
, domain
,
1232 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1234 pdb_set_logon_script(sampass
,
1235 talloc_sub_basic(sampass
, username
, domain
,
1241 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1243 pdb_set_profile_path(sampass
,
1244 talloc_sub_basic(sampass
, username
, domain
,
1249 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1250 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1251 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1253 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1254 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1260 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1261 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1267 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1269 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1270 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1271 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1272 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1273 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1274 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1275 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1276 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1277 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1281 SAFE_FREE(username
);
1283 SAFE_FREE(nt_username
);
1284 SAFE_FREE(fullname
);
1286 SAFE_FREE(dir_drive
);
1287 SAFE_FREE(logon_script
);
1288 SAFE_FREE(profile_path
);
1289 SAFE_FREE(acct_desc
);
1290 SAFE_FREE(workstations
);
1291 SAFE_FREE(munged_dial
);
1292 SAFE_FREE(unknown_str
);
1293 SAFE_FREE(lm_pw_ptr
);
1294 SAFE_FREE(nt_pw_ptr
);
1300 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1303 /* times are stored as 32bit integer
1304 take care on system with 64bit wide time_t
1306 uint32_t logon_time
,
1311 pass_can_change_time
,
1312 pass_must_change_time
;
1313 char *username
= NULL
;
1314 char *domain
= NULL
;
1315 char *nt_username
= NULL
;
1316 char *dir_drive
= NULL
;
1317 char *unknown_str
= NULL
;
1318 char *munged_dial
= NULL
;
1319 char *fullname
= NULL
;
1320 char *homedir
= NULL
;
1321 char *logon_script
= NULL
;
1322 char *profile_path
= NULL
;
1323 char *acct_desc
= NULL
;
1324 char *workstations
= NULL
;
1325 uint32_t username_len
, domain_len
, nt_username_len
,
1326 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1327 fullname_len
, homedir_len
, logon_script_len
,
1328 profile_path_len
, acct_desc_len
, workstations_len
;
1330 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
;
1331 uint16_t acct_ctrl
, logon_divs
;
1332 uint16_t bad_password_count
, logon_count
;
1333 uint8_t *hours
= NULL
;
1334 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1336 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1337 uint32_t pwHistLen
= 0;
1340 bool expand_explicit
= lp_passdb_expand_explicit();
1342 if(sampass
== NULL
|| buf
== NULL
) {
1343 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1347 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1349 /* unpack the buffer into variables */
1350 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1351 &logon_time
, /* d */
1352 &logoff_time
, /* d */
1353 &kickoff_time
, /* d */
1354 &bad_password_time
, /* d */
1355 &pass_last_set_time
, /* d */
1356 &pass_can_change_time
, /* d */
1357 &pass_must_change_time
, /* d */
1358 &username_len
, &username
, /* B */
1359 &domain_len
, &domain
, /* B */
1360 &nt_username_len
, &nt_username
, /* B */
1361 &fullname_len
, &fullname
, /* B */
1362 &homedir_len
, &homedir
, /* B */
1363 &dir_drive_len
, &dir_drive
, /* B */
1364 &logon_script_len
, &logon_script
, /* B */
1365 &profile_path_len
, &profile_path
, /* B */
1366 &acct_desc_len
, &acct_desc
, /* B */
1367 &workstations_len
, &workstations
, /* B */
1368 &unknown_str_len
, &unknown_str
, /* B */
1369 &munged_dial_len
, &munged_dial
, /* B */
1372 &lm_pw_len
, &lm_pw_ptr
, /* B */
1373 &nt_pw_len
, &nt_pw_ptr
, /* B */
1374 /* Change from V1 is addition of password history field. */
1375 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1377 /* Also "remove_me" field was removed. */
1378 &logon_divs
, /* w */
1380 &hourslen
, &hours
, /* B */
1381 &bad_password_count
, /* w */
1382 &logon_count
, /* w */
1383 &unknown_6
); /* d */
1385 if (len
== (uint32_t) -1) {
1390 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1391 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1392 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1393 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1394 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1395 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1397 pdb_set_username(sampass
, username
, PDB_SET
);
1398 pdb_set_domain(sampass
, domain
, PDB_SET
);
1399 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1400 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1403 fstrcpy( tmp_string
, homedir
);
1404 if (expand_explicit
) {
1405 standard_sub_basic( username
, domain
, tmp_string
,
1406 sizeof(tmp_string
) );
1408 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1411 pdb_set_homedir(sampass
,
1412 talloc_sub_basic(sampass
, username
, domain
,
1418 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1420 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1423 fstrcpy( tmp_string
, logon_script
);
1424 if (expand_explicit
) {
1425 standard_sub_basic( username
, domain
, tmp_string
,
1426 sizeof(tmp_string
) );
1428 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1431 pdb_set_logon_script(sampass
,
1432 talloc_sub_basic(sampass
, username
, domain
,
1438 fstrcpy( tmp_string
, profile_path
);
1439 if (expand_explicit
) {
1440 standard_sub_basic( username
, domain
, tmp_string
,
1441 sizeof(tmp_string
) );
1443 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1446 pdb_set_profile_path(sampass
,
1447 talloc_sub_basic(sampass
, username
, domain
,
1452 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1453 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1454 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1456 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1457 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1463 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1464 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1470 /* Change from V1 is addition of password history field. */
1471 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1473 uint8_t *pw_hist
= SMB_MALLOC_ARRAY(uint8_t, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1478 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1479 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1481 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1482 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1483 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1484 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1485 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1486 PW_HISTORY_ENTRY_LEN
);
1489 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1496 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1499 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1500 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1501 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1502 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1503 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1504 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1505 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1506 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1507 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1511 SAFE_FREE(username
);
1513 SAFE_FREE(nt_username
);
1514 SAFE_FREE(fullname
);
1516 SAFE_FREE(dir_drive
);
1517 SAFE_FREE(logon_script
);
1518 SAFE_FREE(profile_path
);
1519 SAFE_FREE(acct_desc
);
1520 SAFE_FREE(workstations
);
1521 SAFE_FREE(munged_dial
);
1522 SAFE_FREE(unknown_str
);
1523 SAFE_FREE(lm_pw_ptr
);
1524 SAFE_FREE(nt_pw_ptr
);
1525 SAFE_FREE(nt_pw_hist_ptr
);
1531 /*********************************************************************
1532 *********************************************************************/
1534 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1537 /* times are stored as 32bit integer
1538 take care on system with 64bit wide time_t
1540 uint32_t logon_time
,
1545 pass_can_change_time
,
1546 pass_must_change_time
;
1547 char *username
= NULL
;
1548 char *domain
= NULL
;
1549 char *nt_username
= NULL
;
1550 char *dir_drive
= NULL
;
1551 char *comment
= NULL
;
1552 char *munged_dial
= NULL
;
1553 char *fullname
= NULL
;
1554 char *homedir
= NULL
;
1555 char *logon_script
= NULL
;
1556 char *profile_path
= NULL
;
1557 char *acct_desc
= NULL
;
1558 char *workstations
= NULL
;
1559 uint32_t username_len
, domain_len
, nt_username_len
,
1560 dir_drive_len
, comment_len
, munged_dial_len
,
1561 fullname_len
, homedir_len
, logon_script_len
,
1562 profile_path_len
, acct_desc_len
, workstations_len
;
1564 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1565 uint16_t logon_divs
;
1566 uint16_t bad_password_count
, logon_count
;
1567 uint8_t *hours
= NULL
;
1568 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1570 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1571 uint32_t pwHistLen
= 0;
1574 bool expand_explicit
= lp_passdb_expand_explicit();
1576 if(sampass
== NULL
|| buf
== NULL
) {
1577 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1581 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1583 /* unpack the buffer into variables */
1584 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1585 &logon_time
, /* d */
1586 &logoff_time
, /* d */
1587 &kickoff_time
, /* d */
1588 &bad_password_time
, /* d */
1589 &pass_last_set_time
, /* d */
1590 &pass_can_change_time
, /* d */
1591 &pass_must_change_time
, /* d */
1592 &username_len
, &username
, /* B */
1593 &domain_len
, &domain
, /* B */
1594 &nt_username_len
, &nt_username
, /* B */
1595 &fullname_len
, &fullname
, /* B */
1596 &homedir_len
, &homedir
, /* B */
1597 &dir_drive_len
, &dir_drive
, /* B */
1598 &logon_script_len
, &logon_script
, /* B */
1599 &profile_path_len
, &profile_path
, /* B */
1600 &acct_desc_len
, &acct_desc
, /* B */
1601 &workstations_len
, &workstations
, /* B */
1602 &comment_len
, &comment
, /* B */
1603 &munged_dial_len
, &munged_dial
, /* B */
1606 &lm_pw_len
, &lm_pw_ptr
, /* B */
1607 &nt_pw_len
, &nt_pw_ptr
, /* B */
1608 /* Change from V1 is addition of password history field. */
1609 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1610 /* Change from V2 is the uint32_t acb_mask */
1612 /* Also "remove_me" field was removed. */
1613 &logon_divs
, /* w */
1615 &hourslen
, &hours
, /* B */
1616 &bad_password_count
, /* w */
1617 &logon_count
, /* w */
1618 &unknown_6
); /* d */
1620 if (len
== (uint32_t) -1) {
1625 pdb_set_logon_time(sampass
, convert_uint32_t_to_time_t(logon_time
), PDB_SET
);
1626 pdb_set_logoff_time(sampass
, convert_uint32_t_to_time_t(logoff_time
), PDB_SET
);
1627 pdb_set_kickoff_time(sampass
, convert_uint32_t_to_time_t(kickoff_time
), PDB_SET
);
1628 pdb_set_bad_password_time(sampass
, convert_uint32_t_to_time_t(bad_password_time
), PDB_SET
);
1629 pdb_set_pass_can_change_time(sampass
, convert_uint32_t_to_time_t(pass_can_change_time
), PDB_SET
);
1630 pdb_set_pass_last_set_time(sampass
, convert_uint32_t_to_time_t(pass_last_set_time
), PDB_SET
);
1632 pdb_set_username(sampass
, username
, PDB_SET
);
1633 pdb_set_domain(sampass
, domain
, PDB_SET
);
1634 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1635 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1638 fstrcpy( tmp_string
, homedir
);
1639 if (expand_explicit
) {
1640 standard_sub_basic( username
, domain
, tmp_string
,
1641 sizeof(tmp_string
) );
1643 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1646 pdb_set_homedir(sampass
,
1647 talloc_sub_basic(sampass
, username
, domain
,
1653 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1655 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1658 fstrcpy( tmp_string
, logon_script
);
1659 if (expand_explicit
) {
1660 standard_sub_basic( username
, domain
, tmp_string
,
1661 sizeof(tmp_string
) );
1663 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1666 pdb_set_logon_script(sampass
,
1667 talloc_sub_basic(sampass
, username
, domain
,
1673 fstrcpy( tmp_string
, profile_path
);
1674 if (expand_explicit
) {
1675 standard_sub_basic( username
, domain
, tmp_string
,
1676 sizeof(tmp_string
) );
1678 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1681 pdb_set_profile_path(sampass
,
1682 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1686 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1687 pdb_set_comment(sampass
, comment
, PDB_SET
);
1688 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1689 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1691 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1692 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1698 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1699 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1705 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1707 uint8_t *pw_hist
= (uint8_t *)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1712 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1713 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1715 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1716 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1717 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1718 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1719 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1720 PW_HISTORY_ENTRY_LEN
);
1723 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1730 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1733 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1734 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1735 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1736 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1737 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1738 /* Change from V2 is the uint32_t acct_ctrl */
1739 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1740 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1741 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1745 SAFE_FREE(username
);
1747 SAFE_FREE(nt_username
);
1748 SAFE_FREE(fullname
);
1750 SAFE_FREE(dir_drive
);
1751 SAFE_FREE(logon_script
);
1752 SAFE_FREE(profile_path
);
1753 SAFE_FREE(acct_desc
);
1754 SAFE_FREE(workstations
);
1755 SAFE_FREE(munged_dial
);
1757 SAFE_FREE(lm_pw_ptr
);
1758 SAFE_FREE(nt_pw_ptr
);
1759 SAFE_FREE(nt_pw_hist_ptr
);
1765 /*********************************************************************
1766 *********************************************************************/
1768 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
1772 /* times are stored as 32bit integer
1773 take care on system with 64bit wide time_t
1775 uint32_t logon_time
,
1780 pass_can_change_time
,
1781 pass_must_change_time
;
1783 uint32_t user_rid
, group_rid
;
1785 const char *username
;
1787 const char *nt_username
;
1788 const char *dir_drive
;
1789 const char *comment
;
1790 const char *munged_dial
;
1791 const char *fullname
;
1792 const char *homedir
;
1793 const char *logon_script
;
1794 const char *profile_path
;
1795 const char *acct_desc
;
1796 const char *workstations
;
1797 uint32_t username_len
, domain_len
, nt_username_len
,
1798 dir_drive_len
, comment_len
, munged_dial_len
,
1799 fullname_len
, homedir_len
, logon_script_len
,
1800 profile_path_len
, acct_desc_len
, workstations_len
;
1802 const uint8_t *lm_pw
;
1803 const uint8_t *nt_pw
;
1804 const uint8_t *nt_pw_hist
;
1805 uint32_t lm_pw_len
= 16;
1806 uint32_t nt_pw_len
= 16;
1807 uint32_t nt_pw_hist_len
;
1808 uint32_t pwHistLen
= 0;
1813 logon_time
= convert_time_t_to_uint32_t(pdb_get_logon_time(sampass
));
1814 logoff_time
= convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass
));
1815 kickoff_time
= convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass
));
1816 bad_password_time
= convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass
));
1817 pass_can_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass
));
1818 pass_must_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass
));
1819 pass_last_set_time
= convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass
));
1821 user_rid
= pdb_get_user_rid(sampass
);
1822 group_rid
= pdb_get_group_rid(sampass
);
1824 username
= pdb_get_username(sampass
);
1826 username_len
= strlen(username
) +1;
1831 domain
= pdb_get_domain(sampass
);
1833 domain_len
= strlen(domain
) +1;
1838 nt_username
= pdb_get_nt_username(sampass
);
1840 nt_username_len
= strlen(nt_username
) +1;
1842 nt_username_len
= 0;
1845 fullname
= pdb_get_fullname(sampass
);
1847 fullname_len
= strlen(fullname
) +1;
1853 * Only updates fields which have been set (not defaults from smb.conf)
1856 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1857 dir_drive
= pdb_get_dir_drive(sampass
);
1862 dir_drive_len
= strlen(dir_drive
) +1;
1867 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1868 homedir
= pdb_get_homedir(sampass
);
1873 homedir_len
= strlen(homedir
) +1;
1878 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1879 logon_script
= pdb_get_logon_script(sampass
);
1881 logon_script
= NULL
;
1884 logon_script_len
= strlen(logon_script
) +1;
1886 logon_script_len
= 0;
1889 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1890 profile_path
= pdb_get_profile_path(sampass
);
1892 profile_path
= NULL
;
1895 profile_path_len
= strlen(profile_path
) +1;
1897 profile_path_len
= 0;
1900 lm_pw
= pdb_get_lanman_passwd(sampass
);
1905 nt_pw
= pdb_get_nt_passwd(sampass
);
1910 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1911 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1912 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1913 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1918 acct_desc
= pdb_get_acct_desc(sampass
);
1920 acct_desc_len
= strlen(acct_desc
) +1;
1925 workstations
= pdb_get_workstations(sampass
);
1927 workstations_len
= strlen(workstations
) +1;
1929 workstations_len
= 0;
1932 comment
= pdb_get_comment(sampass
);
1934 comment_len
= strlen(comment
) +1;
1939 munged_dial
= pdb_get_munged_dial(sampass
);
1941 munged_dial_len
= strlen(munged_dial
) +1;
1943 munged_dial_len
= 0;
1946 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1948 /* one time to get the size needed */
1949 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1951 logoff_time
, /* d */
1952 kickoff_time
, /* d */
1953 bad_password_time
, /* d */
1954 pass_last_set_time
, /* d */
1955 pass_can_change_time
, /* d */
1956 pass_must_change_time
, /* d */
1957 username_len
, username
, /* B */
1958 domain_len
, domain
, /* B */
1959 nt_username_len
, nt_username
, /* B */
1960 fullname_len
, fullname
, /* B */
1961 homedir_len
, homedir
, /* B */
1962 dir_drive_len
, dir_drive
, /* B */
1963 logon_script_len
, logon_script
, /* B */
1964 profile_path_len
, profile_path
, /* B */
1965 acct_desc_len
, acct_desc
, /* B */
1966 workstations_len
, workstations
, /* B */
1967 comment_len
, comment
, /* B */
1968 munged_dial_len
, munged_dial
, /* B */
1971 lm_pw_len
, lm_pw
, /* B */
1972 nt_pw_len
, nt_pw
, /* B */
1973 nt_pw_hist_len
, nt_pw_hist
, /* B */
1974 pdb_get_acct_ctrl(sampass
), /* d */
1975 pdb_get_logon_divs(sampass
), /* w */
1976 pdb_get_hours_len(sampass
), /* d */
1977 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1978 pdb_get_bad_password_count(sampass
), /* w */
1979 pdb_get_logon_count(sampass
), /* w */
1980 pdb_get_unknown_6(sampass
)); /* d */
1986 /* malloc the space needed */
1987 if ( (*buf
=(uint8_t*)SMB_MALLOC(len
)) == NULL
) {
1988 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
1992 /* now for the real call to tdb_pack() */
1993 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
1995 logoff_time
, /* d */
1996 kickoff_time
, /* d */
1997 bad_password_time
, /* d */
1998 pass_last_set_time
, /* d */
1999 pass_can_change_time
, /* d */
2000 pass_must_change_time
, /* d */
2001 username_len
, username
, /* B */
2002 domain_len
, domain
, /* B */
2003 nt_username_len
, nt_username
, /* B */
2004 fullname_len
, fullname
, /* B */
2005 homedir_len
, homedir
, /* B */
2006 dir_drive_len
, dir_drive
, /* B */
2007 logon_script_len
, logon_script
, /* B */
2008 profile_path_len
, profile_path
, /* B */
2009 acct_desc_len
, acct_desc
, /* B */
2010 workstations_len
, workstations
, /* B */
2011 comment_len
, comment
, /* B */
2012 munged_dial_len
, munged_dial
, /* B */
2015 lm_pw_len
, lm_pw
, /* B */
2016 nt_pw_len
, nt_pw
, /* B */
2017 nt_pw_hist_len
, nt_pw_hist
, /* B */
2018 pdb_get_acct_ctrl(sampass
), /* d */
2019 pdb_get_logon_divs(sampass
), /* w */
2020 pdb_get_hours_len(sampass
), /* d */
2021 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2022 pdb_get_bad_password_count(sampass
), /* w */
2023 pdb_get_logon_count(sampass
), /* w */
2024 pdb_get_unknown_6(sampass
)); /* d */
2026 /* check to make sure we got it correct */
2027 if (buflen
!= len
) {
2028 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2029 (unsigned long)buflen
, (unsigned long)len
));
2038 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
2040 /* nothing changed between V3 and V4 */
2041 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2044 static uint32_t init_buffer_from_samu_v4(uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2046 /* nothing changed between V3 and V4 */
2047 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2050 /**********************************************************************
2051 Intialize a struct samu struct from a BYTE buffer of size len
2052 *********************************************************************/
2054 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2055 uint8_t *buf
, uint32_t buflen
)
2058 case SAMU_BUFFER_V0
:
2059 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2060 case SAMU_BUFFER_V1
:
2061 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2062 case SAMU_BUFFER_V2
:
2063 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2064 case SAMU_BUFFER_V3
:
2065 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2066 case SAMU_BUFFER_V4
:
2067 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2073 /**********************************************************************
2074 Intialize a BYTE buffer from a struct samu struct
2075 *********************************************************************/
2077 uint32_t init_buffer_from_samu (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2079 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2082 /*********************************************************************
2083 *********************************************************************/
2085 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2087 uint8_t *buf
= NULL
;
2090 len
= init_buffer_from_samu(&buf
, src
, False
);
2091 if (len
== -1 || !buf
) {
2096 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2101 dst
->methods
= src
->methods
;
2103 if ( src
->unix_pw
) {
2104 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2105 if (!dst
->unix_pw
) {
2111 if (src
->group_sid
) {
2112 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2119 /*********************************************************************
2120 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2121 *********************************************************************/
2123 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2125 time_t LastBadPassword
;
2126 uint16_t BadPasswordCount
;
2130 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2131 if (!BadPasswordCount
) {
2132 DEBUG(9, ("No bad password attempts.\n"));
2137 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2141 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2145 /* First, check if there is a reset time to compare */
2146 if ((resettime
== (uint32_t) -1) || (resettime
== 0)) {
2147 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2151 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2152 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2153 (uint32_t) LastBadPassword
, resettime
, (uint32_t)time(NULL
)));
2154 if (time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(resettime
)*60)){
2155 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2156 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2165 /*********************************************************************
2166 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2167 *********************************************************************/
2169 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2172 time_t LastBadPassword
;
2175 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2176 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2177 pdb_get_username(sampass
)));
2182 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2186 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2190 /* First, check if there is a duration to compare */
2191 if ((duration
== (uint32_t) -1) || (duration
== 0)) {
2192 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2196 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2197 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2198 pdb_get_username(sampass
), (uint32_t)LastBadPassword
, duration
*60, (uint32_t)time(NULL
)));
2200 if (LastBadPassword
== (time_t)0) {
2201 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2202 "administratively locked out with no bad password "
2203 "time. Leaving locked out.\n",
2204 pdb_get_username(sampass
) ));
2208 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(duration
) * 60))) {
2209 pdb_set_acct_ctrl(sampass
,
2210 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2212 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2213 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2222 /*********************************************************************
2223 Increment the bad_password_count
2224 *********************************************************************/
2226 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2228 uint32_t account_policy_lockout
;
2229 bool autolock_updated
= False
, badpw_updated
= False
;
2232 /* Retrieve the account lockout policy */
2234 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2237 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2241 /* If there is no policy, we don't need to continue checking */
2242 if (!account_policy_lockout
) {
2243 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2247 /* Check if the autolock needs to be cleared */
2248 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2251 /* Check if the badpw count needs to be reset */
2252 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2256 Ok, now we can assume that any resetting that needs to be
2257 done has been done, and just get on with incrementing
2258 and autolocking if necessary
2261 pdb_set_bad_password_count(sampass
,
2262 pdb_get_bad_password_count(sampass
)+1,
2264 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2267 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2270 if (!pdb_set_acct_ctrl(sampass
,
2271 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2273 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2280 bool is_dc_trusted_domain_situation(const char *domain_name
)
2282 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2285 /*******************************************************************
2286 Wrapper around retrieving the clear text trust account password.
2287 appropriate account name is stored in account_name.
2288 Caller must free password, but not account_name.
2289 *******************************************************************/
2291 static bool get_trust_pw_clear2(const char *domain
,
2292 const char **account_name
,
2293 enum netr_SchannelType
*channel
,
2295 time_t *_last_set_time
,
2299 time_t last_set_time
;
2301 if (cur_pw
!= NULL
) {
2304 if (_last_set_time
!= NULL
) {
2305 *_last_set_time
= 0;
2307 if (prev_pw
!= NULL
) {
2311 /* if we are a DC and this is not our domain, then lookup an account
2312 * for the domain trust */
2314 if (is_dc_trusted_domain_situation(domain
)) {
2315 if (!lp_allow_trusted_domains()) {
2319 if (!pdb_get_trusteddom_pw(domain
, cur_pw
, NULL
,
2322 DEBUG(0, ("get_trust_pw: could not fetch trust "
2323 "account password for trusted domain %s\n",
2328 if (channel
!= NULL
) {
2329 *channel
= SEC_CHAN_DOMAIN
;
2332 if (account_name
!= NULL
) {
2333 *account_name
= lp_workgroup();
2336 if (_last_set_time
!= NULL
) {
2337 *_last_set_time
= last_set_time
;
2344 * Since we can only be member of one single domain, we are now
2345 * in a member situation:
2347 * - Either we are a DC (selfjoined) and the domain is our
2349 * - Or we are on a member and the domain is our own or some
2350 * other (potentially trusted) domain.
2352 * In both cases, we can only get the machine account password
2353 * for our own domain to connect to our own dc. (For a member,
2354 * request to trusted domains are performed through our dc.)
2356 * So we simply use our own domain name to retrieve the
2357 * machine account passowrd and ignore the request domain here.
2360 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2363 struct timeval expire
;
2367 if (account_name
!= NULL
) {
2368 *account_name
= lp_netbios_name();
2371 if (_last_set_time
!= NULL
) {
2372 *_last_set_time
= last_set_time
;
2375 if (prev_pw
== NULL
) {
2379 ZERO_STRUCT(expire
);
2380 expire
.tv_sec
= lp_machine_password_timeout();
2382 expire
.tv_sec
+= last_set_time
;
2383 if (timeval_expired(&expire
)) {
2387 pwd
= secrets_fetch_prev_machine_password(lp_workgroup());
2395 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2396 "account password for domain %s\n", domain
));
2400 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2401 const char **account_name
,
2402 enum netr_SchannelType
*channel
)
2404 return get_trust_pw_clear2(domain
,
2412 /*******************************************************************
2413 Wrapper around retrieving the trust account password.
2414 appropriate account name is stored in account_name.
2415 *******************************************************************/
2417 static bool get_trust_pw_hash2(const char *domain
,
2418 const char **account_name
,
2419 enum netr_SchannelType
*channel
,
2420 struct samr_Password
*current_nt_hash
,
2421 time_t *last_set_time
,
2422 struct samr_Password
**_previous_nt_hash
)
2424 char *cur_pw
= NULL
;
2425 char *prev_pw
= NULL
;
2426 char **_prev_pw
= NULL
;
2429 if (_previous_nt_hash
!= NULL
) {
2430 *_previous_nt_hash
= NULL
;
2431 _prev_pw
= &prev_pw
;
2434 ok
= get_trust_pw_clear2(domain
, account_name
, channel
,
2435 &cur_pw
, last_set_time
, _prev_pw
);
2437 struct samr_Password
*previous_nt_hash
= NULL
;
2439 E_md4hash(cur_pw
, current_nt_hash
->hash
);
2442 if (prev_pw
== NULL
) {
2446 previous_nt_hash
= SMB_MALLOC_P(struct samr_Password
);
2447 if (previous_nt_hash
== NULL
) {
2451 E_md4hash(prev_pw
, previous_nt_hash
->hash
);
2454 *_previous_nt_hash
= previous_nt_hash
;
2456 } else if (is_dc_trusted_domain_situation(domain
)) {
2460 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2462 if (secrets_fetch_trust_account_password_legacy(domain
,
2463 current_nt_hash
->hash
,
2467 if (account_name
!= NULL
) {
2468 *account_name
= lp_netbios_name();
2474 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2475 "password for domain %s\n", domain
));
2479 bool get_trust_pw_hash(const char *domain
, uint8_t ret_pwd
[16],
2480 const char **account_name
,
2481 enum netr_SchannelType
*channel
)
2483 struct samr_Password current_nt_hash
;
2486 ok
= get_trust_pw_hash2(domain
, account_name
, channel
,
2487 ¤t_nt_hash
, NULL
, NULL
);
2492 memcpy(ret_pwd
, current_nt_hash
.hash
, sizeof(current_nt_hash
.hash
));
2496 NTSTATUS
pdb_get_trust_credentials(const char *netbios_domain
,
2497 const char *dns_domain
, /* optional */
2498 TALLOC_CTX
*mem_ctx
,
2499 struct cli_credentials
**_creds
)
2501 TALLOC_CTX
*frame
= talloc_stackframe();
2503 struct loadparm_context
*lp_ctx
;
2504 enum netr_SchannelType channel
;
2505 time_t last_set_time
;
2506 const char *_account_name
;
2507 const char *account_name
;
2508 char *cur_pw
= NULL
;
2509 char *prev_pw
= NULL
;
2510 struct samr_Password cur_nt_hash
;
2511 struct cli_credentials
*creds
= NULL
;
2515 * If this is our primary trust relationship, use the common
2516 * code to read the secrets.ldb or secrets.tdb file.
2518 if (strequal(netbios_domain
, lp_workgroup())) {
2519 struct db_context
*db_ctx
= secrets_db_ctx();
2520 if (db_ctx
== NULL
) {
2521 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2523 status
= NT_STATUS_INTERNAL_ERROR
;
2527 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2528 if (lp_ctx
== NULL
) {
2529 DEBUG(1, ("loadparm_init_s3 failed\n"));
2530 status
= NT_STATUS_INTERNAL_ERROR
;
2534 creds
= cli_credentials_init(mem_ctx
);
2535 if (creds
== NULL
) {
2536 status
= NT_STATUS_NO_MEMORY
;
2540 cli_credentials_set_conf(creds
, lp_ctx
);
2542 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2544 status
= NT_STATUS_NO_MEMORY
;
2548 status
= cli_credentials_set_machine_account_db_ctx(creds
,
2551 if (!NT_STATUS_IS_OK(status
)) {
2555 } else if (!IS_DC
) {
2556 DEBUG(1, ("Refusing to get trust account info for %s, "
2557 "which is not our primary domain %s, "
2558 "as we are not a DC\n",
2559 netbios_domain
, lp_workgroup()));
2560 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2564 status
= pdb_get_trusteddom_creds(netbios_domain
, mem_ctx
, &creds
);
2565 if (NT_STATUS_IS_OK(status
)) {
2568 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
2572 ok
= get_trust_pw_clear2(netbios_domain
,
2579 ok
= get_trust_pw_hash2(netbios_domain
,
2586 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2588 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2593 account_name
= talloc_asprintf(frame
, "%s$", _account_name
);
2594 if (account_name
== NULL
) {
2595 status
= NT_STATUS_NO_MEMORY
;
2599 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2600 if (lp_ctx
== NULL
) {
2601 DEBUG(1, ("loadparm_init_s3 failed\n"));
2602 status
= NT_STATUS_INTERNAL_ERROR
;
2606 creds
= cli_credentials_init(mem_ctx
);
2607 if (creds
== NULL
) {
2608 status
= NT_STATUS_NO_MEMORY
;
2612 cli_credentials_set_conf(creds
, lp_ctx
);
2614 cli_credentials_set_secure_channel_type(creds
, channel
);
2615 cli_credentials_set_password_last_changed_time(creds
, last_set_time
);
2617 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2619 status
= NT_STATUS_NO_MEMORY
;
2623 if (dns_domain
!= NULL
) {
2624 ok
= cli_credentials_set_realm(creds
, dns_domain
, CRED_SPECIFIED
);
2626 status
= NT_STATUS_NO_MEMORY
;
2631 * It's not possible to use NTLMSSP with a domain trust account.
2633 cli_credentials_set_kerberos_state(creds
, CRED_MUST_USE_KERBEROS
);
2636 * We can't use kerberos against an NT4 domain.
2638 * We should have a mode that also disallows NTLMSSP here,
2639 * as only NETLOGON SCHANNEL is possible.
2641 cli_credentials_set_kerberos_state(creds
, CRED_DONT_USE_KERBEROS
);
2644 ok
= cli_credentials_set_username(creds
, account_name
, CRED_SPECIFIED
);
2646 status
= NT_STATUS_NO_MEMORY
;
2650 if (cur_pw
== NULL
) {
2651 ok
= cli_credentials_set_nt_hash(creds
, &cur_nt_hash
, CRED_SPECIFIED
);
2653 status
= NT_STATUS_NO_MEMORY
;
2657 * We currently can't do kerberos just with an NTHASH.
2659 cli_credentials_set_kerberos_state(creds
, CRED_DONT_USE_KERBEROS
);
2663 ok
= cli_credentials_set_password(creds
, cur_pw
, CRED_SPECIFIED
);
2665 status
= NT_STATUS_NO_MEMORY
;
2669 if (prev_pw
!= NULL
) {
2670 ok
= cli_credentials_set_old_password(creds
, prev_pw
, CRED_SPECIFIED
);
2672 status
= NT_STATUS_NO_MEMORY
;
2680 status
= NT_STATUS_OK
;