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
)
443 for (i
= 0; i
< 32; i
+= 2) {
444 bool ok
= hex_byte(p
+ i
, &pwd
[i
/ 2]);
452 /*************************************************************
453 Routine to set 42 hex hours characters from a 21 byte array.
454 **************************************************************/
456 void pdb_sethexhours(char *p
, const unsigned char *hours
)
459 hex_encode_buf(p
, hours
, 21);
461 strlcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
465 /*************************************************************
466 Routine to get the 42 hex characters and turn them
467 into a 21 byte array.
468 **************************************************************/
470 bool pdb_gethexhours(const char *p
, unsigned char *hours
)
478 for (i
= 0; i
< 42; i
+= 2) {
479 bool ok
= hex_byte(p
, (uint8_t *)&hours
[i
/ 2]);
487 /********************************************************************
488 ********************************************************************/
490 int algorithmic_rid_base(void)
494 rid_offset
= lp_algorithmic_rid_base();
496 if (rid_offset
< BASE_RID
) {
497 /* Try to prevent admin foot-shooting, we can't put algorithmic
498 rids below 1000, that's the 'well known RIDs' on NT */
499 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
500 rid_offset
= BASE_RID
;
502 if (rid_offset
& 1) {
503 DEBUG(0, ("algorithmic rid base must be even\n"));
509 /*******************************************************************
510 Converts NT user RID to a UNIX uid.
511 ********************************************************************/
513 uid_t
algorithmic_pdb_user_rid_to_uid(uint32_t user_rid
)
515 int rid_offset
= algorithmic_rid_base();
516 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
519 uid_t
max_algorithmic_uid(void)
521 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
524 /*******************************************************************
525 converts UNIX uid to an NT User RID.
526 ********************************************************************/
528 uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid
)
530 int rid_offset
= algorithmic_rid_base();
531 return (((((uint32_t)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
534 /*******************************************************************
535 Converts NT group RID to a UNIX gid.
536 ********************************************************************/
538 gid_t
pdb_group_rid_to_gid(uint32_t group_rid
)
540 int rid_offset
= algorithmic_rid_base();
541 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
544 gid_t
max_algorithmic_gid(void)
546 return pdb_group_rid_to_gid(0xffffffff);
549 /*******************************************************************
550 converts NT Group RID to a UNIX uid.
552 warning: you must not call that function only
553 you must do a call to the group mapping first.
554 there is not anymore a direct link between the gid and the rid.
555 ********************************************************************/
557 uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid
)
559 int rid_offset
= algorithmic_rid_base();
560 return (((((uint32_t)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
563 /*******************************************************************
564 Decides if a RID is a well known RID.
565 ********************************************************************/
567 static bool rid_is_well_known(uint32_t rid
)
569 /* Not using rid_offset here, because this is the actual
570 NT fixed value (1000) */
572 return (rid
< BASE_RID
);
575 /*******************************************************************
576 Decides if a RID is a user or group RID.
577 ********************************************************************/
579 bool algorithmic_pdb_rid_is_user(uint32_t rid
)
581 if ( rid_is_well_known(rid
) ) {
583 * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
584 * and DOMAIN_RID_GUEST.
586 if(rid
== DOMAIN_RID_ADMINISTRATOR
|| rid
== DOMAIN_RID_GUEST
)
588 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
594 /*******************************************************************
595 Convert a name into a SID. Used in the lookup name rpc.
596 ********************************************************************/
598 bool lookup_global_sam_name(const char *name
, int flags
, uint32_t *rid
,
599 enum lsa_SidType
*type
)
604 /* Windows treats "MACHINE\None" as a special name for
605 rid 513 on non-DCs. You cannot create a user or group
606 name "None" on Windows. You will get an error that
607 the group already exists. */
609 if ( strequal( name
, "None" ) ) {
610 *rid
= DOMAIN_RID_USERS
;
611 *type
= SID_NAME_DOM_GRP
;
616 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
617 * correctly in the case where foo also exists as a user. If the flag
618 * is set, don't look for users at all. */
620 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
621 struct samu
*sam_account
= NULL
;
622 struct dom_sid user_sid
;
624 if ( !(sam_account
= samu_new( NULL
)) ) {
629 ret
= pdb_getsampwnam(sam_account
, name
);
633 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
636 TALLOC_FREE(sam_account
);
639 if (!sid_check_is_in_our_sam(&user_sid
)) {
640 struct dom_sid_buf buf
;
641 DBG_ERR("User %s with invalid SID %s"
644 dom_sid_str_buf(&user_sid
, &buf
));
648 sid_peek_rid(&user_sid
, rid
);
649 *type
= SID_NAME_USER
;
655 * Maybe it is a group ?
658 map
= talloc_zero(NULL
, GROUP_MAP
);
664 ret
= pdb_getgrnam(map
, name
);
672 /* BUILTIN groups are looked up elsewhere */
673 if (!sid_check_is_in_our_sam(&map
->sid
)) {
674 struct dom_sid_buf buf
;
675 DEBUG(10, ("Found group %s (%s) not in our domain -- "
678 dom_sid_str_buf(&map
->sid
, &buf
)));
683 /* yes it's a mapped group */
684 sid_peek_rid(&map
->sid
, rid
);
685 *type
= map
->sid_name_use
;
690 /*************************************************************
691 Change a password entry in the local passdb backend.
694 - always called as root
695 - ignores the account type except when adding a new account
696 - will create/delete the unix account if the relative
697 add/delete user script is configured
699 *************************************************************/
701 NTSTATUS
local_password_change(const char *user_name
,
703 const char *new_passwd
,
708 struct samu
*sam_pass
;
718 tosctx
= talloc_tos();
720 sam_pass
= samu_new(tosctx
);
722 result
= NT_STATUS_NO_MEMORY
;
726 /* Get the smb passwd entry for this user */
727 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
729 /* Check delete first, we don't need to do anything else if we
730 * are going to delete the account */
731 if (user_exists
&& (local_flags
& LOCAL_DELETE_USER
)) {
733 result
= pdb_delete_user(tosctx
, sam_pass
);
734 if (!NT_STATUS_IS_OK(result
)) {
735 ret
= asprintf(pp_err_str
,
736 "Failed to delete entry for user %s.\n",
741 result
= NT_STATUS_UNSUCCESSFUL
;
743 ret
= asprintf(pp_msg_str
,
744 "Deleted user %s.\n",
753 if (user_exists
&& (local_flags
& LOCAL_ADD_USER
)) {
754 /* the entry already existed */
755 local_flags
&= ~LOCAL_ADD_USER
;
758 if (!user_exists
&& !(local_flags
& LOCAL_ADD_USER
)) {
759 ret
= asprintf(pp_err_str
,
760 "Failed to find entry for user %s.\n",
765 result
= NT_STATUS_NO_SUCH_USER
;
769 /* First thing add the new user if we are required to do so */
770 if (local_flags
& LOCAL_ADD_USER
) {
772 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
774 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
780 result
= pdb_create_user(tosctx
, user_name
, acb
, &rid
);
781 if (!NT_STATUS_IS_OK(result
)) {
782 ret
= asprintf(pp_err_str
,
783 "Failed to add entry for user %s.\n",
788 result
= NT_STATUS_UNSUCCESSFUL
;
792 sam_pass
= samu_new(tosctx
);
794 result
= NT_STATUS_NO_MEMORY
;
798 /* Now get back the smb passwd entry for this new user */
799 user_exists
= pdb_getsampwnam(sam_pass
, user_name
);
801 ret
= asprintf(pp_err_str
,
802 "Failed to add entry for user %s.\n",
807 result
= NT_STATUS_UNSUCCESSFUL
;
812 acb
= pdb_get_acct_ctrl(sam_pass
);
815 * We are root - just write the new password
816 * and the valid last change time.
818 if ((local_flags
& LOCAL_SET_NO_PASSWORD
) && !(acb
& ACB_PWNOTREQ
)) {
820 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
821 ret
= asprintf(pp_err_str
,
822 "Failed to set 'no password required' "
823 "flag for user %s.\n", user_name
);
827 result
= NT_STATUS_UNSUCCESSFUL
;
832 if (local_flags
& LOCAL_SET_PASSWORD
) {
834 * If we're dealing with setting a completely empty user account
835 * ie. One with a password of 'XXXX', but not set disabled (like
836 * an account created from scratch) then if the old password was
837 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
838 * We remove that as we're giving this user their first password
839 * and the decision hasn't really been made to disable them (ie.
840 * don't create them disabled). JRA.
842 if ((pdb_get_lanman_passwd(sam_pass
) == NULL
) &&
843 (acb
& ACB_DISABLED
)) {
844 acb
&= (~ACB_DISABLED
);
845 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
846 ret
= asprintf(pp_err_str
,
847 "Failed to unset 'disabled' "
848 "flag for user %s.\n",
853 result
= NT_STATUS_UNSUCCESSFUL
;
858 acb
&= (~ACB_PWNOTREQ
);
859 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
860 ret
= asprintf(pp_err_str
,
861 "Failed to unset 'no password required'"
862 " flag for user %s.\n", user_name
);
866 result
= NT_STATUS_UNSUCCESSFUL
;
870 if (!pdb_set_plaintext_passwd(sam_pass
, new_passwd
)) {
871 ret
= asprintf(pp_err_str
,
872 "Failed to set password for "
873 "user %s.\n", user_name
);
877 result
= NT_STATUS_UNSUCCESSFUL
;
882 if ((local_flags
& LOCAL_DISABLE_USER
) && !(acb
& ACB_DISABLED
)) {
884 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
885 ret
= asprintf(pp_err_str
,
886 "Failed to set 'disabled' flag for "
887 "user %s.\n", user_name
);
891 result
= NT_STATUS_UNSUCCESSFUL
;
896 if ((local_flags
& LOCAL_ENABLE_USER
) && (acb
& ACB_DISABLED
)) {
897 acb
&= (~ACB_DISABLED
);
898 if (!pdb_set_acct_ctrl(sam_pass
, acb
, PDB_CHANGED
)) {
899 ret
= asprintf(pp_err_str
,
900 "Failed to unset 'disabled' flag for "
901 "user %s.\n", user_name
);
905 result
= NT_STATUS_UNSUCCESSFUL
;
910 /* now commit changes if any */
911 result
= pdb_update_sam_account(sam_pass
);
912 if (!NT_STATUS_IS_OK(result
)) {
913 ret
= asprintf(pp_err_str
,
914 "Failed to modify entry for user %s.\n",
922 if (local_flags
& LOCAL_ADD_USER
) {
923 ret
= asprintf(pp_msg_str
, "Added user %s.\n", user_name
);
924 } else if (local_flags
& LOCAL_DISABLE_USER
) {
925 ret
= asprintf(pp_msg_str
, "Disabled user %s.\n", user_name
);
926 } else if (local_flags
& LOCAL_ENABLE_USER
) {
927 ret
= asprintf(pp_msg_str
, "Enabled user %s.\n", user_name
);
928 } else if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
929 ret
= asprintf(pp_msg_str
,
930 "User %s password set to none.\n", user_name
);
937 result
= NT_STATUS_OK
;
940 TALLOC_FREE(sam_pass
);
944 /**********************************************************************
945 Marshall/unmarshall struct samu structs.
946 *********************************************************************/
948 #define SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
949 #define SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
950 #define SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
951 #define SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
952 /* nothing changed between V3 and V4 */
954 /*********************************************************************
955 *********************************************************************/
957 static bool init_samu_from_buffer_v0(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
960 /* times are stored as 32bit integer
961 take care on system with 64bit wide time_t
967 pass_can_change_time
,
968 pass_must_change_time
;
969 char *username
= NULL
;
971 char *nt_username
= NULL
;
972 char *dir_drive
= NULL
;
973 char *unknown_str
= NULL
;
974 char *munged_dial
= NULL
;
975 char *fullname
= NULL
;
976 char *homedir
= NULL
;
977 char *logon_script
= NULL
;
978 char *profile_path
= NULL
;
979 char *acct_desc
= NULL
;
980 char *workstations
= NULL
;
981 uint32_t username_len
, domain_len
, nt_username_len
,
982 dir_drive_len
, unknown_str_len
, munged_dial_len
,
983 fullname_len
, homedir_len
, logon_script_len
,
984 profile_path_len
, acct_desc_len
, workstations_len
;
986 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
987 uint16_t acct_ctrl
, logon_divs
;
988 uint16_t bad_password_count
, logon_count
;
989 uint8_t *hours
= NULL
;
990 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
992 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
995 if(sampass
== NULL
|| buf
== NULL
) {
996 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
1000 /* SAMU_BUFFER_FORMAT_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1002 /* unpack the buffer into variables */
1003 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V0
,
1004 &logon_time
, /* d */
1005 &logoff_time
, /* d */
1006 &kickoff_time
, /* d */
1007 &pass_last_set_time
, /* d */
1008 &pass_can_change_time
, /* d */
1009 &pass_must_change_time
, /* d */
1010 &username_len
, &username
, /* B */
1011 &domain_len
, &domain
, /* B */
1012 &nt_username_len
, &nt_username
, /* B */
1013 &fullname_len
, &fullname
, /* B */
1014 &homedir_len
, &homedir
, /* B */
1015 &dir_drive_len
, &dir_drive
, /* B */
1016 &logon_script_len
, &logon_script
, /* B */
1017 &profile_path_len
, &profile_path
, /* B */
1018 &acct_desc_len
, &acct_desc
, /* B */
1019 &workstations_len
, &workstations
, /* B */
1020 &unknown_str_len
, &unknown_str
, /* B */
1021 &munged_dial_len
, &munged_dial
, /* B */
1024 &lm_pw_len
, &lm_pw_ptr
, /* B */
1025 &nt_pw_len
, &nt_pw_ptr
, /* B */
1027 &remove_me
, /* remove on the next TDB_FORMAT upgrade */ /* d */
1028 &logon_divs
, /* w */
1030 &hourslen
, &hours
, /* B */
1031 &bad_password_count
, /* w */
1032 &logon_count
, /* w */
1033 &unknown_6
); /* d */
1035 if (len
== (uint32_t) -1) {
1040 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1041 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1042 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1043 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1044 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1046 pdb_set_username(sampass
, username
, PDB_SET
);
1047 pdb_set_domain(sampass
, domain
, PDB_SET
);
1048 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1049 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1052 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1055 pdb_set_homedir(sampass
,
1056 talloc_sub_basic(sampass
, username
, domain
,
1062 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1064 pdb_set_dir_drive(sampass
,
1065 talloc_sub_basic(sampass
, username
, domain
,
1071 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1073 pdb_set_logon_script(sampass
,
1074 talloc_sub_basic(sampass
, username
, domain
,
1080 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1082 pdb_set_profile_path(sampass
,
1083 talloc_sub_basic(sampass
, username
, domain
,
1088 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1089 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1090 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1092 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1093 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1099 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1100 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1106 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1107 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1108 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1109 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1110 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1111 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1112 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1113 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1114 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1115 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1119 SAFE_FREE(username
);
1121 SAFE_FREE(nt_username
);
1122 SAFE_FREE(fullname
);
1124 SAFE_FREE(dir_drive
);
1125 SAFE_FREE(logon_script
);
1126 SAFE_FREE(profile_path
);
1127 SAFE_FREE(acct_desc
);
1128 SAFE_FREE(workstations
);
1129 SAFE_FREE(munged_dial
);
1130 SAFE_FREE(unknown_str
);
1131 SAFE_FREE(lm_pw_ptr
);
1132 SAFE_FREE(nt_pw_ptr
);
1138 /*********************************************************************
1139 *********************************************************************/
1141 static bool init_samu_from_buffer_v1(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1144 /* times are stored as 32bit integer
1145 take care on system with 64bit wide time_t
1147 uint32_t logon_time
,
1152 pass_can_change_time
,
1153 pass_must_change_time
;
1154 char *username
= NULL
;
1155 char *domain
= NULL
;
1156 char *nt_username
= NULL
;
1157 char *dir_drive
= NULL
;
1158 char *unknown_str
= NULL
;
1159 char *munged_dial
= NULL
;
1160 char *fullname
= NULL
;
1161 char *homedir
= NULL
;
1162 char *logon_script
= NULL
;
1163 char *profile_path
= NULL
;
1164 char *acct_desc
= NULL
;
1165 char *workstations
= NULL
;
1166 uint32_t username_len
, domain_len
, nt_username_len
,
1167 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1168 fullname_len
, homedir_len
, logon_script_len
,
1169 profile_path_len
, acct_desc_len
, workstations_len
;
1171 uint32_t user_rid
, group_rid
, remove_me
, hours_len
, unknown_6
;
1172 uint16_t acct_ctrl
, logon_divs
;
1173 uint16_t bad_password_count
, logon_count
;
1174 uint8_t *hours
= NULL
;
1175 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
;
1177 uint32_t lm_pw_len
, nt_pw_len
, hourslen
;
1180 if(sampass
== NULL
|| buf
== NULL
) {
1181 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1185 /* SAMU_BUFFER_FORMAT_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1187 /* unpack the buffer into variables */
1188 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V1
,
1189 &logon_time
, /* d */
1190 &logoff_time
, /* d */
1191 &kickoff_time
, /* d */
1192 /* Change from V0 is addition of bad_password_time field. */
1193 &bad_password_time
, /* d */
1194 &pass_last_set_time
, /* d */
1195 &pass_can_change_time
, /* d */
1196 &pass_must_change_time
, /* d */
1197 &username_len
, &username
, /* B */
1198 &domain_len
, &domain
, /* B */
1199 &nt_username_len
, &nt_username
, /* B */
1200 &fullname_len
, &fullname
, /* B */
1201 &homedir_len
, &homedir
, /* B */
1202 &dir_drive_len
, &dir_drive
, /* B */
1203 &logon_script_len
, &logon_script
, /* B */
1204 &profile_path_len
, &profile_path
, /* B */
1205 &acct_desc_len
, &acct_desc
, /* B */
1206 &workstations_len
, &workstations
, /* B */
1207 &unknown_str_len
, &unknown_str
, /* B */
1208 &munged_dial_len
, &munged_dial
, /* B */
1211 &lm_pw_len
, &lm_pw_ptr
, /* B */
1212 &nt_pw_len
, &nt_pw_ptr
, /* B */
1215 &logon_divs
, /* w */
1217 &hourslen
, &hours
, /* B */
1218 &bad_password_count
, /* w */
1219 &logon_count
, /* w */
1220 &unknown_6
); /* d */
1222 if (len
== (uint32_t) -1) {
1227 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1228 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1229 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1231 /* Change from V0 is addition of bad_password_time field. */
1232 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1233 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1234 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1236 pdb_set_username(sampass
, username
, PDB_SET
);
1237 pdb_set_domain(sampass
, domain
, PDB_SET
);
1238 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1239 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1242 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
1245 pdb_set_homedir(sampass
,
1246 talloc_sub_basic(sampass
, username
, domain
,
1252 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1254 pdb_set_dir_drive(sampass
,
1255 talloc_sub_basic(sampass
, username
, domain
,
1261 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
1263 pdb_set_logon_script(sampass
,
1264 talloc_sub_basic(sampass
, username
, domain
,
1270 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
1272 pdb_set_profile_path(sampass
,
1273 talloc_sub_basic(sampass
, username
, domain
,
1278 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1279 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1280 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1282 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1283 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1289 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1290 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1296 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1298 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1299 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1300 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1301 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1302 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1303 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1304 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1305 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1306 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1310 SAFE_FREE(username
);
1312 SAFE_FREE(nt_username
);
1313 SAFE_FREE(fullname
);
1315 SAFE_FREE(dir_drive
);
1316 SAFE_FREE(logon_script
);
1317 SAFE_FREE(profile_path
);
1318 SAFE_FREE(acct_desc
);
1319 SAFE_FREE(workstations
);
1320 SAFE_FREE(munged_dial
);
1321 SAFE_FREE(unknown_str
);
1322 SAFE_FREE(lm_pw_ptr
);
1323 SAFE_FREE(nt_pw_ptr
);
1329 static bool init_samu_from_buffer_v2(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1332 /* times are stored as 32bit integer
1333 take care on system with 64bit wide time_t
1335 uint32_t logon_time
,
1340 pass_can_change_time
,
1341 pass_must_change_time
;
1342 char *username
= NULL
;
1343 char *domain
= NULL
;
1344 char *nt_username
= NULL
;
1345 char *dir_drive
= NULL
;
1346 char *unknown_str
= NULL
;
1347 char *munged_dial
= NULL
;
1348 char *fullname
= NULL
;
1349 char *homedir
= NULL
;
1350 char *logon_script
= NULL
;
1351 char *profile_path
= NULL
;
1352 char *acct_desc
= NULL
;
1353 char *workstations
= NULL
;
1354 uint32_t username_len
, domain_len
, nt_username_len
,
1355 dir_drive_len
, unknown_str_len
, munged_dial_len
,
1356 fullname_len
, homedir_len
, logon_script_len
,
1357 profile_path_len
, acct_desc_len
, workstations_len
;
1359 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
;
1360 uint16_t acct_ctrl
, logon_divs
;
1361 uint16_t bad_password_count
, logon_count
;
1362 uint8_t *hours
= NULL
;
1363 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1365 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1366 uint32_t pwHistLen
= 0;
1369 bool expand_explicit
= lp_passdb_expand_explicit();
1371 if(sampass
== NULL
|| buf
== NULL
) {
1372 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1376 /* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1378 /* unpack the buffer into variables */
1379 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V2
,
1380 &logon_time
, /* d */
1381 &logoff_time
, /* d */
1382 &kickoff_time
, /* d */
1383 &bad_password_time
, /* d */
1384 &pass_last_set_time
, /* d */
1385 &pass_can_change_time
, /* d */
1386 &pass_must_change_time
, /* d */
1387 &username_len
, &username
, /* B */
1388 &domain_len
, &domain
, /* B */
1389 &nt_username_len
, &nt_username
, /* B */
1390 &fullname_len
, &fullname
, /* B */
1391 &homedir_len
, &homedir
, /* B */
1392 &dir_drive_len
, &dir_drive
, /* B */
1393 &logon_script_len
, &logon_script
, /* B */
1394 &profile_path_len
, &profile_path
, /* B */
1395 &acct_desc_len
, &acct_desc
, /* B */
1396 &workstations_len
, &workstations
, /* B */
1397 &unknown_str_len
, &unknown_str
, /* B */
1398 &munged_dial_len
, &munged_dial
, /* B */
1401 &lm_pw_len
, &lm_pw_ptr
, /* B */
1402 &nt_pw_len
, &nt_pw_ptr
, /* B */
1403 /* Change from V1 is addition of password history field. */
1404 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1406 /* Also "remove_me" field was removed. */
1407 &logon_divs
, /* w */
1409 &hourslen
, &hours
, /* B */
1410 &bad_password_count
, /* w */
1411 &logon_count
, /* w */
1412 &unknown_6
); /* d */
1414 if (len
== (uint32_t) -1) {
1419 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1420 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1421 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1422 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1423 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1424 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1426 pdb_set_username(sampass
, username
, PDB_SET
);
1427 pdb_set_domain(sampass
, domain
, PDB_SET
);
1428 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1429 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1432 fstrcpy( tmp_string
, homedir
);
1433 if (expand_explicit
) {
1434 standard_sub_basic( username
, domain
, tmp_string
,
1435 sizeof(tmp_string
) );
1437 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1440 pdb_set_homedir(sampass
,
1441 talloc_sub_basic(sampass
, username
, domain
,
1447 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1449 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1452 fstrcpy( tmp_string
, logon_script
);
1453 if (expand_explicit
) {
1454 standard_sub_basic( username
, domain
, tmp_string
,
1455 sizeof(tmp_string
) );
1457 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1460 pdb_set_logon_script(sampass
,
1461 talloc_sub_basic(sampass
, username
, domain
,
1467 fstrcpy( tmp_string
, profile_path
);
1468 if (expand_explicit
) {
1469 standard_sub_basic( username
, domain
, tmp_string
,
1470 sizeof(tmp_string
) );
1472 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1475 pdb_set_profile_path(sampass
,
1476 talloc_sub_basic(sampass
, username
, domain
,
1481 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1482 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1483 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1485 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1486 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1492 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1493 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1499 /* Change from V1 is addition of password history field. */
1500 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1502 uint8_t *pw_hist
= SMB_MALLOC_ARRAY(uint8_t, pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1507 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1508 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1510 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1511 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1512 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1513 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1514 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1515 PW_HISTORY_ENTRY_LEN
);
1518 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1525 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1528 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1529 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1530 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1531 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1532 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1533 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1534 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1535 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1536 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1540 SAFE_FREE(username
);
1542 SAFE_FREE(nt_username
);
1543 SAFE_FREE(fullname
);
1545 SAFE_FREE(dir_drive
);
1546 SAFE_FREE(logon_script
);
1547 SAFE_FREE(profile_path
);
1548 SAFE_FREE(acct_desc
);
1549 SAFE_FREE(workstations
);
1550 SAFE_FREE(munged_dial
);
1551 SAFE_FREE(unknown_str
);
1552 SAFE_FREE(lm_pw_ptr
);
1553 SAFE_FREE(nt_pw_ptr
);
1554 SAFE_FREE(nt_pw_hist_ptr
);
1560 /*********************************************************************
1561 *********************************************************************/
1563 static bool init_samu_from_buffer_v3(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
1566 /* times are stored as 32bit integer
1567 take care on system with 64bit wide time_t
1569 uint32_t logon_time
,
1574 pass_can_change_time
,
1575 pass_must_change_time
;
1576 char *username
= NULL
;
1577 char *domain
= NULL
;
1578 char *nt_username
= NULL
;
1579 char *dir_drive
= NULL
;
1580 char *comment
= NULL
;
1581 char *munged_dial
= NULL
;
1582 char *fullname
= NULL
;
1583 char *homedir
= NULL
;
1584 char *logon_script
= NULL
;
1585 char *profile_path
= NULL
;
1586 char *acct_desc
= NULL
;
1587 char *workstations
= NULL
;
1588 uint32_t username_len
, domain_len
, nt_username_len
,
1589 dir_drive_len
, comment_len
, munged_dial_len
,
1590 fullname_len
, homedir_len
, logon_script_len
,
1591 profile_path_len
, acct_desc_len
, workstations_len
;
1593 uint32_t user_rid
, group_rid
, hours_len
, unknown_6
, acct_ctrl
;
1594 uint16_t logon_divs
;
1595 uint16_t bad_password_count
, logon_count
;
1596 uint8_t *hours
= NULL
;
1597 uint8_t *lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
1599 uint32_t lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
1600 uint32_t pwHistLen
= 0;
1603 bool expand_explicit
= lp_passdb_expand_explicit();
1605 if(sampass
== NULL
|| buf
== NULL
) {
1606 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1610 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1612 /* unpack the buffer into variables */
1613 len
= tdb_unpack (buf
, buflen
, SAMU_BUFFER_FORMAT_V3
,
1614 &logon_time
, /* d */
1615 &logoff_time
, /* d */
1616 &kickoff_time
, /* d */
1617 &bad_password_time
, /* d */
1618 &pass_last_set_time
, /* d */
1619 &pass_can_change_time
, /* d */
1620 &pass_must_change_time
, /* d */
1621 &username_len
, &username
, /* B */
1622 &domain_len
, &domain
, /* B */
1623 &nt_username_len
, &nt_username
, /* B */
1624 &fullname_len
, &fullname
, /* B */
1625 &homedir_len
, &homedir
, /* B */
1626 &dir_drive_len
, &dir_drive
, /* B */
1627 &logon_script_len
, &logon_script
, /* B */
1628 &profile_path_len
, &profile_path
, /* B */
1629 &acct_desc_len
, &acct_desc
, /* B */
1630 &workstations_len
, &workstations
, /* B */
1631 &comment_len
, &comment
, /* B */
1632 &munged_dial_len
, &munged_dial
, /* B */
1635 &lm_pw_len
, &lm_pw_ptr
, /* B */
1636 &nt_pw_len
, &nt_pw_ptr
, /* B */
1637 /* Change from V1 is addition of password history field. */
1638 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1639 /* Change from V2 is the uint32_t acb_mask */
1641 /* Also "remove_me" field was removed. */
1642 &logon_divs
, /* w */
1644 &hourslen
, &hours
, /* B */
1645 &bad_password_count
, /* w */
1646 &logon_count
, /* w */
1647 &unknown_6
); /* d */
1649 if (len
== (uint32_t) -1) {
1654 pdb_set_logon_time(sampass
, convert_uint32_t_to_time_t(logon_time
), PDB_SET
);
1655 pdb_set_logoff_time(sampass
, convert_uint32_t_to_time_t(logoff_time
), PDB_SET
);
1656 pdb_set_kickoff_time(sampass
, convert_uint32_t_to_time_t(kickoff_time
), PDB_SET
);
1657 pdb_set_bad_password_time(sampass
, convert_uint32_t_to_time_t(bad_password_time
), PDB_SET
);
1658 pdb_set_pass_can_change_time(sampass
, convert_uint32_t_to_time_t(pass_can_change_time
), PDB_SET
);
1659 pdb_set_pass_last_set_time(sampass
, convert_uint32_t_to_time_t(pass_last_set_time
), PDB_SET
);
1661 pdb_set_username(sampass
, username
, PDB_SET
);
1662 pdb_set_domain(sampass
, domain
, PDB_SET
);
1663 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1664 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1667 fstrcpy( tmp_string
, homedir
);
1668 if (expand_explicit
) {
1669 standard_sub_basic( username
, domain
, tmp_string
,
1670 sizeof(tmp_string
) );
1672 pdb_set_homedir(sampass
, tmp_string
, PDB_SET
);
1675 pdb_set_homedir(sampass
,
1676 talloc_sub_basic(sampass
, username
, domain
,
1682 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1684 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1687 fstrcpy( tmp_string
, logon_script
);
1688 if (expand_explicit
) {
1689 standard_sub_basic( username
, domain
, tmp_string
,
1690 sizeof(tmp_string
) );
1692 pdb_set_logon_script(sampass
, tmp_string
, PDB_SET
);
1695 pdb_set_logon_script(sampass
,
1696 talloc_sub_basic(sampass
, username
, domain
,
1702 fstrcpy( tmp_string
, profile_path
);
1703 if (expand_explicit
) {
1704 standard_sub_basic( username
, domain
, tmp_string
,
1705 sizeof(tmp_string
) );
1707 pdb_set_profile_path(sampass
, tmp_string
, PDB_SET
);
1710 pdb_set_profile_path(sampass
,
1711 talloc_sub_basic(sampass
, username
, domain
, lp_logon_path()),
1715 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1716 pdb_set_comment(sampass
, comment
, PDB_SET
);
1717 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1718 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1720 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1721 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1727 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1728 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1734 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1736 uint8_t *pw_hist
= (uint8_t *)SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1741 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1742 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1744 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1745 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1746 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1747 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1748 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1749 PW_HISTORY_ENTRY_LEN
);
1752 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1759 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1762 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1763 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1764 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1765 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1766 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1767 /* Change from V2 is the uint32_t acct_ctrl */
1768 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1769 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1770 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
1774 SAFE_FREE(username
);
1776 SAFE_FREE(nt_username
);
1777 SAFE_FREE(fullname
);
1779 SAFE_FREE(dir_drive
);
1780 SAFE_FREE(logon_script
);
1781 SAFE_FREE(profile_path
);
1782 SAFE_FREE(acct_desc
);
1783 SAFE_FREE(workstations
);
1784 SAFE_FREE(munged_dial
);
1786 SAFE_FREE(lm_pw_ptr
);
1787 SAFE_FREE(nt_pw_ptr
);
1788 SAFE_FREE(nt_pw_hist_ptr
);
1794 /*********************************************************************
1795 *********************************************************************/
1797 static uint32_t init_buffer_from_samu_v3 (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
1801 /* times are stored as 32bit integer
1802 take care on system with 64bit wide time_t
1804 uint32_t logon_time
,
1809 pass_can_change_time
,
1810 pass_must_change_time
;
1812 uint32_t user_rid
, group_rid
;
1814 const char *username
;
1816 const char *nt_username
;
1817 const char *dir_drive
;
1818 const char *comment
;
1819 const char *munged_dial
;
1820 const char *fullname
;
1821 const char *homedir
;
1822 const char *logon_script
;
1823 const char *profile_path
;
1824 const char *acct_desc
;
1825 const char *workstations
;
1826 uint32_t username_len
, domain_len
, nt_username_len
,
1827 dir_drive_len
, comment_len
, munged_dial_len
,
1828 fullname_len
, homedir_len
, logon_script_len
,
1829 profile_path_len
, acct_desc_len
, workstations_len
;
1831 const uint8_t *lm_pw
;
1832 const uint8_t *nt_pw
;
1833 const uint8_t *nt_pw_hist
;
1834 uint32_t lm_pw_len
= 16;
1835 uint32_t nt_pw_len
= 16;
1836 uint32_t nt_pw_hist_len
;
1837 uint32_t pwHistLen
= 0;
1842 logon_time
= convert_time_t_to_uint32_t(pdb_get_logon_time(sampass
));
1843 logoff_time
= convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass
));
1844 kickoff_time
= convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass
));
1845 bad_password_time
= convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass
));
1846 pass_can_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass
));
1847 pass_must_change_time
= convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass
));
1848 pass_last_set_time
= convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass
));
1850 user_rid
= pdb_get_user_rid(sampass
);
1851 group_rid
= pdb_get_group_rid(sampass
);
1853 username
= pdb_get_username(sampass
);
1855 username_len
= strlen(username
) +1;
1860 domain
= pdb_get_domain(sampass
);
1862 domain_len
= strlen(domain
) +1;
1867 nt_username
= pdb_get_nt_username(sampass
);
1869 nt_username_len
= strlen(nt_username
) +1;
1871 nt_username_len
= 0;
1874 fullname
= pdb_get_fullname(sampass
);
1876 fullname_len
= strlen(fullname
) +1;
1882 * Only updates fields which have been set (not defaults from smb.conf)
1885 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1886 dir_drive
= pdb_get_dir_drive(sampass
);
1891 dir_drive_len
= strlen(dir_drive
) +1;
1896 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1897 homedir
= pdb_get_homedir(sampass
);
1902 homedir_len
= strlen(homedir
) +1;
1907 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1908 logon_script
= pdb_get_logon_script(sampass
);
1910 logon_script
= NULL
;
1913 logon_script_len
= strlen(logon_script
) +1;
1915 logon_script_len
= 0;
1918 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1919 profile_path
= pdb_get_profile_path(sampass
);
1921 profile_path
= NULL
;
1924 profile_path_len
= strlen(profile_path
) +1;
1926 profile_path_len
= 0;
1929 lm_pw
= pdb_get_lanman_passwd(sampass
);
1934 nt_pw
= pdb_get_nt_passwd(sampass
);
1939 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1940 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1941 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1942 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1947 acct_desc
= pdb_get_acct_desc(sampass
);
1949 acct_desc_len
= strlen(acct_desc
) +1;
1954 workstations
= pdb_get_workstations(sampass
);
1956 workstations_len
= strlen(workstations
) +1;
1958 workstations_len
= 0;
1961 comment
= pdb_get_comment(sampass
);
1963 comment_len
= strlen(comment
) +1;
1968 munged_dial
= pdb_get_munged_dial(sampass
);
1970 munged_dial_len
= strlen(munged_dial
) +1;
1972 munged_dial_len
= 0;
1975 /* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1977 /* one time to get the size needed */
1978 len
= tdb_pack(NULL
, 0, SAMU_BUFFER_FORMAT_V3
,
1980 logoff_time
, /* d */
1981 kickoff_time
, /* d */
1982 bad_password_time
, /* d */
1983 pass_last_set_time
, /* d */
1984 pass_can_change_time
, /* d */
1985 pass_must_change_time
, /* d */
1986 username_len
, username
, /* B */
1987 domain_len
, domain
, /* B */
1988 nt_username_len
, nt_username
, /* B */
1989 fullname_len
, fullname
, /* B */
1990 homedir_len
, homedir
, /* B */
1991 dir_drive_len
, dir_drive
, /* B */
1992 logon_script_len
, logon_script
, /* B */
1993 profile_path_len
, profile_path
, /* B */
1994 acct_desc_len
, acct_desc
, /* B */
1995 workstations_len
, workstations
, /* B */
1996 comment_len
, comment
, /* B */
1997 munged_dial_len
, munged_dial
, /* B */
2000 lm_pw_len
, lm_pw
, /* B */
2001 nt_pw_len
, nt_pw
, /* B */
2002 nt_pw_hist_len
, nt_pw_hist
, /* B */
2003 pdb_get_acct_ctrl(sampass
), /* d */
2004 pdb_get_logon_divs(sampass
), /* w */
2005 pdb_get_hours_len(sampass
), /* d */
2006 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2007 pdb_get_bad_password_count(sampass
), /* w */
2008 pdb_get_logon_count(sampass
), /* w */
2009 pdb_get_unknown_6(sampass
)); /* d */
2015 /* malloc the space needed */
2016 if ( (*buf
=(uint8_t*)SMB_MALLOC(len
)) == NULL
) {
2017 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2021 /* now for the real call to tdb_pack() */
2022 buflen
= tdb_pack(*buf
, len
, SAMU_BUFFER_FORMAT_V3
,
2024 logoff_time
, /* d */
2025 kickoff_time
, /* d */
2026 bad_password_time
, /* d */
2027 pass_last_set_time
, /* d */
2028 pass_can_change_time
, /* d */
2029 pass_must_change_time
, /* d */
2030 username_len
, username
, /* B */
2031 domain_len
, domain
, /* B */
2032 nt_username_len
, nt_username
, /* B */
2033 fullname_len
, fullname
, /* B */
2034 homedir_len
, homedir
, /* B */
2035 dir_drive_len
, dir_drive
, /* B */
2036 logon_script_len
, logon_script
, /* B */
2037 profile_path_len
, profile_path
, /* B */
2038 acct_desc_len
, acct_desc
, /* B */
2039 workstations_len
, workstations
, /* B */
2040 comment_len
, comment
, /* B */
2041 munged_dial_len
, munged_dial
, /* B */
2044 lm_pw_len
, lm_pw
, /* B */
2045 nt_pw_len
, nt_pw
, /* B */
2046 nt_pw_hist_len
, nt_pw_hist
, /* B */
2047 pdb_get_acct_ctrl(sampass
), /* d */
2048 pdb_get_logon_divs(sampass
), /* w */
2049 pdb_get_hours_len(sampass
), /* d */
2050 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
2051 pdb_get_bad_password_count(sampass
), /* w */
2052 pdb_get_logon_count(sampass
), /* w */
2053 pdb_get_unknown_6(sampass
)); /* d */
2055 /* check to make sure we got it correct */
2056 if (buflen
!= len
) {
2057 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2058 (unsigned long)buflen
, (unsigned long)len
));
2067 static bool init_samu_from_buffer_v4(struct samu
*sampass
, uint8_t *buf
, uint32_t buflen
)
2069 /* nothing changed between V3 and V4 */
2070 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2073 static uint32_t init_buffer_from_samu_v4(uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2075 /* nothing changed between V3 and V4 */
2076 return init_buffer_from_samu_v3(buf
, sampass
, size_only
);
2079 /**********************************************************************
2080 Initialize a struct samu struct from a BYTE buffer of size len
2081 *********************************************************************/
2083 bool init_samu_from_buffer(struct samu
*sampass
, uint32_t level
,
2084 uint8_t *buf
, uint32_t buflen
)
2087 case SAMU_BUFFER_V0
:
2088 return init_samu_from_buffer_v0(sampass
, buf
, buflen
);
2089 case SAMU_BUFFER_V1
:
2090 return init_samu_from_buffer_v1(sampass
, buf
, buflen
);
2091 case SAMU_BUFFER_V2
:
2092 return init_samu_from_buffer_v2(sampass
, buf
, buflen
);
2093 case SAMU_BUFFER_V3
:
2094 return init_samu_from_buffer_v3(sampass
, buf
, buflen
);
2095 case SAMU_BUFFER_V4
:
2096 return init_samu_from_buffer_v4(sampass
, buf
, buflen
);
2102 /**********************************************************************
2103 Initialize a BYTE buffer from a struct samu struct
2104 *********************************************************************/
2106 uint32_t init_buffer_from_samu (uint8_t **buf
, struct samu
*sampass
, bool size_only
)
2108 return init_buffer_from_samu_v4(buf
, sampass
, size_only
);
2111 /*********************************************************************
2112 *********************************************************************/
2114 bool pdb_copy_sam_account(struct samu
*dst
, struct samu
*src
)
2116 uint8_t *buf
= NULL
;
2119 len
= init_buffer_from_samu(&buf
, src
, False
);
2120 if (len
== -1 || !buf
) {
2125 if (!init_samu_from_buffer( dst
, SAMU_BUFFER_LATEST
, buf
, len
)) {
2130 dst
->methods
= src
->methods
;
2132 if ( src
->unix_pw
) {
2133 dst
->unix_pw
= tcopy_passwd( dst
, src
->unix_pw
);
2134 if (!dst
->unix_pw
) {
2140 if (src
->group_sid
) {
2141 pdb_set_group_sid(dst
, src
->group_sid
, PDB_SET
);
2148 /*********************************************************************
2149 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2150 *********************************************************************/
2152 bool pdb_update_bad_password_count(struct samu
*sampass
, bool *updated
)
2154 time_t LastBadPassword
;
2155 uint16_t BadPasswordCount
;
2159 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
2160 if (!BadPasswordCount
) {
2161 DEBUG(9, ("No bad password attempts.\n"));
2166 res
= pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME
, &resettime
);
2170 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2174 /* First, check if there is a reset time to compare */
2175 if ((resettime
== (uint32_t) -1) || (resettime
== 0)) {
2176 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2180 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2181 DBG_INFO("LastBadPassword=%" PRIu64
", resettime=%d, "
2182 "current time=%" PRIu64
".\n",
2183 (uint64_t)LastBadPassword
,
2185 (uint64_t)time(NULL
));
2186 if (time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(resettime
)*60)){
2187 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2188 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2197 /*********************************************************************
2198 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2199 *********************************************************************/
2201 bool pdb_update_autolock_flag(struct samu
*sampass
, bool *updated
)
2204 time_t LastBadPassword
;
2207 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
2208 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2209 pdb_get_username(sampass
)));
2214 res
= pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION
, &duration
);
2218 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2222 /* First, check if there is a duration to compare */
2223 if ((duration
== (uint32_t) -1) || (duration
== 0)) {
2224 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2228 LastBadPassword
= pdb_get_bad_password_time(sampass
);
2229 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2230 pdb_get_username(sampass
), (uint32_t)LastBadPassword
, duration
*60, (uint32_t)time(NULL
)));
2232 if (LastBadPassword
== (time_t)0) {
2233 DEBUG(1,("pdb_update_autolock_flag: Account %s "
2234 "administratively locked out with no bad password "
2235 "time. Leaving locked out.\n",
2236 pdb_get_username(sampass
) ));
2240 if ((time(NULL
) > (LastBadPassword
+ convert_uint32_t_to_time_t(duration
) * 60))) {
2241 pdb_set_acct_ctrl(sampass
,
2242 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
2244 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
2245 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
2254 /*********************************************************************
2255 Increment the bad_password_count
2256 *********************************************************************/
2258 bool pdb_increment_bad_password_count(struct samu
*sampass
)
2260 uint32_t account_policy_lockout
;
2261 bool autolock_updated
= False
, badpw_updated
= False
;
2264 /* Retrieve the account lockout policy */
2266 ret
= pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
2269 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2273 /* If there is no policy, we don't need to continue checking */
2274 if (!account_policy_lockout
) {
2275 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2279 /* Check if the autolock needs to be cleared */
2280 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
2283 /* Check if the badpw count needs to be reset */
2284 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
2288 Ok, now we can assume that any resetting that needs to be
2289 done has been done, and just get on with incrementing
2290 and autolocking if necessary
2293 pdb_set_bad_password_count(sampass
,
2294 pdb_get_bad_password_count(sampass
)+1,
2296 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
2299 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
2302 if (!pdb_set_acct_ctrl(sampass
,
2303 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
2305 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2312 bool is_dc_trusted_domain_situation(const char *domain_name
)
2314 return IS_DC
&& !strequal(domain_name
, lp_workgroup());
2317 /*******************************************************************
2318 Wrapper around retrieving the clear text trust account password.
2319 appropriate account name is stored in account_name.
2320 Caller must free password, but not account_name.
2321 *******************************************************************/
2323 static bool get_trust_pw_clear2(const char *domain
,
2324 const char **account_name
,
2325 enum netr_SchannelType
*channel
,
2327 time_t *_last_set_time
,
2331 time_t last_set_time
;
2333 if (cur_pw
!= NULL
) {
2336 if (_last_set_time
!= NULL
) {
2337 *_last_set_time
= 0;
2339 if (prev_pw
!= NULL
) {
2343 /* if we are a DC and this is not our domain, then lookup an account
2344 * for the domain trust */
2346 if (is_dc_trusted_domain_situation(domain
)) {
2347 if (!lp_allow_trusted_domains()) {
2351 if (!pdb_get_trusteddom_pw(domain
, cur_pw
, NULL
,
2354 DEBUG(0, ("get_trust_pw: could not fetch trust "
2355 "account password for trusted domain %s\n",
2360 if (channel
!= NULL
) {
2361 *channel
= SEC_CHAN_DOMAIN
;
2364 if (account_name
!= NULL
) {
2365 *account_name
= lp_workgroup();
2368 if (_last_set_time
!= NULL
) {
2369 *_last_set_time
= last_set_time
;
2376 * Since we can only be member of one single domain, we are now
2377 * in a member situation:
2379 * - Either we are a DC (selfjoined) and the domain is our
2381 * - Or we are on a member and the domain is our own or some
2382 * other (potentially trusted) domain.
2384 * In both cases, we can only get the machine account password
2385 * for our own domain to connect to our own dc. (For a member,
2386 * request to trusted domains are performed through our dc.)
2388 * So we simply use our own domain name to retrieve the
2389 * machine account password and ignore the request domain here.
2392 pwd
= secrets_fetch_machine_password(lp_workgroup(), &last_set_time
, channel
);
2395 struct timeval expire
;
2399 if (account_name
!= NULL
) {
2400 *account_name
= lp_netbios_name();
2403 if (_last_set_time
!= NULL
) {
2404 *_last_set_time
= last_set_time
;
2407 if (prev_pw
== NULL
) {
2411 ZERO_STRUCT(expire
);
2412 expire
.tv_sec
= lp_machine_password_timeout();
2414 expire
.tv_sec
+= last_set_time
;
2415 if (timeval_expired(&expire
)) {
2419 pwd
= secrets_fetch_prev_machine_password(lp_workgroup());
2427 DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2428 "account password for domain %s\n", domain
));
2432 bool get_trust_pw_clear(const char *domain
, char **ret_pwd
,
2433 const char **account_name
,
2434 enum netr_SchannelType
*channel
)
2436 return get_trust_pw_clear2(domain
,
2444 /*******************************************************************
2445 Wrapper around retrieving the trust account password.
2446 appropriate account name is stored in account_name.
2447 *******************************************************************/
2449 static bool get_trust_pw_hash2(const char *domain
,
2450 const char **account_name
,
2451 enum netr_SchannelType
*channel
,
2452 struct samr_Password
*current_nt_hash
,
2453 time_t *last_set_time
,
2454 struct samr_Password
**_previous_nt_hash
)
2456 char *cur_pw
= NULL
;
2457 char *prev_pw
= NULL
;
2458 char **_prev_pw
= NULL
;
2461 if (_previous_nt_hash
!= NULL
) {
2462 *_previous_nt_hash
= NULL
;
2463 _prev_pw
= &prev_pw
;
2466 ok
= get_trust_pw_clear2(domain
, account_name
, channel
,
2467 &cur_pw
, last_set_time
, _prev_pw
);
2469 struct samr_Password
*previous_nt_hash
= NULL
;
2471 E_md4hash(cur_pw
, current_nt_hash
->hash
);
2472 BURN_FREE_STR(cur_pw
);
2474 if (prev_pw
== NULL
) {
2478 previous_nt_hash
= SMB_MALLOC_P(struct samr_Password
);
2479 if (previous_nt_hash
== NULL
) {
2483 E_md4hash(prev_pw
, previous_nt_hash
->hash
);
2484 BURN_FREE_STR(prev_pw
);
2486 *_previous_nt_hash
= previous_nt_hash
;
2488 } else if (is_dc_trusted_domain_situation(domain
)) {
2492 /* as a fallback, try to get the hashed pwd directly from the tdb... */
2494 if (secrets_fetch_trust_account_password_legacy(domain
,
2495 current_nt_hash
->hash
,
2499 if (account_name
!= NULL
) {
2500 *account_name
= lp_netbios_name();
2506 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2507 "password for domain %s\n", domain
));
2511 bool get_trust_pw_hash(const char *domain
, uint8_t ret_pwd
[16],
2512 const char **account_name
,
2513 enum netr_SchannelType
*channel
)
2515 struct samr_Password current_nt_hash
;
2518 ok
= get_trust_pw_hash2(domain
, account_name
, channel
,
2519 ¤t_nt_hash
, NULL
, NULL
);
2524 memcpy(ret_pwd
, current_nt_hash
.hash
, sizeof(current_nt_hash
.hash
));
2528 NTSTATUS
pdb_get_trust_credentials(const char *netbios_domain
,
2529 const char *dns_domain
, /* optional */
2530 TALLOC_CTX
*mem_ctx
,
2531 struct cli_credentials
**_creds
)
2533 TALLOC_CTX
*frame
= talloc_stackframe();
2535 struct loadparm_context
*lp_ctx
;
2536 enum netr_SchannelType channel
;
2537 time_t last_set_time
;
2538 const char *_account_name
;
2539 const char *account_name
;
2540 char *cur_pw
= NULL
;
2541 char *prev_pw
= NULL
;
2542 struct samr_Password cur_nt_hash
;
2543 struct cli_credentials
*creds
= NULL
;
2547 * If this is our primary trust relationship, use the common
2548 * code to read the secrets.ldb or secrets.tdb file.
2550 if (strequal(netbios_domain
, lp_workgroup())) {
2551 struct db_context
*db_ctx
= secrets_db_ctx();
2552 if (db_ctx
== NULL
) {
2553 DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2555 status
= NT_STATUS_INTERNAL_ERROR
;
2559 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2560 if (lp_ctx
== NULL
) {
2561 DEBUG(1, ("loadparm_init_s3 failed\n"));
2562 status
= NT_STATUS_INTERNAL_ERROR
;
2566 creds
= cli_credentials_init(mem_ctx
);
2567 if (creds
== NULL
) {
2568 status
= NT_STATUS_NO_MEMORY
;
2572 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2574 status
= NT_STATUS_INTERNAL_ERROR
;
2578 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2580 status
= NT_STATUS_NO_MEMORY
;
2584 status
= cli_credentials_set_machine_account_db_ctx(creds
,
2587 if (!NT_STATUS_IS_OK(status
)) {
2591 } else if (!IS_DC
) {
2592 DEBUG(1, ("Refusing to get trust account info for %s, "
2593 "which is not our primary domain %s, "
2594 "as we are not a DC\n",
2595 netbios_domain
, lp_workgroup()));
2596 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2600 status
= pdb_get_trusteddom_creds(netbios_domain
, mem_ctx
, &creds
);
2601 if (NT_STATUS_IS_OK(status
)) {
2604 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
2608 ok
= get_trust_pw_clear2(netbios_domain
,
2615 ok
= get_trust_pw_hash2(netbios_domain
,
2622 DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2624 status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2629 account_name
= talloc_asprintf(frame
, "%s$", _account_name
);
2630 if (account_name
== NULL
) {
2631 status
= NT_STATUS_NO_MEMORY
;
2635 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
2636 if (lp_ctx
== NULL
) {
2637 DEBUG(1, ("loadparm_init_s3 failed\n"));
2638 status
= NT_STATUS_INTERNAL_ERROR
;
2642 creds
= cli_credentials_init(mem_ctx
);
2643 if (creds
== NULL
) {
2644 status
= NT_STATUS_NO_MEMORY
;
2648 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
2650 status
= NT_STATUS_INTERNAL_ERROR
;
2654 cli_credentials_set_secure_channel_type(creds
, channel
);
2655 cli_credentials_set_password_last_changed_time(creds
, last_set_time
);
2657 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
2659 status
= NT_STATUS_NO_MEMORY
;
2663 if (dns_domain
!= NULL
) {
2664 ok
= cli_credentials_set_realm(creds
, dns_domain
, CRED_SPECIFIED
);
2666 status
= NT_STATUS_NO_MEMORY
;
2671 * It's not possible to use NTLMSSP with a domain trust account.
2673 cli_credentials_set_kerberos_state(creds
,
2674 CRED_USE_KERBEROS_REQUIRED
,
2678 * We can't use kerberos against an NT4 domain.
2680 * We should have a mode that also disallows NTLMSSP here,
2681 * as only NETLOGON SCHANNEL is possible.
2683 cli_credentials_set_kerberos_state(creds
,
2684 CRED_USE_KERBEROS_DISABLED
,
2688 ok
= cli_credentials_set_username(creds
, account_name
, CRED_SPECIFIED
);
2690 status
= NT_STATUS_NO_MEMORY
;
2694 if (cur_pw
== NULL
) {
2695 ok
= cli_credentials_set_nt_hash(creds
, &cur_nt_hash
, CRED_SPECIFIED
);
2697 status
= NT_STATUS_NO_MEMORY
;
2701 * We currently can't do kerberos just with an NTHASH.
2703 cli_credentials_set_kerberos_state(creds
,
2704 CRED_USE_KERBEROS_DISABLED
,
2709 ok
= cli_credentials_set_password(creds
, cur_pw
, CRED_SPECIFIED
);
2711 status
= NT_STATUS_NO_MEMORY
;
2715 if (prev_pw
!= NULL
) {
2716 ok
= cli_credentials_set_old_password(creds
, prev_pw
, CRED_SPECIFIED
);
2718 status
= NT_STATUS_NO_MEMORY
;
2726 status
= NT_STATUS_OK
;