Let get_trust_pw() determine the machine_account_name to use.
[Samba/gebeck_regimport.git] / source3 / passdb / passdb.c
blobf9b972da9b0db9dff4a757e03fe27e9eb932e891
1 /*
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/>.
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 /******************************************************************
31 get the default domain/netbios name to be used when
32 testing authentication. For example, if you connect
33 to a Windows member server using a bogus domain name, the
34 Windows box will map the BOGUS\user to DOMAIN\user. A
35 standalone box will map to WKS\user.
36 ******************************************************************/
38 const char *my_sam_name(void)
40 /* standalone servers can only use the local netbios name */
41 if ( lp_server_role() == ROLE_STANDALONE )
42 return global_myname();
44 /* Windows domain members default to the DOMAIN
45 name when not specified */
46 return lp_workgroup();
49 /**********************************************************************
50 ***********************************************************************/
52 static int samu_destroy(struct samu *user)
54 data_blob_clear_free( &user->lm_pw );
55 data_blob_clear_free( &user->nt_pw );
57 if ( user->plaintext_pw )
58 memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
60 return 0;
63 /**********************************************************************
64 generate a new struct samuser
65 ***********************************************************************/
67 struct samu *samu_new( TALLOC_CTX *ctx )
69 struct samu *user;
71 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
72 DEBUG(0,("samuser_new: Talloc failed!\n"));
73 return NULL;
76 talloc_set_destructor( user, samu_destroy );
78 /* no initial methods */
80 user->methods = NULL;
82 /* Don't change these timestamp settings without a good reason.
83 They are important for NT member server compatibility. */
85 user->logon_time = (time_t)0;
86 user->pass_last_set_time = (time_t)0;
87 user->pass_can_change_time = (time_t)0;
88 user->logoff_time = get_time_t_max();
89 user->kickoff_time = get_time_t_max();
90 user->pass_must_change_time = get_time_t_max();
91 user->fields_present = 0x00ffffff;
92 user->logon_divs = 168; /* hours per week */
93 user->hours_len = 21; /* 21 times 8 bits = 168 */
94 memset(user->hours, 0xff, user->hours_len); /* available at all hours */
95 user->bad_password_count = 0;
96 user->logon_count = 0;
97 user->unknown_6 = 0x000004ec; /* don't know */
99 /* Some parts of samba strlen their pdb_get...() returns,
100 so this keeps the interface unchanged for now. */
102 user->username = "";
103 user->domain = "";
104 user->nt_username = "";
105 user->full_name = "";
106 user->home_dir = "";
107 user->logon_script = "";
108 user->profile_path = "";
109 user->acct_desc = "";
110 user->workstations = "";
111 user->comment = "";
112 user->munged_dial = "";
114 user->plaintext_pw = NULL;
116 /* Unless we know otherwise have a Account Control Bit
117 value of 'normal user'. This helps User Manager, which
118 asks for a filtered list of users. */
120 user->acct_ctrl = ACB_NORMAL;
123 return user;
126 /*********************************************************************
127 Initialize a struct samu from a struct passwd including the user
128 and group SIDs. The *user structure is filled out with the Unix
129 attributes and a user SID.
130 *********************************************************************/
132 static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, bool create)
134 const char *guest_account = lp_guestaccount();
135 const char *domain = global_myname();
136 uint32 urid;
138 if ( !pwd ) {
139 return NT_STATUS_NO_SUCH_USER;
142 /* Basic properties based upon the Unix account information */
144 pdb_set_username(user, pwd->pw_name, PDB_SET);
145 pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
146 pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
147 #if 0
148 /* This can lead to a primary group of S-1-22-2-XX which
149 will be rejected by other parts of the Samba code.
150 Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
151 --jerry */
153 gid_to_sid(&group_sid, pwd->pw_gid);
154 pdb_set_group_sid(user, &group_sid, PDB_SET);
155 #endif
157 /* save the password structure for later use */
159 user->unix_pw = tcopy_passwd( user, pwd );
161 /* Special case for the guest account which must have a RID of 501 */
163 if ( strequal( pwd->pw_name, guest_account ) ) {
164 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
165 return NT_STATUS_NO_SUCH_USER;
167 return NT_STATUS_OK;
170 /* Non-guest accounts...Check for a workstation or user account */
172 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
173 /* workstation */
175 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
176 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
177 pwd->pw_name));
178 return NT_STATUS_INVALID_COMPUTER_NAME;
181 else {
182 /* user */
184 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
185 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
186 pwd->pw_name));
187 return NT_STATUS_INVALID_ACCOUNT_NAME;
190 /* set some basic attributes */
192 pdb_set_profile_path(user, talloc_sub_specified(user,
193 lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
194 PDB_DEFAULT);
195 pdb_set_homedir(user, talloc_sub_specified(user,
196 lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
197 PDB_DEFAULT);
198 pdb_set_dir_drive(user, talloc_sub_specified(user,
199 lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
200 PDB_DEFAULT);
201 pdb_set_logon_script(user, talloc_sub_specified(user,
202 lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
203 PDB_DEFAULT);
206 /* Now deal with the user SID. If we have a backend that can generate
207 RIDs, then do so. But sometimes the caller just wanted a structure
208 initialized and will fill in these fields later (such as from a
209 NET_USER_INFO_3 structure) */
211 if ( create && !pdb_rid_algorithm() ) {
212 uint32 user_rid;
213 DOM_SID user_sid;
215 if ( !pdb_new_rid( &user_rid ) ) {
216 DEBUG(3, ("Could not allocate a new RID\n"));
217 return NT_STATUS_ACCESS_DENIED;
220 sid_copy( &user_sid, get_global_sam_sid() );
221 sid_append_rid( &user_sid, user_rid );
223 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
224 DEBUG(3, ("pdb_set_user_sid failed\n"));
225 return NT_STATUS_INTERNAL_ERROR;
228 return NT_STATUS_OK;
231 /* generate a SID for the user with the RID algorithm */
233 urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
235 if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
236 return NT_STATUS_INTERNAL_ERROR;
239 return NT_STATUS_OK;
242 /********************************************************************
243 Set the Unix user attributes
244 ********************************************************************/
246 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
248 return samu_set_unix_internal( user, pwd, False );
251 NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
253 return samu_set_unix_internal( user, pwd, True );
256 /**********************************************************
257 Encode the account control bits into a string.
258 length = length of string to encode into (including terminating
259 null). length *MUST BE MORE THAN 2* !
260 **********************************************************/
262 char *pdb_encode_acct_ctrl(uint32 acct_ctrl, size_t length)
264 fstring acct_str;
265 char *result;
267 size_t i = 0;
269 SMB_ASSERT(length <= sizeof(acct_str));
271 acct_str[i++] = '[';
273 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
274 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
275 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
276 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
277 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
278 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
279 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
280 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
281 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
282 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
283 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
285 for ( ; i < length - 2 ; i++ )
286 acct_str[i] = ' ';
288 i = length - 2;
289 acct_str[i++] = ']';
290 acct_str[i++] = '\0';
292 result = talloc_strdup(talloc_tos(), acct_str);
293 SMB_ASSERT(result != NULL);
294 return result;
297 /**********************************************************
298 Decode the account control bits from a string.
299 **********************************************************/
301 uint32 pdb_decode_acct_ctrl(const char *p)
303 uint32 acct_ctrl = 0;
304 bool finished = False;
307 * Check if the account type bits have been encoded after the
308 * NT password (in the form [NDHTUWSLXI]).
311 if (*p != '[')
312 return 0;
314 for (p++; *p && !finished; p++) {
315 switch (*p) {
316 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
317 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
318 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
319 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
320 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
321 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
322 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
323 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
324 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
325 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
326 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
327 case ' ': { break; }
328 case ':':
329 case '\n':
330 case '\0':
331 case ']':
332 default: { finished = True; }
336 return acct_ctrl;
339 /*************************************************************
340 Routine to set 32 hex password characters from a 16 byte array.
341 **************************************************************/
343 void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32 acct_ctrl)
345 if (pwd != NULL) {
346 int i;
347 for (i = 0; i < 16; i++)
348 slprintf(&p[i*2], 3, "%02X", pwd[i]);
349 } else {
350 if (acct_ctrl & ACB_PWNOTREQ)
351 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32);
352 else
353 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32);
357 /*************************************************************
358 Routine to get the 32 hex characters and turn them
359 into a 16 byte array.
360 **************************************************************/
362 bool pdb_gethexpwd(const char *p, unsigned char *pwd)
364 int i;
365 unsigned char lonybble, hinybble;
366 const char *hexchars = "0123456789ABCDEF";
367 char *p1, *p2;
369 if (!p)
370 return (False);
372 for (i = 0; i < 32; i += 2) {
373 hinybble = toupper_ascii(p[i]);
374 lonybble = toupper_ascii(p[i + 1]);
376 p1 = strchr(hexchars, hinybble);
377 p2 = strchr(hexchars, lonybble);
379 if (!p1 || !p2)
380 return (False);
382 hinybble = PTR_DIFF(p1, hexchars);
383 lonybble = PTR_DIFF(p2, hexchars);
385 pwd[i / 2] = (hinybble << 4) | lonybble;
387 return (True);
390 /*************************************************************
391 Routine to set 42 hex hours characters from a 21 byte array.
392 **************************************************************/
394 void pdb_sethexhours(char *p, const unsigned char *hours)
396 if (hours != NULL) {
397 int i;
398 for (i = 0; i < 21; i++) {
399 slprintf(&p[i*2], 3, "%02X", hours[i]);
401 } else {
402 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
406 /*************************************************************
407 Routine to get the 42 hex characters and turn them
408 into a 21 byte array.
409 **************************************************************/
411 bool pdb_gethexhours(const char *p, unsigned char *hours)
413 int i;
414 unsigned char lonybble, hinybble;
415 const char *hexchars = "0123456789ABCDEF";
416 char *p1, *p2;
418 if (!p) {
419 return (False);
422 for (i = 0; i < 42; i += 2) {
423 hinybble = toupper_ascii(p[i]);
424 lonybble = toupper_ascii(p[i + 1]);
426 p1 = strchr(hexchars, hinybble);
427 p2 = strchr(hexchars, lonybble);
429 if (!p1 || !p2) {
430 return (False);
433 hinybble = PTR_DIFF(p1, hexchars);
434 lonybble = PTR_DIFF(p2, hexchars);
436 hours[i / 2] = (hinybble << 4) | lonybble;
438 return (True);
441 /********************************************************************
442 ********************************************************************/
444 int algorithmic_rid_base(void)
446 static int rid_offset = 0;
448 if (rid_offset != 0)
449 return rid_offset;
451 rid_offset = lp_algorithmic_rid_base();
453 if (rid_offset < BASE_RID) {
454 /* Try to prevent admin foot-shooting, we can't put algorithmic
455 rids below 1000, that's the 'well known RIDs' on NT */
456 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
457 rid_offset = BASE_RID;
459 if (rid_offset & 1) {
460 DEBUG(0, ("algorithmic rid base must be even\n"));
461 rid_offset += 1;
463 return rid_offset;
466 /*******************************************************************
467 Converts NT user RID to a UNIX uid.
468 ********************************************************************/
470 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
472 int rid_offset = algorithmic_rid_base();
473 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
476 uid_t max_algorithmic_uid(void)
478 return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
481 /*******************************************************************
482 converts UNIX uid to an NT User RID.
483 ********************************************************************/
485 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
487 int rid_offset = algorithmic_rid_base();
488 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
491 /*******************************************************************
492 Converts NT group RID to a UNIX gid.
493 ********************************************************************/
495 gid_t pdb_group_rid_to_gid(uint32 group_rid)
497 int rid_offset = algorithmic_rid_base();
498 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
501 gid_t max_algorithmic_gid(void)
503 return pdb_group_rid_to_gid(0xffffffff);
506 /*******************************************************************
507 converts NT Group RID to a UNIX uid.
509 warning: you must not call that function only
510 you must do a call to the group mapping first.
511 there is not anymore a direct link between the gid and the rid.
512 ********************************************************************/
514 uint32 algorithmic_pdb_gid_to_group_rid(gid_t gid)
516 int rid_offset = algorithmic_rid_base();
517 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
520 /*******************************************************************
521 Decides if a RID is a well known RID.
522 ********************************************************************/
524 static bool rid_is_well_known(uint32 rid)
526 /* Not using rid_offset here, because this is the actual
527 NT fixed value (1000) */
529 return (rid < BASE_RID);
532 /*******************************************************************
533 Decides if a RID is a user or group RID.
534 ********************************************************************/
536 bool algorithmic_pdb_rid_is_user(uint32 rid)
538 if ( rid_is_well_known(rid) ) {
540 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
541 * and DOMAIN_USER_RID_GUEST.
543 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
544 return True;
545 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
546 return True;
548 return False;
551 /*******************************************************************
552 Convert a name into a SID. Used in the lookup name rpc.
553 ********************************************************************/
555 bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
556 enum lsa_SidType *type)
558 GROUP_MAP map;
559 bool ret;
561 /* Windows treats "MACHINE\None" as a special name for
562 rid 513 on non-DCs. You cannot create a user or group
563 name "None" on Windows. You will get an error that
564 the group already exists. */
566 if ( strequal( name, "None" ) ) {
567 *rid = DOMAIN_GROUP_RID_USERS;
568 *type = SID_NAME_DOM_GRP;
570 return True;
573 /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
574 * correctly in the case where foo also exists as a user. If the flag
575 * is set, don't look for users at all. */
577 if ((flags & LOOKUP_NAME_GROUP) == 0) {
578 struct samu *sam_account = NULL;
579 DOM_SID user_sid;
581 if ( !(sam_account = samu_new( NULL )) ) {
582 return False;
585 become_root();
586 ret = pdb_getsampwnam(sam_account, name);
587 unbecome_root();
589 if (ret) {
590 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
593 TALLOC_FREE(sam_account);
595 if (ret) {
596 if (!sid_check_is_in_our_domain(&user_sid)) {
597 DEBUG(0, ("User %s with invalid SID %s in passdb\n",
598 name, sid_string_static(&user_sid)));
599 return False;
602 sid_peek_rid(&user_sid, rid);
603 *type = SID_NAME_USER;
604 return True;
609 * Maybe it is a group ?
612 become_root();
613 ret = pdb_getgrnam(&map, name);
614 unbecome_root();
616 if (!ret) {
617 return False;
620 /* BUILTIN groups are looked up elsewhere */
621 if (!sid_check_is_in_our_domain(&map.sid)) {
622 DEBUG(10, ("Found group %s (%s) not in our domain -- "
623 "ignoring.", name,
624 sid_string_static(&map.sid)));
625 return False;
628 /* yes it's a mapped group */
629 sid_peek_rid(&map.sid, rid);
630 *type = map.sid_name_use;
631 return True;
634 /*************************************************************
635 Change a password entry in the local smbpasswd file.
636 *************************************************************/
638 NTSTATUS local_password_change(const char *user_name,
639 int local_flags,
640 const char *new_passwd,
641 char **pp_err_str,
642 char **pp_msg_str)
644 struct samu *sam_pass=NULL;
645 uint32 other_acb;
646 NTSTATUS result;
648 *pp_err_str = NULL;
649 *pp_msg_str = NULL;
651 /* Get the smb passwd entry for this user */
653 if ( !(sam_pass = samu_new( NULL )) ) {
654 return NT_STATUS_NO_MEMORY;
657 become_root();
658 if(!pdb_getsampwnam(sam_pass, user_name)) {
659 unbecome_root();
660 TALLOC_FREE(sam_pass);
662 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
663 int tmp_debug = DEBUGLEVEL;
664 struct passwd *pwd;
666 /* Might not exist in /etc/passwd. */
668 if (tmp_debug < 1) {
669 DEBUGLEVEL = 1;
672 if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) {
673 return NT_STATUS_NO_SUCH_USER;
676 /* create the struct samu and initialize the basic Unix properties */
678 if ( !(sam_pass = samu_new( NULL )) ) {
679 return NT_STATUS_NO_MEMORY;
682 result = samu_set_unix( sam_pass, pwd );
684 DEBUGLEVEL = tmp_debug;
686 TALLOC_FREE( pwd );
688 if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) {
689 return result;
692 if (!NT_STATUS_IS_OK(result)) {
693 asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n",
694 user_name, nt_errstr(result));
695 return result;
697 } else {
698 asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name);
699 return NT_STATUS_NO_SUCH_USER;
701 } else {
702 unbecome_root();
703 /* the entry already existed */
704 local_flags &= ~LOCAL_ADD_USER;
707 /* the 'other' acb bits not being changed here */
708 other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
709 if (local_flags & LOCAL_TRUST_ACCOUNT) {
710 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
711 asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
712 TALLOC_FREE(sam_pass);
713 return NT_STATUS_UNSUCCESSFUL;
715 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
716 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
717 asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
718 TALLOC_FREE(sam_pass);
719 return NT_STATUS_UNSUCCESSFUL;
721 } else {
722 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
723 asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name);
724 TALLOC_FREE(sam_pass);
725 return NT_STATUS_UNSUCCESSFUL;
730 * We are root - just write the new password
731 * and the valid last change time.
734 if (local_flags & LOCAL_DISABLE_USER) {
735 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
736 asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name);
737 TALLOC_FREE(sam_pass);
738 return NT_STATUS_UNSUCCESSFUL;
740 } else if (local_flags & LOCAL_ENABLE_USER) {
741 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
742 asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name);
743 TALLOC_FREE(sam_pass);
744 return NT_STATUS_UNSUCCESSFUL;
748 if (local_flags & LOCAL_SET_NO_PASSWORD) {
749 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
750 asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name);
751 TALLOC_FREE(sam_pass);
752 return NT_STATUS_UNSUCCESSFUL;
754 } else if (local_flags & LOCAL_SET_PASSWORD) {
756 * If we're dealing with setting a completely empty user account
757 * ie. One with a password of 'XXXX', but not set disabled (like
758 * an account created from scratch) then if the old password was
759 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
760 * We remove that as we're giving this user their first password
761 * and the decision hasn't really been made to disable them (ie.
762 * don't create them disabled). JRA.
764 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
765 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
766 asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name);
767 TALLOC_FREE(sam_pass);
768 return NT_STATUS_UNSUCCESSFUL;
771 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
772 asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name);
773 TALLOC_FREE(sam_pass);
774 return NT_STATUS_UNSUCCESSFUL;
777 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
778 asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name);
779 TALLOC_FREE(sam_pass);
780 return NT_STATUS_UNSUCCESSFUL;
784 if (local_flags & LOCAL_ADD_USER) {
785 if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
786 asprintf(pp_msg_str, "Added user %s.\n", user_name);
787 TALLOC_FREE(sam_pass);
788 return NT_STATUS_OK;
789 } else {
790 asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name);
791 TALLOC_FREE(sam_pass);
792 return NT_STATUS_UNSUCCESSFUL;
794 } else if (local_flags & LOCAL_DELETE_USER) {
795 if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
796 asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name);
797 TALLOC_FREE(sam_pass);
798 return NT_STATUS_UNSUCCESSFUL;
800 asprintf(pp_msg_str, "Deleted user %s.\n", user_name);
801 } else {
802 result = pdb_update_sam_account(sam_pass);
803 if(!NT_STATUS_IS_OK(result)) {
804 asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name);
805 TALLOC_FREE(sam_pass);
806 return result;
808 if(local_flags & LOCAL_DISABLE_USER)
809 asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
810 else if (local_flags & LOCAL_ENABLE_USER)
811 asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
812 else if (local_flags & LOCAL_SET_NO_PASSWORD)
813 asprintf(pp_msg_str, "User %s password set to none.\n", user_name);
816 TALLOC_FREE(sam_pass);
817 return NT_STATUS_OK;
820 /**********************************************************************
821 Marshall/unmarshall struct samu structs.
822 *********************************************************************/
824 #define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
826 /*********************************************************************
827 *********************************************************************/
829 bool init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
832 /* times are stored as 32bit integer
833 take care on system with 64bit wide time_t
834 --SSS */
835 uint32 logon_time,
836 logoff_time,
837 kickoff_time,
838 bad_password_time,
839 pass_last_set_time,
840 pass_can_change_time,
841 pass_must_change_time;
842 char *username = NULL;
843 char *domain = NULL;
844 char *nt_username = NULL;
845 char *dir_drive = NULL;
846 char *unknown_str = NULL;
847 char *munged_dial = NULL;
848 char *fullname = NULL;
849 char *homedir = NULL;
850 char *logon_script = NULL;
851 char *profile_path = NULL;
852 char *acct_desc = NULL;
853 char *workstations = NULL;
854 uint32 username_len, domain_len, nt_username_len,
855 dir_drive_len, unknown_str_len, munged_dial_len,
856 fullname_len, homedir_len, logon_script_len,
857 profile_path_len, acct_desc_len, workstations_len;
859 uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
860 uint16 logon_divs;
861 uint16 bad_password_count, logon_count;
862 uint8 *hours = NULL;
863 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
864 uint32 len = 0;
865 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
866 uint32 pwHistLen = 0;
867 bool ret = True;
868 fstring tmp_string;
869 bool expand_explicit = lp_passdb_expand_explicit();
871 if(sampass == NULL || buf == NULL) {
872 DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
873 return False;
876 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
878 /* unpack the buffer into variables */
879 len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING_V3,
880 &logon_time, /* d */
881 &logoff_time, /* d */
882 &kickoff_time, /* d */
883 &bad_password_time, /* d */
884 &pass_last_set_time, /* d */
885 &pass_can_change_time, /* d */
886 &pass_must_change_time, /* d */
887 &username_len, &username, /* B */
888 &domain_len, &domain, /* B */
889 &nt_username_len, &nt_username, /* B */
890 &fullname_len, &fullname, /* B */
891 &homedir_len, &homedir, /* B */
892 &dir_drive_len, &dir_drive, /* B */
893 &logon_script_len, &logon_script, /* B */
894 &profile_path_len, &profile_path, /* B */
895 &acct_desc_len, &acct_desc, /* B */
896 &workstations_len, &workstations, /* B */
897 &unknown_str_len, &unknown_str, /* B */
898 &munged_dial_len, &munged_dial, /* B */
899 &user_rid, /* d */
900 &group_rid, /* d */
901 &lm_pw_len, &lm_pw_ptr, /* B */
902 &nt_pw_len, &nt_pw_ptr, /* B */
903 /* Change from V1 is addition of password history field. */
904 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
905 /* Change from V2 is the uint32 acb_mask */
906 &acct_ctrl, /* d */
907 /* Also "remove_me" field was removed. */
908 &logon_divs, /* w */
909 &hours_len, /* d */
910 &hourslen, &hours, /* B */
911 &bad_password_count, /* w */
912 &logon_count, /* w */
913 &unknown_6); /* d */
915 if (len == (uint32) -1) {
916 ret = False;
917 goto done;
920 pdb_set_logon_time(sampass, convert_uint32_to_time_t(logon_time), PDB_SET);
921 pdb_set_logoff_time(sampass, convert_uint32_to_time_t(logoff_time), PDB_SET);
922 pdb_set_kickoff_time(sampass, convert_uint32_to_time_t(kickoff_time), PDB_SET);
923 pdb_set_bad_password_time(sampass, convert_uint32_to_time_t(bad_password_time), PDB_SET);
924 pdb_set_pass_can_change_time(sampass, convert_uint32_to_time_t(pass_can_change_time), PDB_SET);
925 pdb_set_pass_must_change_time(sampass, convert_uint32_to_time_t(pass_must_change_time), PDB_SET);
926 pdb_set_pass_last_set_time(sampass, convert_uint32_to_time_t(pass_last_set_time), PDB_SET);
928 pdb_set_username(sampass, username, PDB_SET);
929 pdb_set_domain(sampass, domain, PDB_SET);
930 pdb_set_nt_username(sampass, nt_username, PDB_SET);
931 pdb_set_fullname(sampass, fullname, PDB_SET);
933 if (homedir) {
934 fstrcpy( tmp_string, homedir );
935 if (expand_explicit) {
936 standard_sub_basic( username, domain, tmp_string,
937 sizeof(tmp_string) );
939 pdb_set_homedir(sampass, tmp_string, PDB_SET);
941 else {
942 pdb_set_homedir(sampass,
943 talloc_sub_basic(sampass, username, domain,
944 lp_logon_home()),
945 PDB_DEFAULT);
948 if (dir_drive)
949 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
950 else
951 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
953 if (logon_script) {
954 fstrcpy( tmp_string, logon_script );
955 if (expand_explicit) {
956 standard_sub_basic( username, domain, tmp_string,
957 sizeof(tmp_string) );
959 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
961 else {
962 pdb_set_logon_script(sampass,
963 talloc_sub_basic(sampass, username, domain,
964 lp_logon_script()),
965 PDB_DEFAULT);
968 if (profile_path) {
969 fstrcpy( tmp_string, profile_path );
970 if (expand_explicit) {
971 standard_sub_basic( username, domain, tmp_string,
972 sizeof(tmp_string) );
974 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
976 else {
977 pdb_set_profile_path(sampass,
978 talloc_sub_basic(sampass, username, domain, lp_logon_path()),
979 PDB_DEFAULT);
982 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
983 pdb_set_workstations(sampass, workstations, PDB_SET);
984 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
986 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
987 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
988 ret = False;
989 goto done;
993 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
994 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
995 ret = False;
996 goto done;
1000 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1001 if (pwHistLen) {
1002 uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1003 if (!pw_hist) {
1004 ret = False;
1005 goto done;
1007 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1008 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1009 int i;
1010 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1011 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1012 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1013 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1014 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1015 PW_HISTORY_ENTRY_LEN);
1018 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1019 SAFE_FREE(pw_hist);
1020 ret = False;
1021 goto done;
1023 SAFE_FREE(pw_hist);
1024 } else {
1025 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1028 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1029 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1030 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1031 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1032 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1033 /* Change from V2 is the uint32 acct_ctrl */
1034 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1035 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1036 pdb_set_hours(sampass, hours, PDB_SET);
1038 done:
1040 SAFE_FREE(username);
1041 SAFE_FREE(domain);
1042 SAFE_FREE(nt_username);
1043 SAFE_FREE(fullname);
1044 SAFE_FREE(homedir);
1045 SAFE_FREE(dir_drive);
1046 SAFE_FREE(logon_script);
1047 SAFE_FREE(profile_path);
1048 SAFE_FREE(acct_desc);
1049 SAFE_FREE(workstations);
1050 SAFE_FREE(munged_dial);
1051 SAFE_FREE(unknown_str);
1052 SAFE_FREE(lm_pw_ptr);
1053 SAFE_FREE(nt_pw_ptr);
1054 SAFE_FREE(nt_pw_hist_ptr);
1055 SAFE_FREE(hours);
1057 return ret;
1060 /*********************************************************************
1061 *********************************************************************/
1063 uint32 init_buffer_from_sam_v3 (uint8 **buf, struct samu *sampass, bool size_only)
1065 size_t len, buflen;
1067 /* times are stored as 32bit integer
1068 take care on system with 64bit wide time_t
1069 --SSS */
1070 uint32 logon_time,
1071 logoff_time,
1072 kickoff_time,
1073 bad_password_time,
1074 pass_last_set_time,
1075 pass_can_change_time,
1076 pass_must_change_time;
1078 uint32 user_rid, group_rid;
1080 const char *username;
1081 const char *domain;
1082 const char *nt_username;
1083 const char *dir_drive;
1084 const char *unknown_str;
1085 const char *munged_dial;
1086 const char *fullname;
1087 const char *homedir;
1088 const char *logon_script;
1089 const char *profile_path;
1090 const char *acct_desc;
1091 const char *workstations;
1092 uint32 username_len, domain_len, nt_username_len,
1093 dir_drive_len, unknown_str_len, munged_dial_len,
1094 fullname_len, homedir_len, logon_script_len,
1095 profile_path_len, acct_desc_len, workstations_len;
1097 const uint8 *lm_pw;
1098 const uint8 *nt_pw;
1099 const uint8 *nt_pw_hist;
1100 uint32 lm_pw_len = 16;
1101 uint32 nt_pw_len = 16;
1102 uint32 nt_pw_hist_len;
1103 uint32 pwHistLen = 0;
1105 *buf = NULL;
1106 buflen = 0;
1108 logon_time = convert_time_t_to_uint32(pdb_get_logon_time(sampass));
1109 logoff_time = convert_time_t_to_uint32(pdb_get_logoff_time(sampass));
1110 kickoff_time = convert_time_t_to_uint32(pdb_get_kickoff_time(sampass));
1111 bad_password_time = convert_time_t_to_uint32(pdb_get_bad_password_time(sampass));
1112 pass_can_change_time = convert_time_t_to_uint32(pdb_get_pass_can_change_time_noncalc(sampass));
1113 pass_must_change_time = convert_time_t_to_uint32(pdb_get_pass_must_change_time(sampass));
1114 pass_last_set_time = convert_time_t_to_uint32(pdb_get_pass_last_set_time(sampass));
1116 user_rid = pdb_get_user_rid(sampass);
1117 group_rid = pdb_get_group_rid(sampass);
1119 username = pdb_get_username(sampass);
1120 if (username) {
1121 username_len = strlen(username) +1;
1122 } else {
1123 username_len = 0;
1126 domain = pdb_get_domain(sampass);
1127 if (domain) {
1128 domain_len = strlen(domain) +1;
1129 } else {
1130 domain_len = 0;
1133 nt_username = pdb_get_nt_username(sampass);
1134 if (nt_username) {
1135 nt_username_len = strlen(nt_username) +1;
1136 } else {
1137 nt_username_len = 0;
1140 fullname = pdb_get_fullname(sampass);
1141 if (fullname) {
1142 fullname_len = strlen(fullname) +1;
1143 } else {
1144 fullname_len = 0;
1148 * Only updates fields which have been set (not defaults from smb.conf)
1151 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1152 dir_drive = pdb_get_dir_drive(sampass);
1153 } else {
1154 dir_drive = NULL;
1156 if (dir_drive) {
1157 dir_drive_len = strlen(dir_drive) +1;
1158 } else {
1159 dir_drive_len = 0;
1162 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1163 homedir = pdb_get_homedir(sampass);
1164 } else {
1165 homedir = NULL;
1167 if (homedir) {
1168 homedir_len = strlen(homedir) +1;
1169 } else {
1170 homedir_len = 0;
1173 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1174 logon_script = pdb_get_logon_script(sampass);
1175 } else {
1176 logon_script = NULL;
1178 if (logon_script) {
1179 logon_script_len = strlen(logon_script) +1;
1180 } else {
1181 logon_script_len = 0;
1184 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1185 profile_path = pdb_get_profile_path(sampass);
1186 } else {
1187 profile_path = NULL;
1189 if (profile_path) {
1190 profile_path_len = strlen(profile_path) +1;
1191 } else {
1192 profile_path_len = 0;
1195 lm_pw = pdb_get_lanman_passwd(sampass);
1196 if (!lm_pw) {
1197 lm_pw_len = 0;
1200 nt_pw = pdb_get_nt_passwd(sampass);
1201 if (!nt_pw) {
1202 nt_pw_len = 0;
1205 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1206 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
1207 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1208 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1209 } else {
1210 nt_pw_hist_len = 0;
1213 acct_desc = pdb_get_acct_desc(sampass);
1214 if (acct_desc) {
1215 acct_desc_len = strlen(acct_desc) +1;
1216 } else {
1217 acct_desc_len = 0;
1220 workstations = pdb_get_workstations(sampass);
1221 if (workstations) {
1222 workstations_len = strlen(workstations) +1;
1223 } else {
1224 workstations_len = 0;
1227 unknown_str = NULL;
1228 unknown_str_len = 0;
1230 munged_dial = pdb_get_munged_dial(sampass);
1231 if (munged_dial) {
1232 munged_dial_len = strlen(munged_dial) +1;
1233 } else {
1234 munged_dial_len = 0;
1237 /* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1239 /* one time to get the size needed */
1240 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V3,
1241 logon_time, /* d */
1242 logoff_time, /* d */
1243 kickoff_time, /* d */
1244 bad_password_time, /* d */
1245 pass_last_set_time, /* d */
1246 pass_can_change_time, /* d */
1247 pass_must_change_time, /* d */
1248 username_len, username, /* B */
1249 domain_len, domain, /* B */
1250 nt_username_len, nt_username, /* B */
1251 fullname_len, fullname, /* B */
1252 homedir_len, homedir, /* B */
1253 dir_drive_len, dir_drive, /* B */
1254 logon_script_len, logon_script, /* B */
1255 profile_path_len, profile_path, /* B */
1256 acct_desc_len, acct_desc, /* B */
1257 workstations_len, workstations, /* B */
1258 unknown_str_len, unknown_str, /* B */
1259 munged_dial_len, munged_dial, /* B */
1260 user_rid, /* d */
1261 group_rid, /* d */
1262 lm_pw_len, lm_pw, /* B */
1263 nt_pw_len, nt_pw, /* B */
1264 nt_pw_hist_len, nt_pw_hist, /* B */
1265 pdb_get_acct_ctrl(sampass), /* d */
1266 pdb_get_logon_divs(sampass), /* w */
1267 pdb_get_hours_len(sampass), /* d */
1268 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1269 pdb_get_bad_password_count(sampass), /* w */
1270 pdb_get_logon_count(sampass), /* w */
1271 pdb_get_unknown_6(sampass)); /* d */
1273 if (size_only) {
1274 return buflen;
1277 /* malloc the space needed */
1278 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
1279 DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
1280 return (-1);
1283 /* now for the real call to tdb_pack() */
1284 buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING_V3,
1285 logon_time, /* d */
1286 logoff_time, /* d */
1287 kickoff_time, /* d */
1288 bad_password_time, /* d */
1289 pass_last_set_time, /* d */
1290 pass_can_change_time, /* d */
1291 pass_must_change_time, /* d */
1292 username_len, username, /* B */
1293 domain_len, domain, /* B */
1294 nt_username_len, nt_username, /* B */
1295 fullname_len, fullname, /* B */
1296 homedir_len, homedir, /* B */
1297 dir_drive_len, dir_drive, /* B */
1298 logon_script_len, logon_script, /* B */
1299 profile_path_len, profile_path, /* B */
1300 acct_desc_len, acct_desc, /* B */
1301 workstations_len, workstations, /* B */
1302 unknown_str_len, unknown_str, /* B */
1303 munged_dial_len, munged_dial, /* B */
1304 user_rid, /* d */
1305 group_rid, /* d */
1306 lm_pw_len, lm_pw, /* B */
1307 nt_pw_len, nt_pw, /* B */
1308 nt_pw_hist_len, nt_pw_hist, /* B */
1309 pdb_get_acct_ctrl(sampass), /* d */
1310 pdb_get_logon_divs(sampass), /* w */
1311 pdb_get_hours_len(sampass), /* d */
1312 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
1313 pdb_get_bad_password_count(sampass), /* w */
1314 pdb_get_logon_count(sampass), /* w */
1315 pdb_get_unknown_6(sampass)); /* d */
1317 /* check to make sure we got it correct */
1318 if (buflen != len) {
1319 DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
1320 (unsigned long)buflen, (unsigned long)len));
1321 /* error */
1322 SAFE_FREE (*buf);
1323 return (-1);
1326 return (buflen);
1330 /*********************************************************************
1331 *********************************************************************/
1333 bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
1335 uint8 *buf = NULL;
1336 int len;
1338 len = init_buffer_from_sam_v3(&buf, src, False);
1339 if (len == -1 || !buf) {
1340 SAFE_FREE(buf);
1341 return False;
1344 if (!init_sam_from_buffer_v3( dst, buf, len )) {
1345 free(buf);
1346 return False;
1349 dst->methods = src->methods;
1351 if ( src->unix_pw ) {
1352 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
1353 if (!dst->unix_pw) {
1354 free(buf);
1355 return False;
1359 free(buf);
1360 return True;
1363 /*********************************************************************
1364 Update the bad password count checking the AP_RESET_COUNT_TIME
1365 *********************************************************************/
1367 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
1369 time_t LastBadPassword;
1370 uint16 BadPasswordCount;
1371 uint32 resettime;
1372 bool res;
1374 BadPasswordCount = pdb_get_bad_password_count(sampass);
1375 if (!BadPasswordCount) {
1376 DEBUG(9, ("No bad password attempts.\n"));
1377 return True;
1380 become_root();
1381 res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
1382 unbecome_root();
1384 if (!res) {
1385 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
1386 return False;
1389 /* First, check if there is a reset time to compare */
1390 if ((resettime == (uint32) -1) || (resettime == 0)) {
1391 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
1392 return True;
1395 LastBadPassword = pdb_get_bad_password_time(sampass);
1396 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
1397 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
1398 if (time(NULL) > (LastBadPassword + convert_uint32_to_time_t(resettime)*60)){
1399 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1400 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1401 if (updated) {
1402 *updated = True;
1406 return True;
1409 /*********************************************************************
1410 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
1411 *********************************************************************/
1413 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
1415 uint32 duration;
1416 time_t LastBadPassword;
1417 bool res;
1419 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
1420 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
1421 pdb_get_username(sampass)));
1422 return True;
1425 become_root();
1426 res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
1427 unbecome_root();
1429 if (!res) {
1430 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1431 return False;
1434 /* First, check if there is a duration to compare */
1435 if ((duration == (uint32) -1) || (duration == 0)) {
1436 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
1437 return True;
1440 LastBadPassword = pdb_get_bad_password_time(sampass);
1441 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
1442 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
1444 if (LastBadPassword == (time_t)0) {
1445 DEBUG(1,("pdb_update_autolock_flag: Account %s "
1446 "administratively locked out with no bad password "
1447 "time. Leaving locked out.\n",
1448 pdb_get_username(sampass) ));
1449 return True;
1452 if ((time(NULL) > (LastBadPassword + convert_uint32_to_time_t(duration) * 60))) {
1453 pdb_set_acct_ctrl(sampass,
1454 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
1455 PDB_CHANGED);
1456 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1457 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1458 if (updated) {
1459 *updated = True;
1463 return True;
1466 /*********************************************************************
1467 Increment the bad_password_count
1468 *********************************************************************/
1470 bool pdb_increment_bad_password_count(struct samu *sampass)
1472 uint32 account_policy_lockout;
1473 bool autolock_updated = False, badpw_updated = False;
1474 bool ret;
1476 /* Retrieve the account lockout policy */
1477 become_root();
1478 ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
1479 unbecome_root();
1480 if ( !ret ) {
1481 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1482 return False;
1485 /* If there is no policy, we don't need to continue checking */
1486 if (!account_policy_lockout) {
1487 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
1488 return True;
1491 /* Check if the autolock needs to be cleared */
1492 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
1493 return False;
1495 /* Check if the badpw count needs to be reset */
1496 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
1497 return False;
1500 Ok, now we can assume that any resetting that needs to be
1501 done has been done, and just get on with incrementing
1502 and autolocking if necessary
1505 pdb_set_bad_password_count(sampass,
1506 pdb_get_bad_password_count(sampass)+1,
1507 PDB_CHANGED);
1508 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
1511 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
1512 return True;
1514 if (!pdb_set_acct_ctrl(sampass,
1515 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
1516 PDB_CHANGED)) {
1517 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
1518 return False;
1521 return True;
1525 /*******************************************************************
1526 Wrapper around retrieving the trust account password.
1527 appropriate account name is stored in account_name.
1528 *******************************************************************/
1530 bool get_trust_pw(const char *domain, uint8 ret_pwd[16],
1531 const char **account_name, uint32 *channel)
1533 DOM_SID sid;
1534 char *pwd;
1535 time_t last_set_time;
1537 /* if we are a DC and this is not our domain, then lookup an account
1538 for the domain trust */
1540 if (IS_DC && !strequal(domain, lp_workgroup()) &&
1541 lp_allow_trusted_domains())
1543 if (!pdb_get_trusteddom_pw(domain, &pwd, &sid, &last_set_time))
1545 DEBUG(0, ("get_trust_pw: could not fetch trust "
1546 "account password for trusted domain %s\n",
1547 domain));
1548 return False;
1551 *channel = SEC_CHAN_DOMAIN;
1552 E_md4hash(pwd, ret_pwd);
1553 SAFE_FREE(pwd);
1555 if (account_name != NULL) {
1556 *account_name = lp_workgroup();
1559 return True;
1562 /* Just get the account for the requested domain. In the future this
1563 * might also cover to be member of more than one domain. */
1565 if (secrets_fetch_trust_account_password(domain, ret_pwd,
1566 &last_set_time, channel))
1568 if (account_name != NULL) {
1569 *account_name = global_myname();
1572 return True;
1575 DEBUG(5, ("get_trust_pw: could not fetch trust account "
1576 "password for domain %s\n", domain));
1577 return False;