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"
36 #include "source3/lib/substitute.h"
39 #define DBGC_CLASS DBGC_PASSDB
41 /**********************************************************************
42 ***********************************************************************/
44 static int samu_destroy(struct samu
*user
)
46 data_blob_clear_free( &user
->lm_pw
);
47 data_blob_clear_free( &user
->nt_pw
);
49 if ( user
->plaintext_pw
)
50 BURN_STR(user
->plaintext_pw
);
55 /**********************************************************************
56 generate a new struct samuser
57 ***********************************************************************/
59 struct samu
*samu_new( TALLOC_CTX
*ctx
)
63 if ( !(user
= talloc_zero( ctx
, struct samu
)) ) {
64 DEBUG(0,("samuser_new: Talloc failed!\n"));
68 talloc_set_destructor( user
, samu_destroy
);
70 /* no initial methods */
74 /* Don't change these timestamp settings without a good reason.
75 They are important for NT member server compatibility. */
77 user
->logon_time
= (time_t)0;
78 user
->pass_last_set_time
= (time_t)0;
79 user
->pass_can_change_time
= (time_t)0;
80 user
->logoff_time
= get_time_t_max();
81 user
->kickoff_time
= get_time_t_max();
82 user
->fields_present
= 0x00ffffff;
83 user
->logon_divs
= 168; /* hours per week */
84 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
85 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
86 user
->bad_password_count
= 0;
87 user
->logon_count
= 0;
88 user
->unknown_6
= 0x000004ec; /* don't know */
90 /* Some parts of samba strlen their pdb_get...() returns,
91 so this keeps the interface unchanged for now. */
95 user
->nt_username
= "";
98 user
->logon_script
= "";
99 user
->profile_path
= "";
100 user
->acct_desc
= "";
101 user
->workstations
= "";
103 user
->munged_dial
= "";
105 user
->plaintext_pw
= NULL
;
107 /* Unless we know otherwise have a Account Control Bit
108 value of 'normal user'. This helps User Manager, which
109 asks for a filtered list of users. */
111 user
->acct_ctrl
= ACB_NORMAL
;
116 static int count_commas(const char *str
)
119 const char *comma
= str
;
121 while ((comma
= strchr(comma
, ',')) != NULL
) {
128 /*********************************************************************
129 Initialize a struct samu from a struct passwd including the user
130 and group SIDs. The *user structure is filled out with the Unix
131 attributes and a user SID.
132 *********************************************************************/
134 static NTSTATUS
samu_set_unix_internal(struct pdb_methods
*methods
,
135 struct samu
*user
, const struct passwd
*pwd
, bool create
)
137 const char *guest_account
= lp_guest_account();
138 const char *domain
= lp_netbios_name();
144 return NT_STATUS_NO_SUCH_USER
;
147 /* Basic properties based upon the Unix account information */
149 ok
= pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
151 return NT_STATUS_NO_MEMORY
;
156 if (count_commas(pwd
->pw_gecos
) == 3) {
158 * Heuristic: This seems to be a gecos field that has been
159 * edited by chfn(1). Only use the part before the first
160 * comma. Fixes bug 5198.
162 fullname
= talloc_strndup(
163 talloc_tos(), pwd
->pw_gecos
,
164 strchr(pwd
->pw_gecos
, ',') - pwd
->pw_gecos
);
165 if (fullname
== NULL
) {
166 return NT_STATUS_NO_MEMORY
;
170 if (fullname
!= NULL
) {
171 ok
= pdb_set_fullname(user
, fullname
, PDB_SET
);
173 ok
= pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
175 TALLOC_FREE(fullname
);
178 return NT_STATUS_NO_MEMORY
;
181 ok
= pdb_set_domain(user
, get_global_sam_name(), PDB_DEFAULT
);
183 return NT_STATUS_NO_MEMORY
;
186 /* This can lead to a primary group of S-1-22-2-XX which
187 will be rejected by other parts of the Samba code.
188 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
191 gid_to_sid(&group_sid
, pwd
->pw_gid
);
192 pdb_set_group_sid(user
, &group_sid
, PDB_SET
);
195 /* save the password structure for later use */
197 user
->unix_pw
= tcopy_passwd( user
, pwd
);
198 if (user
->unix_pw
== NULL
) {
199 return NT_STATUS_NO_MEMORY
;
202 /* Special case for the guest account which must have a RID of 501 */
204 if ( strequal( pwd
->pw_name
, guest_account
) ) {
205 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_RID_GUEST
, PDB_DEFAULT
)) {
206 return NT_STATUS_NO_SUCH_USER
;
211 /* Non-guest accounts...Check for a workstation or user account */
213 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
216 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
217 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
219 return NT_STATUS_INVALID_COMPUTER_NAME
;
225 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
226 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
228 return NT_STATUS_INVALID_ACCOUNT_NAME
;
231 /* set some basic attributes */
233 ok
= pdb_set_profile_path(
235 talloc_sub_specified(
244 ok
&= pdb_set_homedir(
246 talloc_sub_specified(
255 ok
&= pdb_set_dir_drive(
257 talloc_sub_specified(
266 ok
&= pdb_set_logon_script(
268 talloc_sub_specified(
278 return NT_STATUS_NO_MEMORY
;
282 /* Now deal with the user SID. If we have a backend that can generate
283 RIDs, then do so. But sometimes the caller just wanted a structure
284 initialized and will fill in these fields later (such as from a
285 netr_SamInfo3 structure) */
287 if ( create
&& (methods
->capabilities(methods
) & PDB_CAP_STORE_RIDS
)) {
289 struct dom_sid user_sid
;
291 if ( !methods
->new_rid(methods
, &user_rid
) ) {
292 DEBUG(3, ("Could not allocate a new RID\n"));
293 return NT_STATUS_ACCESS_DENIED
;
296 sid_compose(&user_sid
, get_global_sam_sid(), user_rid
);
298 if ( !pdb_set_user_sid(user
, &user_sid
, PDB_SET
) ) {
299 DEBUG(3, ("pdb_set_user_sid failed\n"));
300 return NT_STATUS_INTERNAL_ERROR
;
306 /* generate a SID for the user with the RID algorithm */
308 urid
= algorithmic_pdb_uid_to_user_rid( user
->unix_pw
->pw_uid
);
310 if ( !pdb_set_user_sid_from_rid( user
, urid
, PDB_SET
) ) {
311 return NT_STATUS_INTERNAL_ERROR
;
317 /********************************************************************
318 Set the Unix user attributes
319 ********************************************************************/
321 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
323 return samu_set_unix_internal( NULL
, user
, pwd
, False
);
326 NTSTATUS
samu_alloc_rid_unix(struct pdb_methods
*methods
,
327 struct samu
*user
, const struct passwd
*pwd
)
329 return samu_set_unix_internal( methods
, user
, pwd
, True
);
332 /**********************************************************
333 Encode the account control bits into a string.
334 length = length of string to encode into (including terminating
335 null). length *MUST BE MORE THAN 2* !
336 **********************************************************/
338 char *pdb_encode_acct_ctrl(uint32_t acct_ctrl
, size_t length
)
345 SMB_ASSERT(length
<= sizeof(acct_str
));
349 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
350 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
351 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
352 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
353 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
354 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
355 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
356 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
357 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
358 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
359 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
361 for ( ; i
< length
- 2 ; i
++ )
366 acct_str
[i
++] = '\0';
368 result
= talloc_strdup(talloc_tos(), acct_str
);
369 SMB_ASSERT(result
!= NULL
);
373 /**********************************************************
374 Decode the account control bits from a string.
375 **********************************************************/
377 uint32_t pdb_decode_acct_ctrl(const char *p
)
379 uint32_t acct_ctrl
= 0;
380 bool finished
= false;
383 * Check if the account type bits have been encoded after the
384 * NT password (in the form [NDHTUWSLXI]).
390 for (p
++; *p
&& !finished
; p
++) {
392 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
393 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
394 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
395 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
396 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
397 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
398 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
399 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
400 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
401 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
402 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
408 default: { finished
= true; }
415 /*************************************************************
416 Routine to set 32 hex password characters from a 16 byte array.
417 **************************************************************/
419 void pdb_sethexpwd(char p
[33], const unsigned char *pwd
, uint32_t acct_ctrl
)
422 hex_encode_buf(p
, pwd
, 16);
424 if (acct_ctrl
& ACB_PWNOTREQ
)
425 strlcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
427 strlcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
431 /*************************************************************
432 Routine to get the 32 hex characters and turn them
433 into a 16 byte array.
434 **************************************************************/
436 bool pdb_gethexpwd(const char *p
, unsigned char *pwd
)
439 unsigned char lonybble
, hinybble
;
440 const char *hexchars
= "0123456789ABCDEF";
446 for (i
= 0; i
< 32; i
+= 2) {
447 hinybble
= toupper_m(p
[i
]);
448 lonybble
= toupper_m(p
[i
+ 1]);
450 p1
= strchr(hexchars
, hinybble
);
451 p2
= strchr(hexchars
, lonybble
);
456 hinybble
= PTR_DIFF(p1
, hexchars
);
457 lonybble
= PTR_DIFF(p2
, hexchars
);
459 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
464 /*************************************************************
465 Routine to set 42 hex hours characters from a 21 byte array.
466 **************************************************************/
468 void pdb_sethexhours(char *p
, const unsigned char *hours
)
471 hex_encode_buf(p
, hours
, 21);
473 strlcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
477 /*************************************************************
478 Routine to get the 42 hex characters and turn them
479 into a 21 byte array.
480 **************************************************************/
482 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
485 unsigned char lonybble
, hinybble
;
486 const char *hexchars
= "0123456789ABCDEF";
493 for (i
= 0; i
< 42; i
+= 2) {
494 hinybble
= toupper_m(p
[i
]);
495 lonybble
= toupper_m(p
[i
+ 1]);
497 p1
= strchr(hexchars
, hinybble
);
498 p2
= strchr(hexchars
, lonybble
);
504 hinybble
= PTR_DIFF(p1
, hexchars
);
505 lonybble
= PTR_DIFF(p2
, hexchars
);
507 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
512 /********************************************************************
513 ********************************************************************/
515 int algorithmic_rid_base(void)
519 rid_offset
= lp_algorithmic_rid_base();
521 if (rid_offset
< BASE_RID
) {
522 /* Try to prevent admin foot-shooting, we can't put algorithmic
523 rids below 1000, that's the 'well known RIDs' on NT */
524 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
525 rid_offset
= BASE_RID
;
527 if (rid_offset
& 1) {
528 DEBUG(0, ("algorithmic rid base must be even\n"));
534 /*******************************************************************
535 Converts NT user RID to a UNIX uid.
536 ********************************************************************/
538 uid_t
algorithmic_pdb_user_rid_to_uid(uint32_t user_rid
)
540 int rid_offset
= algorithmic_rid_base();
541 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
544 uid_t
max_algorithmic_uid(void)
546 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
549 /*******************************************************************
550 converts UNIX uid to an NT User RID.
551 ********************************************************************/
553 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid
)
555 int rid_offset
= algorithmic_rid_base();
556 return (((((uint32_t)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
559 /*******************************************************************
560 Converts NT group RID to a UNIX gid.
561 ********************************************************************/
563 gid_t
pdb_group_rid_to_gid(uint32_t group_rid
)
565 int rid_offset
= algorithmic_rid_base();
566 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
569 gid_t
max_algorithmic_gid(void)
571 return pdb_group_rid_to_gid(0xffffffff);
574 /*******************************************************************
575 converts NT Group RID to a UNIX uid.
577 warning: you must not call that function only
578 you must do a call to the group mapping first.
579 there is not anymore a direct link between the gid and the rid.
580 ********************************************************************/
582 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid
)
584 int rid_offset
= algorithmic_rid_base();
585 return (((((uint32_t)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
588 /*******************************************************************
589 Decides if a RID is a well known RID.
590 ********************************************************************/
592 static bool rid_is_well_known(uint32_t rid
)
594 /* Not using rid_offset here, because this is the actual
595 NT fixed value (1000) */
597 return (rid
< BASE_RID
);
600 /*******************************************************************
601 Decides if a RID is a user or group RID.
602 ********************************************************************/
604 bool algorithmic_pdb_rid_is_user(uint32_t rid
)
606 if ( rid_is_well_known(rid
) ) {
608 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
609 * and DOMAIN_RID_GUEST.
611 if(rid
== DOMAIN_RID_ADMINISTRATOR
|| rid
== DOMAIN_RID_GUEST
)
613 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
619 /*******************************************************************
620 Convert a name into a SID. Used in the lookup name rpc.
621 ********************************************************************/
623 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
624 enum lsa_SidType
*type
)
629 /* Windows treats "MACHINE\None" as a special name for
630 rid 513 on non-DCs. You cannot create a user or group
631 name "None" on Windows. You will get an error that
632 the group already exists. */
634 if ( strequal( name
, "None" ) ) {
635 *rid
= DOMAIN_RID_USERS
;
636 *type
= SID_NAME_DOM_GRP
;
641 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
642 * correctly in the case where foo also exists as a user. If the flag
643 * is set, don't look for users at all. */
645 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
646 struct samu
*sam_account
= NULL
;
647 struct dom_sid user_sid
;
649 if ( !(sam_account
= samu_new( NULL
)) ) {
654 ret
= pdb_getsampwnam(sam_account
, name
);
658 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
661 TALLOC_FREE(sam_account
);
664 if (!sid_check_is_in_our_sam(&user_sid
)) {
665 struct dom_sid_buf buf
;
666 DBG_ERR("User %s with invalid SID %s"
669 dom_sid_str_buf(&user_sid
, &buf
));
673 sid_peek_rid(&user_sid
, rid
);
674 *type
= SID_NAME_USER
;
680 * Maybe it is a group ?
683 map
= talloc_zero(NULL
, GROUP_MAP
);
689 ret
= pdb_getgrnam(map
, name
);
697 /* BUILTIN groups are looked up elsewhere */
698 if (!sid_check_is_in_our_sam(&map
->sid
)) {
699 struct dom_sid_buf buf
;
700 DEBUG(10, ("Found group %s (%s) not in our domain -- "
703 dom_sid_str_buf(&map
->sid
, &buf
)));
708 /* yes it's a mapped group */
709 sid_peek_rid(&map
->sid
, rid
);
710 *type
= map
->sid_name_use
;
715 /*************************************************************
716 Change a password entry in the local passdb backend.
719 - always called as root
720 - ignores the account type except when adding a new account
721 - will create/delete the unix account if the relative
722 add/delete user script is configured
724 *************************************************************/
726 NTSTATUS
local_password_change(const char *user_name
,
728 const char *new_passwd
,
733 struct samu
*sam_pass
;
743 tosctx
= talloc_tos();
745 sam_pass
= samu_new(tosctx
);
747 result
= NT_STATUS_NO_MEMORY
;
751 /* Get the smb passwd entry for this user */
752 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
754 /* Check delete first, we don't need to do anything else if we
755 * are going to delete the account */
756 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
758 result
= pdb_delete_user(tosctx
, sam_pass
);
759 if (!NT_STATUS_IS_OK(result
)) {
760 ret
= asprintf(pp_err_str
,
761 "Failed to delete entry for user %s.\n",
766 result
= NT_STATUS_UNSUCCESSFUL
;
768 ret
= asprintf(pp_msg_str
,
769 "Deleted user %s.\n",
778 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
779 /* the entry already existed */
780 local_flags
&= ~LOCAL_ADD_USER
;
783 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
784 ret
= asprintf(pp_err_str
,
785 "Failed to find entry for user %s.\n",
790 result
= NT_STATUS_NO_SUCH_USER
;
794 /* First thing add the new user if we are required to do so */
795 if (local_flags
& LOCAL_ADD_USER
) {
797 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
799 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
805 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
806 if (!NT_STATUS_IS_OK(result
)) {
807 ret
= asprintf(pp_err_str
,
808 "Failed to add entry for user %s.\n",
813 result
= NT_STATUS_UNSUCCESSFUL
;
817 sam_pass
= samu_new(tosctx
);
819 result
= NT_STATUS_NO_MEMORY
;
823 /* Now get back the smb passwd entry for this new user */
824 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
826 ret
= asprintf(pp_err_str
,
827 "Failed to add entry for user %s.\n",
832 result
= NT_STATUS_UNSUCCESSFUL
;
837 acb
= pdb_get_acct_ctrl(sam_pass
);
840 * We are root - just write the new password
841 * and the valid last change time.
843 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
845 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
846 ret
= asprintf(pp_err_str
,
847 "Failed to set 'no password required' "
848 "flag for user %s.\n", user_name
);
852 result
= NT_STATUS_UNSUCCESSFUL
;
857 if (local_flags
& LOCAL_SET_PASSWORD
) {
859 * If we're dealing with setting a completely empty user account
860 * ie. One with a password of 'XXXX', but not set disabled (like
861 * an account created from scratch) then if the old password was
862 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
863 * We remove that as we're giving this user their first password
864 * and the decision hasn't really been made to disable them (ie.
865 * don't create them disabled). JRA.
867 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
868 (acb
& ACB_DISABLED
)) {
869 acb
&= (~ACB_DISABLED
);
870 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
871 ret
= asprintf(pp_err_str
,
872 "Failed to unset 'disabled' "
873 "flag for user %s.\n",
878 result
= NT_STATUS_UNSUCCESSFUL
;
883 acb
&= (~ACB_PWNOTREQ
);
884 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
885 ret
= asprintf(pp_err_str
,
886 "Failed to unset 'no password required'"
887 " flag for user %s.\n", user_name
);
891 result
= NT_STATUS_UNSUCCESSFUL
;
895 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
896 ret
= asprintf(pp_err_str
,
897 "Failed to set password for "
898 "user %s.\n", user_name
);
902 result
= NT_STATUS_UNSUCCESSFUL
;
907 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
909 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
910 ret
= asprintf(pp_err_str
,
911 "Failed to set 'disabled' flag for "
912 "user %s.\n", user_name
);
916 result
= NT_STATUS_UNSUCCESSFUL
;
921 if ((local_flags
& LOCAL_ENABLE_USER
) && (acb
& ACB_DISABLED
)) {
922 acb
&= (~ACB_DISABLED
);
923 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
924 ret
= asprintf(pp_err_str
,
925 "Failed to unset 'disabled' flag for "
926 "user %s.\n", user_name
);
930 result
= NT_STATUS_UNSUCCESSFUL
;
935 /* now commit changes if any */
936 result
= pdb_update_sam_account(sam_pass
);
937 if (!NT_STATUS_IS_OK(result
)) {
938 ret
= asprintf(pp_err_str
,
939 "Failed to modify entry for user %s.\n",
947 if (local_flags
& LOCAL_ADD_USER
) {
948 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
949 } else if (local_flags
& LOCAL_DISABLE_USER
) {
950 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
951 } else if (local_flags
& LOCAL_ENABLE_USER
) {
952 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
953 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
954 ret
= asprintf(pp_msg_str
,
955 "User %s password set to none.\n", user_name
);
962 result
= NT_STATUS_OK
;
965 TALLOC_FREE(sam_pass
);
969 /**********************************************************************
970 Marshall/unmarshall struct samu structs.
971 *********************************************************************/
973 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
974 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
975 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
976 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
977 /* nothing changed between V3 and V4 */
979 /*********************************************************************
980 *********************************************************************/
982 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
985 /* times are stored as 32bit integer
986 take care on system with 64bit wide time_t
992 pass_can_change_time
,
993 pass_must_change_time
;
994 char *username
= NULL
;
996 char *nt_username
= NULL
;
997 char *dir_drive
= NULL
;
998 char *unknown_str
= NULL
;
999 char *munged_dial
= NULL
;
1000 char *fullname
= NULL
;
1001 char *homedir
= NULL
;
1002 char *logon_script
= NULL
;
1003 char *profile_path
= NULL
;
1004 char *acct_desc
= NULL
;
1005 char *workstations
= NULL
;
1006 uint32_t username_len
, domain_len
, nt_username_len
,
1007 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1008 fullname_len
, homedir_len
, logon_script_len
,
1009 profile_path_len
, acct_desc_len
, workstations_len
;
1011 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1012 uint16_t acct_ctrl
, logon_divs
;
1013 uint16_t bad_password_count
, logon_count
;
1014 uint8_t *hours
= NULL
;
1015 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1017 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1020 if(sampass
== NULL
|| buf
== NULL
) {
1021 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
1025 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1027 /* unpack the buffer into variables */
1028 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
1029 &logon_time
, /* d */
1030 &logoff_time
, /* d */
1031 &kickoff_time
, /* d */
1032 &pass_last_set_time
, /* d */
1033 &pass_can_change_time
, /* d */
1034 &pass_must_change_time
, /* d */
1035 &username_len
, &username
, /* B */
1036 &domain_len
, &domain
, /* B */
1037 &nt_username_len
, &nt_username
, /* B */
1038 &fullname_len
, &fullname
, /* B */
1039 &homedir_len
, &homedir
, /* B */
1040 &dir_drive_len
, &dir_drive
, /* B */
1041 &logon_script_len
, &logon_script
, /* B */
1042 &profile_path_len
, &profile_path
, /* B */
1043 &acct_desc_len
, &acct_desc
, /* B */
1044 &workstations_len
, &workstations
, /* B */
1045 &unknown_str_len
, &unknown_str
, /* B */
1046 &munged_dial_len
, &munged_dial
, /* B */
1049 &lm_pw_len
, &lm_pw_ptr
, /* B */
1050 &nt_pw_len
, &nt_pw_ptr
, /* B */
1052 &remove_me
, /* remove on the next TDB_FORMAT upgarde */ /* d */
1053 &logon_divs
, /* w */
1055 &hourslen
, &hours
, /* B */
1056 &bad_password_count
, /* w */
1057 &logon_count
, /* w */
1058 &unknown_6
); /* d */
1060 if (len
== (uint32_t) -1) {
1065 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1066 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1067 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1068 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1069 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1071 pdb_set_username(sampass
, username
, PDB_SET
);
1072 pdb_set_domain(sampass
, domain
, PDB_SET
);
1073 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1074 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1077 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1080 pdb_set_homedir(sampass
,
1081 talloc_sub_basic(sampass
, username
, domain
,
1087 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1089 pdb_set_dir_drive(sampass
,
1090 talloc_sub_basic(sampass
, username
, domain
,
1096 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1098 pdb_set_logon_script(sampass
,
1099 talloc_sub_basic(sampass
, username
, domain
,
1105 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1107 pdb_set_profile_path(sampass
,
1108 talloc_sub_basic(sampass
, username
, domain
,
1113 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1114 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1115 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1117 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1118 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1124 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1125 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1131 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1132 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1133 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1134 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1135 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1136 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1137 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1138 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1139 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1140 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1144 SAFE_FREE(username
);
1146 SAFE_FREE(nt_username
);
1147 SAFE_FREE(fullname
);
1149 SAFE_FREE(dir_drive
);
1150 SAFE_FREE(logon_script
);
1151 SAFE_FREE(profile_path
);
1152 SAFE_FREE(acct_desc
);
1153 SAFE_FREE(workstations
);
1154 SAFE_FREE(munged_dial
);
1155 SAFE_FREE(unknown_str
);
1156 SAFE_FREE(lm_pw_ptr
);
1157 SAFE_FREE(nt_pw_ptr
);
1163 /*********************************************************************
1164 *********************************************************************/
1166 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1169 /* times are stored as 32bit integer
1170 take care on system with 64bit wide time_t
1172 uint32_t logon_time
,
1177 pass_can_change_time
,
1178 pass_must_change_time
;
1179 char *username
= NULL
;
1180 char *domain
= NULL
;
1181 char *nt_username
= NULL
;
1182 char *dir_drive
= NULL
;
1183 char *unknown_str
= NULL
;
1184 char *munged_dial
= NULL
;
1185 char *fullname
= NULL
;
1186 char *homedir
= NULL
;
1187 char *logon_script
= NULL
;
1188 char *profile_path
= NULL
;
1189 char *acct_desc
= NULL
;
1190 char *workstations
= NULL
;
1191 uint32_t username_len
, domain_len
, nt_username_len
,
1192 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1193 fullname_len
, homedir_len
, logon_script_len
,
1194 profile_path_len
, acct_desc_len
, workstations_len
;
1196 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1197 uint16_t acct_ctrl
, logon_divs
;
1198 uint16_t bad_password_count
, logon_count
;
1199 uint8_t *hours
= NULL
;
1200 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1202 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1205 if(sampass
== NULL
|| buf
== NULL
) {
1206 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1210 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1212 /* unpack the buffer into variables */
1213 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1214 &logon_time
, /* d */
1215 &logoff_time
, /* d */
1216 &kickoff_time
, /* d */
1217 /* Change from V0 is addition of bad_password_time field. */
1218 &bad_password_time
, /* d */
1219 &pass_last_set_time
, /* d */
1220 &pass_can_change_time
, /* d */
1221 &pass_must_change_time
, /* d */
1222 &username_len
, &username
, /* B */
1223 &domain_len
, &domain
, /* B */
1224 &nt_username_len
, &nt_username
, /* B */
1225 &fullname_len
, &fullname
, /* B */
1226 &homedir_len
, &homedir
, /* B */
1227 &dir_drive_len
, &dir_drive
, /* B */
1228 &logon_script_len
, &logon_script
, /* B */
1229 &profile_path_len
, &profile_path
, /* B */
1230 &acct_desc_len
, &acct_desc
, /* B */
1231 &workstations_len
, &workstations
, /* B */
1232 &unknown_str_len
, &unknown_str
, /* B */
1233 &munged_dial_len
, &munged_dial
, /* B */
1236 &lm_pw_len
, &lm_pw_ptr
, /* B */
1237 &nt_pw_len
, &nt_pw_ptr
, /* B */
1240 &logon_divs
, /* w */
1242 &hourslen
, &hours
, /* B */
1243 &bad_password_count
, /* w */
1244 &logon_count
, /* w */
1245 &unknown_6
); /* d */
1247 if (len
== (uint32_t) -1) {
1252 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1253 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1254 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1256 /* Change from V0 is addition of bad_password_time field. */
1257 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1258 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1259 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1261 pdb_set_username(sampass
, username
, PDB_SET
);
1262 pdb_set_domain(sampass
, domain
, PDB_SET
);
1263 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1264 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1267 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1270 pdb_set_homedir(sampass
,
1271 talloc_sub_basic(sampass
, username
, domain
,
1277 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1279 pdb_set_dir_drive(sampass
,
1280 talloc_sub_basic(sampass
, username
, domain
,
1286 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1288 pdb_set_logon_script(sampass
,
1289 talloc_sub_basic(sampass
, username
, domain
,
1295 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1297 pdb_set_profile_path(sampass
,
1298 talloc_sub_basic(sampass
, username
, domain
,
1303 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1304 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1305 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1307 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1308 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1314 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1315 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1321 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1323 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1324 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1325 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1326 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1327 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1328 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1329 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1330 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1331 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1335 SAFE_FREE(username
);
1337 SAFE_FREE(nt_username
);
1338 SAFE_FREE(fullname
);
1340 SAFE_FREE(dir_drive
);
1341 SAFE_FREE(logon_script
);
1342 SAFE_FREE(profile_path
);
1343 SAFE_FREE(acct_desc
);
1344 SAFE_FREE(workstations
);
1345 SAFE_FREE(munged_dial
);
1346 SAFE_FREE(unknown_str
);
1347 SAFE_FREE(lm_pw_ptr
);
1348 SAFE_FREE(nt_pw_ptr
);
1354 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1357 /* times are stored as 32bit integer
1358 take care on system with 64bit wide time_t
1360 uint32_t logon_time
,
1365 pass_can_change_time
,
1366 pass_must_change_time
;
1367 char *username
= NULL
;
1368 char *domain
= NULL
;
1369 char *nt_username
= NULL
;
1370 char *dir_drive
= NULL
;
1371 char *unknown_str
= NULL
;
1372 char *munged_dial
= NULL
;
1373 char *fullname
= NULL
;
1374 char *homedir
= NULL
;
1375 char *logon_script
= NULL
;
1376 char *profile_path
= NULL
;
1377 char *acct_desc
= NULL
;
1378 char *workstations
= NULL
;
1379 uint32_t username_len
, domain_len
, nt_username_len
,
1380 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1381 fullname_len
, homedir_len
, logon_script_len
,
1382 profile_path_len
, acct_desc_len
, workstations_len
;
1384 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
;
1385 uint16_t acct_ctrl
, logon_divs
;
1386 uint16_t bad_password_count
, logon_count
;
1387 uint8_t *hours
= NULL
;
1388 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1390 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1391 uint32_t pwHistLen
= 0;
1394 bool expand_explicit
= lp_passdb_expand_explicit();
1396 if(sampass
== NULL
|| buf
== NULL
) {
1397 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1401 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1403 /* unpack the buffer into variables */
1404 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1405 &logon_time
, /* d */
1406 &logoff_time
, /* d */
1407 &kickoff_time
, /* d */
1408 &bad_password_time
, /* d */
1409 &pass_last_set_time
, /* d */
1410 &pass_can_change_time
, /* d */
1411 &pass_must_change_time
, /* d */
1412 &username_len
, &username
, /* B */
1413 &domain_len
, &domain
, /* B */
1414 &nt_username_len
, &nt_username
, /* B */
1415 &fullname_len
, &fullname
, /* B */
1416 &homedir_len
, &homedir
, /* B */
1417 &dir_drive_len
, &dir_drive
, /* B */
1418 &logon_script_len
, &logon_script
, /* B */
1419 &profile_path_len
, &profile_path
, /* B */
1420 &acct_desc_len
, &acct_desc
, /* B */
1421 &workstations_len
, &workstations
, /* B */
1422 &unknown_str_len
, &unknown_str
, /* B */
1423 &munged_dial_len
, &munged_dial
, /* B */
1426 &lm_pw_len
, &lm_pw_ptr
, /* B */
1427 &nt_pw_len
, &nt_pw_ptr
, /* B */
1428 /* Change from V1 is addition of password history field. */
1429 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1431 /* Also "remove_me" field was removed. */
1432 &logon_divs
, /* w */
1434 &hourslen
, &hours
, /* B */
1435 &bad_password_count
, /* w */
1436 &logon_count
, /* w */
1437 &unknown_6
); /* d */
1439 if (len
== (uint32_t) -1) {
1444 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1445 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1446 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1447 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1448 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1449 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1451 pdb_set_username(sampass
, username
, PDB_SET
);
1452 pdb_set_domain(sampass
, domain
, PDB_SET
);
1453 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1454 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1457 fstrcpy( tmp_string
, homedir
);
1458 if (expand_explicit
) {
1459 standard_sub_basic( username
, domain
, tmp_string
,
1460 sizeof(tmp_string
) );
1462 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1465 pdb_set_homedir(sampass
,
1466 talloc_sub_basic(sampass
, username
, domain
,
1472 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1474 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1477 fstrcpy( tmp_string
, logon_script
);
1478 if (expand_explicit
) {
1479 standard_sub_basic( username
, domain
, tmp_string
,
1480 sizeof(tmp_string
) );
1482 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1485 pdb_set_logon_script(sampass
,
1486 talloc_sub_basic(sampass
, username
, domain
,
1492 fstrcpy( tmp_string
, profile_path
);
1493 if (expand_explicit
) {
1494 standard_sub_basic( username
, domain
, tmp_string
,
1495 sizeof(tmp_string
) );
1497 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1500 pdb_set_profile_path(sampass
,
1501 talloc_sub_basic(sampass
, username
, domain
,
1506 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1507 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1508 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1510 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1511 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1517 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1518 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1524 /* Change from V1 is addition of password history field. */
1525 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1527 uint8_t *pw_hist
= SMB_MALLOC_ARRAY(uint8_t, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1532 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1533 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1535 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1536 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1537 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1538 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1539 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1540 PW_HISTORY_ENTRY_LEN
);
1543 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1550 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1553 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1554 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1555 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1556 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1557 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1558 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1559 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1560 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1561 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1565 SAFE_FREE(username
);
1567 SAFE_FREE(nt_username
);
1568 SAFE_FREE(fullname
);
1570 SAFE_FREE(dir_drive
);
1571 SAFE_FREE(logon_script
);
1572 SAFE_FREE(profile_path
);
1573 SAFE_FREE(acct_desc
);
1574 SAFE_FREE(workstations
);
1575 SAFE_FREE(munged_dial
);
1576 SAFE_FREE(unknown_str
);
1577 SAFE_FREE(lm_pw_ptr
);
1578 SAFE_FREE(nt_pw_ptr
);
1579 SAFE_FREE(nt_pw_hist_ptr
);
1585 /*********************************************************************
1586 *********************************************************************/
1588 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1591 /* times are stored as 32bit integer
1592 take care on system with 64bit wide time_t
1594 uint32_t logon_time
,
1599 pass_can_change_time
,
1600 pass_must_change_time
;
1601 char *username
= NULL
;
1602 char *domain
= NULL
;
1603 char *nt_username
= NULL
;
1604 char *dir_drive
= NULL
;
1605 char *comment
= NULL
;
1606 char *munged_dial
= NULL
;
1607 char *fullname
= NULL
;
1608 char *homedir
= NULL
;
1609 char *logon_script
= NULL
;
1610 char *profile_path
= NULL
;
1611 char *acct_desc
= NULL
;
1612 char *workstations
= NULL
;
1613 uint32_t username_len
, domain_len
, nt_username_len
,
1614 dir_drive_len
, comment_len
, munged_dial_len
,
1615 fullname_len
, homedir_len
, logon_script_len
,
1616 profile_path_len
, acct_desc_len
, workstations_len
;
1618 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1619 uint16_t logon_divs
;
1620 uint16_t bad_password_count
, logon_count
;
1621 uint8_t *hours
= NULL
;
1622 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1624 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1625 uint32_t pwHistLen
= 0;
1628 bool expand_explicit
= lp_passdb_expand_explicit();
1630 if(sampass
== NULL
|| buf
== NULL
) {
1631 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1635 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1637 /* unpack the buffer into variables */
1638 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1639 &logon_time
, /* d */
1640 &logoff_time
, /* d */
1641 &kickoff_time
, /* d */
1642 &bad_password_time
, /* d */
1643 &pass_last_set_time
, /* d */
1644 &pass_can_change_time
, /* d */
1645 &pass_must_change_time
, /* d */
1646 &username_len
, &username
, /* B */
1647 &domain_len
, &domain
, /* B */
1648 &nt_username_len
, &nt_username
, /* B */
1649 &fullname_len
, &fullname
, /* B */
1650 &homedir_len
, &homedir
, /* B */
1651 &dir_drive_len
, &dir_drive
, /* B */
1652 &logon_script_len
, &logon_script
, /* B */
1653 &profile_path_len
, &profile_path
, /* B */
1654 &acct_desc_len
, &acct_desc
, /* B */
1655 &workstations_len
, &workstations
, /* B */
1656 &comment_len
, &comment
, /* B */
1657 &munged_dial_len
, &munged_dial
, /* B */
1660 &lm_pw_len
, &lm_pw_ptr
, /* B */
1661 &nt_pw_len
, &nt_pw_ptr
, /* B */
1662 /* Change from V1 is addition of password history field. */
1663 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1664 /* Change from V2 is the uint32_t acb_mask */
1666 /* Also "remove_me" field was removed. */
1667 &logon_divs
, /* w */
1669 &hourslen
, &hours
, /* B */
1670 &bad_password_count
, /* w */
1671 &logon_count
, /* w */
1672 &unknown_6
); /* d */
1674 if (len
== (uint32_t) -1) {
1679 pdb_set_logon_time(sampass
, convert_uint32_t_to_time_t(logon_time
), PDB_SET
);
1680 pdb_set_logoff_time(sampass
, convert_uint32_t_to_time_t(logoff_time
), PDB_SET
);
1681 pdb_set_kickoff_time(sampass
, convert_uint32_t_to_time_t(kickoff_time
), PDB_SET
);
1682 pdb_set_bad_password_time(sampass
, convert_uint32_t_to_time_t(bad_password_time
), PDB_SET
);
1683 pdb_set_pass_can_change_time(sampass
, convert_uint32_t_to_time_t(pass_can_change_time
), PDB_SET
);
1684 pdb_set_pass_last_set_time(sampass
, convert_uint32_t_to_time_t(pass_last_set_time
), PDB_SET
);
1686 pdb_set_username(sampass
, username
, PDB_SET
);
1687 pdb_set_domain(sampass
, domain
, PDB_SET
);
1688 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1689 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1692 fstrcpy( tmp_string
, homedir
);
1693 if (expand_explicit
) {
1694 standard_sub_basic( username
, domain
, tmp_string
,
1695 sizeof(tmp_string
) );
1697 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1700 pdb_set_homedir(sampass
,
1701 talloc_sub_basic(sampass
, username
, domain
,
1707 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1709 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1712 fstrcpy( tmp_string
, logon_script
);
1713 if (expand_explicit
) {
1714 standard_sub_basic( username
, domain
, tmp_string
,
1715 sizeof(tmp_string
) );
1717 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1720 pdb_set_logon_script(sampass
,
1721 talloc_sub_basic(sampass
, username
, domain
,
1727 fstrcpy( tmp_string
, profile_path
);
1728 if (expand_explicit
) {
1729 standard_sub_basic( username
, domain
, tmp_string
,
1730 sizeof(tmp_string
) );
1732 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1735 pdb_set_profile_path(sampass
,
1736 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1740 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1741 pdb_set_comment(sampass
, comment
, PDB_SET
);
1742 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1743 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1745 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1746 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1752 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1753 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1759 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1761 uint8_t *pw_hist
= (uint8_t *)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1766 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1767 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1769 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1770 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1771 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1772 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1773 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1774 PW_HISTORY_ENTRY_LEN
);
1777 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1784 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1787 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1788 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1789 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1790 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1791 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1792 /* Change from V2 is the uint32_t acct_ctrl */
1793 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1794 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1795 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1799 SAFE_FREE(username
);
1801 SAFE_FREE(nt_username
);
1802 SAFE_FREE(fullname
);
1804 SAFE_FREE(dir_drive
);
1805 SAFE_FREE(logon_script
);
1806 SAFE_FREE(profile_path
);
1807 SAFE_FREE(acct_desc
);
1808 SAFE_FREE(workstations
);
1809 SAFE_FREE(munged_dial
);
1811 SAFE_FREE(lm_pw_ptr
);
1812 SAFE_FREE(nt_pw_ptr
);
1813 SAFE_FREE(nt_pw_hist_ptr
);
1819 /*********************************************************************
1820 *********************************************************************/
1822 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
1826 /* times are stored as 32bit integer
1827 take care on system with 64bit wide time_t
1829 uint32_t logon_time
,
1834 pass_can_change_time
,
1835 pass_must_change_time
;
1837 uint32_t user_rid
, group_rid
;
1839 const char *username
;
1841 const char *nt_username
;
1842 const char *dir_drive
;
1843 const char *comment
;
1844 const char *munged_dial
;
1845 const char *fullname
;
1846 const char *homedir
;
1847 const char *logon_script
;
1848 const char *profile_path
;
1849 const char *acct_desc
;
1850 const char *workstations
;
1851 uint32_t username_len
, domain_len
, nt_username_len
,
1852 dir_drive_len
, comment_len
, munged_dial_len
,
1853 fullname_len
, homedir_len
, logon_script_len
,
1854 profile_path_len
, acct_desc_len
, workstations_len
;
1856 const uint8_t *lm_pw
;
1857 const uint8_t *nt_pw
;
1858 const uint8_t *nt_pw_hist
;
1859 uint32_t lm_pw_len
= 16;
1860 uint32_t nt_pw_len
= 16;
1861 uint32_t nt_pw_hist_len
;
1862 uint32_t pwHistLen
= 0;
1867 logon_time
= convert_time_t_to_uint32_t(pdb_get_logon_time(sampass
));
1868 logoff_time
= convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass
));
1869 kickoff_time
= convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass
));
1870 bad_password_time
= convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass
));
1871 pass_can_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass
));
1872 pass_must_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass
));
1873 pass_last_set_time
= convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass
));
1875 user_rid
= pdb_get_user_rid(sampass
);
1876 group_rid
= pdb_get_group_rid(sampass
);
1878 username
= pdb_get_username(sampass
);
1880 username_len
= strlen(username
) +1;
1885 domain
= pdb_get_domain(sampass
);
1887 domain_len
= strlen(domain
) +1;
1892 nt_username
= pdb_get_nt_username(sampass
);
1894 nt_username_len
= strlen(nt_username
) +1;
1896 nt_username_len
= 0;
1899 fullname
= pdb_get_fullname(sampass
);
1901 fullname_len
= strlen(fullname
) +1;
1907 * Only updates fields which have been set (not defaults from smb.conf)
1910 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1911 dir_drive
= pdb_get_dir_drive(sampass
);
1916 dir_drive_len
= strlen(dir_drive
) +1;
1921 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1922 homedir
= pdb_get_homedir(sampass
);
1927 homedir_len
= strlen(homedir
) +1;
1932 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1933 logon_script
= pdb_get_logon_script(sampass
);
1935 logon_script
= NULL
;
1938 logon_script_len
= strlen(logon_script
) +1;
1940 logon_script_len
= 0;
1943 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1944 profile_path
= pdb_get_profile_path(sampass
);
1946 profile_path
= NULL
;
1949 profile_path_len
= strlen(profile_path
) +1;
1951 profile_path_len
= 0;
1954 lm_pw
= pdb_get_lanman_passwd(sampass
);
1959 nt_pw
= pdb_get_nt_passwd(sampass
);
1964 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1965 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1966 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1967 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1972 acct_desc
= pdb_get_acct_desc(sampass
);
1974 acct_desc_len
= strlen(acct_desc
) +1;
1979 workstations
= pdb_get_workstations(sampass
);
1981 workstations_len
= strlen(workstations
) +1;
1983 workstations_len
= 0;
1986 comment
= pdb_get_comment(sampass
);
1988 comment_len
= strlen(comment
) +1;
1993 munged_dial
= pdb_get_munged_dial(sampass
);
1995 munged_dial_len
= strlen(munged_dial
) +1;
1997 munged_dial_len
= 0;
2000 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
2002 /* one time to get the size needed */
2003 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
2005 logoff_time
, /* d */
2006 kickoff_time
, /* d */
2007 bad_password_time
, /* d */
2008 pass_last_set_time
, /* d */
2009 pass_can_change_time
, /* d */
2010 pass_must_change_time
, /* d */
2011 username_len
, username
, /* B */
2012 domain_len
, domain
, /* B */
2013 nt_username_len
, nt_username
, /* B */
2014 fullname_len
, fullname
, /* B */
2015 homedir_len
, homedir
, /* B */
2016 dir_drive_len
, dir_drive
, /* B */
2017 logon_script_len
, logon_script
, /* B */
2018 profile_path_len
, profile_path
, /* B */
2019 acct_desc_len
, acct_desc
, /* B */
2020 workstations_len
, workstations
, /* B */
2021 comment_len
, comment
, /* B */
2022 munged_dial_len
, munged_dial
, /* B */
2025 lm_pw_len
, lm_pw
, /* B */
2026 nt_pw_len
, nt_pw
, /* B */
2027 nt_pw_hist_len
, nt_pw_hist
, /* B */
2028 pdb_get_acct_ctrl(sampass
), /* d */
2029 pdb_get_logon_divs(sampass
), /* w */
2030 pdb_get_hours_len(sampass
), /* d */
2031 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2032 pdb_get_bad_password_count(sampass
), /* w */
2033 pdb_get_logon_count(sampass
), /* w */
2034 pdb_get_unknown_6(sampass
)); /* d */
2040 /* malloc the space needed */
2041 if ( (*buf
=(uint8_t*)SMB_MALLOC(len
)) == NULL
) {
2042 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2046 /* now for the real call to tdb_pack() */
2047 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
2049 logoff_time
, /* d */
2050 kickoff_time
, /* d */
2051 bad_password_time
, /* d */
2052 pass_last_set_time
, /* d */
2053 pass_can_change_time
, /* d */
2054 pass_must_change_time
, /* d */
2055 username_len
, username
, /* B */
2056 domain_len
, domain
, /* B */
2057 nt_username_len
, nt_username
, /* B */
2058 fullname_len
, fullname
, /* B */
2059 homedir_len
, homedir
, /* B */
2060 dir_drive_len
, dir_drive
, /* B */
2061 logon_script_len
, logon_script
, /* B */
2062 profile_path_len
, profile_path
, /* B */
2063 acct_desc_len
, acct_desc
, /* B */
2064 workstations_len
, workstations
, /* B */
2065 comment_len
, comment
, /* B */
2066 munged_dial_len
, munged_dial
, /* B */
2069 lm_pw_len
, lm_pw
, /* B */
2070 nt_pw_len
, nt_pw
, /* B */
2071 nt_pw_hist_len
, nt_pw_hist
, /* B */
2072 pdb_get_acct_ctrl(sampass
), /* d */
2073 pdb_get_logon_divs(sampass
), /* w */
2074 pdb_get_hours_len(sampass
), /* d */
2075 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2076 pdb_get_bad_password_count(sampass
), /* w */
2077 pdb_get_logon_count(sampass
), /* w */
2078 pdb_get_unknown_6(sampass
)); /* d */
2080 /* check to make sure we got it correct */
2081 if (buflen
!= len
) {
2082 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2083 (unsigned long)buflen
, (unsigned long)len
));
2092 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
2094 /* nothing changed between V3 and V4 */
2095 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2098 static uint32_t init_buffer_from_samu_v4(uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2100 /* nothing changed between V3 and V4 */
2101 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2104 /**********************************************************************
2105 Intialize a struct samu struct from a BYTE buffer of size len
2106 *********************************************************************/
2108 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2109 uint8_t *buf
, uint32_t buflen
)
2112 case SAMU_BUFFER_V0
:
2113 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2114 case SAMU_BUFFER_V1
:
2115 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2116 case SAMU_BUFFER_V2
:
2117 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2118 case SAMU_BUFFER_V3
:
2119 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2120 case SAMU_BUFFER_V4
:
2121 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2127 /**********************************************************************
2128 Intialize a BYTE buffer from a struct samu struct
2129 *********************************************************************/
2131 uint32_t init_buffer_from_samu (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2133 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2136 /*********************************************************************
2137 *********************************************************************/
2139 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2141 uint8_t *buf
= NULL
;
2144 len
= init_buffer_from_samu(&buf
, src
, False
);
2145 if (len
== -1 || !buf
) {
2150 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2155 dst
->methods
= src
->methods
;
2157 if ( src
->unix_pw
) {
2158 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2159 if (!dst
->unix_pw
) {
2165 if (src
->group_sid
) {
2166 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2173 /*********************************************************************
2174 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2175 *********************************************************************/
2177 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2179 time_t LastBadPassword
;
2180 uint16_t BadPasswordCount
;
2184 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2185 if (!BadPasswordCount
) {
2186 DEBUG(9, ("No bad password attempts.\n"));
2191 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2195 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2199 /* First, check if there is a reset time to compare */
2200 if ((resettime
== (uint32_t) -1) || (resettime
== 0)) {
2201 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2205 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2206 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2207 (uint32_t) LastBadPassword
, resettime
, (uint32_t)time(NULL
)));
2208 if (time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(resettime
)*60)){
2209 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2210 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2219 /*********************************************************************
2220 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2221 *********************************************************************/
2223 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2226 time_t LastBadPassword
;
2229 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2230 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2231 pdb_get_username(sampass
)));
2236 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2240 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2244 /* First, check if there is a duration to compare */
2245 if ((duration
== (uint32_t) -1) || (duration
== 0)) {
2246 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2250 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2251 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2252 pdb_get_username(sampass
), (uint32_t)LastBadPassword
, duration
*60, (uint32_t)time(NULL
)));
2254 if (LastBadPassword
== (time_t)0) {
2255 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2256 "administratively locked out with no bad password "
2257 "time. Leaving locked out.\n",
2258 pdb_get_username(sampass
) ));
2262 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(duration
) * 60))) {
2263 pdb_set_acct_ctrl(sampass
,
2264 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2266 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2267 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2276 /*********************************************************************
2277 Increment the bad_password_count
2278 *********************************************************************/
2280 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2282 uint32_t account_policy_lockout
;
2283 bool autolock_updated
= False
, badpw_updated
= False
;
2286 /* Retrieve the account lockout policy */
2288 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2291 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2295 /* If there is no policy, we don't need to continue checking */
2296 if (!account_policy_lockout
) {
2297 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2301 /* Check if the autolock needs to be cleared */
2302 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2305 /* Check if the badpw count needs to be reset */
2306 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2310 Ok, now we can assume that any resetting that needs to be
2311 done has been done, and just get on with incrementing
2312 and autolocking if necessary
2315 pdb_set_bad_password_count(sampass
,
2316 pdb_get_bad_password_count(sampass
)+1,
2318 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2321 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2324 if (!pdb_set_acct_ctrl(sampass
,
2325 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2327 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2334 bool is_dc_trusted_domain_situation(const char *domain_name
)
2336 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2339 /*******************************************************************
2340 Wrapper around retrieving the clear text trust account password.
2341 appropriate account name is stored in account_name.
2342 Caller must free password, but not account_name.
2343 *******************************************************************/
2345 static bool get_trust_pw_clear2(const char *domain
,
2346 const char **account_name
,
2347 enum netr_SchannelType
*channel
,
2349 time_t *_last_set_time
,
2353 time_t last_set_time
;
2355 if (cur_pw
!= NULL
) {
2358 if (_last_set_time
!= NULL
) {
2359 *_last_set_time
= 0;
2361 if (prev_pw
!= NULL
) {
2365 /* if we are a DC and this is not our domain, then lookup an account
2366 * for the domain trust */
2368 if (is_dc_trusted_domain_situation(domain
)) {
2369 if (!lp_allow_trusted_domains()) {
2373 if (!pdb_get_trusteddom_pw(domain
, cur_pw
, NULL
,
2376 DEBUG(0, ("get_trust_pw: could not fetch trust "
2377 "account password for trusted domain %s\n",
2382 if (channel
!= NULL
) {
2383 *channel
= SEC_CHAN_DOMAIN
;
2386 if (account_name
!= NULL
) {
2387 *account_name
= lp_workgroup();
2390 if (_last_set_time
!= NULL
) {
2391 *_last_set_time
= last_set_time
;
2398 * Since we can only be member of one single domain, we are now
2399 * in a member situation:
2401 * - Either we are a DC (selfjoined) and the domain is our
2403 * - Or we are on a member and the domain is our own or some
2404 * other (potentially trusted) domain.
2406 * In both cases, we can only get the machine account password
2407 * for our own domain to connect to our own dc. (For a member,
2408 * request to trusted domains are performed through our dc.)
2410 * So we simply use our own domain name to retrieve the
2411 * machine account passowrd and ignore the request domain here.
2414 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2417 struct timeval expire
;
2421 if (account_name
!= NULL
) {
2422 *account_name
= lp_netbios_name();
2425 if (_last_set_time
!= NULL
) {
2426 *_last_set_time
= last_set_time
;
2429 if (prev_pw
== NULL
) {
2433 ZERO_STRUCT(expire
);
2434 expire
.tv_sec
= lp_machine_password_timeout();
2436 expire
.tv_sec
+= last_set_time
;
2437 if (timeval_expired(&expire
)) {
2441 pwd
= secrets_fetch_prev_machine_password(lp_workgroup());
2449 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2450 "account password for domain %s\n", domain
));
2454 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2455 const char **account_name
,
2456 enum netr_SchannelType
*channel
)
2458 return get_trust_pw_clear2(domain
,
2466 /*******************************************************************
2467 Wrapper around retrieving the trust account password.
2468 appropriate account name is stored in account_name.
2469 *******************************************************************/
2471 static bool get_trust_pw_hash2(const char *domain
,
2472 const char **account_name
,
2473 enum netr_SchannelType
*channel
,
2474 struct samr_Password
*current_nt_hash
,
2475 time_t *last_set_time
,
2476 struct samr_Password
**_previous_nt_hash
)
2478 char *cur_pw
= NULL
;
2479 char *prev_pw
= NULL
;
2480 char **_prev_pw
= NULL
;
2483 if (_previous_nt_hash
!= NULL
) {
2484 *_previous_nt_hash
= NULL
;
2485 _prev_pw
= &prev_pw
;
2488 ok
= get_trust_pw_clear2(domain
, account_name
, channel
,
2489 &cur_pw
, last_set_time
, _prev_pw
);
2491 struct samr_Password
*previous_nt_hash
= NULL
;
2493 E_md4hash(cur_pw
, current_nt_hash
->hash
);
2494 BURN_FREE_STR(cur_pw
);
2496 if (prev_pw
== NULL
) {
2500 previous_nt_hash
= SMB_MALLOC_P(struct samr_Password
);
2501 if (previous_nt_hash
== NULL
) {
2505 E_md4hash(prev_pw
, previous_nt_hash
->hash
);
2506 BURN_FREE_STR(prev_pw
);
2508 *_previous_nt_hash
= previous_nt_hash
;
2510 } else if (is_dc_trusted_domain_situation(domain
)) {
2514 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2516 if (secrets_fetch_trust_account_password_legacy(domain
,
2517 current_nt_hash
->hash
,
2521 if (account_name
!= NULL
) {
2522 *account_name
= lp_netbios_name();
2528 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2529 "password for domain %s\n", domain
));
2533 bool get_trust_pw_hash(const char *domain
, uint8_t ret_pwd
[16],
2534 const char **account_name
,
2535 enum netr_SchannelType
*channel
)
2537 struct samr_Password current_nt_hash
;
2540 ok
= get_trust_pw_hash2(domain
, account_name
, channel
,
2541 ¤t_nt_hash
, NULL
, NULL
);
2546 memcpy(ret_pwd
, current_nt_hash
.hash
, sizeof(current_nt_hash
.hash
));
2550 NTSTATUS
pdb_get_trust_credentials(const char *netbios_domain
,
2551 const char *dns_domain
, /* optional */
2552 TALLOC_CTX
*mem_ctx
,
2553 struct cli_credentials
**_creds
)
2555 TALLOC_CTX
*frame
= talloc_stackframe();
2557 struct loadparm_context
*lp_ctx
;
2558 enum netr_SchannelType channel
;
2559 time_t last_set_time
;
2560 const char *_account_name
;
2561 const char *account_name
;
2562 char *cur_pw
= NULL
;
2563 char *prev_pw
= NULL
;
2564 struct samr_Password cur_nt_hash
;
2565 struct cli_credentials
*creds
= NULL
;
2569 * If this is our primary trust relationship, use the common
2570 * code to read the secrets.ldb or secrets.tdb file.
2572 if (strequal(netbios_domain
, lp_workgroup())) {
2573 struct db_context
*db_ctx
= secrets_db_ctx();
2574 if (db_ctx
== NULL
) {
2575 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2577 status
= NT_STATUS_INTERNAL_ERROR
;
2581 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2582 if (lp_ctx
== NULL
) {
2583 DEBUG(1, ("loadparm_init_s3 failed\n"));
2584 status
= NT_STATUS_INTERNAL_ERROR
;
2588 creds
= cli_credentials_init(mem_ctx
);
2589 if (creds
== NULL
) {
2590 status
= NT_STATUS_NO_MEMORY
;
2594 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2596 status
= NT_STATUS_INTERNAL_ERROR
;
2600 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2602 status
= NT_STATUS_NO_MEMORY
;
2606 status
= cli_credentials_set_machine_account_db_ctx(creds
,
2609 if (!NT_STATUS_IS_OK(status
)) {
2613 } else if (!IS_DC
) {
2614 DEBUG(1, ("Refusing to get trust account info for %s, "
2615 "which is not our primary domain %s, "
2616 "as we are not a DC\n",
2617 netbios_domain
, lp_workgroup()));
2618 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2622 status
= pdb_get_trusteddom_creds(netbios_domain
, mem_ctx
, &creds
);
2623 if (NT_STATUS_IS_OK(status
)) {
2626 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
2630 ok
= get_trust_pw_clear2(netbios_domain
,
2637 ok
= get_trust_pw_hash2(netbios_domain
,
2644 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2646 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2651 account_name
= talloc_asprintf(frame
, "%s$", _account_name
);
2652 if (account_name
== NULL
) {
2653 status
= NT_STATUS_NO_MEMORY
;
2657 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2658 if (lp_ctx
== NULL
) {
2659 DEBUG(1, ("loadparm_init_s3 failed\n"));
2660 status
= NT_STATUS_INTERNAL_ERROR
;
2664 creds
= cli_credentials_init(mem_ctx
);
2665 if (creds
== NULL
) {
2666 status
= NT_STATUS_NO_MEMORY
;
2670 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2672 status
= NT_STATUS_INTERNAL_ERROR
;
2676 cli_credentials_set_secure_channel_type(creds
, channel
);
2677 cli_credentials_set_password_last_changed_time(creds
, last_set_time
);
2679 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2681 status
= NT_STATUS_NO_MEMORY
;
2685 if (dns_domain
!= NULL
) {
2686 ok
= cli_credentials_set_realm(creds
, dns_domain
, CRED_SPECIFIED
);
2688 status
= NT_STATUS_NO_MEMORY
;
2693 * It's not possible to use NTLMSSP with a domain trust account.
2695 cli_credentials_set_kerberos_state(creds
,
2696 CRED_USE_KERBEROS_REQUIRED
,
2700 * We can't use kerberos against an NT4 domain.
2702 * We should have a mode that also disallows NTLMSSP here,
2703 * as only NETLOGON SCHANNEL is possible.
2705 cli_credentials_set_kerberos_state(creds
,
2706 CRED_USE_KERBEROS_DISABLED
,
2710 ok
= cli_credentials_set_username(creds
, account_name
, CRED_SPECIFIED
);
2712 status
= NT_STATUS_NO_MEMORY
;
2716 if (cur_pw
== NULL
) {
2717 ok
= cli_credentials_set_nt_hash(creds
, &cur_nt_hash
, CRED_SPECIFIED
);
2719 status
= NT_STATUS_NO_MEMORY
;
2723 * We currently can't do kerberos just with an NTHASH.
2725 cli_credentials_set_kerberos_state(creds
,
2726 CRED_USE_KERBEROS_DISABLED
,
2731 ok
= cli_credentials_set_password(creds
, cur_pw
, CRED_SPECIFIED
);
2733 status
= NT_STATUS_NO_MEMORY
;
2737 if (prev_pw
!= NULL
) {
2738 ok
= cli_credentials_set_old_password(creds
, prev_pw
, CRED_SPECIFIED
);
2740 status
= NT_STATUS_NO_MEMORY
;
2748 status
= NT_STATUS_OK
;