r4904: sync up with 3.0 for 3.0.11pre2
[Samba.git] / source / passdb / passdb.c
blob1f5e4be6cf60584414621e634fe5ec0bdcfeaba1
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-2001
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Simo Sorce 2003
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 *get_default_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 Fill the SAM_ACCOUNT with default values.
51 ***********************************************************/
53 void pdb_fill_default_sam(SAM_ACCOUNT *user)
55 ZERO_STRUCT(user->private); /* Don't touch the talloc context */
57 /* no initial methods */
58 user->methods = NULL;
60 /* Don't change these timestamp settings without a good reason.
61 They are important for NT member server compatibility. */
63 user->private.logon_time = (time_t)0;
64 user->private.pass_last_set_time = (time_t)0;
65 user->private.pass_can_change_time = (time_t)0;
66 user->private.logoff_time =
67 user->private.kickoff_time =
68 user->private.pass_must_change_time = get_time_t_max();
69 user->private.fields_present = 0x00ffffff;
70 user->private.logon_divs = 168; /* hours per week */
71 user->private.hours_len = 21; /* 21 times 8 bits = 168 */
72 memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */
73 user->private.bad_password_count = 0;
74 user->private.logon_count = 0;
75 user->private.unknown_6 = 0x000004ec; /* don't know */
77 /* Some parts of samba strlen their pdb_get...() returns,
78 so this keeps the interface unchanged for now. */
80 user->private.username = "";
81 user->private.domain = "";
82 user->private.nt_username = "";
83 user->private.full_name = "";
84 user->private.home_dir = "";
85 user->private.logon_script = "";
86 user->private.profile_path = "";
87 user->private.acct_desc = "";
88 user->private.workstations = "";
89 user->private.unknown_str = "";
90 user->private.munged_dial = "";
92 user->private.plaintext_pw = NULL;
94 /*
95 Unless we know otherwise have a Account Control Bit
96 value of 'normal user'. This helps User Manager, which
97 asks for a filtered list of users.
100 user->private.acct_ctrl = ACB_NORMAL;
103 static void destroy_pdb_talloc(SAM_ACCOUNT **user)
105 if (*user) {
106 data_blob_clear_free(&((*user)->private.lm_pw));
107 data_blob_clear_free(&((*user)->private.nt_pw));
109 if((*user)->private.plaintext_pw!=NULL)
110 memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw));
111 talloc_destroy((*user)->mem_ctx);
112 *user = NULL;
117 /**********************************************************************
118 Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
119 ***********************************************************************/
121 NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
123 if (*user != NULL) {
124 DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
125 #if 0
126 smb_panic("non-NULL pointer passed to pdb_init_sam\n");
127 #endif
128 return NT_STATUS_UNSUCCESSFUL;
131 if (!mem_ctx) {
132 DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
133 return NT_STATUS_UNSUCCESSFUL;
136 *user=TALLOC_P(mem_ctx, SAM_ACCOUNT);
138 if (*user==NULL) {
139 DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
140 return NT_STATUS_NO_MEMORY;
143 (*user)->mem_ctx = mem_ctx;
145 (*user)->free_fn = NULL;
147 pdb_fill_default_sam(*user);
149 return NT_STATUS_OK;
153 /*************************************************************
154 Allocates memory and initialises a struct sam_passwd.
155 ************************************************************/
157 NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
159 TALLOC_CTX *mem_ctx;
160 NTSTATUS nt_status;
162 mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
164 if (!mem_ctx) {
165 DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
166 return NT_STATUS_NO_MEMORY;
169 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
170 talloc_destroy(mem_ctx);
171 return nt_status;
174 (*user)->free_fn = destroy_pdb_talloc;
176 return NT_STATUS_OK;
179 /**************************************************************************
180 * This function will take care of all the steps needed to correctly
181 * allocate and set the user SID, please do use this function to create new
182 * users, messing with SIDs is not good.
184 * account_data must be provided initialized, pwd may be null.
185 * SSS
186 ***************************************************************************/
188 static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
190 const char *guest_account = lp_guestaccount();
191 GROUP_MAP map;
192 BOOL ret;
194 if (!account_data || !pwd) {
195 return NT_STATUS_INVALID_PARAMETER;
198 /* this is a hack this thing should not be set
199 this way --SSS */
200 if (!(guest_account && *guest_account)) {
201 DEBUG(1, ("NULL guest account!?!?\n"));
202 return NT_STATUS_UNSUCCESSFUL;
203 } else {
204 /* Ensure this *must* be set right */
205 if (strcmp(pwd->pw_name, guest_account) == 0) {
206 if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
207 return NT_STATUS_UNSUCCESSFUL;
209 if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {
210 return NT_STATUS_UNSUCCESSFUL;
212 return NT_STATUS_OK;
216 if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
217 DEBUG(0,("Can't set User SID from RID!\n"));
218 return NT_STATUS_INVALID_PARAMETER;
221 /* call the mapping code here */
222 become_root();
223 ret = pdb_getgrgid(&map, pwd->pw_gid);
224 unbecome_root();
226 if( ret ) {
227 if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
228 DEBUG(0,("Can't set Group SID!\n"));
229 return NT_STATUS_INVALID_PARAMETER;
232 else {
233 if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
234 DEBUG(0,("Can't set Group SID\n"));
235 return NT_STATUS_INVALID_PARAMETER;
239 return NT_STATUS_OK;
242 /*************************************************************
243 Initialises a struct sam_passwd with sane values.
244 ************************************************************/
246 NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
248 NTSTATUS ret;
250 if (!pwd) {
251 return NT_STATUS_UNSUCCESSFUL;
254 pdb_fill_default_sam(sam_account);
256 pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
257 pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
259 pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
261 pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
263 /* When we get a proper uid -> SID and SID -> uid allocation
264 mechinism, we should call it here.
266 We can't just set this to 0 or allow it only to be filled
267 in when added to the backend, because the user's SID
268 may already be in security descriptors etc.
270 -- abartlet 11-May-02
273 ret = pdb_set_sam_sids(sam_account, pwd);
274 if (!NT_STATUS_IS_OK(ret)) return ret;
276 /* check if this is a user account or a machine account */
277 if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
279 pdb_set_profile_path(sam_account,
280 talloc_sub_specified((sam_account)->mem_ctx,
281 lp_logon_path(),
282 pwd->pw_name, global_myname(),
283 pwd->pw_uid, pwd->pw_gid),
284 PDB_DEFAULT);
286 pdb_set_homedir(sam_account,
287 talloc_sub_specified((sam_account)->mem_ctx,
288 lp_logon_home(),
289 pwd->pw_name, global_myname(),
290 pwd->pw_uid, pwd->pw_gid),
291 PDB_DEFAULT);
293 pdb_set_dir_drive(sam_account,
294 talloc_sub_specified((sam_account)->mem_ctx,
295 lp_logon_drive(),
296 pwd->pw_name, global_myname(),
297 pwd->pw_uid, pwd->pw_gid),
298 PDB_DEFAULT);
300 pdb_set_logon_script(sam_account,
301 talloc_sub_specified((sam_account)->mem_ctx,
302 lp_logon_script(),
303 pwd->pw_name, global_myname(),
304 pwd->pw_uid, pwd->pw_gid),
305 PDB_DEFAULT);
306 if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
307 DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
308 return NT_STATUS_UNSUCCESSFUL;
310 } else {
311 if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
312 DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
313 return NT_STATUS_UNSUCCESSFUL;
316 return NT_STATUS_OK;
320 /*************************************************************
321 Initialises a struct sam_passwd with sane values.
322 ************************************************************/
324 NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
326 NTSTATUS nt_status;
328 if (!pwd) {
329 new_sam_acct = NULL;
330 return NT_STATUS_INVALID_PARAMETER;
333 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
334 new_sam_acct = NULL;
335 return nt_status;
338 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
339 pdb_free_sam(new_sam_acct);
340 new_sam_acct = NULL;
341 return nt_status;
344 return NT_STATUS_OK;
348 /*************************************************************
349 Initialises a SAM_ACCOUNT ready to add a new account, based
350 on the UNIX user. Pass in a RID if you have one
351 ************************************************************/
353 NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
354 uint32 rid)
356 NTSTATUS nt_status = NT_STATUS_NO_MEMORY;
357 struct passwd *pwd;
358 BOOL ret;
360 pwd = Get_Pwnam(username);
362 if (!pwd)
363 return NT_STATUS_NO_SUCH_USER;
365 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
366 *new_sam_acct = NULL;
367 return nt_status;
370 /* see if we need to generate a new rid using the 2.2 algorithm */
371 if ( rid == 0 && lp_enable_rid_algorithm() ) {
372 DEBUG(10,("pdb_init_sam_new: no RID specified. Generating one via old algorithm\n"));
373 rid = algorithmic_pdb_uid_to_user_rid(pwd->pw_uid);
376 /* set the new SID */
378 ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
380 return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
385 * Free the contets of the SAM_ACCOUNT, but not the structure.
387 * Also wipes the LM and NT hashes and plaintext password from
388 * memory.
390 * @param user SAM_ACCOUNT to free members of.
393 static void pdb_free_sam_contents(SAM_ACCOUNT *user)
396 /* Kill off sensitive data. Free()ed by the
397 talloc mechinism */
399 data_blob_clear_free(&(user->private.lm_pw));
400 data_blob_clear_free(&(user->private.nt_pw));
401 if (user->private.plaintext_pw!=NULL)
402 memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw));
404 if (user->private.backend_private_data && user->private.backend_private_data_free_fn) {
405 user->private.backend_private_data_free_fn(&user->private.backend_private_data);
410 /************************************************************
411 Reset the SAM_ACCOUNT and free the NT/LM hashes.
412 ***********************************************************/
414 NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
416 if (user == NULL) {
417 DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
418 #if 0
419 smb_panic("NULL pointer passed to pdb_free_sam\n");
420 #endif
421 return NT_STATUS_UNSUCCESSFUL;
424 pdb_free_sam_contents(user);
426 pdb_fill_default_sam(user);
428 return NT_STATUS_OK;
432 /************************************************************
433 Free the SAM_ACCOUNT and the member pointers.
434 ***********************************************************/
436 NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
438 if (*user == NULL) {
439 DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
440 #if 0
441 smb_panic("NULL pointer passed to pdb_free_sam\n");
442 #endif
443 return NT_STATUS_UNSUCCESSFUL;
446 pdb_free_sam_contents(*user);
448 if ((*user)->free_fn) {
449 (*user)->free_fn(user);
452 return NT_STATUS_OK;
455 /**********************************************************
456 Encode the account control bits into a string.
457 length = length of string to encode into (including terminating
458 null). length *MUST BE MORE THAN 2* !
459 **********************************************************/
461 char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
463 static fstring acct_str;
465 size_t i = 0;
467 SMB_ASSERT(length <= sizeof(acct_str));
469 acct_str[i++] = '[';
471 if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
472 if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
473 if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
474 if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
475 if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
476 if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
477 if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
478 if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
479 if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
480 if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
481 if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
483 for ( ; i < length - 2 ; i++ )
484 acct_str[i] = ' ';
486 i = length - 2;
487 acct_str[i++] = ']';
488 acct_str[i++] = '\0';
490 return acct_str;
493 /**********************************************************
494 Decode the account control bits from a string.
495 **********************************************************/
497 uint16 pdb_decode_acct_ctrl(const char *p)
499 uint16 acct_ctrl = 0;
500 BOOL finished = False;
503 * Check if the account type bits have been encoded after the
504 * NT password (in the form [NDHTUWSLXI]).
507 if (*p != '[')
508 return 0;
510 for (p++; *p && !finished; p++) {
511 switch (*p) {
512 case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
513 case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
514 case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
515 case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
516 case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
517 case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
518 case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
519 case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
520 case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
521 case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
522 case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
523 case ' ': { break; }
524 case ':':
525 case '\n':
526 case '\0':
527 case ']':
528 default: { finished = True; }
532 return acct_ctrl;
535 /*************************************************************
536 Routine to set 32 hex password characters from a 16 byte array.
537 **************************************************************/
539 void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
541 if (pwd != NULL) {
542 int i;
543 for (i = 0; i < 16; i++)
544 slprintf(&p[i*2], 3, "%02X", pwd[i]);
545 } else {
546 if (acct_ctrl & ACB_PWNOTREQ)
547 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
548 else
549 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
553 /*************************************************************
554 Routine to get the 32 hex characters and turn them
555 into a 16 byte array.
556 **************************************************************/
558 BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
560 int i;
561 unsigned char lonybble, hinybble;
562 const char *hexchars = "0123456789ABCDEF";
563 char *p1, *p2;
565 if (!p)
566 return (False);
568 for (i = 0; i < 32; i += 2) {
569 hinybble = toupper(p[i]);
570 lonybble = toupper(p[i + 1]);
572 p1 = strchr(hexchars, hinybble);
573 p2 = strchr(hexchars, lonybble);
575 if (!p1 || !p2)
576 return (False);
578 hinybble = PTR_DIFF(p1, hexchars);
579 lonybble = PTR_DIFF(p2, hexchars);
581 pwd[i / 2] = (hinybble << 4) | lonybble;
583 return (True);
586 /*************************************************************
587 Routine to set 42 hex hours characters from a 21 byte array.
588 **************************************************************/
590 void pdb_sethexhours(char *p, const unsigned char *hours)
592 if (hours != NULL) {
593 int i;
594 for (i = 0; i < 21; i++) {
595 slprintf(&p[i*2], 3, "%02X", hours[i]);
597 } else {
598 safe_strcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 43);
602 /*************************************************************
603 Routine to get the 42 hex characters and turn them
604 into a 21 byte array.
605 **************************************************************/
607 BOOL pdb_gethexhours(const char *p, unsigned char *hours)
609 int i;
610 unsigned char lonybble, hinybble;
611 const char *hexchars = "0123456789ABCDEF";
612 char *p1, *p2;
614 if (!p) {
615 return (False);
618 for (i = 0; i < 42; i += 2) {
619 hinybble = toupper(p[i]);
620 lonybble = toupper(p[i + 1]);
622 p1 = strchr(hexchars, hinybble);
623 p2 = strchr(hexchars, lonybble);
625 if (!p1 || !p2) {
626 return (False);
629 hinybble = PTR_DIFF(p1, hexchars);
630 lonybble = PTR_DIFF(p2, hexchars);
632 hours[i / 2] = (hinybble << 4) | lonybble;
634 return (True);
637 int algorithmic_rid_base(void)
639 static int rid_offset = 0;
641 if (rid_offset != 0)
642 return rid_offset;
644 rid_offset = lp_algorithmic_rid_base();
646 if (rid_offset < BASE_RID) {
647 /* Try to prevent admin foot-shooting, we can't put algorithmic
648 rids below 1000, that's the 'well known RIDs' on NT */
649 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
650 rid_offset = BASE_RID;
652 if (rid_offset & 1) {
653 DEBUG(0, ("algorithmic rid base must be even\n"));
654 rid_offset += 1;
656 return rid_offset;
659 /*******************************************************************
660 Converts NT user RID to a UNIX uid.
661 ********************************************************************/
663 uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
665 int rid_offset = algorithmic_rid_base();
666 return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
669 /*******************************************************************
670 converts UNIX uid to an NT User RID.
671 ********************************************************************/
673 uint32 algorithmic_pdb_uid_to_user_rid(uid_t uid)
675 int rid_offset = algorithmic_rid_base();
676 return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
679 /*******************************************************************
680 Converts NT group RID to a UNIX gid.
681 ********************************************************************/
683 gid_t pdb_group_rid_to_gid(uint32 group_rid)
685 int rid_offset = algorithmic_rid_base();
686 return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
689 /*******************************************************************
690 converts NT Group RID to a UNIX uid.
692 warning: you must not call that function only
693 you must do a call to the group mapping first.
694 there is not anymore a direct link between the gid and the rid.
695 ********************************************************************/
697 uint32 pdb_gid_to_group_rid(gid_t gid)
699 int rid_offset = algorithmic_rid_base();
700 return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
703 /*******************************************************************
704 Decides if a RID is a well known RID.
705 ********************************************************************/
707 static BOOL pdb_rid_is_well_known(uint32 rid)
709 /* Not using rid_offset here, because this is the actual
710 NT fixed value (1000) */
712 return (rid < BASE_RID);
715 /*******************************************************************
716 Decides if a RID is a user or group RID.
717 ********************************************************************/
719 BOOL algorithmic_pdb_rid_is_user(uint32 rid)
721 if(pdb_rid_is_well_known(rid)) {
723 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
724 * and DOMAIN_USER_RID_GUEST.
726 if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
727 return True;
728 } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
729 return True;
731 return False;
734 /*******************************************************************
735 Convert a rid into a name. Used in the lookup SID rpc.
736 ********************************************************************/
738 BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
740 uint32 rid;
741 SAM_ACCOUNT *sam_account = NULL;
742 GROUP_MAP map;
743 BOOL ret;
745 if (sid_equal(get_global_sam_sid(), sid)) {
746 *psid_name_use = SID_NAME_DOMAIN;
747 fstrcpy(name, "");
748 DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
749 sid_string_static(sid)));
750 return True;
753 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
754 DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
755 sid_string_static(&map.sid)));
756 return False;
758 *psid_name_use = SID_NAME_UNKNOWN;
760 DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
762 if (rid == DOMAIN_USER_RID_ADMIN) {
763 const char **admin_list = lp_admin_users(-1);
764 *psid_name_use = SID_NAME_USER;
765 if (admin_list) {
766 const char *p = *admin_list;
767 if(!next_token(&p, name, NULL, sizeof(fstring)))
768 fstrcpy(name, "Administrator");
769 } else {
770 fstrcpy(name, "Administrator");
772 return True;
775 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
776 return False;
779 /* see if the passdb can help us with the name of the user */
781 /* BEING ROOT BLLOCK */
782 become_root();
783 if (pdb_getsampwsid(sam_account, sid)) {
784 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
785 fstrcpy(name, pdb_get_username(sam_account));
786 *psid_name_use = SID_NAME_USER;
788 pdb_free_sam(&sam_account);
790 return True;
792 pdb_free_sam(&sam_account);
794 ret = pdb_getgrsid(&map, *sid);
795 unbecome_root();
796 /* END BECOME_ROOT BLOCK */
798 if ( ret ) {
799 if (map.gid!=(gid_t)-1) {
800 DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
801 } else {
802 DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
805 fstrcpy(name, map.nt_name);
806 *psid_name_use = map.sid_name_use;
807 return True;
810 if (algorithmic_pdb_rid_is_user(rid)) {
811 uid_t uid;
812 struct passwd *pw = NULL;
814 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
816 uid = algorithmic_pdb_user_rid_to_uid(rid);
817 pw = sys_getpwuid( uid );
819 DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
820 pw ? "succeeded" : "failed" ));
822 if ( !pw )
823 fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
824 else
825 fstrcpy( name, pw->pw_name );
827 DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
828 (unsigned int)rid ));
830 *psid_name_use = SID_NAME_USER;
832 return ( pw != NULL );
833 } else {
834 gid_t gid;
835 struct group *gr;
837 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
839 gid = pdb_group_rid_to_gid(rid);
840 gr = getgrgid(gid);
842 *psid_name_use = SID_NAME_ALIAS;
844 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
845 gr ? "succeeded" : "failed" ));
847 if( !gr )
848 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
849 else
850 fstrcpy( name, gr->gr_name);
852 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
853 (unsigned int)rid ));
855 /* assume algorithmic groups are domain global groups */
857 *psid_name_use = SID_NAME_DOM_GRP;
859 return ( gr != NULL );
863 /*******************************************************************
864 Convert a name into a SID. Used in the lookup name rpc.
865 ********************************************************************/
867 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
869 DOM_SID local_sid;
870 DOM_SID sid;
871 fstring user;
872 SAM_ACCOUNT *sam_account = NULL;
873 struct group *grp;
874 GROUP_MAP map;
876 *psid_name_use = SID_NAME_UNKNOWN;
879 * user may be quoted a const string, and map_username and
880 * friends can modify it. Make a modifiable copy. JRA.
883 fstrcpy(user, c_user);
885 sid_copy(&local_sid, get_global_sam_sid());
887 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
888 fstring sid_str;
889 sid_copy( psid, &sid);
890 sid_to_string(sid_str, &sid);
891 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
892 (unsigned int)*psid_name_use ));
893 return True;
896 (void)map_username(user);
898 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
899 return False;
902 /* BEGIN ROOT BLOCK */
904 become_root();
905 if (pdb_getsampwnam(sam_account, user)) {
906 unbecome_root();
907 sid_copy(psid, pdb_get_user_sid(sam_account));
908 *psid_name_use = SID_NAME_USER;
910 pdb_free_sam(&sam_account);
911 return True;
914 pdb_free_sam(&sam_account);
917 * Maybe it was a group ?
920 /* check if it's a mapped group */
921 if (pdb_getgrnam(&map, user)) {
922 /* yes it's a mapped group */
923 sid_copy(&local_sid, &map.sid);
924 *psid_name_use = map.sid_name_use;
925 } else {
926 /* it's not a mapped group */
927 grp = getgrnam(user);
928 if(!grp) {
929 unbecome_root(); /* ---> exit form block */
930 return False;
934 *check if it's mapped, if it is reply it doesn't exist
936 * that's to prevent this case:
938 * unix group ug is mapped to nt group ng
939 * someone does a lookup on ug
940 * we must not reply as it doesn't "exist" anymore
941 * for NT. For NT only ng exists.
942 * JFM, 30/11/2001
945 if (pdb_getgrgid(&map, grp->gr_gid)){
946 unbecome_root(); /* ---> exit form block */
947 return False;
950 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
951 *psid_name_use = SID_NAME_ALIAS;
953 unbecome_root();
954 /* END ROOT BLOCK */
956 sid_copy( psid, &local_sid);
958 return True;
961 /*************************************************************
962 Change a password entry in the local smbpasswd file.
963 *************************************************************/
965 BOOL local_password_change(const char *user_name, int local_flags,
966 const char *new_passwd,
967 char *err_str, size_t err_str_len,
968 char *msg_str, size_t msg_str_len)
970 SAM_ACCOUNT *sam_pass=NULL;
971 uint16 other_acb;
973 *err_str = '\0';
974 *msg_str = '\0';
976 /* Get the smb passwd entry for this user */
977 pdb_init_sam(&sam_pass);
979 become_root();
980 if(!pdb_getsampwnam(sam_pass, user_name)) {
981 unbecome_root();
982 pdb_free_sam(&sam_pass);
984 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
985 /* Might not exist in /etc/passwd. Use rid algorithm here */
986 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
987 slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name);
988 return False;
990 } else {
991 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
992 return False;
994 } else {
995 unbecome_root();
996 /* the entry already existed */
997 local_flags &= ~LOCAL_ADD_USER;
1000 /* the 'other' acb bits not being changed here */
1001 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
1002 if (local_flags & LOCAL_TRUST_ACCOUNT) {
1003 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
1004 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
1005 pdb_free_sam(&sam_pass);
1006 return False;
1008 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
1009 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
1010 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
1011 pdb_free_sam(&sam_pass);
1012 return False;
1014 } else {
1015 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1016 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1017 pdb_free_sam(&sam_pass);
1018 return False;
1023 * We are root - just write the new password
1024 * and the valid last change time.
1027 if (local_flags & LOCAL_DISABLE_USER) {
1028 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1029 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1030 pdb_free_sam(&sam_pass);
1031 return False;
1033 } else if (local_flags & LOCAL_ENABLE_USER) {
1034 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1035 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1036 pdb_free_sam(&sam_pass);
1037 return False;
1041 if (local_flags & LOCAL_SET_NO_PASSWORD) {
1042 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1043 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1044 pdb_free_sam(&sam_pass);
1045 return False;
1047 } else if (local_flags & LOCAL_SET_PASSWORD) {
1049 * If we're dealing with setting a completely empty user account
1050 * ie. One with a password of 'XXXX', but not set disabled (like
1051 * an account created from scratch) then if the old password was
1052 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1053 * We remove that as we're giving this user their first password
1054 * and the decision hasn't really been made to disable them (ie.
1055 * don't create them disabled). JRA.
1057 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1058 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1059 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1060 pdb_free_sam(&sam_pass);
1061 return False;
1064 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1065 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1066 pdb_free_sam(&sam_pass);
1067 return False;
1070 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1071 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1072 pdb_free_sam(&sam_pass);
1073 return False;
1077 if (local_flags & LOCAL_ADD_USER) {
1078 if (pdb_add_sam_account(sam_pass)) {
1079 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1080 pdb_free_sam(&sam_pass);
1081 return True;
1082 } else {
1083 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1084 pdb_free_sam(&sam_pass);
1085 return False;
1087 } else if (local_flags & LOCAL_DELETE_USER) {
1088 if (!pdb_delete_sam_account(sam_pass)) {
1089 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1090 pdb_free_sam(&sam_pass);
1091 return False;
1093 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1094 } else {
1095 if(!pdb_update_sam_account(sam_pass)) {
1096 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1097 pdb_free_sam(&sam_pass);
1098 return False;
1100 if(local_flags & LOCAL_DISABLE_USER)
1101 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1102 else if (local_flags & LOCAL_ENABLE_USER)
1103 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1104 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1105 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1108 pdb_free_sam(&sam_pass);
1109 return True;
1112 /****************************************************************************
1113 Convert a uid to SID - algorithmic.
1114 ****************************************************************************/
1116 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1118 if ( !lp_enable_rid_algorithm() )
1119 return NULL;
1121 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1122 sid_copy( psid, get_global_sam_sid() );
1123 sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1124 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1125 (unsigned int)uid, sid_string_static(psid) ));
1127 return psid;
1130 /****************************************************************************
1131 Convert a uid to SID - locally.
1132 ****************************************************************************/
1134 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1136 SAM_ACCOUNT *sampw = NULL;
1137 struct passwd *unix_pw;
1138 BOOL ret;
1140 unix_pw = sys_getpwuid( uid );
1142 if ( !unix_pw ) {
1143 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1144 return algorithmic_uid_to_sid( psid, uid);
1147 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1148 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1149 return NULL;
1152 become_root();
1153 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1154 unbecome_root();
1156 if ( ret )
1157 sid_copy( psid, pdb_get_user_sid(sampw) );
1158 else {
1159 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1160 unix_pw->pw_name, (unsigned long)uid));
1162 return algorithmic_uid_to_sid( psid, uid);
1165 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1166 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1168 return psid;
1171 /****************************************************************************
1172 Convert a SID to uid - locally.
1173 ****************************************************************************/
1175 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1177 SAM_ACCOUNT *sampw = NULL;
1178 struct passwd *unix_pw;
1179 const char *user_name;
1181 *name_type = SID_NAME_UNKNOWN;
1184 * We can only convert to a uid if this is our local
1185 * Domain SID (ie. we are the controling authority).
1187 if (!sid_check_is_in_our_domain(psid) ) {
1188 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1189 return False;
1192 /* lookup the user account */
1194 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1195 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1196 return False;
1199 become_root();
1200 if ( !pdb_getsampwsid(sampw, psid) ) {
1201 unbecome_root();
1202 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1203 sid_string_static(psid)));
1204 return False;
1206 unbecome_root();
1208 user_name = pdb_get_username(sampw);
1210 unix_pw = sys_getpwnam( user_name );
1212 if ( !unix_pw ) {
1213 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1214 user_name));
1215 pdb_free_sam( &sampw );
1216 return False;
1219 *puid = unix_pw->pw_uid;
1221 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1222 (unsigned int)*puid, user_name ));
1224 *name_type = SID_NAME_USER;
1226 return True;
1229 /****************************************************************************
1230 Convert a gid to SID - algorithmic.
1231 ****************************************************************************/
1233 DOM_SID *algorithmic_gid_to_sid(DOM_SID *psid, uid_t gid)
1235 if ( !lp_enable_rid_algorithm() )
1236 return NULL;
1238 DEBUG(8,("algorithmic_gid_to_sid: falling back to RID algorithm\n"));
1239 sid_copy( psid, get_global_sam_sid() );
1240 sid_append_rid( psid, pdb_gid_to_group_rid(gid) );
1241 DEBUG(10,("algorithmic_gid_to_sid: gid (%d) -> SID %s.\n",
1242 (unsigned int)gid, sid_string_static(psid) ));
1244 return psid;
1247 /****************************************************************************
1248 Convert a gid to SID - locally.
1249 ****************************************************************************/
1251 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1253 GROUP_MAP group;
1254 BOOL ret;
1256 /* we don't need to disable winbindd since the gid is stored in
1257 the GROUP_MAP object */
1259 /* done as root since ldap backend requires root to open a connection */
1261 become_root();
1262 ret = pdb_getgrgid( &group, gid );
1263 unbecome_root();
1265 if ( !ret ) {
1267 /* algorithmic to rid mapping if enabled */
1269 if ( lp_enable_rid_algorithm() ) {
1271 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1272 (unsigned int)gid, sid_string_static(psid)));
1274 return algorithmic_gid_to_sid(psid, gid);
1276 else
1277 return NULL;
1280 sid_copy( psid, &group.sid );
1282 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1283 (unsigned int)gid, sid_string_static(psid)));
1285 return psid;
1288 /****************************************************************************
1289 Convert a SID to gid - locally.
1290 ****************************************************************************/
1292 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1294 uint32 rid;
1295 GROUP_MAP group;
1296 BOOL ret;
1298 *name_type = SID_NAME_UNKNOWN;
1300 /* This call can enumerate group mappings for foreign sids as well.
1301 So don't check for a match against our domain SID */
1303 /* we don't need to disable winbindd since the gid is stored in
1304 the GROUP_MAP object */
1306 become_root();
1307 ret = pdb_getgrsid(&group, *psid);
1308 unbecome_root();
1310 if ( !ret ) {
1312 /* Fallback to algorithmic rid mapping if enabled */
1314 if ( lp_enable_rid_algorithm() ) {
1316 if (!sid_check_is_in_our_domain(psid) ) {
1317 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1318 return False;
1321 if (!sid_peek_rid(psid, &rid)) {
1322 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1323 return False;
1326 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1328 if (algorithmic_pdb_rid_is_user(rid)) {
1329 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1330 return False;
1331 } else {
1332 *pgid = pdb_group_rid_to_gid(rid);
1333 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1334 return True;
1338 return False;
1341 *pgid = group.gid;
1342 *name_type = group.sid_name_use;
1344 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1345 (unsigned int)*pgid));
1347 return True;
1350 /**********************************************************************
1351 Marshall/unmarshall SAM_ACCOUNT structs.
1352 *********************************************************************/
1354 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1355 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1356 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1358 /**********************************************************************
1359 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1360 *********************************************************************/
1362 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1364 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1367 /**********************************************************************
1368 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1369 *********************************************************************/
1371 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1373 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1377 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1380 /* times are stored as 32bit integer
1381 take care on system with 64bit wide time_t
1382 --SSS */
1383 uint32 logon_time,
1384 logoff_time,
1385 kickoff_time,
1386 pass_last_set_time,
1387 pass_can_change_time,
1388 pass_must_change_time;
1389 char *username;
1390 char *domain;
1391 char *nt_username;
1392 char *dir_drive;
1393 char *unknown_str;
1394 char *munged_dial;
1395 char *fullname;
1396 char *homedir;
1397 char *logon_script;
1398 char *profile_path;
1399 char *acct_desc;
1400 char *workstations;
1401 uint32 username_len, domain_len, nt_username_len,
1402 dir_drive_len, unknown_str_len, munged_dial_len,
1403 fullname_len, homedir_len, logon_script_len,
1404 profile_path_len, acct_desc_len, workstations_len;
1406 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1407 uint16 acct_ctrl, logon_divs;
1408 uint16 bad_password_count, logon_count;
1409 uint8 *hours;
1410 uint8 *lm_pw_ptr, *nt_pw_ptr;
1411 uint32 len = 0;
1412 uint32 lm_pw_len, nt_pw_len, hourslen;
1413 BOOL ret = True;
1415 if(sampass == NULL || buf == NULL) {
1416 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1417 return False;
1420 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1422 /* unpack the buffer into variables */
1423 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1424 &logon_time, /* d */
1425 &logoff_time, /* d */
1426 &kickoff_time, /* d */
1427 &pass_last_set_time, /* d */
1428 &pass_can_change_time, /* d */
1429 &pass_must_change_time, /* d */
1430 &username_len, &username, /* B */
1431 &domain_len, &domain, /* B */
1432 &nt_username_len, &nt_username, /* B */
1433 &fullname_len, &fullname, /* B */
1434 &homedir_len, &homedir, /* B */
1435 &dir_drive_len, &dir_drive, /* B */
1436 &logon_script_len, &logon_script, /* B */
1437 &profile_path_len, &profile_path, /* B */
1438 &acct_desc_len, &acct_desc, /* B */
1439 &workstations_len, &workstations, /* B */
1440 &unknown_str_len, &unknown_str, /* B */
1441 &munged_dial_len, &munged_dial, /* B */
1442 &user_rid, /* d */
1443 &group_rid, /* d */
1444 &lm_pw_len, &lm_pw_ptr, /* B */
1445 &nt_pw_len, &nt_pw_ptr, /* B */
1446 &acct_ctrl, /* w */
1447 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1448 &logon_divs, /* w */
1449 &hours_len, /* d */
1450 &hourslen, &hours, /* B */
1451 &bad_password_count, /* w */
1452 &logon_count, /* w */
1453 &unknown_6); /* d */
1455 if (len == (uint32) -1) {
1456 ret = False;
1457 goto done;
1460 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1461 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1462 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1463 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1464 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1465 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1467 pdb_set_username(sampass, username, PDB_SET);
1468 pdb_set_domain(sampass, domain, PDB_SET);
1469 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1470 pdb_set_fullname(sampass, fullname, PDB_SET);
1472 if (homedir) {
1473 pdb_set_homedir(sampass, homedir, PDB_SET);
1475 else {
1476 pdb_set_homedir(sampass,
1477 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1478 PDB_DEFAULT);
1481 if (dir_drive)
1482 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1483 else {
1484 pdb_set_dir_drive(sampass,
1485 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1486 PDB_DEFAULT);
1489 if (logon_script)
1490 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1491 else {
1492 pdb_set_logon_script(sampass,
1493 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1494 PDB_DEFAULT);
1497 if (profile_path) {
1498 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1499 } else {
1500 pdb_set_profile_path(sampass,
1501 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1502 PDB_DEFAULT);
1505 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1506 pdb_set_workstations(sampass, workstations, PDB_SET);
1507 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1509 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1510 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1511 ret = False;
1512 goto done;
1516 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1517 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1518 ret = False;
1519 goto done;
1523 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1524 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1525 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1526 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1527 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1528 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1529 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1530 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1531 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1532 pdb_set_hours(sampass, hours, PDB_SET);
1534 done:
1536 SAFE_FREE(username);
1537 SAFE_FREE(domain);
1538 SAFE_FREE(nt_username);
1539 SAFE_FREE(fullname);
1540 SAFE_FREE(homedir);
1541 SAFE_FREE(dir_drive);
1542 SAFE_FREE(logon_script);
1543 SAFE_FREE(profile_path);
1544 SAFE_FREE(acct_desc);
1545 SAFE_FREE(workstations);
1546 SAFE_FREE(munged_dial);
1547 SAFE_FREE(unknown_str);
1548 SAFE_FREE(lm_pw_ptr);
1549 SAFE_FREE(nt_pw_ptr);
1550 SAFE_FREE(hours);
1552 return ret;
1555 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1558 /* times are stored as 32bit integer
1559 take care on system with 64bit wide time_t
1560 --SSS */
1561 uint32 logon_time,
1562 logoff_time,
1563 kickoff_time,
1564 bad_password_time,
1565 pass_last_set_time,
1566 pass_can_change_time,
1567 pass_must_change_time;
1568 char *username;
1569 char *domain;
1570 char *nt_username;
1571 char *dir_drive;
1572 char *unknown_str;
1573 char *munged_dial;
1574 char *fullname;
1575 char *homedir;
1576 char *logon_script;
1577 char *profile_path;
1578 char *acct_desc;
1579 char *workstations;
1580 uint32 username_len, domain_len, nt_username_len,
1581 dir_drive_len, unknown_str_len, munged_dial_len,
1582 fullname_len, homedir_len, logon_script_len,
1583 profile_path_len, acct_desc_len, workstations_len;
1585 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1586 uint16 acct_ctrl, logon_divs;
1587 uint16 bad_password_count, logon_count;
1588 uint8 *hours;
1589 uint8 *lm_pw_ptr, *nt_pw_ptr;
1590 uint32 len = 0;
1591 uint32 lm_pw_len, nt_pw_len, hourslen;
1592 BOOL ret = True;
1594 if(sampass == NULL || buf == NULL) {
1595 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1596 return False;
1599 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1601 /* unpack the buffer into variables */
1602 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1603 &logon_time, /* d */
1604 &logoff_time, /* d */
1605 &kickoff_time, /* d */
1606 /* Change from V0 is addition of bad_password_time field. */
1607 &bad_password_time, /* d */
1608 &pass_last_set_time, /* d */
1609 &pass_can_change_time, /* d */
1610 &pass_must_change_time, /* d */
1611 &username_len, &username, /* B */
1612 &domain_len, &domain, /* B */
1613 &nt_username_len, &nt_username, /* B */
1614 &fullname_len, &fullname, /* B */
1615 &homedir_len, &homedir, /* B */
1616 &dir_drive_len, &dir_drive, /* B */
1617 &logon_script_len, &logon_script, /* B */
1618 &profile_path_len, &profile_path, /* B */
1619 &acct_desc_len, &acct_desc, /* B */
1620 &workstations_len, &workstations, /* B */
1621 &unknown_str_len, &unknown_str, /* B */
1622 &munged_dial_len, &munged_dial, /* B */
1623 &user_rid, /* d */
1624 &group_rid, /* d */
1625 &lm_pw_len, &lm_pw_ptr, /* B */
1626 &nt_pw_len, &nt_pw_ptr, /* B */
1627 &acct_ctrl, /* w */
1628 &remove_me, /* d */
1629 &logon_divs, /* w */
1630 &hours_len, /* d */
1631 &hourslen, &hours, /* B */
1632 &bad_password_count, /* w */
1633 &logon_count, /* w */
1634 &unknown_6); /* d */
1636 if (len == (uint32) -1) {
1637 ret = False;
1638 goto done;
1641 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1642 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1643 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1645 /* Change from V0 is addition of bad_password_time field. */
1646 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1647 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1648 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1649 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1651 pdb_set_username(sampass, username, PDB_SET);
1652 pdb_set_domain(sampass, domain, PDB_SET);
1653 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1654 pdb_set_fullname(sampass, fullname, PDB_SET);
1656 if (homedir) {
1657 pdb_set_homedir(sampass, homedir, PDB_SET);
1659 else {
1660 pdb_set_homedir(sampass,
1661 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1662 PDB_DEFAULT);
1665 if (dir_drive)
1666 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1667 else {
1668 pdb_set_dir_drive(sampass,
1669 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1670 PDB_DEFAULT);
1673 if (logon_script)
1674 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1675 else {
1676 pdb_set_logon_script(sampass,
1677 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1678 PDB_DEFAULT);
1681 if (profile_path) {
1682 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1683 } else {
1684 pdb_set_profile_path(sampass,
1685 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1686 PDB_DEFAULT);
1689 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1690 pdb_set_workstations(sampass, workstations, PDB_SET);
1691 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1693 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1694 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1695 ret = False;
1696 goto done;
1700 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1701 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1702 ret = False;
1703 goto done;
1707 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1709 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1710 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1711 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1712 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1713 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1714 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1715 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1716 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1717 pdb_set_hours(sampass, hours, PDB_SET);
1719 done:
1721 SAFE_FREE(username);
1722 SAFE_FREE(domain);
1723 SAFE_FREE(nt_username);
1724 SAFE_FREE(fullname);
1725 SAFE_FREE(homedir);
1726 SAFE_FREE(dir_drive);
1727 SAFE_FREE(logon_script);
1728 SAFE_FREE(profile_path);
1729 SAFE_FREE(acct_desc);
1730 SAFE_FREE(workstations);
1731 SAFE_FREE(munged_dial);
1732 SAFE_FREE(unknown_str);
1733 SAFE_FREE(lm_pw_ptr);
1734 SAFE_FREE(nt_pw_ptr);
1735 SAFE_FREE(hours);
1737 return ret;
1741 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1744 /* times are stored as 32bit integer
1745 take care on system with 64bit wide time_t
1746 --SSS */
1747 uint32 logon_time,
1748 logoff_time,
1749 kickoff_time,
1750 bad_password_time,
1751 pass_last_set_time,
1752 pass_can_change_time,
1753 pass_must_change_time;
1754 char *username;
1755 char *domain;
1756 char *nt_username;
1757 char *dir_drive;
1758 char *unknown_str;
1759 char *munged_dial;
1760 char *fullname;
1761 char *homedir;
1762 char *logon_script;
1763 char *profile_path;
1764 char *acct_desc;
1765 char *workstations;
1766 uint32 username_len, domain_len, nt_username_len,
1767 dir_drive_len, unknown_str_len, munged_dial_len,
1768 fullname_len, homedir_len, logon_script_len,
1769 profile_path_len, acct_desc_len, workstations_len;
1771 uint32 user_rid, group_rid, hours_len, unknown_6;
1772 uint16 acct_ctrl, logon_divs;
1773 uint16 bad_password_count, logon_count;
1774 uint8 *hours;
1775 uint8 *lm_pw_ptr, *nt_pw_ptr, *nt_pw_hist_ptr;
1776 uint32 len = 0;
1777 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1778 uint32 pwHistLen = 0;
1779 BOOL ret = True;
1780 fstring tmpstring;
1782 if(sampass == NULL || buf == NULL) {
1783 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1784 return False;
1787 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1789 /* unpack the buffer into variables */
1790 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1791 &logon_time, /* d */
1792 &logoff_time, /* d */
1793 &kickoff_time, /* d */
1794 &bad_password_time, /* d */
1795 &pass_last_set_time, /* d */
1796 &pass_can_change_time, /* d */
1797 &pass_must_change_time, /* d */
1798 &username_len, &username, /* B */
1799 &domain_len, &domain, /* B */
1800 &nt_username_len, &nt_username, /* B */
1801 &fullname_len, &fullname, /* B */
1802 &homedir_len, &homedir, /* B */
1803 &dir_drive_len, &dir_drive, /* B */
1804 &logon_script_len, &logon_script, /* B */
1805 &profile_path_len, &profile_path, /* B */
1806 &acct_desc_len, &acct_desc, /* B */
1807 &workstations_len, &workstations, /* B */
1808 &unknown_str_len, &unknown_str, /* B */
1809 &munged_dial_len, &munged_dial, /* B */
1810 &user_rid, /* d */
1811 &group_rid, /* d */
1812 &lm_pw_len, &lm_pw_ptr, /* B */
1813 &nt_pw_len, &nt_pw_ptr, /* B */
1814 /* Change from V1 is addition of password history field. */
1815 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1816 &acct_ctrl, /* w */
1817 /* Also "remove_me" field was removed. */
1818 &logon_divs, /* w */
1819 &hours_len, /* d */
1820 &hourslen, &hours, /* B */
1821 &bad_password_count, /* w */
1822 &logon_count, /* w */
1823 &unknown_6); /* d */
1825 if (len == (uint32) -1) {
1826 ret = False;
1827 goto done;
1830 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1831 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1832 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1833 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1834 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1835 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1836 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1838 pdb_set_username(sampass, username, PDB_SET);
1839 pdb_set_domain(sampass, domain, PDB_SET);
1840 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1841 pdb_set_fullname(sampass, fullname, PDB_SET);
1843 if (homedir) {
1844 fstrcpy( tmpstring, homedir );
1845 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1846 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1848 else {
1849 pdb_set_homedir(sampass,
1850 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1851 PDB_DEFAULT);
1854 if (dir_drive)
1855 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1856 else
1857 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1859 if (logon_script) {
1860 fstrcpy( tmpstring, logon_script );
1861 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1862 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1864 else {
1865 pdb_set_logon_script(sampass,
1866 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1867 PDB_DEFAULT);
1870 if (profile_path) {
1871 fstrcpy( tmpstring, profile_path );
1872 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1873 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1875 else {
1876 pdb_set_profile_path(sampass,
1877 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1878 PDB_DEFAULT);
1881 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1882 pdb_set_workstations(sampass, workstations, PDB_SET);
1883 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1885 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1886 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1887 ret = False;
1888 goto done;
1892 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1893 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1894 ret = False;
1895 goto done;
1899 /* Change from V1 is addition of password history field. */
1900 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1901 if (pwHistLen) {
1902 char *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1903 if (!pw_hist) {
1904 ret = False;
1905 goto done;
1907 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1908 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1909 int i;
1910 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1911 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1912 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1913 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1914 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1915 PW_HISTORY_ENTRY_LEN);
1918 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1919 SAFE_FREE(pw_hist);
1920 ret = False;
1921 goto done;
1923 SAFE_FREE(pw_hist);
1924 } else {
1925 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1928 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1929 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1930 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1931 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1932 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1933 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1934 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1935 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1936 pdb_set_hours(sampass, hours, PDB_SET);
1938 done:
1940 SAFE_FREE(username);
1941 SAFE_FREE(domain);
1942 SAFE_FREE(nt_username);
1943 SAFE_FREE(fullname);
1944 SAFE_FREE(homedir);
1945 SAFE_FREE(dir_drive);
1946 SAFE_FREE(logon_script);
1947 SAFE_FREE(profile_path);
1948 SAFE_FREE(acct_desc);
1949 SAFE_FREE(workstations);
1950 SAFE_FREE(munged_dial);
1951 SAFE_FREE(unknown_str);
1952 SAFE_FREE(lm_pw_ptr);
1953 SAFE_FREE(nt_pw_ptr);
1954 SAFE_FREE(nt_pw_hist_ptr);
1955 SAFE_FREE(hours);
1957 return ret;
1960 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1962 size_t len, buflen;
1964 /* times are stored as 32bit integer
1965 take care on system with 64bit wide time_t
1966 --SSS */
1967 uint32 logon_time,
1968 logoff_time,
1969 kickoff_time,
1970 bad_password_time,
1971 pass_last_set_time,
1972 pass_can_change_time,
1973 pass_must_change_time;
1975 uint32 user_rid, group_rid;
1977 const char *username;
1978 const char *domain;
1979 const char *nt_username;
1980 const char *dir_drive;
1981 const char *unknown_str;
1982 const char *munged_dial;
1983 const char *fullname;
1984 const char *homedir;
1985 const char *logon_script;
1986 const char *profile_path;
1987 const char *acct_desc;
1988 const char *workstations;
1989 uint32 username_len, domain_len, nt_username_len,
1990 dir_drive_len, unknown_str_len, munged_dial_len,
1991 fullname_len, homedir_len, logon_script_len,
1992 profile_path_len, acct_desc_len, workstations_len;
1994 const uint8 *lm_pw;
1995 const uint8 *nt_pw;
1996 const uint8 *nt_pw_hist;
1997 uint32 lm_pw_len = 16;
1998 uint32 nt_pw_len = 16;
1999 uint32 nt_pw_hist_len;
2000 uint32 pwHistLen = 0;
2002 /* do we have a valid SAM_ACCOUNT pointer? */
2003 if (sampass == NULL) {
2004 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
2005 return -1;
2008 *buf = NULL;
2009 buflen = 0;
2011 logon_time = (uint32)pdb_get_logon_time(sampass);
2012 logoff_time = (uint32)pdb_get_logoff_time(sampass);
2013 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
2014 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
2015 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
2016 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
2017 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
2019 user_rid = pdb_get_user_rid(sampass);
2020 group_rid = pdb_get_group_rid(sampass);
2022 username = pdb_get_username(sampass);
2023 if (username) {
2024 username_len = strlen(username) +1;
2025 } else {
2026 username_len = 0;
2029 domain = pdb_get_domain(sampass);
2030 if (domain) {
2031 domain_len = strlen(domain) +1;
2032 } else {
2033 domain_len = 0;
2036 nt_username = pdb_get_nt_username(sampass);
2037 if (nt_username) {
2038 nt_username_len = strlen(nt_username) +1;
2039 } else {
2040 nt_username_len = 0;
2043 fullname = pdb_get_fullname(sampass);
2044 if (fullname) {
2045 fullname_len = strlen(fullname) +1;
2046 } else {
2047 fullname_len = 0;
2051 * Only updates fields which have been set (not defaults from smb.conf)
2054 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2055 dir_drive = pdb_get_dir_drive(sampass);
2056 } else {
2057 dir_drive = NULL;
2059 if (dir_drive) {
2060 dir_drive_len = strlen(dir_drive) +1;
2061 } else {
2062 dir_drive_len = 0;
2065 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2066 homedir = pdb_get_homedir(sampass);
2067 } else {
2068 homedir = NULL;
2070 if (homedir) {
2071 homedir_len = strlen(homedir) +1;
2072 } else {
2073 homedir_len = 0;
2076 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2077 logon_script = pdb_get_logon_script(sampass);
2078 } else {
2079 logon_script = NULL;
2081 if (logon_script) {
2082 logon_script_len = strlen(logon_script) +1;
2083 } else {
2084 logon_script_len = 0;
2087 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2088 profile_path = pdb_get_profile_path(sampass);
2089 } else {
2090 profile_path = NULL;
2092 if (profile_path) {
2093 profile_path_len = strlen(profile_path) +1;
2094 } else {
2095 profile_path_len = 0;
2098 lm_pw = pdb_get_lanman_passwd(sampass);
2099 if (!lm_pw) {
2100 lm_pw_len = 0;
2103 nt_pw = pdb_get_nt_passwd(sampass);
2104 if (!nt_pw) {
2105 nt_pw_len = 0;
2108 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
2109 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2110 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2111 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2112 } else {
2113 nt_pw_hist_len = 0;
2116 acct_desc = pdb_get_acct_desc(sampass);
2117 if (acct_desc) {
2118 acct_desc_len = strlen(acct_desc) +1;
2119 } else {
2120 acct_desc_len = 0;
2123 workstations = pdb_get_workstations(sampass);
2124 if (workstations) {
2125 workstations_len = strlen(workstations) +1;
2126 } else {
2127 workstations_len = 0;
2130 unknown_str = NULL;
2131 unknown_str_len = 0;
2133 munged_dial = pdb_get_munged_dial(sampass);
2134 if (munged_dial) {
2135 munged_dial_len = strlen(munged_dial) +1;
2136 } else {
2137 munged_dial_len = 0;
2140 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2142 /* one time to get the size needed */
2143 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2144 logon_time, /* d */
2145 logoff_time, /* d */
2146 kickoff_time, /* d */
2147 bad_password_time, /* d */
2148 pass_last_set_time, /* d */
2149 pass_can_change_time, /* d */
2150 pass_must_change_time, /* d */
2151 username_len, username, /* B */
2152 domain_len, domain, /* B */
2153 nt_username_len, nt_username, /* B */
2154 fullname_len, fullname, /* B */
2155 homedir_len, homedir, /* B */
2156 dir_drive_len, dir_drive, /* B */
2157 logon_script_len, logon_script, /* B */
2158 profile_path_len, profile_path, /* B */
2159 acct_desc_len, acct_desc, /* B */
2160 workstations_len, workstations, /* B */
2161 unknown_str_len, unknown_str, /* B */
2162 munged_dial_len, munged_dial, /* B */
2163 user_rid, /* d */
2164 group_rid, /* d */
2165 lm_pw_len, lm_pw, /* B */
2166 nt_pw_len, nt_pw, /* B */
2167 nt_pw_hist_len, nt_pw_hist, /* B */
2168 pdb_get_acct_ctrl(sampass), /* w */
2169 pdb_get_logon_divs(sampass), /* w */
2170 pdb_get_hours_len(sampass), /* d */
2171 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2172 pdb_get_bad_password_count(sampass), /* w */
2173 pdb_get_logon_count(sampass), /* w */
2174 pdb_get_unknown_6(sampass)); /* d */
2176 if (size_only) {
2177 return buflen;
2180 /* malloc the space needed */
2181 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2182 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2183 return (-1);
2186 /* now for the real call to tdb_pack() */
2187 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2188 logon_time, /* d */
2189 logoff_time, /* d */
2190 kickoff_time, /* d */
2191 bad_password_time, /* d */
2192 pass_last_set_time, /* d */
2193 pass_can_change_time, /* d */
2194 pass_must_change_time, /* d */
2195 username_len, username, /* B */
2196 domain_len, domain, /* B */
2197 nt_username_len, nt_username, /* B */
2198 fullname_len, fullname, /* B */
2199 homedir_len, homedir, /* B */
2200 dir_drive_len, dir_drive, /* B */
2201 logon_script_len, logon_script, /* B */
2202 profile_path_len, profile_path, /* B */
2203 acct_desc_len, acct_desc, /* B */
2204 workstations_len, workstations, /* B */
2205 unknown_str_len, unknown_str, /* B */
2206 munged_dial_len, munged_dial, /* B */
2207 user_rid, /* d */
2208 group_rid, /* d */
2209 lm_pw_len, lm_pw, /* B */
2210 nt_pw_len, nt_pw, /* B */
2211 nt_pw_hist_len, nt_pw_hist, /* B */
2212 pdb_get_acct_ctrl(sampass), /* w */
2213 pdb_get_logon_divs(sampass), /* w */
2214 pdb_get_hours_len(sampass), /* d */
2215 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2216 pdb_get_bad_password_count(sampass), /* w */
2217 pdb_get_logon_count(sampass), /* w */
2218 pdb_get_unknown_6(sampass)); /* d */
2220 /* check to make sure we got it correct */
2221 if (buflen != len) {
2222 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2223 (unsigned long)buflen, (unsigned long)len));
2224 /* error */
2225 SAFE_FREE (*buf);
2226 return (-1);
2229 return (buflen);
2232 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2234 BOOL result;
2235 uint8 *buf;
2236 int len;
2238 if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2239 return False;
2241 len = init_buffer_from_sam_v2(&buf, src, False);
2243 if (len == -1)
2244 return False;
2246 result = init_sam_from_buffer_v2(*dst, buf, len);
2247 (*dst)->methods = src->methods;
2249 free(buf);
2251 return result;
2254 /**********************************************************************
2255 **********************************************************************/
2257 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2259 uid_t u_low, u_high;
2260 gid_t g_low, g_high;
2262 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2263 return False;
2266 *low = (u_low < g_low) ? u_low : g_low;
2267 *high = (u_high < g_high) ? u_high : g_high;
2269 return True;
2272 /******************************************************************
2273 Get the the non-algorithmic RID range if idmap range are defined
2274 ******************************************************************/
2276 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2278 uint32 id_low, id_high;
2280 if (!lp_enable_rid_algorithm()) {
2281 *low = BASE_RID;
2282 *high = (uint32)-1;
2285 if (!get_free_ugid_range(&id_low, &id_high)) {
2286 return False;
2289 *low = algorithmic_pdb_uid_to_user_rid(id_low);
2290 if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2291 *high = (uint32)-1;
2292 } else {
2293 *high = algorithmic_pdb_uid_to_user_rid(id_high);
2296 return True;
2299 /*********************************************************************
2300 Update the bad password count checking the AP_RESET_COUNT_TIME
2301 *********************************************************************/
2303 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2305 time_t LastBadPassword;
2306 uint16 BadPasswordCount;
2307 uint32 resettime;
2309 if (!sampass) return False;
2311 BadPasswordCount = pdb_get_bad_password_count(sampass);
2312 if (!BadPasswordCount) {
2313 DEBUG(9, ("No bad password attempts.\n"));
2314 return True;
2317 if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
2318 DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
2319 return False;
2322 /* First, check if there is a reset time to compare */
2323 if ((resettime == (uint32) -1) || (resettime == 0)) {
2324 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2325 return True;
2328 LastBadPassword = pdb_get_bad_password_time(sampass);
2329 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2330 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2331 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2332 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2333 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2334 if (updated) {
2335 *updated = True;
2339 return True;
2342 /*********************************************************************
2343 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2344 *********************************************************************/
2346 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2348 uint32 duration;
2349 time_t LastBadPassword;
2351 if (!sampass) return False;
2353 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2354 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2355 pdb_get_username(sampass)));
2356 return True;
2359 if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2360 DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
2361 return False;
2364 /* First, check if there is a duration to compare */
2365 if ((duration == (uint32) -1) || (duration == 0)) {
2366 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2367 return True;
2370 LastBadPassword = pdb_get_bad_password_time(sampass);
2371 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2372 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2374 if (LastBadPassword == (time_t)0) {
2375 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2376 bad password time. Leaving locked out.\n",
2377 pdb_get_username(sampass) ));
2378 return True;
2381 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2382 pdb_set_acct_ctrl(sampass,
2383 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2384 PDB_CHANGED);
2385 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2386 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2387 if (updated) {
2388 *updated = True;
2392 return True;
2395 /*********************************************************************
2396 Increment the bad_password_count
2397 *********************************************************************/
2399 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2401 uint32 account_policy_lockout;
2402 BOOL autolock_updated = False, badpw_updated = False;
2404 if (!sampass)
2405 return False;
2407 /* Retrieve the account lockout policy */
2408 if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
2409 &account_policy_lockout)) {
2410 DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
2411 return False;
2414 /* If there is no policy, we don't need to continue checking */
2415 if (!account_policy_lockout) {
2416 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2417 return True;
2420 /* Check if the autolock needs to be cleared */
2421 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2422 return False;
2424 /* Check if the badpw count needs to be reset */
2425 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2426 return False;
2429 Ok, now we can assume that any resetting that needs to be
2430 done has been done, and just get on with incrementing
2431 and autolocking if necessary
2434 pdb_set_bad_password_count(sampass,
2435 pdb_get_bad_password_count(sampass)+1,
2436 PDB_CHANGED);
2437 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2440 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2441 return True;
2443 if (!pdb_set_acct_ctrl(sampass,
2444 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2445 PDB_CHANGED)) {
2446 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2447 return False;
2450 return True;