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 2 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, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DBGC_CLASS DBGC_PASSDB
31 /******************************************************************
32 get the default domain/netbios name to be used when
33 testing authentication. For example, if you connect
34 to a Windows member server using a bogus domain name, the
35 Windows box will map the BOGUS\user to DOMAIN\user. A
36 standalone box will map to WKS\user.
37 ******************************************************************/
39 const char *my_sam_name(void)
41 /* standalone servers can only use the local netbios name */
42 if ( lp_server_role() == ROLE_STANDALONE
)
43 return global_myname();
45 /* Windows domain members default to the DOMAIN
46 name when not specified */
47 return lp_workgroup();
50 /************************************************************
51 Fill the struct samu with default values.
52 ***********************************************************/
54 static void samu_init( struct samu
*user
)
56 /* no initial methods */
59 /* Don't change these timestamp settings without a good reason.
60 They are important for NT member server compatibility. */
62 user
->logon_time
= (time_t)0;
63 user
->pass_last_set_time
= (time_t)0;
64 user
->pass_can_change_time
= (time_t)0;
65 user
->logoff_time
= get_time_t_max();
66 user
->kickoff_time
= get_time_t_max();
67 user
->pass_must_change_time
= get_time_t_max();
68 user
->fields_present
= 0x00ffffff;
69 user
->logon_divs
= 168; /* hours per week */
70 user
->hours_len
= 21; /* 21 times 8 bits = 168 */
71 memset(user
->hours
, 0xff, user
->hours_len
); /* available at all hours */
72 user
->bad_password_count
= 0;
73 user
->logon_count
= 0;
74 user
->unknown_6
= 0x000004ec; /* don't know */
76 /* Some parts of samba strlen their pdb_get...() returns,
77 so this keeps the interface unchanged for now. */
81 user
->nt_username
= "";
84 user
->logon_script
= "";
85 user
->profile_path
= "";
87 user
->workstations
= "";
88 user
->unknown_str
= "";
89 user
->munged_dial
= "";
91 user
->plaintext_pw
= NULL
;
94 Unless we know otherwise have a Account Control Bit
95 value of 'normal user'. This helps User Manager, which
96 asks for a filtered list of users.
99 user
->acct_ctrl
= ACB_NORMAL
;
102 /**********************************************************************
103 ***********************************************************************/
105 static int samu_destroy(void *p
)
107 struct samu
*user
= p
;
109 data_blob_clear_free( &user
->lm_pw
);
110 data_blob_clear_free( &user
->nt_pw
);
112 if ( user
->plaintext_pw
)
113 memset( user
->plaintext_pw
, 0x0, strlen(user
->plaintext_pw
) );
118 /**********************************************************************
119 generate a new struct samuser
120 ***********************************************************************/
122 struct samu
* samu_new( TALLOC_CTX
*ctx
)
126 if ( !(user
= TALLOC_ZERO_P( ctx
, struct samu
)) ) {
127 DEBUG(0,("samuser_new: Talloc failed!\n"));
133 talloc_set_destructor( user
, samu_destroy
);
138 /*********************************************************************
139 Initialize a struct samu from a struct passwd including the user
141 *********************************************************************/
143 NTSTATUS
samu_set_unix(struct samu
*user
, const struct passwd
*pwd
)
145 const char *guest_account
= lp_guestaccount();
149 /* Set the Unix attributes */
152 return NT_STATUS_NO_SUCH_USER
;
155 pdb_set_username(user
, pwd
->pw_name
, PDB_SET
);
156 pdb_set_fullname(user
, pwd
->pw_gecos
, PDB_SET
);
157 pdb_set_unix_homedir(user
, pwd
->pw_dir
, PDB_SET
);
158 pdb_set_domain (user
, get_global_sam_name(), PDB_DEFAULT
);
160 /* Special case for the guest account which must have a RID of 501.
161 By default the guest account is a member of of the domain users
162 group as well as the domain guests group. Verified against
165 if ( !guest_account
) {
166 DEBUG(0,("samu_set_unix: No guest user defined!\n"));
167 return NT_STATUS_INVALID_ACCOUNT_NAME
;
170 if ( strequal( pwd
->pw_name
, guest_account
) )
172 if ( !pdb_set_user_sid_from_rid(user
, DOMAIN_USER_RID_GUEST
, PDB_DEFAULT
)) {
173 return NT_STATUS_NO_SUCH_USER
;
176 if ( !pdb_set_group_sid_from_rid(user
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
) ) {
177 return NT_STATUS_NO_SUCH_USER
;
182 /* normal user setup -- we really need to throw away the mapping algorithm here */
184 if (!pdb_set_user_sid_from_rid(user
, algorithmic_pdb_uid_to_user_rid(pwd
->pw_uid
), PDB_SET
)) {
185 DEBUG(0,("Can't set User SID from RID!\n"));
186 return NT_STATUS_INVALID_PARAMETER
;
189 #if 1 /* I think we could throw away the primaryGroupSID attribute altogether
190 and just build it from the UNIX_TOKEN. --jerry */
192 /* call the mapping code here */
195 ret
= pdb_getgrgid(&map
, pwd
->pw_gid
);
198 /* We do not want to fall back to the rid mapping algorithm. Windows
199 standalone servers set the 0x201 rid as the primary group and
200 LookupSid( S-1...-513 ) returns SERVER\None. Do something similar.
201 Use the Domain Users RID as a a placeholder. This is a workaround only. */
204 if ( !pdb_set_group_sid(user
, &map
.sid
, PDB_SET
) ) {
205 DEBUG(0,("Can't set Group SID!\n"));
206 return NT_STATUS_INVALID_PARAMETER
;
209 if ( !pdb_set_group_sid_from_rid(user
, DOMAIN_GROUP_RID_USERS
, PDB_SET
))
210 return NT_STATUS_INVALID_PARAMETER
;
214 if (pwd
->pw_name
[strlen(pwd
->pw_name
)-1] == '$') {
217 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_DEFAULT
)) {
218 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
220 return NT_STATUS_INVALID_COMPUTER_NAME
;
223 /* we're done here for a machine account */
230 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
, PDB_DEFAULT
)) {
231 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
233 return NT_STATUS_INVALID_ACCOUNT_NAME
;
237 /* set some basic attributes */
239 pdb_set_profile_path(user
, talloc_sub_specified(user
,
240 lp_logon_path(), pwd
->pw_name
, global_myname(), pwd
->pw_uid
, pwd
->pw_gid
),
242 pdb_set_homedir(user
, talloc_sub_specified(user
,
243 lp_logon_home(), pwd
->pw_name
, global_myname(), pwd
->pw_uid
, pwd
->pw_gid
),
245 pdb_set_dir_drive(user
, talloc_sub_specified(user
,
246 lp_logon_drive(), pwd
->pw_name
, global_myname(), pwd
->pw_uid
, pwd
->pw_gid
),
248 pdb_set_logon_script(user
, talloc_sub_specified(user
,
249 lp_logon_script(), pwd
->pw_name
, global_myname(), pwd
->pw_uid
, pwd
->pw_gid
),
255 /*************************************************************
256 Initialises a struct samu ready to add a new account, based
258 ************************************************************/
260 NTSTATUS
pdb_init_sam_new(struct samu
**new_sam_acct
, const char *username
)
265 DOM_SID user_sid
, group_sid
;
267 enum SID_NAME_USE type
;
269 mem_ctx
= talloc_new(NULL
);
270 if (mem_ctx
== NULL
) {
271 DEBUG(0, ("talloc_new failed\n"));
272 return NT_STATUS_NO_MEMORY
;
275 if ( !(pwd
= Get_Pwnam_alloc(mem_ctx
, username
)) ) {
276 DEBUG(10, ("Could not find user %s\n", username
));
277 result
= NT_STATUS_NO_SUCH_USER
;
281 if ( !(*new_sam_acct
= samu_new( NULL
)) ) {
282 result
= NT_STATUS_NO_MEMORY
;
286 result
= samu_set_unix( *new_sam_acct
, pwd
);
288 if (!NT_STATUS_IS_OK(result
)) {
289 DEBUG(10, ("samu_set_unix failed: %s\n", nt_errstr(result
)));
293 if (pdb_rid_algorithm()) {
294 if (!pdb_set_user_sid_from_rid(
296 algorithmic_pdb_uid_to_user_rid(pwd
->pw_uid
),
298 result
= NT_STATUS_INTERNAL_ERROR
;
301 if (!pdb_set_group_sid_from_rid(
302 *new_sam_acct
, pdb_gid_to_group_rid(pwd
->pw_gid
),
304 result
= NT_STATUS_INTERNAL_ERROR
;
307 result
= NT_STATUS_OK
;
311 /* No algorithmic mapping, meaning that we have to figure out the
312 * primary group SID according to group mapping and the user SID must
313 * be a newly allocated one */
315 if (!pdb_gid_to_sid(pwd
->pw_gid
, &group_sid
)) {
319 grp
= getgrgid(pwd
->pw_gid
);
321 DEBUG(1, ("Primary group %d of user %s does not "
322 "exist.\n", pwd
->pw_gid
, username
));
323 result
= NT_STATUS_INVALID_PRIMARY_GROUP
;
327 DEBUG(5, ("Primary group %s of user %s is not mapped to "
328 "a domain group, auto-mapping it\n",
329 grp
->gr_name
, username
));
330 result
= map_unix_group(grp
, &map
);
331 if (!NT_STATUS_IS_OK(result
)) {
332 DEBUG(1, ("Failed to map group %s\n", grp
->gr_name
));
335 sid_copy(&group_sid
, &map
.sid
);
336 DEBUG(5, ("Mapped unix group %s to SID %s\n",
337 grp
->gr_name
, sid_string_static(&group_sid
)));
340 /* Now check that it's actually a domain group and not something
343 if (!lookup_sid(mem_ctx
, &group_sid
, NULL
, NULL
, &type
)) {
344 DEBUG(3, ("Could not lookup %s's primary group sid %s\n",
345 username
, sid_string_static(&group_sid
)));
346 result
= NT_STATUS_INVALID_PRIMARY_GROUP
;
350 if (type
!= SID_NAME_DOM_GRP
) {
351 DEBUG(3, ("Primary group for user %s is a %s and not a domain "
352 "group\n", username
, sid_type_lookup(type
)));
353 result
= NT_STATUS_INVALID_PRIMARY_GROUP
;
357 if (!pdb_set_group_sid(*new_sam_acct
, &group_sid
, PDB_SET
)) {
358 DEBUG(3, ("Could not set group SID\n"));
359 result
= NT_STATUS_INTERNAL_ERROR
;
363 if (!pdb_new_rid(&user_rid
)) {
364 DEBUG(3, ("Could not allocate a new RID\n"));
365 result
= NT_STATUS_ACCESS_DENIED
;
369 sid_copy(&user_sid
, get_global_sam_sid());
370 sid_append_rid(&user_sid
, user_rid
);
372 if (!pdb_set_user_sid(*new_sam_acct
, &user_sid
, PDB_SET
)) {
373 DEBUG(3, ("pdb_set_user_sid failed\n"));
374 result
= NT_STATUS_INTERNAL_ERROR
;
378 result
= NT_STATUS_OK
;
381 if (!NT_STATUS_IS_OK(result
) && (*new_sam_acct
!= NULL
)) {
382 TALLOC_FREE(new_sam_acct
);
385 TALLOC_FREE(mem_ctx
);
390 /**********************************************************
391 Encode the account control bits into a string.
392 length = length of string to encode into (including terminating
393 null). length *MUST BE MORE THAN 2* !
394 **********************************************************/
396 char *pdb_encode_acct_ctrl(uint16 acct_ctrl
, size_t length
)
398 static fstring acct_str
;
402 SMB_ASSERT(length
<= sizeof(acct_str
));
406 if (acct_ctrl
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
407 if (acct_ctrl
& ACB_DISABLED
) acct_str
[i
++] = 'D';
408 if (acct_ctrl
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
409 if (acct_ctrl
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
410 if (acct_ctrl
& ACB_NORMAL
) acct_str
[i
++] = 'U';
411 if (acct_ctrl
& ACB_MNS
) acct_str
[i
++] = 'M';
412 if (acct_ctrl
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
413 if (acct_ctrl
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
414 if (acct_ctrl
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
415 if (acct_ctrl
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
416 if (acct_ctrl
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
418 for ( ; i
< length
- 2 ; i
++ )
423 acct_str
[i
++] = '\0';
428 /**********************************************************
429 Decode the account control bits from a string.
430 **********************************************************/
432 uint16
pdb_decode_acct_ctrl(const char *p
)
434 uint16 acct_ctrl
= 0;
435 BOOL finished
= False
;
438 * Check if the account type bits have been encoded after the
439 * NT password (in the form [NDHTUWSLXI]).
445 for (p
++; *p
&& !finished
; p
++) {
447 case 'N': { acct_ctrl
|= ACB_PWNOTREQ
; break; /* 'N'o password. */ }
448 case 'D': { acct_ctrl
|= ACB_DISABLED
; break; /* 'D'isabled. */ }
449 case 'H': { acct_ctrl
|= ACB_HOMDIRREQ
; break; /* 'H'omedir required. */ }
450 case 'T': { acct_ctrl
|= ACB_TEMPDUP
; break; /* 'T'emp account. */ }
451 case 'U': { acct_ctrl
|= ACB_NORMAL
; break; /* 'U'ser account (normal). */ }
452 case 'M': { acct_ctrl
|= ACB_MNS
; break; /* 'M'NS logon user account. What is this ? */ }
453 case 'W': { acct_ctrl
|= ACB_WSTRUST
; break; /* 'W'orkstation account. */ }
454 case 'S': { acct_ctrl
|= ACB_SVRTRUST
; break; /* 'S'erver account. */ }
455 case 'L': { acct_ctrl
|= ACB_AUTOLOCK
; break; /* 'L'ocked account. */ }
456 case 'X': { acct_ctrl
|= ACB_PWNOEXP
; break; /* No 'X'piry on password */ }
457 case 'I': { acct_ctrl
|= ACB_DOMTRUST
; break; /* 'I'nterdomain trust account. */ }
463 default: { finished
= True
; }
470 /*************************************************************
471 Routine to set 32 hex password characters from a 16 byte array.
472 **************************************************************/
474 void pdb_sethexpwd(char *p
, const unsigned char *pwd
, uint16 acct_ctrl
)
478 for (i
= 0; i
< 16; i
++)
479 slprintf(&p
[i
*2], 3, "%02X", pwd
[i
]);
481 if (acct_ctrl
& ACB_PWNOTREQ
)
482 safe_strcpy(p
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
484 safe_strcpy(p
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
488 /*************************************************************
489 Routine to get the 32 hex characters and turn them
490 into a 16 byte array.
491 **************************************************************/
493 BOOL
pdb_gethexpwd(const char *p
, unsigned char *pwd
)
496 unsigned char lonybble
, hinybble
;
497 const char *hexchars
= "0123456789ABCDEF";
503 for (i
= 0; i
< 32; i
+= 2) {
504 hinybble
= toupper_ascii(p
[i
]);
505 lonybble
= toupper_ascii(p
[i
+ 1]);
507 p1
= strchr(hexchars
, hinybble
);
508 p2
= strchr(hexchars
, lonybble
);
513 hinybble
= PTR_DIFF(p1
, hexchars
);
514 lonybble
= PTR_DIFF(p2
, hexchars
);
516 pwd
[i
/ 2] = (hinybble
<< 4) | lonybble
;
521 /*************************************************************
522 Routine to set 42 hex hours characters from a 21 byte array.
523 **************************************************************/
525 void pdb_sethexhours(char *p
, const unsigned char *hours
)
529 for (i
= 0; i
< 21; i
++) {
530 slprintf(&p
[i
*2], 3, "%02X", hours
[i
]);
533 safe_strcpy(p
, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
537 /*************************************************************
538 Routine to get the 42 hex characters and turn them
539 into a 21 byte array.
540 **************************************************************/
542 BOOL
pdb_gethexhours(const char *p
, unsigned char *hours
)
545 unsigned char lonybble
, hinybble
;
546 const char *hexchars
= "0123456789ABCDEF";
553 for (i
= 0; i
< 42; i
+= 2) {
554 hinybble
= toupper_ascii(p
[i
]);
555 lonybble
= toupper_ascii(p
[i
+ 1]);
557 p1
= strchr(hexchars
, hinybble
);
558 p2
= strchr(hexchars
, lonybble
);
564 hinybble
= PTR_DIFF(p1
, hexchars
);
565 lonybble
= PTR_DIFF(p2
, hexchars
);
567 hours
[i
/ 2] = (hinybble
<< 4) | lonybble
;
572 int algorithmic_rid_base(void)
574 static int rid_offset
= 0;
579 rid_offset
= lp_algorithmic_rid_base();
581 if (rid_offset
< BASE_RID
) {
582 /* Try to prevent admin foot-shooting, we can't put algorithmic
583 rids below 1000, that's the 'well known RIDs' on NT */
584 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID
));
585 rid_offset
= BASE_RID
;
587 if (rid_offset
& 1) {
588 DEBUG(0, ("algorithmic rid base must be even\n"));
594 /*******************************************************************
595 Converts NT user RID to a UNIX uid.
596 ********************************************************************/
598 uid_t
algorithmic_pdb_user_rid_to_uid(uint32 user_rid
)
600 int rid_offset
= algorithmic_rid_base();
601 return (uid_t
)(((user_rid
& (~USER_RID_TYPE
)) - rid_offset
)/RID_MULTIPLIER
);
604 uid_t
max_algorithmic_uid(void)
606 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
609 /*******************************************************************
610 converts UNIX uid to an NT User RID.
611 ********************************************************************/
613 uint32
algorithmic_pdb_uid_to_user_rid(uid_t uid
)
615 int rid_offset
= algorithmic_rid_base();
616 return (((((uint32
)uid
)*RID_MULTIPLIER
) + rid_offset
) | USER_RID_TYPE
);
619 /*******************************************************************
620 Converts NT group RID to a UNIX gid.
621 ********************************************************************/
623 gid_t
pdb_group_rid_to_gid(uint32 group_rid
)
625 int rid_offset
= algorithmic_rid_base();
626 return (gid_t
)(((group_rid
& (~GROUP_RID_TYPE
))- rid_offset
)/RID_MULTIPLIER
);
629 gid_t
max_algorithmic_gid(void)
631 return pdb_group_rid_to_gid(0xffffffff);
634 /*******************************************************************
635 converts NT Group RID to a UNIX uid.
637 warning: you must not call that function only
638 you must do a call to the group mapping first.
639 there is not anymore a direct link between the gid and the rid.
640 ********************************************************************/
642 uint32
pdb_gid_to_group_rid(gid_t gid
)
644 int rid_offset
= algorithmic_rid_base();
645 return (((((uint32
)gid
)*RID_MULTIPLIER
) + rid_offset
) | GROUP_RID_TYPE
);
648 /*******************************************************************
649 Decides if a RID is a well known RID.
650 ********************************************************************/
652 static BOOL
pdb_rid_is_well_known(uint32 rid
)
654 /* Not using rid_offset here, because this is the actual
655 NT fixed value (1000) */
657 return (rid
< BASE_RID
);
660 /*******************************************************************
661 Decides if a RID is a user or group RID.
662 ********************************************************************/
664 BOOL
algorithmic_pdb_rid_is_user(uint32 rid
)
666 if(pdb_rid_is_well_known(rid
)) {
668 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
669 * and DOMAIN_USER_RID_GUEST.
671 if(rid
== DOMAIN_USER_RID_ADMIN
|| rid
== DOMAIN_USER_RID_GUEST
)
673 } else if((rid
& RID_TYPE_MASK
) == USER_RID_TYPE
) {
679 /*******************************************************************
680 Convert a name into a SID. Used in the lookup name rpc.
681 ********************************************************************/
683 BOOL
lookup_global_sam_name(const char *user
, int flags
, uint32_t *rid
,
684 enum SID_NAME_USE
*type
)
689 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
690 * correctly in the case where foo also exists as a user. If the flag
691 * is set, don't look for users at all. */
693 if ((flags
& LOOKUP_NAME_GROUP
) == 0) {
694 struct samu
*sam_account
= NULL
;
697 if ( !(sam_account
= samu_new( NULL
)) ) {
702 ret
= pdb_getsampwnam(sam_account
, user
);
706 sid_copy(&user_sid
, pdb_get_user_sid(sam_account
));
709 TALLOC_FREE(sam_account
);
712 if (!sid_check_is_in_our_domain(&user_sid
)) {
713 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
714 user
, sid_string_static(&user_sid
)));
718 sid_peek_rid(&user_sid
, rid
);
719 *type
= SID_NAME_USER
;
725 * Maybe it is a group ?
729 ret
= pdb_getgrnam(&map
, user
);
736 /* BUILTIN groups are looked up elsewhere */
737 if (!sid_check_is_in_our_domain(&map
.sid
)) {
738 DEBUG(10, ("Found group %s (%s) not in our domain -- "
740 sid_string_static(&map
.sid
)));
744 /* yes it's a mapped group */
745 sid_peek_rid(&map
.sid
, rid
);
746 *type
= map
.sid_name_use
;
750 /*************************************************************
751 Change a password entry in the local smbpasswd file.
752 *************************************************************/
754 NTSTATUS
local_password_change(const char *user_name
, int local_flags
,
755 const char *new_passwd
,
756 char *err_str
, size_t err_str_len
,
757 char *msg_str
, size_t msg_str_len
)
759 struct samu
*sam_pass
=NULL
;
766 /* Get the smb passwd entry for this user */
768 if ( !(sam_pass
= samu_new( NULL
)) ) {
769 return NT_STATUS_NO_MEMORY
;
773 if(!pdb_getsampwnam(sam_pass
, user_name
)) {
775 TALLOC_FREE(sam_pass
);
777 if ((local_flags
& LOCAL_ADD_USER
) || (local_flags
& LOCAL_DELETE_USER
)) {
778 int tmp_debug
= DEBUGLEVEL
;
780 /* Might not exist in /etc/passwd. */
786 result
= pdb_init_sam_new(&sam_pass
, user_name
);
787 DEBUGLEVEL
= tmp_debug
;
788 if (NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PRIMARY_GROUP
)) {
792 if (!NT_STATUS_IS_OK(result
)) {
793 slprintf(err_str
, err_str_len
-1, "Failed to "
794 "initialize account for user %s: %s\n",
795 user_name
, nt_errstr(result
));
799 slprintf(err_str
, err_str_len
-1,"Failed to find entry for user %s.\n", user_name
);
800 return NT_STATUS_NO_SUCH_USER
;
804 /* the entry already existed */
805 local_flags
&= ~LOCAL_ADD_USER
;
808 /* the 'other' acb bits not being changed here */
809 other_acb
= (pdb_get_acct_ctrl(sam_pass
) & (!(ACB_WSTRUST
|ACB_DOMTRUST
|ACB_SVRTRUST
|ACB_NORMAL
)));
810 if (local_flags
& LOCAL_TRUST_ACCOUNT
) {
811 if (!pdb_set_acct_ctrl(sam_pass
, ACB_WSTRUST
| other_acb
, PDB_CHANGED
) ) {
812 slprintf(err_str
, err_str_len
- 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name
);
813 TALLOC_FREE(sam_pass
);
814 return NT_STATUS_UNSUCCESSFUL
;
816 } else if (local_flags
& LOCAL_INTERDOM_ACCOUNT
) {
817 if (!pdb_set_acct_ctrl(sam_pass
, ACB_DOMTRUST
| other_acb
, PDB_CHANGED
)) {
818 slprintf(err_str
, err_str_len
- 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name
);
819 TALLOC_FREE(sam_pass
);
820 return NT_STATUS_UNSUCCESSFUL
;
823 if (!pdb_set_acct_ctrl(sam_pass
, ACB_NORMAL
| other_acb
, PDB_CHANGED
)) {
824 slprintf(err_str
, err_str_len
- 1, "Failed to set 'normal account' flags for user %s.\n", user_name
);
825 TALLOC_FREE(sam_pass
);
826 return NT_STATUS_UNSUCCESSFUL
;
831 * We are root - just write the new password
832 * and the valid last change time.
835 if (local_flags
& LOCAL_DISABLE_USER
) {
836 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_DISABLED
, PDB_CHANGED
)) {
837 slprintf(err_str
, err_str_len
-1, "Failed to set 'disabled' flag for user %s.\n", user_name
);
838 TALLOC_FREE(sam_pass
);
839 return NT_STATUS_UNSUCCESSFUL
;
841 } else if (local_flags
& LOCAL_ENABLE_USER
) {
842 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
843 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
844 TALLOC_FREE(sam_pass
);
845 return NT_STATUS_UNSUCCESSFUL
;
849 if (local_flags
& LOCAL_SET_NO_PASSWORD
) {
850 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)|ACB_PWNOTREQ
, PDB_CHANGED
)) {
851 slprintf(err_str
, err_str_len
-1, "Failed to set 'no password required' flag for user %s.\n", user_name
);
852 TALLOC_FREE(sam_pass
);
853 return NT_STATUS_UNSUCCESSFUL
;
855 } else if (local_flags
& LOCAL_SET_PASSWORD
) {
857 * If we're dealing with setting a completely empty user account
858 * ie. One with a password of 'XXXX', but not set disabled (like
859 * an account created from scratch) then if the old password was
860 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
861 * We remove that as we're giving this user their first password
862 * and the decision hasn't really been made to disable them (ie.
863 * don't create them disabled). JRA.
865 if ((pdb_get_lanman_passwd(sam_pass
)==NULL
) && (pdb_get_acct_ctrl(sam_pass
)&ACB_DISABLED
)) {
866 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_DISABLED
), PDB_CHANGED
)) {
867 slprintf(err_str
, err_str_len
-1, "Failed to unset 'disabled' flag for user %s.\n", user_name
);
868 TALLOC_FREE(sam_pass
);
869 return NT_STATUS_UNSUCCESSFUL
;
872 if (!pdb_set_acct_ctrl (sam_pass
, pdb_get_acct_ctrl(sam_pass
)&(~ACB_PWNOTREQ
), PDB_CHANGED
)) {
873 slprintf(err_str
, err_str_len
-1, "Failed to unset 'no password required' flag for user %s.\n", user_name
);
874 TALLOC_FREE(sam_pass
);
875 return NT_STATUS_UNSUCCESSFUL
;
878 if (!pdb_set_plaintext_passwd (sam_pass
, new_passwd
)) {
879 slprintf(err_str
, err_str_len
-1, "Failed to set password for user %s.\n", user_name
);
880 TALLOC_FREE(sam_pass
);
881 return NT_STATUS_UNSUCCESSFUL
;
885 if (local_flags
& LOCAL_ADD_USER
) {
886 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass
))) {
887 slprintf(msg_str
, msg_str_len
-1, "Added user %s.\n", user_name
);
888 TALLOC_FREE(sam_pass
);
891 slprintf(err_str
, err_str_len
-1, "Failed to add entry for user %s.\n", user_name
);
892 TALLOC_FREE(sam_pass
);
893 return NT_STATUS_UNSUCCESSFUL
;
895 } else if (local_flags
& LOCAL_DELETE_USER
) {
896 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass
))) {
897 slprintf(err_str
,err_str_len
-1, "Failed to delete entry for user %s.\n", user_name
);
898 TALLOC_FREE(sam_pass
);
899 return NT_STATUS_UNSUCCESSFUL
;
901 slprintf(msg_str
, msg_str_len
-1, "Deleted user %s.\n", user_name
);
903 result
= pdb_update_sam_account(sam_pass
);
904 if(!NT_STATUS_IS_OK(result
)) {
905 slprintf(err_str
, err_str_len
-1, "Failed to modify entry for user %s.\n", user_name
);
906 TALLOC_FREE(sam_pass
);
909 if(local_flags
& LOCAL_DISABLE_USER
)
910 slprintf(msg_str
, msg_str_len
-1, "Disabled user %s.\n", user_name
);
911 else if (local_flags
& LOCAL_ENABLE_USER
)
912 slprintf(msg_str
, msg_str_len
-1, "Enabled user %s.\n", user_name
);
913 else if (local_flags
& LOCAL_SET_NO_PASSWORD
)
914 slprintf(msg_str
, msg_str_len
-1, "User %s password set to none.\n", user_name
);
917 TALLOC_FREE(sam_pass
);
921 /**********************************************************************
922 Marshall/unmarshall struct samu structs.
923 *********************************************************************/
925 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
927 /*********************************************************************
928 *********************************************************************/
930 BOOL
init_sam_from_buffer_v2(struct samu
*sampass
, uint8
*buf
, uint32 buflen
)
933 /* times are stored as 32bit integer
934 take care on system with 64bit wide time_t
941 pass_can_change_time
,
942 pass_must_change_time
;
943 char *username
= NULL
;
945 char *nt_username
= NULL
;
946 char *dir_drive
= NULL
;
947 char *unknown_str
= NULL
;
948 char *munged_dial
= NULL
;
949 char *fullname
= NULL
;
950 char *homedir
= NULL
;
951 char *logon_script
= NULL
;
952 char *profile_path
= NULL
;
953 char *acct_desc
= NULL
;
954 char *workstations
= NULL
;
955 uint32 username_len
, domain_len
, nt_username_len
,
956 dir_drive_len
, unknown_str_len
, munged_dial_len
,
957 fullname_len
, homedir_len
, logon_script_len
,
958 profile_path_len
, acct_desc_len
, workstations_len
;
960 uint32 user_rid
, group_rid
, hours_len
, unknown_6
;
961 uint16 acct_ctrl
, logon_divs
;
962 uint16 bad_password_count
, logon_count
;
964 uint8
*lm_pw_ptr
= NULL
, *nt_pw_ptr
= NULL
, *nt_pw_hist_ptr
= NULL
;
966 uint32 lm_pw_len
, nt_pw_len
, nt_pw_hist_len
, hourslen
;
967 uint32 pwHistLen
= 0;
970 BOOL expand_explicit
= lp_passdb_expand_explicit();
972 if(sampass
== NULL
|| buf
== NULL
) {
973 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
977 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
979 /* unpack the buffer into variables */
980 len
= tdb_unpack ((char *)buf
, buflen
, TDB_FORMAT_STRING_V2
,
982 &logoff_time
, /* d */
983 &kickoff_time
, /* d */
984 &bad_password_time
, /* d */
985 &pass_last_set_time
, /* d */
986 &pass_can_change_time
, /* d */
987 &pass_must_change_time
, /* d */
988 &username_len
, &username
, /* B */
989 &domain_len
, &domain
, /* B */
990 &nt_username_len
, &nt_username
, /* B */
991 &fullname_len
, &fullname
, /* B */
992 &homedir_len
, &homedir
, /* B */
993 &dir_drive_len
, &dir_drive
, /* B */
994 &logon_script_len
, &logon_script
, /* B */
995 &profile_path_len
, &profile_path
, /* B */
996 &acct_desc_len
, &acct_desc
, /* B */
997 &workstations_len
, &workstations
, /* B */
998 &unknown_str_len
, &unknown_str
, /* B */
999 &munged_dial_len
, &munged_dial
, /* B */
1002 &lm_pw_len
, &lm_pw_ptr
, /* B */
1003 &nt_pw_len
, &nt_pw_ptr
, /* B */
1004 /* Change from V1 is addition of password history field. */
1005 &nt_pw_hist_len
, &nt_pw_hist_ptr
, /* B */
1007 /* Also "remove_me" field was removed. */
1008 &logon_divs
, /* w */
1010 &hourslen
, &hours
, /* B */
1011 &bad_password_count
, /* w */
1012 &logon_count
, /* w */
1013 &unknown_6
); /* d */
1015 if (len
== (uint32
) -1) {
1020 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
1021 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
1022 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
1023 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
1024 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
1025 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
1026 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
1028 pdb_set_username(sampass
, username
, PDB_SET
);
1029 pdb_set_domain(sampass
, domain
, PDB_SET
);
1030 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
1031 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
1034 fstrcpy( tmpstring
, homedir
);
1035 if (expand_explicit
) {
1036 standard_sub_basic( username
, tmpstring
,
1037 sizeof(tmpstring
) );
1039 pdb_set_homedir(sampass
, tmpstring
, PDB_SET
);
1042 pdb_set_homedir(sampass
,
1043 talloc_sub_basic(sampass
, username
, lp_logon_home()),
1048 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
1050 pdb_set_dir_drive(sampass
, lp_logon_drive(), PDB_DEFAULT
);
1053 fstrcpy( tmpstring
, logon_script
);
1054 if (expand_explicit
) {
1055 standard_sub_basic( username
, tmpstring
,
1056 sizeof(tmpstring
) );
1058 pdb_set_logon_script(sampass
, tmpstring
, PDB_SET
);
1061 pdb_set_logon_script(sampass
,
1062 talloc_sub_basic(sampass
, username
, lp_logon_script()),
1067 fstrcpy( tmpstring
, profile_path
);
1068 if (expand_explicit
) {
1069 standard_sub_basic( username
, tmpstring
,
1070 sizeof(tmpstring
) );
1072 pdb_set_profile_path(sampass
, tmpstring
, PDB_SET
);
1075 pdb_set_profile_path(sampass
,
1076 talloc_sub_basic(sampass
, username
, lp_logon_path()),
1080 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
1081 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
1082 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
1084 if (lm_pw_ptr
&& lm_pw_len
== LM_HASH_LEN
) {
1085 if (!pdb_set_lanman_passwd(sampass
, lm_pw_ptr
, PDB_SET
)) {
1091 if (nt_pw_ptr
&& nt_pw_len
== NT_HASH_LEN
) {
1092 if (!pdb_set_nt_passwd(sampass
, nt_pw_ptr
, PDB_SET
)) {
1098 /* Change from V1 is addition of password history field. */
1099 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1101 uint8
*pw_hist
= SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1106 memset(pw_hist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
1107 if (nt_pw_hist_ptr
&& nt_pw_hist_len
) {
1109 SMB_ASSERT((nt_pw_hist_len
% PW_HISTORY_ENTRY_LEN
) == 0);
1110 nt_pw_hist_len
/= PW_HISTORY_ENTRY_LEN
;
1111 for (i
= 0; (i
< pwHistLen
) && (i
< nt_pw_hist_len
); i
++) {
1112 memcpy(&pw_hist
[i
*PW_HISTORY_ENTRY_LEN
],
1113 &nt_pw_hist_ptr
[i
*PW_HISTORY_ENTRY_LEN
],
1114 PW_HISTORY_ENTRY_LEN
);
1117 if (!pdb_set_pw_history(sampass
, pw_hist
, pwHistLen
, PDB_SET
)) {
1124 pdb_set_pw_history(sampass
, NULL
, 0, PDB_SET
);
1127 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
1128 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
1129 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
1130 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
1131 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
1132 pdb_set_unknown_6(sampass
, unknown_6
, PDB_SET
);
1133 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
1134 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
1135 pdb_set_hours(sampass
, hours
, PDB_SET
);
1139 SAFE_FREE(username
);
1141 SAFE_FREE(nt_username
);
1142 SAFE_FREE(fullname
);
1144 SAFE_FREE(dir_drive
);
1145 SAFE_FREE(logon_script
);
1146 SAFE_FREE(profile_path
);
1147 SAFE_FREE(acct_desc
);
1148 SAFE_FREE(workstations
);
1149 SAFE_FREE(munged_dial
);
1150 SAFE_FREE(unknown_str
);
1151 SAFE_FREE(lm_pw_ptr
);
1152 SAFE_FREE(nt_pw_ptr
);
1153 SAFE_FREE(nt_pw_hist_ptr
);
1159 /*********************************************************************
1160 *********************************************************************/
1162 uint32
init_buffer_from_sam_v2 (uint8
**buf
, const struct samu
*sampass
, BOOL size_only
)
1166 /* times are stored as 32bit integer
1167 take care on system with 64bit wide time_t
1174 pass_can_change_time
,
1175 pass_must_change_time
;
1177 uint32 user_rid
, group_rid
;
1179 const char *username
;
1181 const char *nt_username
;
1182 const char *dir_drive
;
1183 const char *unknown_str
;
1184 const char *munged_dial
;
1185 const char *fullname
;
1186 const char *homedir
;
1187 const char *logon_script
;
1188 const char *profile_path
;
1189 const char *acct_desc
;
1190 const char *workstations
;
1191 uint32 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
;
1198 const uint8
*nt_pw_hist
;
1199 uint32 lm_pw_len
= 16;
1200 uint32 nt_pw_len
= 16;
1201 uint32 nt_pw_hist_len
;
1202 uint32 pwHistLen
= 0;
1204 /* do we have a valid struct samu pointer? */
1205 if (sampass
== NULL
) {
1206 DEBUG(0, ("init_buffer_from_sam: struct samu is NULL!\n"));
1213 logon_time
= (uint32
)pdb_get_logon_time(sampass
);
1214 logoff_time
= (uint32
)pdb_get_logoff_time(sampass
);
1215 kickoff_time
= (uint32
)pdb_get_kickoff_time(sampass
);
1216 bad_password_time
= (uint32
)pdb_get_bad_password_time(sampass
);
1217 pass_can_change_time
= (uint32
)pdb_get_pass_can_change_time(sampass
);
1218 pass_must_change_time
= (uint32
)pdb_get_pass_must_change_time(sampass
);
1219 pass_last_set_time
= (uint32
)pdb_get_pass_last_set_time(sampass
);
1221 user_rid
= pdb_get_user_rid(sampass
);
1222 group_rid
= pdb_get_group_rid(sampass
);
1224 username
= pdb_get_username(sampass
);
1226 username_len
= strlen(username
) +1;
1231 domain
= pdb_get_domain(sampass
);
1233 domain_len
= strlen(domain
) +1;
1238 nt_username
= pdb_get_nt_username(sampass
);
1240 nt_username_len
= strlen(nt_username
) +1;
1242 nt_username_len
= 0;
1245 fullname
= pdb_get_fullname(sampass
);
1247 fullname_len
= strlen(fullname
) +1;
1253 * Only updates fields which have been set (not defaults from smb.conf)
1256 if (!IS_SAM_DEFAULT(sampass
, PDB_DRIVE
)) {
1257 dir_drive
= pdb_get_dir_drive(sampass
);
1262 dir_drive_len
= strlen(dir_drive
) +1;
1267 if (!IS_SAM_DEFAULT(sampass
, PDB_SMBHOME
)) {
1268 homedir
= pdb_get_homedir(sampass
);
1273 homedir_len
= strlen(homedir
) +1;
1278 if (!IS_SAM_DEFAULT(sampass
, PDB_LOGONSCRIPT
)) {
1279 logon_script
= pdb_get_logon_script(sampass
);
1281 logon_script
= NULL
;
1284 logon_script_len
= strlen(logon_script
) +1;
1286 logon_script_len
= 0;
1289 if (!IS_SAM_DEFAULT(sampass
, PDB_PROFILE
)) {
1290 profile_path
= pdb_get_profile_path(sampass
);
1292 profile_path
= NULL
;
1295 profile_path_len
= strlen(profile_path
) +1;
1297 profile_path_len
= 0;
1300 lm_pw
= pdb_get_lanman_passwd(sampass
);
1305 nt_pw
= pdb_get_nt_passwd(sampass
);
1310 pdb_get_account_policy(AP_PASSWORD_HISTORY
, &pwHistLen
);
1311 nt_pw_hist
= pdb_get_pw_history(sampass
, &nt_pw_hist_len
);
1312 if (pwHistLen
&& nt_pw_hist
&& nt_pw_hist_len
) {
1313 nt_pw_hist_len
*= PW_HISTORY_ENTRY_LEN
;
1318 acct_desc
= pdb_get_acct_desc(sampass
);
1320 acct_desc_len
= strlen(acct_desc
) +1;
1325 workstations
= pdb_get_workstations(sampass
);
1327 workstations_len
= strlen(workstations
) +1;
1329 workstations_len
= 0;
1333 unknown_str_len
= 0;
1335 munged_dial
= pdb_get_munged_dial(sampass
);
1337 munged_dial_len
= strlen(munged_dial
) +1;
1339 munged_dial_len
= 0;
1342 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1344 /* one time to get the size needed */
1345 len
= tdb_pack(NULL
, 0, TDB_FORMAT_STRING_V2
,
1347 logoff_time
, /* d */
1348 kickoff_time
, /* d */
1349 bad_password_time
, /* d */
1350 pass_last_set_time
, /* d */
1351 pass_can_change_time
, /* d */
1352 pass_must_change_time
, /* d */
1353 username_len
, username
, /* B */
1354 domain_len
, domain
, /* B */
1355 nt_username_len
, nt_username
, /* B */
1356 fullname_len
, fullname
, /* B */
1357 homedir_len
, homedir
, /* B */
1358 dir_drive_len
, dir_drive
, /* B */
1359 logon_script_len
, logon_script
, /* B */
1360 profile_path_len
, profile_path
, /* B */
1361 acct_desc_len
, acct_desc
, /* B */
1362 workstations_len
, workstations
, /* B */
1363 unknown_str_len
, unknown_str
, /* B */
1364 munged_dial_len
, munged_dial
, /* B */
1367 lm_pw_len
, lm_pw
, /* B */
1368 nt_pw_len
, nt_pw
, /* B */
1369 nt_pw_hist_len
, nt_pw_hist
, /* B */
1370 pdb_get_acct_ctrl(sampass
), /* w */
1371 pdb_get_logon_divs(sampass
), /* w */
1372 pdb_get_hours_len(sampass
), /* d */
1373 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1374 pdb_get_bad_password_count(sampass
), /* w */
1375 pdb_get_logon_count(sampass
), /* w */
1376 pdb_get_unknown_6(sampass
)); /* d */
1382 /* malloc the space needed */
1383 if ( (*buf
=(uint8
*)SMB_MALLOC(len
)) == NULL
) {
1384 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
1388 /* now for the real call to tdb_pack() */
1389 buflen
= tdb_pack((char *)*buf
, len
, TDB_FORMAT_STRING_V2
,
1391 logoff_time
, /* d */
1392 kickoff_time
, /* d */
1393 bad_password_time
, /* d */
1394 pass_last_set_time
, /* d */
1395 pass_can_change_time
, /* d */
1396 pass_must_change_time
, /* d */
1397 username_len
, username
, /* B */
1398 domain_len
, domain
, /* B */
1399 nt_username_len
, nt_username
, /* B */
1400 fullname_len
, fullname
, /* B */
1401 homedir_len
, homedir
, /* B */
1402 dir_drive_len
, dir_drive
, /* B */
1403 logon_script_len
, logon_script
, /* B */
1404 profile_path_len
, profile_path
, /* B */
1405 acct_desc_len
, acct_desc
, /* B */
1406 workstations_len
, workstations
, /* B */
1407 unknown_str_len
, unknown_str
, /* B */
1408 munged_dial_len
, munged_dial
, /* B */
1411 lm_pw_len
, lm_pw
, /* B */
1412 nt_pw_len
, nt_pw
, /* B */
1413 nt_pw_hist_len
, nt_pw_hist
, /* B */
1414 pdb_get_acct_ctrl(sampass
), /* w */
1415 pdb_get_logon_divs(sampass
), /* w */
1416 pdb_get_hours_len(sampass
), /* d */
1417 MAX_HOURS_LEN
, pdb_get_hours(sampass
), /* B */
1418 pdb_get_bad_password_count(sampass
), /* w */
1419 pdb_get_logon_count(sampass
), /* w */
1420 pdb_get_unknown_6(sampass
)); /* d */
1422 /* check to make sure we got it correct */
1423 if (buflen
!= len
) {
1424 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1425 (unsigned long)buflen
, (unsigned long)len
));
1435 /*********************************************************************
1436 *********************************************************************/
1438 BOOL
pdb_copy_sam_account(const struct samu
*src
, struct samu
**dst
)
1444 if ( !*dst
&& !(*dst
= samu_new(NULL
)) )
1447 len
= init_buffer_from_sam_v2(&buf
, src
, False
);
1452 result
= init_sam_from_buffer_v2(*dst
, buf
, len
);
1453 (*dst
)->methods
= src
->methods
;
1460 /*********************************************************************
1461 Update the bad password count checking the AP_RESET_COUNT_TIME
1462 *********************************************************************/
1464 BOOL
pdb_update_bad_password_count(struct samu
*sampass
, BOOL
*updated
)
1466 time_t LastBadPassword
;
1467 uint16 BadPasswordCount
;
1470 if (!sampass
) return False
;
1472 BadPasswordCount
= pdb_get_bad_password_count(sampass
);
1473 if (!BadPasswordCount
) {
1474 DEBUG(9, ("No bad password attempts.\n"));
1478 if (!pdb_get_account_policy(AP_RESET_COUNT_TIME
, &resettime
)) {
1479 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1483 /* First, check if there is a reset time to compare */
1484 if ((resettime
== (uint32
) -1) || (resettime
== 0)) {
1485 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1489 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1490 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1491 (uint32
) LastBadPassword
, resettime
, (uint32
)time(NULL
)));
1492 if (time(NULL
) > (LastBadPassword
+ (time_t)resettime
*60)){
1493 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1494 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1503 /*********************************************************************
1504 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1505 *********************************************************************/
1507 BOOL
pdb_update_autolock_flag(struct samu
*sampass
, BOOL
*updated
)
1510 time_t LastBadPassword
;
1512 if (!sampass
) return False
;
1514 if (!(pdb_get_acct_ctrl(sampass
) & ACB_AUTOLOCK
)) {
1515 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1516 pdb_get_username(sampass
)));
1520 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION
, &duration
)) {
1521 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1525 /* First, check if there is a duration to compare */
1526 if ((duration
== (uint32
) -1) || (duration
== 0)) {
1527 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1531 LastBadPassword
= pdb_get_bad_password_time(sampass
);
1532 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1533 pdb_get_username(sampass
), (uint32
)LastBadPassword
, duration
*60, (uint32
)time(NULL
)));
1535 if (LastBadPassword
== (time_t)0) {
1536 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
1537 bad password time. Leaving locked out.\n",
1538 pdb_get_username(sampass
) ));
1542 if ((time(NULL
) > (LastBadPassword
+ (time_t) duration
* 60))) {
1543 pdb_set_acct_ctrl(sampass
,
1544 pdb_get_acct_ctrl(sampass
) & ~ACB_AUTOLOCK
,
1546 pdb_set_bad_password_count(sampass
, 0, PDB_CHANGED
);
1547 pdb_set_bad_password_time(sampass
, 0, PDB_CHANGED
);
1556 /*********************************************************************
1557 Increment the bad_password_count
1558 *********************************************************************/
1560 BOOL
pdb_increment_bad_password_count(struct samu
*sampass
)
1562 uint32 account_policy_lockout
;
1563 BOOL autolock_updated
= False
, badpw_updated
= False
;
1569 /* Retrieve the account lockout policy */
1571 ret
= pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT
, &account_policy_lockout
);
1574 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1578 /* If there is no policy, we don't need to continue checking */
1579 if (!account_policy_lockout
) {
1580 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1584 /* Check if the autolock needs to be cleared */
1585 if (!pdb_update_autolock_flag(sampass
, &autolock_updated
))
1588 /* Check if the badpw count needs to be reset */
1589 if (!pdb_update_bad_password_count(sampass
, &badpw_updated
))
1593 Ok, now we can assume that any resetting that needs to be
1594 done has been done, and just get on with incrementing
1595 and autolocking if necessary
1598 pdb_set_bad_password_count(sampass
,
1599 pdb_get_bad_password_count(sampass
)+1,
1601 pdb_set_bad_password_time(sampass
, time(NULL
), PDB_CHANGED
);
1604 if (pdb_get_bad_password_count(sampass
) < account_policy_lockout
)
1607 if (!pdb_set_acct_ctrl(sampass
,
1608 pdb_get_acct_ctrl(sampass
) | ACB_AUTOLOCK
,
1610 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));