r13600: Move functions local to tdbsam to pdb_tdb.c
[Samba.git] / source / passdb / passdb.c
blob6c84cccf79d9b40b6018fd1cf80a5c8a9f02d95b
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 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.
26 #include "includes.h"
28 #undef DBGC_CLASS
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 */
57 user->methods = NULL;
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. */
79 user->username = "";
80 user->domain = "";
81 user->nt_username = "";
82 user->full_name = "";
83 user->home_dir = "";
84 user->logon_script = "";
85 user->profile_path = "";
86 user->acct_desc = "";
87 user->workstations = "";
88 user->unknown_str = "";
89 user->munged_dial = "";
91 user->plaintext_pw = NULL;
93 /*
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) );
115 return 0;
118 /**********************************************************************
119 generate a new struct samuser
120 ***********************************************************************/
122 struct samu* samu_new( TALLOC_CTX *ctx )
124 struct samu *user;
126 if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
127 DEBUG(0,("samuser_new: Talloc failed!\n"));
128 return NULL;
131 samu_init( user );
133 talloc_set_destructor( user, samu_destroy );
135 return user;
138 /*********************************************************************
139 Initialize a struct samu from a struct passwd including the user
140 and group SIDs
141 *********************************************************************/
143 NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
145 const char *guest_account = lp_guestaccount();
146 GROUP_MAP map;
147 BOOL ret;
149 /* Set the Unix attributes */
151 if ( !pwd ) {
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
163 Windows NT - 2003 */
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;
179 return NT_STATUS_OK;
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 */
194 become_root();
195 ret = pdb_getgrgid(&map, pwd->pw_gid);
196 unbecome_root();
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. */
203 if( ret ) {
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;
208 } else {
209 if ( !pdb_set_group_sid_from_rid(user, DOMAIN_GROUP_RID_USERS, PDB_SET))
210 return NT_STATUS_INVALID_PARAMETER;
212 #endif
214 if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
215 /* workstation */
217 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
218 DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
219 pwd->pw_name));
220 return NT_STATUS_INVALID_COMPUTER_NAME;
223 /* we're done here for a machine account */
225 return NT_STATUS_OK;
227 else {
228 /* user */
230 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
231 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
232 pwd->pw_name));
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),
241 PDB_DEFAULT);
242 pdb_set_homedir(user, talloc_sub_specified(user,
243 lp_logon_home(), pwd->pw_name, global_myname(), pwd->pw_uid, pwd->pw_gid),
244 PDB_DEFAULT);
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),
247 PDB_DEFAULT);
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),
250 PDB_DEFAULT);
252 return NT_STATUS_OK;
255 /*************************************************************
256 Initialises a struct samu ready to add a new account, based
257 on the UNIX user.
258 ************************************************************/
260 NTSTATUS pdb_init_sam_new(struct samu **new_sam_acct, const char *username)
262 NTSTATUS result;
263 struct passwd *pwd;
264 uint32 user_rid;
265 DOM_SID user_sid, group_sid;
266 TALLOC_CTX *mem_ctx;
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;
278 goto done;
281 if ( !(*new_sam_acct = samu_new( NULL )) ) {
282 result = NT_STATUS_NO_MEMORY;
283 goto done;
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)));
290 goto done;
293 if (pdb_rid_algorithm()) {
294 if (!pdb_set_user_sid_from_rid(
295 *new_sam_acct,
296 algorithmic_pdb_uid_to_user_rid(pwd->pw_uid),
297 PDB_SET)) {
298 result = NT_STATUS_INTERNAL_ERROR;
299 goto done;
301 if (!pdb_set_group_sid_from_rid(
302 *new_sam_acct, pdb_gid_to_group_rid(pwd->pw_gid),
303 PDB_SET)) {
304 result = NT_STATUS_INTERNAL_ERROR;
305 goto done;
307 result = NT_STATUS_OK;
308 goto done;
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)) {
316 struct group *grp;
317 GROUP_MAP map;
319 grp = getgrgid(pwd->pw_gid);
320 if (grp == NULL) {
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;
324 goto done;
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));
333 goto done;
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
341 * else */
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;
347 goto done;
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;
354 goto done;
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;
360 goto done;
363 if (!pdb_new_rid(&user_rid)) {
364 DEBUG(3, ("Could not allocate a new RID\n"));
365 result = NT_STATUS_ACCESS_DENIED;
366 goto done;
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;
375 goto done;
378 result = NT_STATUS_OK;
380 done:
381 if (!NT_STATUS_IS_OK(result) && (*new_sam_acct != NULL)) {
382 TALLOC_FREE(new_sam_acct);
385 TALLOC_FREE(mem_ctx);
386 return result;
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;
400 size_t i = 0;
402 SMB_ASSERT(length <= sizeof(acct_str));
404 acct_str[i++] = '[';
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++ )
419 acct_str[i] = ' ';
421 i = length - 2;
422 acct_str[i++] = ']';
423 acct_str[i++] = '\0';
425 return acct_str;
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]).
442 if (*p != '[')
443 return 0;
445 for (p++; *p && !finished; p++) {
446 switch (*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. */ }
458 case ' ': { break; }
459 case ':':
460 case '\n':
461 case '\0':
462 case ']':
463 default: { finished = True; }
467 return acct_ctrl;
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)
476 if (pwd != NULL) {
477 int i;
478 for (i = 0; i < 16; i++)
479 slprintf(&p[i*2], 3, "%02X", pwd[i]);
480 } else {
481 if (acct_ctrl & ACB_PWNOTREQ)
482 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
483 else
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)
495 int i;
496 unsigned char lonybble, hinybble;
497 const char *hexchars = "0123456789ABCDEF";
498 char *p1, *p2;
500 if (!p)
501 return (False);
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);
510 if (!p1 || !p2)
511 return (False);
513 hinybble = PTR_DIFF(p1, hexchars);
514 lonybble = PTR_DIFF(p2, hexchars);
516 pwd[i / 2] = (hinybble << 4) | lonybble;
518 return (True);
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)
527 if (hours != NULL) {
528 int i;
529 for (i = 0; i < 21; i++) {
530 slprintf(&p[i*2], 3, "%02X", hours[i]);
532 } else {
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)
544 int i;
545 unsigned char lonybble, hinybble;
546 const char *hexchars = "0123456789ABCDEF";
547 char *p1, *p2;
549 if (!p) {
550 return (False);
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);
560 if (!p1 || !p2) {
561 return (False);
564 hinybble = PTR_DIFF(p1, hexchars);
565 lonybble = PTR_DIFF(p2, hexchars);
567 hours[i / 2] = (hinybble << 4) | lonybble;
569 return (True);
572 int algorithmic_rid_base(void)
574 static int rid_offset = 0;
576 if (rid_offset != 0)
577 return rid_offset;
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"));
589 rid_offset += 1;
591 return rid_offset;
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)
672 return True;
673 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
674 return True;
676 return False;
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)
686 GROUP_MAP map;
687 BOOL ret;
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;
695 DOM_SID user_sid;
697 if ( !(sam_account = samu_new( NULL )) ) {
698 return False;
701 become_root();
702 ret = pdb_getsampwnam(sam_account, user);
703 unbecome_root();
705 if (ret) {
706 sid_copy(&user_sid, pdb_get_user_sid(sam_account));
709 TALLOC_FREE(sam_account);
711 if (ret) {
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)));
715 return False;
718 sid_peek_rid(&user_sid, rid);
719 *type = SID_NAME_USER;
720 return True;
725 * Maybe it is a group ?
728 become_root();
729 ret = pdb_getgrnam(&map, user);
730 unbecome_root();
732 if (!ret) {
733 return False;
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 -- "
739 "ignoring.", user,
740 sid_string_static(&map.sid)));
741 return False;
744 /* yes it's a mapped group */
745 sid_peek_rid(&map.sid, rid);
746 *type = map.sid_name_use;
747 return True;
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;
760 uint16 other_acb;
761 NTSTATUS result;
763 *err_str = '\0';
764 *msg_str = '\0';
766 /* Get the smb passwd entry for this user */
768 if ( !(sam_pass = samu_new( NULL )) ) {
769 return NT_STATUS_NO_MEMORY;
772 become_root();
773 if(!pdb_getsampwnam(sam_pass, user_name)) {
774 unbecome_root();
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. */
782 if (tmp_debug < 1) {
783 DEBUGLEVEL = 1;
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)) {
789 return result;
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));
796 return result;
798 } else {
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;
802 } else {
803 unbecome_root();
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;
822 } else {
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);
889 return NT_STATUS_OK;
890 } else {
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);
902 } else {
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);
907 return result;
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);
918 return NT_STATUS_OK;
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
935 --SSS */
936 uint32 logon_time,
937 logoff_time,
938 kickoff_time,
939 bad_password_time,
940 pass_last_set_time,
941 pass_can_change_time,
942 pass_must_change_time;
943 char *username = NULL;
944 char *domain = 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;
963 uint8 *hours = NULL;
964 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
965 uint32 len = 0;
966 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
967 uint32 pwHistLen = 0;
968 BOOL ret = True;
969 fstring tmpstring;
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"));
974 return False;
977 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
979 /* unpack the buffer into variables */
980 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
981 &logon_time, /* d */
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 */
1000 &user_rid, /* d */
1001 &group_rid, /* d */
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 */
1006 &acct_ctrl, /* w */
1007 /* Also "remove_me" field was removed. */
1008 &logon_divs, /* w */
1009 &hours_len, /* d */
1010 &hourslen, &hours, /* B */
1011 &bad_password_count, /* w */
1012 &logon_count, /* w */
1013 &unknown_6); /* d */
1015 if (len == (uint32) -1) {
1016 ret = False;
1017 goto done;
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);
1033 if (homedir) {
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);
1041 else {
1042 pdb_set_homedir(sampass,
1043 talloc_sub_basic(sampass, username, lp_logon_home()),
1044 PDB_DEFAULT);
1047 if (dir_drive)
1048 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1049 else
1050 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1052 if (logon_script) {
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);
1060 else {
1061 pdb_set_logon_script(sampass,
1062 talloc_sub_basic(sampass, username, lp_logon_script()),
1063 PDB_DEFAULT);
1066 if (profile_path) {
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);
1074 else {
1075 pdb_set_profile_path(sampass,
1076 talloc_sub_basic(sampass, username, lp_logon_path()),
1077 PDB_DEFAULT);
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)) {
1086 ret = False;
1087 goto done;
1091 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1092 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1093 ret = False;
1094 goto done;
1098 /* Change from V1 is addition of password history field. */
1099 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1100 if (pwHistLen) {
1101 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1102 if (!pw_hist) {
1103 ret = False;
1104 goto done;
1106 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1107 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1108 int i;
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)) {
1118 SAFE_FREE(pw_hist);
1119 ret = False;
1120 goto done;
1122 SAFE_FREE(pw_hist);
1123 } else {
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);
1137 done:
1139 SAFE_FREE(username);
1140 SAFE_FREE(domain);
1141 SAFE_FREE(nt_username);
1142 SAFE_FREE(fullname);
1143 SAFE_FREE(homedir);
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);
1154 SAFE_FREE(hours);
1156 return ret;
1159 /*********************************************************************
1160 *********************************************************************/
1162 uint32 init_buffer_from_sam_v2 (uint8 **buf, const struct samu *sampass, BOOL size_only)
1164 size_t len, buflen;
1166 /* times are stored as 32bit integer
1167 take care on system with 64bit wide time_t
1168 --SSS */
1169 uint32 logon_time,
1170 logoff_time,
1171 kickoff_time,
1172 bad_password_time,
1173 pass_last_set_time,
1174 pass_can_change_time,
1175 pass_must_change_time;
1177 uint32 user_rid, group_rid;
1179 const char *username;
1180 const char *domain;
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;
1196 const uint8 *lm_pw;
1197 const uint8 *nt_pw;
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"));
1207 return -1;
1210 *buf = NULL;
1211 buflen = 0;
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);
1225 if (username) {
1226 username_len = strlen(username) +1;
1227 } else {
1228 username_len = 0;
1231 domain = pdb_get_domain(sampass);
1232 if (domain) {
1233 domain_len = strlen(domain) +1;
1234 } else {
1235 domain_len = 0;
1238 nt_username = pdb_get_nt_username(sampass);
1239 if (nt_username) {
1240 nt_username_len = strlen(nt_username) +1;
1241 } else {
1242 nt_username_len = 0;
1245 fullname = pdb_get_fullname(sampass);
1246 if (fullname) {
1247 fullname_len = strlen(fullname) +1;
1248 } else {
1249 fullname_len = 0;
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);
1258 } else {
1259 dir_drive = NULL;
1261 if (dir_drive) {
1262 dir_drive_len = strlen(dir_drive) +1;
1263 } else {
1264 dir_drive_len = 0;
1267 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1268 homedir = pdb_get_homedir(sampass);
1269 } else {
1270 homedir = NULL;
1272 if (homedir) {
1273 homedir_len = strlen(homedir) +1;
1274 } else {
1275 homedir_len = 0;
1278 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1279 logon_script = pdb_get_logon_script(sampass);
1280 } else {
1281 logon_script = NULL;
1283 if (logon_script) {
1284 logon_script_len = strlen(logon_script) +1;
1285 } else {
1286 logon_script_len = 0;
1289 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1290 profile_path = pdb_get_profile_path(sampass);
1291 } else {
1292 profile_path = NULL;
1294 if (profile_path) {
1295 profile_path_len = strlen(profile_path) +1;
1296 } else {
1297 profile_path_len = 0;
1300 lm_pw = pdb_get_lanman_passwd(sampass);
1301 if (!lm_pw) {
1302 lm_pw_len = 0;
1305 nt_pw = pdb_get_nt_passwd(sampass);
1306 if (!nt_pw) {
1307 nt_pw_len = 0;
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;
1314 } else {
1315 nt_pw_hist_len = 0;
1318 acct_desc = pdb_get_acct_desc(sampass);
1319 if (acct_desc) {
1320 acct_desc_len = strlen(acct_desc) +1;
1321 } else {
1322 acct_desc_len = 0;
1325 workstations = pdb_get_workstations(sampass);
1326 if (workstations) {
1327 workstations_len = strlen(workstations) +1;
1328 } else {
1329 workstations_len = 0;
1332 unknown_str = NULL;
1333 unknown_str_len = 0;
1335 munged_dial = pdb_get_munged_dial(sampass);
1336 if (munged_dial) {
1337 munged_dial_len = strlen(munged_dial) +1;
1338 } else {
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,
1346 logon_time, /* d */
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 */
1365 user_rid, /* d */
1366 group_rid, /* d */
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 */
1378 if (size_only) {
1379 return buflen;
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"));
1385 return (-1);
1388 /* now for the real call to tdb_pack() */
1389 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
1390 logon_time, /* d */
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 */
1409 user_rid, /* d */
1410 group_rid, /* d */
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));
1426 /* error */
1427 SAFE_FREE (*buf);
1428 return (-1);
1431 return (buflen);
1435 /*********************************************************************
1436 *********************************************************************/
1438 BOOL pdb_copy_sam_account(const struct samu *src, struct samu **dst)
1440 BOOL result;
1441 uint8 *buf;
1442 int len;
1444 if ( !*dst && !(*dst = samu_new(NULL)) )
1445 return False;
1447 len = init_buffer_from_sam_v2(&buf, src, False);
1449 if (len == -1)
1450 return False;
1452 result = init_sam_from_buffer_v2(*dst, buf, len);
1453 (*dst)->methods = src->methods;
1455 free(buf);
1457 return result;
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;
1468 uint32 resettime;
1470 if (!sampass) return False;
1472 BadPasswordCount = pdb_get_bad_password_count(sampass);
1473 if (!BadPasswordCount) {
1474 DEBUG(9, ("No bad password attempts.\n"));
1475 return True;
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"));
1480 return False;
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"));
1486 return True;
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);
1495 if (updated) {
1496 *updated = True;
1500 return True;
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)
1509 uint32 duration;
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)));
1517 return True;
1520 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
1521 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
1522 return False;
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"));
1528 return True;
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) ));
1539 return True;
1542 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
1543 pdb_set_acct_ctrl(sampass,
1544 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
1545 PDB_CHANGED);
1546 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
1547 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
1548 if (updated) {
1549 *updated = True;
1553 return True;
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;
1564 BOOL ret;
1566 if (!sampass)
1567 return False;
1569 /* Retrieve the account lockout policy */
1570 become_root();
1571 ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
1572 unbecome_root();
1573 if ( !ret ) {
1574 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
1575 return False;
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"));
1581 return True;
1584 /* Check if the autolock needs to be cleared */
1585 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
1586 return False;
1588 /* Check if the badpw count needs to be reset */
1589 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
1590 return False;
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,
1600 PDB_CHANGED);
1601 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
1604 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
1605 return True;
1607 if (!pdb_set_acct_ctrl(sampass,
1608 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
1609 PDB_CHANGED)) {
1610 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
1611 return False;
1614 return True;