r12224: adding more characters to the invalid share name string
[Samba.git] / source / passdb / passdb.c
blobe073db3499c572ed450fc961918545fde24abc92
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_u); /* 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_u.logon_time = (time_t)0;
64 user->private_u.pass_last_set_time = (time_t)0;
65 user->private_u.pass_can_change_time = (time_t)0;
66 user->private_u.logoff_time =
67 user->private_u.kickoff_time =
68 user->private_u.pass_must_change_time = get_time_t_max();
69 user->private_u.fields_present = 0x00ffffff;
70 user->private_u.logon_divs = 168; /* hours per week */
71 user->private_u.hours_len = 21; /* 21 times 8 bits = 168 */
72 memset(user->private_u.hours, 0xff, user->private_u.hours_len); /* available at all hours */
73 user->private_u.bad_password_count = 0;
74 user->private_u.logon_count = 0;
75 user->private_u.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_u.username = "";
81 user->private_u.domain = "";
82 user->private_u.nt_username = "";
83 user->private_u.full_name = "";
84 user->private_u.home_dir = "";
85 user->private_u.logon_script = "";
86 user->private_u.profile_path = "";
87 user->private_u.acct_desc = "";
88 user->private_u.workstations = "";
89 user->private_u.unknown_str = "";
90 user->private_u.munged_dial = "";
92 user->private_u.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_u.acct_ctrl = ACB_NORMAL;
103 static void destroy_pdb_talloc(SAM_ACCOUNT **user)
105 if (*user) {
106 data_blob_clear_free(&((*user)->private_u.lm_pw));
107 data_blob_clear_free(&((*user)->private_u.nt_pw));
109 if((*user)->private_u.plaintext_pw!=NULL)
110 memset((*user)->private_u.plaintext_pw,'\0',strlen((*user)->private_u.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_u.lm_pw));
400 data_blob_clear_free(&(user->private_u.nt_pw));
401 if (user->private_u.plaintext_pw!=NULL)
402 memset(user->private_u.plaintext_pw,'\0',strlen(user->private_u.plaintext_pw));
404 if (user->private_u.backend_private_data && user->private_u.backend_private_data_free_fn) {
405 user->private_u.backend_private_data_free_fn(&user->private_u.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 Look up a rid in the SAM we're responsible for (i.e. passdb)
736 ********************************************************************/
738 BOOL lookup_global_sam_rid(uint32 rid, fstring name,
739 enum SID_NAME_USE *psid_name_use)
741 SAM_ACCOUNT *sam_account = NULL;
742 GROUP_MAP map;
743 BOOL ret;
744 DOM_SID sid;
746 *psid_name_use = SID_NAME_UNKNOWN;
748 DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
749 (unsigned int)rid));
751 sid_copy(&sid, get_global_sam_sid());
752 sid_append_rid(&sid, rid);
754 /* see if the passdb can help us with the name of the user */
755 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
756 return False;
759 /* BEING ROOT BLLOCK */
760 become_root();
761 if (pdb_getsampwsid(sam_account, &sid)) {
762 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
763 fstrcpy(name, pdb_get_username(sam_account));
764 *psid_name_use = SID_NAME_USER;
766 pdb_free_sam(&sam_account);
768 return True;
770 pdb_free_sam(&sam_account);
772 ret = pdb_getgrsid(&map, sid);
773 unbecome_root();
774 /* END BECOME_ROOT BLOCK */
776 if ( ret ) {
777 if (map.gid!=(gid_t)-1) {
778 DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
779 "gid %u\n", map.nt_name,
780 (unsigned int)map.gid));
781 } else {
782 DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
783 "no unix gid. Returning name.\n",
784 map.nt_name));
787 fstrcpy(name, map.nt_name);
788 *psid_name_use = map.sid_name_use;
789 return True;
792 if (rid == DOMAIN_USER_RID_ADMIN) {
793 *psid_name_use = SID_NAME_USER;
794 fstrcpy(name, "Administrator");
795 return True;
798 if (algorithmic_pdb_rid_is_user(rid)) {
799 uid_t uid;
800 struct passwd *pw = NULL;
802 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
804 uid = algorithmic_pdb_user_rid_to_uid(rid);
805 pw = sys_getpwuid( uid );
807 DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
808 (unsigned int)uid, pw ? "succeeded" : "failed" ));
810 if ( !pw )
811 fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
812 else
813 fstrcpy( name, pw->pw_name );
815 DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
816 name, (unsigned int)rid ));
818 *psid_name_use = SID_NAME_USER;
820 return ( pw != NULL );
821 } else {
822 gid_t gid;
823 struct group *gr;
825 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
827 gid = pdb_group_rid_to_gid(rid);
828 gr = getgrgid(gid);
830 DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
831 (unsigned int)gid, gr ? "succeeded" : "failed" ));
833 if( !gr )
834 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
835 else
836 fstrcpy( name, gr->gr_name);
838 DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
839 name, (unsigned int)rid ));
841 /* assume algorithmic groups are domain global groups */
843 *psid_name_use = SID_NAME_DOM_GRP;
845 return ( gr != NULL );
849 /*******************************************************************
850 Convert a name into a SID. Used in the lookup name rpc.
851 ********************************************************************/
853 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
855 DOM_SID local_sid;
856 DOM_SID sid;
857 fstring user;
858 SAM_ACCOUNT *sam_account = NULL;
859 struct group *grp;
860 GROUP_MAP map;
862 *psid_name_use = SID_NAME_UNKNOWN;
865 * user may be quoted a const string, and map_username and
866 * friends can modify it. Make a modifiable copy. JRA.
869 fstrcpy(user, c_user);
871 sid_copy(&local_sid, get_global_sam_sid());
873 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
874 fstring sid_str;
875 sid_copy( psid, &sid);
876 sid_to_string(sid_str, &sid);
877 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
878 (unsigned int)*psid_name_use ));
879 return True;
882 (void)map_username(user);
884 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
885 return False;
888 /* BEGIN ROOT BLOCK */
890 become_root();
891 if (pdb_getsampwnam(sam_account, user)) {
892 unbecome_root();
893 sid_copy(psid, pdb_get_user_sid(sam_account));
894 *psid_name_use = SID_NAME_USER;
896 pdb_free_sam(&sam_account);
897 return True;
900 pdb_free_sam(&sam_account);
903 * Maybe it was a group ?
906 /* check if it's a mapped group */
907 if (pdb_getgrnam(&map, user)) {
908 /* yes it's a mapped group */
909 sid_copy(&local_sid, &map.sid);
910 *psid_name_use = map.sid_name_use;
911 } else {
912 /* it's not a mapped group */
913 grp = getgrnam(user);
914 if(!grp) {
915 unbecome_root(); /* ---> exit form block */
916 return False;
920 *check if it's mapped, if it is reply it doesn't exist
922 * that's to prevent this case:
924 * unix group ug is mapped to nt group ng
925 * someone does a lookup on ug
926 * we must not reply as it doesn't "exist" anymore
927 * for NT. For NT only ng exists.
928 * JFM, 30/11/2001
931 if (pdb_getgrgid(&map, grp->gr_gid)){
932 unbecome_root(); /* ---> exit form block */
933 return False;
936 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
937 *psid_name_use = SID_NAME_ALIAS;
939 unbecome_root();
940 /* END ROOT BLOCK */
942 sid_copy( psid, &local_sid);
944 return True;
947 /*************************************************************
948 Change a password entry in the local smbpasswd file.
949 *************************************************************/
951 BOOL local_password_change(const char *user_name, int local_flags,
952 const char *new_passwd,
953 char *err_str, size_t err_str_len,
954 char *msg_str, size_t msg_str_len)
956 SAM_ACCOUNT *sam_pass=NULL;
957 uint16 other_acb;
959 *err_str = '\0';
960 *msg_str = '\0';
962 /* Get the smb passwd entry for this user */
963 pdb_init_sam(&sam_pass);
965 become_root();
966 if(!pdb_getsampwnam(sam_pass, user_name)) {
967 unbecome_root();
968 pdb_free_sam(&sam_pass);
970 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
971 /* Might not exist in /etc/passwd. Use rid algorithm here */
972 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
973 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);
974 return False;
976 } else {
977 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
978 return False;
980 } else {
981 unbecome_root();
982 /* the entry already existed */
983 local_flags &= ~LOCAL_ADD_USER;
986 /* the 'other' acb bits not being changed here */
987 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
988 if (local_flags & LOCAL_TRUST_ACCOUNT) {
989 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
990 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
991 pdb_free_sam(&sam_pass);
992 return False;
994 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
995 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
996 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
997 pdb_free_sam(&sam_pass);
998 return False;
1000 } else {
1001 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1002 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1003 pdb_free_sam(&sam_pass);
1004 return False;
1009 * We are root - just write the new password
1010 * and the valid last change time.
1013 if (local_flags & LOCAL_DISABLE_USER) {
1014 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1015 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1016 pdb_free_sam(&sam_pass);
1017 return False;
1019 } else if (local_flags & LOCAL_ENABLE_USER) {
1020 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1021 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1022 pdb_free_sam(&sam_pass);
1023 return False;
1027 if (local_flags & LOCAL_SET_NO_PASSWORD) {
1028 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1029 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1030 pdb_free_sam(&sam_pass);
1031 return False;
1033 } else if (local_flags & LOCAL_SET_PASSWORD) {
1035 * If we're dealing with setting a completely empty user account
1036 * ie. One with a password of 'XXXX', but not set disabled (like
1037 * an account created from scratch) then if the old password was
1038 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1039 * We remove that as we're giving this user their first password
1040 * and the decision hasn't really been made to disable them (ie.
1041 * don't create them disabled). JRA.
1043 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1044 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1045 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1046 pdb_free_sam(&sam_pass);
1047 return False;
1050 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1051 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1052 pdb_free_sam(&sam_pass);
1053 return False;
1056 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1057 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1058 pdb_free_sam(&sam_pass);
1059 return False;
1063 if (local_flags & LOCAL_ADD_USER) {
1064 if (pdb_add_sam_account(sam_pass)) {
1065 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1066 pdb_free_sam(&sam_pass);
1067 return True;
1068 } else {
1069 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1070 pdb_free_sam(&sam_pass);
1071 return False;
1073 } else if (local_flags & LOCAL_DELETE_USER) {
1074 if (!pdb_delete_sam_account(sam_pass)) {
1075 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1076 pdb_free_sam(&sam_pass);
1077 return False;
1079 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1080 } else {
1081 if(!pdb_update_sam_account(sam_pass)) {
1082 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1083 pdb_free_sam(&sam_pass);
1084 return False;
1086 if(local_flags & LOCAL_DISABLE_USER)
1087 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1088 else if (local_flags & LOCAL_ENABLE_USER)
1089 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1090 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1091 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1094 pdb_free_sam(&sam_pass);
1095 return True;
1098 /****************************************************************************
1099 Convert a uid to SID - algorithmic.
1100 ****************************************************************************/
1102 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1104 if ( !lp_enable_rid_algorithm() )
1105 return NULL;
1107 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1108 sid_copy( psid, get_global_sam_sid() );
1109 sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1110 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1111 (unsigned int)uid, sid_string_static(psid) ));
1113 return psid;
1116 /****************************************************************************
1117 Convert a uid to SID - locally.
1118 ****************************************************************************/
1120 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1122 SAM_ACCOUNT *sampw = NULL;
1123 struct passwd *unix_pw;
1124 BOOL ret;
1126 unix_pw = sys_getpwuid( uid );
1128 if ( !unix_pw ) {
1129 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1130 return algorithmic_uid_to_sid( psid, uid);
1133 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1134 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1135 return NULL;
1138 become_root();
1139 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1140 unbecome_root();
1142 if ( ret )
1143 sid_copy( psid, pdb_get_user_sid(sampw) );
1144 else {
1145 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1146 unix_pw->pw_name, (unsigned long)uid));
1148 algorithmic_uid_to_sid( psid, uid);
1151 pdb_free_sam(&sampw);
1153 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1154 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1156 return psid;
1159 /****************************************************************************
1160 Convert a SID to uid - locally.
1161 ****************************************************************************/
1163 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1165 SAM_ACCOUNT *sampw = NULL;
1166 struct passwd *unix_pw;
1167 const char *user_name;
1169 *name_type = SID_NAME_UNKNOWN;
1172 * We can only convert to a uid if this is our local
1173 * Domain SID (ie. we are the controling authority).
1175 if (!sid_check_is_in_our_domain(psid) ) {
1176 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1177 return False;
1180 /* lookup the user account */
1182 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1183 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1184 return False;
1187 become_root();
1188 if ( !pdb_getsampwsid(sampw, psid) ) {
1189 unbecome_root();
1190 pdb_free_sam(&sampw);
1191 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1192 sid_string_static(psid)));
1193 return False;
1195 unbecome_root();
1197 user_name = pdb_get_username(sampw);
1199 unix_pw = sys_getpwnam( user_name );
1201 if ( !unix_pw ) {
1202 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1203 user_name));
1204 pdb_free_sam( &sampw );
1205 return False;
1208 *puid = unix_pw->pw_uid;
1210 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1211 (unsigned int)*puid, user_name ));
1213 *name_type = SID_NAME_USER;
1214 pdb_free_sam( &sampw );
1215 return True;
1218 /****************************************************************************
1219 Convert a gid to SID - locally.
1220 ****************************************************************************/
1222 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1224 GROUP_MAP group;
1225 BOOL ret;
1227 /* we don't need to disable winbindd since the gid is stored in
1228 the GROUP_MAP object */
1230 /* done as root since ldap backend requires root to open a connection */
1232 become_root();
1233 ret = pdb_getgrgid( &group, gid );
1234 unbecome_root();
1236 if ( !ret ) {
1238 /* fallback to rid mapping if enabled */
1240 if ( lp_enable_rid_algorithm() ) {
1241 sid_copy(psid, get_global_sam_sid());
1242 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
1244 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1245 (unsigned int)gid, sid_string_static(psid)));
1247 return psid;
1249 else
1250 return NULL;
1253 sid_copy( psid, &group.sid );
1255 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1256 (unsigned int)gid, sid_string_static(psid)));
1258 return psid;
1261 /****************************************************************************
1262 Convert a SID to gid - locally.
1263 ****************************************************************************/
1265 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1267 uint32 rid;
1268 GROUP_MAP group;
1269 BOOL ret;
1271 *name_type = SID_NAME_UNKNOWN;
1273 /* This call can enumerate group mappings for foreign sids as well.
1274 So don't check for a match against our domain SID */
1276 /* we don't need to disable winbindd since the gid is stored in
1277 the GROUP_MAP object */
1279 become_root();
1280 ret = pdb_getgrsid(&group, *psid);
1281 unbecome_root();
1283 if ( !ret ) {
1285 /* Fallback to algorithmic rid mapping if enabled */
1287 if ( lp_enable_rid_algorithm() ) {
1289 if (!sid_check_is_in_our_domain(psid) ) {
1290 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1291 return False;
1294 if (!sid_peek_rid(psid, &rid)) {
1295 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1296 return False;
1299 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1301 if (algorithmic_pdb_rid_is_user(rid)) {
1302 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1303 return False;
1304 } else {
1305 *pgid = pdb_group_rid_to_gid(rid);
1306 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1307 return True;
1311 return False;
1314 *pgid = group.gid;
1315 *name_type = group.sid_name_use;
1317 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1318 (unsigned int)*pgid));
1320 return True;
1323 /**********************************************************************
1324 Marshall/unmarshall SAM_ACCOUNT structs.
1325 *********************************************************************/
1327 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1328 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1329 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1331 /**********************************************************************
1332 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1333 *********************************************************************/
1335 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1337 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1340 /**********************************************************************
1341 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1342 *********************************************************************/
1344 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1346 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1350 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1353 /* times are stored as 32bit integer
1354 take care on system with 64bit wide time_t
1355 --SSS */
1356 uint32 logon_time,
1357 logoff_time,
1358 kickoff_time,
1359 pass_last_set_time,
1360 pass_can_change_time,
1361 pass_must_change_time;
1362 char *username = NULL;
1363 char *domain = NULL;
1364 char *nt_username = NULL;
1365 char *dir_drive = NULL;
1366 char *unknown_str = NULL;
1367 char *munged_dial = NULL;
1368 char *fullname = NULL;
1369 char *homedir = NULL;
1370 char *logon_script = NULL;
1371 char *profile_path = NULL;
1372 char *acct_desc = NULL;
1373 char *workstations = NULL;
1374 uint32 username_len, domain_len, nt_username_len,
1375 dir_drive_len, unknown_str_len, munged_dial_len,
1376 fullname_len, homedir_len, logon_script_len,
1377 profile_path_len, acct_desc_len, workstations_len;
1379 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1380 uint16 acct_ctrl, logon_divs;
1381 uint16 bad_password_count, logon_count;
1382 uint8 *hours = NULL;
1383 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1384 uint32 len = 0;
1385 uint32 lm_pw_len, nt_pw_len, hourslen;
1386 BOOL ret = True;
1388 if(sampass == NULL || buf == NULL) {
1389 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1390 return False;
1393 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1395 /* unpack the buffer into variables */
1396 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1397 &logon_time, /* d */
1398 &logoff_time, /* d */
1399 &kickoff_time, /* d */
1400 &pass_last_set_time, /* d */
1401 &pass_can_change_time, /* d */
1402 &pass_must_change_time, /* d */
1403 &username_len, &username, /* B */
1404 &domain_len, &domain, /* B */
1405 &nt_username_len, &nt_username, /* B */
1406 &fullname_len, &fullname, /* B */
1407 &homedir_len, &homedir, /* B */
1408 &dir_drive_len, &dir_drive, /* B */
1409 &logon_script_len, &logon_script, /* B */
1410 &profile_path_len, &profile_path, /* B */
1411 &acct_desc_len, &acct_desc, /* B */
1412 &workstations_len, &workstations, /* B */
1413 &unknown_str_len, &unknown_str, /* B */
1414 &munged_dial_len, &munged_dial, /* B */
1415 &user_rid, /* d */
1416 &group_rid, /* d */
1417 &lm_pw_len, &lm_pw_ptr, /* B */
1418 &nt_pw_len, &nt_pw_ptr, /* B */
1419 &acct_ctrl, /* w */
1420 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1421 &logon_divs, /* w */
1422 &hours_len, /* d */
1423 &hourslen, &hours, /* B */
1424 &bad_password_count, /* w */
1425 &logon_count, /* w */
1426 &unknown_6); /* d */
1428 if (len == (uint32) -1) {
1429 ret = False;
1430 goto done;
1433 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1434 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1435 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1436 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1437 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1438 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1440 pdb_set_username(sampass, username, PDB_SET);
1441 pdb_set_domain(sampass, domain, PDB_SET);
1442 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1443 pdb_set_fullname(sampass, fullname, PDB_SET);
1445 if (homedir) {
1446 pdb_set_homedir(sampass, homedir, PDB_SET);
1448 else {
1449 pdb_set_homedir(sampass,
1450 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1451 PDB_DEFAULT);
1454 if (dir_drive)
1455 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1456 else {
1457 pdb_set_dir_drive(sampass,
1458 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1459 PDB_DEFAULT);
1462 if (logon_script)
1463 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1464 else {
1465 pdb_set_logon_script(sampass,
1466 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1467 PDB_DEFAULT);
1470 if (profile_path) {
1471 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1472 } else {
1473 pdb_set_profile_path(sampass,
1474 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1475 PDB_DEFAULT);
1478 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1479 pdb_set_workstations(sampass, workstations, PDB_SET);
1480 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1482 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1483 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1484 ret = False;
1485 goto done;
1489 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1490 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1491 ret = False;
1492 goto done;
1496 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1497 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1498 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1499 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1500 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1501 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1502 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1503 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1504 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1505 pdb_set_hours(sampass, hours, PDB_SET);
1507 done:
1509 SAFE_FREE(username);
1510 SAFE_FREE(domain);
1511 SAFE_FREE(nt_username);
1512 SAFE_FREE(fullname);
1513 SAFE_FREE(homedir);
1514 SAFE_FREE(dir_drive);
1515 SAFE_FREE(logon_script);
1516 SAFE_FREE(profile_path);
1517 SAFE_FREE(acct_desc);
1518 SAFE_FREE(workstations);
1519 SAFE_FREE(munged_dial);
1520 SAFE_FREE(unknown_str);
1521 SAFE_FREE(lm_pw_ptr);
1522 SAFE_FREE(nt_pw_ptr);
1523 SAFE_FREE(hours);
1525 return ret;
1528 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1531 /* times are stored as 32bit integer
1532 take care on system with 64bit wide time_t
1533 --SSS */
1534 uint32 logon_time,
1535 logoff_time,
1536 kickoff_time,
1537 bad_password_time,
1538 pass_last_set_time,
1539 pass_can_change_time,
1540 pass_must_change_time;
1541 char *username = NULL;
1542 char *domain = NULL;
1543 char *nt_username = NULL;
1544 char *dir_drive = NULL;
1545 char *unknown_str = NULL;
1546 char *munged_dial = NULL;
1547 char *fullname = NULL;
1548 char *homedir = NULL;
1549 char *logon_script = NULL;
1550 char *profile_path = NULL;
1551 char *acct_desc = NULL;
1552 char *workstations = NULL;
1553 uint32 username_len, domain_len, nt_username_len,
1554 dir_drive_len, unknown_str_len, munged_dial_len,
1555 fullname_len, homedir_len, logon_script_len,
1556 profile_path_len, acct_desc_len, workstations_len;
1558 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1559 uint16 acct_ctrl, logon_divs;
1560 uint16 bad_password_count, logon_count;
1561 uint8 *hours = NULL;
1562 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1563 uint32 len = 0;
1564 uint32 lm_pw_len, nt_pw_len, hourslen;
1565 BOOL ret = True;
1567 if(sampass == NULL || buf == NULL) {
1568 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1569 return False;
1572 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1574 /* unpack the buffer into variables */
1575 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1576 &logon_time, /* d */
1577 &logoff_time, /* d */
1578 &kickoff_time, /* d */
1579 /* Change from V0 is addition of bad_password_time field. */
1580 &bad_password_time, /* d */
1581 &pass_last_set_time, /* d */
1582 &pass_can_change_time, /* d */
1583 &pass_must_change_time, /* d */
1584 &username_len, &username, /* B */
1585 &domain_len, &domain, /* B */
1586 &nt_username_len, &nt_username, /* B */
1587 &fullname_len, &fullname, /* B */
1588 &homedir_len, &homedir, /* B */
1589 &dir_drive_len, &dir_drive, /* B */
1590 &logon_script_len, &logon_script, /* B */
1591 &profile_path_len, &profile_path, /* B */
1592 &acct_desc_len, &acct_desc, /* B */
1593 &workstations_len, &workstations, /* B */
1594 &unknown_str_len, &unknown_str, /* B */
1595 &munged_dial_len, &munged_dial, /* B */
1596 &user_rid, /* d */
1597 &group_rid, /* d */
1598 &lm_pw_len, &lm_pw_ptr, /* B */
1599 &nt_pw_len, &nt_pw_ptr, /* B */
1600 &acct_ctrl, /* w */
1601 &remove_me, /* d */
1602 &logon_divs, /* w */
1603 &hours_len, /* d */
1604 &hourslen, &hours, /* B */
1605 &bad_password_count, /* w */
1606 &logon_count, /* w */
1607 &unknown_6); /* d */
1609 if (len == (uint32) -1) {
1610 ret = False;
1611 goto done;
1614 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1615 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1616 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1618 /* Change from V0 is addition of bad_password_time field. */
1619 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1620 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1621 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1622 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1624 pdb_set_username(sampass, username, PDB_SET);
1625 pdb_set_domain(sampass, domain, PDB_SET);
1626 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1627 pdb_set_fullname(sampass, fullname, PDB_SET);
1629 if (homedir) {
1630 pdb_set_homedir(sampass, homedir, PDB_SET);
1632 else {
1633 pdb_set_homedir(sampass,
1634 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1635 PDB_DEFAULT);
1638 if (dir_drive)
1639 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1640 else {
1641 pdb_set_dir_drive(sampass,
1642 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1643 PDB_DEFAULT);
1646 if (logon_script)
1647 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1648 else {
1649 pdb_set_logon_script(sampass,
1650 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1651 PDB_DEFAULT);
1654 if (profile_path) {
1655 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1656 } else {
1657 pdb_set_profile_path(sampass,
1658 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1659 PDB_DEFAULT);
1662 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1663 pdb_set_workstations(sampass, workstations, PDB_SET);
1664 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1666 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1667 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1668 ret = False;
1669 goto done;
1673 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1674 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1675 ret = False;
1676 goto done;
1680 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1682 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1683 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1684 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1685 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1686 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1687 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1688 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1689 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1690 pdb_set_hours(sampass, hours, PDB_SET);
1692 done:
1694 SAFE_FREE(username);
1695 SAFE_FREE(domain);
1696 SAFE_FREE(nt_username);
1697 SAFE_FREE(fullname);
1698 SAFE_FREE(homedir);
1699 SAFE_FREE(dir_drive);
1700 SAFE_FREE(logon_script);
1701 SAFE_FREE(profile_path);
1702 SAFE_FREE(acct_desc);
1703 SAFE_FREE(workstations);
1704 SAFE_FREE(munged_dial);
1705 SAFE_FREE(unknown_str);
1706 SAFE_FREE(lm_pw_ptr);
1707 SAFE_FREE(nt_pw_ptr);
1708 SAFE_FREE(hours);
1710 return ret;
1714 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1717 /* times are stored as 32bit integer
1718 take care on system with 64bit wide time_t
1719 --SSS */
1720 uint32 logon_time,
1721 logoff_time,
1722 kickoff_time,
1723 bad_password_time,
1724 pass_last_set_time,
1725 pass_can_change_time,
1726 pass_must_change_time;
1727 char *username = NULL;
1728 char *domain = NULL;
1729 char *nt_username = NULL;
1730 char *dir_drive = NULL;
1731 char *unknown_str = NULL;
1732 char *munged_dial = NULL;
1733 char *fullname = NULL;
1734 char *homedir = NULL;
1735 char *logon_script = NULL;
1736 char *profile_path = NULL;
1737 char *acct_desc = NULL;
1738 char *workstations = NULL;
1739 uint32 username_len, domain_len, nt_username_len,
1740 dir_drive_len, unknown_str_len, munged_dial_len,
1741 fullname_len, homedir_len, logon_script_len,
1742 profile_path_len, acct_desc_len, workstations_len;
1744 uint32 user_rid, group_rid, hours_len, unknown_6;
1745 uint16 acct_ctrl, logon_divs;
1746 uint16 bad_password_count, logon_count;
1747 uint8 *hours = NULL;
1748 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1749 uint32 len = 0;
1750 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1751 uint32 pwHistLen = 0;
1752 BOOL ret = True;
1753 fstring tmpstring;
1754 BOOL expand_explicit = lp_passdb_expand_explicit();
1756 if(sampass == NULL || buf == NULL) {
1757 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1758 return False;
1761 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1763 /* unpack the buffer into variables */
1764 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1765 &logon_time, /* d */
1766 &logoff_time, /* d */
1767 &kickoff_time, /* d */
1768 &bad_password_time, /* d */
1769 &pass_last_set_time, /* d */
1770 &pass_can_change_time, /* d */
1771 &pass_must_change_time, /* d */
1772 &username_len, &username, /* B */
1773 &domain_len, &domain, /* B */
1774 &nt_username_len, &nt_username, /* B */
1775 &fullname_len, &fullname, /* B */
1776 &homedir_len, &homedir, /* B */
1777 &dir_drive_len, &dir_drive, /* B */
1778 &logon_script_len, &logon_script, /* B */
1779 &profile_path_len, &profile_path, /* B */
1780 &acct_desc_len, &acct_desc, /* B */
1781 &workstations_len, &workstations, /* B */
1782 &unknown_str_len, &unknown_str, /* B */
1783 &munged_dial_len, &munged_dial, /* B */
1784 &user_rid, /* d */
1785 &group_rid, /* d */
1786 &lm_pw_len, &lm_pw_ptr, /* B */
1787 &nt_pw_len, &nt_pw_ptr, /* B */
1788 /* Change from V1 is addition of password history field. */
1789 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1790 &acct_ctrl, /* w */
1791 /* Also "remove_me" field was removed. */
1792 &logon_divs, /* w */
1793 &hours_len, /* d */
1794 &hourslen, &hours, /* B */
1795 &bad_password_count, /* w */
1796 &logon_count, /* w */
1797 &unknown_6); /* d */
1799 if (len == (uint32) -1) {
1800 ret = False;
1801 goto done;
1804 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1805 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1806 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1807 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1808 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1809 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1810 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1812 pdb_set_username(sampass, username, PDB_SET);
1813 pdb_set_domain(sampass, domain, PDB_SET);
1814 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1815 pdb_set_fullname(sampass, fullname, PDB_SET);
1817 if (homedir) {
1818 fstrcpy( tmpstring, homedir );
1819 if (expand_explicit) {
1820 standard_sub_basic( username, tmpstring,
1821 sizeof(tmpstring) );
1823 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1825 else {
1826 pdb_set_homedir(sampass,
1827 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1828 PDB_DEFAULT);
1831 if (dir_drive)
1832 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1833 else
1834 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1836 if (logon_script) {
1837 fstrcpy( tmpstring, logon_script );
1838 if (expand_explicit) {
1839 standard_sub_basic( username, tmpstring,
1840 sizeof(tmpstring) );
1842 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1844 else {
1845 pdb_set_logon_script(sampass,
1846 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1847 PDB_DEFAULT);
1850 if (profile_path) {
1851 fstrcpy( tmpstring, profile_path );
1852 if (expand_explicit) {
1853 standard_sub_basic( username, tmpstring,
1854 sizeof(tmpstring) );
1856 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1858 else {
1859 pdb_set_profile_path(sampass,
1860 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1861 PDB_DEFAULT);
1864 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1865 pdb_set_workstations(sampass, workstations, PDB_SET);
1866 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1868 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1869 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1870 ret = False;
1871 goto done;
1875 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1876 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1877 ret = False;
1878 goto done;
1882 /* Change from V1 is addition of password history field. */
1883 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1884 if (pwHistLen) {
1885 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1886 if (!pw_hist) {
1887 ret = False;
1888 goto done;
1890 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1891 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1892 int i;
1893 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1894 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1895 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1896 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1897 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1898 PW_HISTORY_ENTRY_LEN);
1901 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1902 SAFE_FREE(pw_hist);
1903 ret = False;
1904 goto done;
1906 SAFE_FREE(pw_hist);
1907 } else {
1908 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1911 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1912 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1913 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1914 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1915 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1916 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1917 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1918 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1919 pdb_set_hours(sampass, hours, PDB_SET);
1921 done:
1923 SAFE_FREE(username);
1924 SAFE_FREE(domain);
1925 SAFE_FREE(nt_username);
1926 SAFE_FREE(fullname);
1927 SAFE_FREE(homedir);
1928 SAFE_FREE(dir_drive);
1929 SAFE_FREE(logon_script);
1930 SAFE_FREE(profile_path);
1931 SAFE_FREE(acct_desc);
1932 SAFE_FREE(workstations);
1933 SAFE_FREE(munged_dial);
1934 SAFE_FREE(unknown_str);
1935 SAFE_FREE(lm_pw_ptr);
1936 SAFE_FREE(nt_pw_ptr);
1937 SAFE_FREE(nt_pw_hist_ptr);
1938 SAFE_FREE(hours);
1940 return ret;
1943 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1945 size_t len, buflen;
1947 /* times are stored as 32bit integer
1948 take care on system with 64bit wide time_t
1949 --SSS */
1950 uint32 logon_time,
1951 logoff_time,
1952 kickoff_time,
1953 bad_password_time,
1954 pass_last_set_time,
1955 pass_can_change_time,
1956 pass_must_change_time;
1958 uint32 user_rid, group_rid;
1960 const char *username;
1961 const char *domain;
1962 const char *nt_username;
1963 const char *dir_drive;
1964 const char *unknown_str;
1965 const char *munged_dial;
1966 const char *fullname;
1967 const char *homedir;
1968 const char *logon_script;
1969 const char *profile_path;
1970 const char *acct_desc;
1971 const char *workstations;
1972 uint32 username_len, domain_len, nt_username_len,
1973 dir_drive_len, unknown_str_len, munged_dial_len,
1974 fullname_len, homedir_len, logon_script_len,
1975 profile_path_len, acct_desc_len, workstations_len;
1977 const uint8 *lm_pw;
1978 const uint8 *nt_pw;
1979 const uint8 *nt_pw_hist;
1980 uint32 lm_pw_len = 16;
1981 uint32 nt_pw_len = 16;
1982 uint32 nt_pw_hist_len;
1983 uint32 pwHistLen = 0;
1985 /* do we have a valid SAM_ACCOUNT pointer? */
1986 if (sampass == NULL) {
1987 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
1988 return -1;
1991 *buf = NULL;
1992 buflen = 0;
1994 logon_time = (uint32)pdb_get_logon_time(sampass);
1995 logoff_time = (uint32)pdb_get_logoff_time(sampass);
1996 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
1997 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
1998 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
1999 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
2000 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
2002 user_rid = pdb_get_user_rid(sampass);
2003 group_rid = pdb_get_group_rid(sampass);
2005 username = pdb_get_username(sampass);
2006 if (username) {
2007 username_len = strlen(username) +1;
2008 } else {
2009 username_len = 0;
2012 domain = pdb_get_domain(sampass);
2013 if (domain) {
2014 domain_len = strlen(domain) +1;
2015 } else {
2016 domain_len = 0;
2019 nt_username = pdb_get_nt_username(sampass);
2020 if (nt_username) {
2021 nt_username_len = strlen(nt_username) +1;
2022 } else {
2023 nt_username_len = 0;
2026 fullname = pdb_get_fullname(sampass);
2027 if (fullname) {
2028 fullname_len = strlen(fullname) +1;
2029 } else {
2030 fullname_len = 0;
2034 * Only updates fields which have been set (not defaults from smb.conf)
2037 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2038 dir_drive = pdb_get_dir_drive(sampass);
2039 } else {
2040 dir_drive = NULL;
2042 if (dir_drive) {
2043 dir_drive_len = strlen(dir_drive) +1;
2044 } else {
2045 dir_drive_len = 0;
2048 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2049 homedir = pdb_get_homedir(sampass);
2050 } else {
2051 homedir = NULL;
2053 if (homedir) {
2054 homedir_len = strlen(homedir) +1;
2055 } else {
2056 homedir_len = 0;
2059 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2060 logon_script = pdb_get_logon_script(sampass);
2061 } else {
2062 logon_script = NULL;
2064 if (logon_script) {
2065 logon_script_len = strlen(logon_script) +1;
2066 } else {
2067 logon_script_len = 0;
2070 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2071 profile_path = pdb_get_profile_path(sampass);
2072 } else {
2073 profile_path = NULL;
2075 if (profile_path) {
2076 profile_path_len = strlen(profile_path) +1;
2077 } else {
2078 profile_path_len = 0;
2081 lm_pw = pdb_get_lanman_passwd(sampass);
2082 if (!lm_pw) {
2083 lm_pw_len = 0;
2086 nt_pw = pdb_get_nt_passwd(sampass);
2087 if (!nt_pw) {
2088 nt_pw_len = 0;
2091 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
2092 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2093 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2094 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2095 } else {
2096 nt_pw_hist_len = 0;
2099 acct_desc = pdb_get_acct_desc(sampass);
2100 if (acct_desc) {
2101 acct_desc_len = strlen(acct_desc) +1;
2102 } else {
2103 acct_desc_len = 0;
2106 workstations = pdb_get_workstations(sampass);
2107 if (workstations) {
2108 workstations_len = strlen(workstations) +1;
2109 } else {
2110 workstations_len = 0;
2113 unknown_str = NULL;
2114 unknown_str_len = 0;
2116 munged_dial = pdb_get_munged_dial(sampass);
2117 if (munged_dial) {
2118 munged_dial_len = strlen(munged_dial) +1;
2119 } else {
2120 munged_dial_len = 0;
2123 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2125 /* one time to get the size needed */
2126 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2127 logon_time, /* d */
2128 logoff_time, /* d */
2129 kickoff_time, /* d */
2130 bad_password_time, /* d */
2131 pass_last_set_time, /* d */
2132 pass_can_change_time, /* d */
2133 pass_must_change_time, /* d */
2134 username_len, username, /* B */
2135 domain_len, domain, /* B */
2136 nt_username_len, nt_username, /* B */
2137 fullname_len, fullname, /* B */
2138 homedir_len, homedir, /* B */
2139 dir_drive_len, dir_drive, /* B */
2140 logon_script_len, logon_script, /* B */
2141 profile_path_len, profile_path, /* B */
2142 acct_desc_len, acct_desc, /* B */
2143 workstations_len, workstations, /* B */
2144 unknown_str_len, unknown_str, /* B */
2145 munged_dial_len, munged_dial, /* B */
2146 user_rid, /* d */
2147 group_rid, /* d */
2148 lm_pw_len, lm_pw, /* B */
2149 nt_pw_len, nt_pw, /* B */
2150 nt_pw_hist_len, nt_pw_hist, /* B */
2151 pdb_get_acct_ctrl(sampass), /* w */
2152 pdb_get_logon_divs(sampass), /* w */
2153 pdb_get_hours_len(sampass), /* d */
2154 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2155 pdb_get_bad_password_count(sampass), /* w */
2156 pdb_get_logon_count(sampass), /* w */
2157 pdb_get_unknown_6(sampass)); /* d */
2159 if (size_only) {
2160 return buflen;
2163 /* malloc the space needed */
2164 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2165 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2166 return (-1);
2169 /* now for the real call to tdb_pack() */
2170 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2171 logon_time, /* d */
2172 logoff_time, /* d */
2173 kickoff_time, /* d */
2174 bad_password_time, /* d */
2175 pass_last_set_time, /* d */
2176 pass_can_change_time, /* d */
2177 pass_must_change_time, /* d */
2178 username_len, username, /* B */
2179 domain_len, domain, /* B */
2180 nt_username_len, nt_username, /* B */
2181 fullname_len, fullname, /* B */
2182 homedir_len, homedir, /* B */
2183 dir_drive_len, dir_drive, /* B */
2184 logon_script_len, logon_script, /* B */
2185 profile_path_len, profile_path, /* B */
2186 acct_desc_len, acct_desc, /* B */
2187 workstations_len, workstations, /* B */
2188 unknown_str_len, unknown_str, /* B */
2189 munged_dial_len, munged_dial, /* B */
2190 user_rid, /* d */
2191 group_rid, /* d */
2192 lm_pw_len, lm_pw, /* B */
2193 nt_pw_len, nt_pw, /* B */
2194 nt_pw_hist_len, nt_pw_hist, /* B */
2195 pdb_get_acct_ctrl(sampass), /* w */
2196 pdb_get_logon_divs(sampass), /* w */
2197 pdb_get_hours_len(sampass), /* d */
2198 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2199 pdb_get_bad_password_count(sampass), /* w */
2200 pdb_get_logon_count(sampass), /* w */
2201 pdb_get_unknown_6(sampass)); /* d */
2203 /* check to make sure we got it correct */
2204 if (buflen != len) {
2205 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2206 (unsigned long)buflen, (unsigned long)len));
2207 /* error */
2208 SAFE_FREE (*buf);
2209 return (-1);
2212 return (buflen);
2215 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2217 BOOL result;
2218 uint8 *buf;
2219 int len;
2221 if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2222 return False;
2224 len = init_buffer_from_sam_v2(&buf, src, False);
2226 if (len == -1)
2227 return False;
2229 result = init_sam_from_buffer_v2(*dst, buf, len);
2230 (*dst)->methods = src->methods;
2232 free(buf);
2234 return result;
2237 /**********************************************************************
2238 **********************************************************************/
2240 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2242 uid_t u_low, u_high;
2243 gid_t g_low, g_high;
2245 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2246 return False;
2249 *low = (u_low < g_low) ? u_low : g_low;
2250 *high = (u_high < g_high) ? u_high : g_high;
2252 return True;
2255 /******************************************************************
2256 Get the the non-algorithmic RID range if idmap range are defined
2257 ******************************************************************/
2259 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2261 uint32 id_low, id_high;
2263 if (!lp_enable_rid_algorithm()) {
2264 *low = BASE_RID;
2265 *high = (uint32)-1;
2268 if (!get_free_ugid_range(&id_low, &id_high)) {
2269 return False;
2272 *low = algorithmic_pdb_uid_to_user_rid(id_low);
2273 if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2274 *high = (uint32)-1;
2275 } else {
2276 *high = algorithmic_pdb_uid_to_user_rid(id_high);
2279 return True;
2282 /*********************************************************************
2283 Update the bad password count checking the AP_RESET_COUNT_TIME
2284 *********************************************************************/
2286 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2288 time_t LastBadPassword;
2289 uint16 BadPasswordCount;
2290 uint32 resettime;
2292 if (!sampass) return False;
2294 BadPasswordCount = pdb_get_bad_password_count(sampass);
2295 if (!BadPasswordCount) {
2296 DEBUG(9, ("No bad password attempts.\n"));
2297 return True;
2300 if (!pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime)) {
2301 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2302 return False;
2305 /* First, check if there is a reset time to compare */
2306 if ((resettime == (uint32) -1) || (resettime == 0)) {
2307 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2308 return True;
2311 LastBadPassword = pdb_get_bad_password_time(sampass);
2312 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2313 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2314 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2315 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2316 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2317 if (updated) {
2318 *updated = True;
2322 return True;
2325 /*********************************************************************
2326 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2327 *********************************************************************/
2329 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2331 uint32 duration;
2332 time_t LastBadPassword;
2334 if (!sampass) return False;
2336 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2337 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2338 pdb_get_username(sampass)));
2339 return True;
2342 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2343 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2344 return False;
2347 /* First, check if there is a duration to compare */
2348 if ((duration == (uint32) -1) || (duration == 0)) {
2349 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2350 return True;
2353 LastBadPassword = pdb_get_bad_password_time(sampass);
2354 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2355 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2357 if (LastBadPassword == (time_t)0) {
2358 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2359 bad password time. Leaving locked out.\n",
2360 pdb_get_username(sampass) ));
2361 return True;
2364 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2365 pdb_set_acct_ctrl(sampass,
2366 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2367 PDB_CHANGED);
2368 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2369 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2370 if (updated) {
2371 *updated = True;
2375 return True;
2378 /*********************************************************************
2379 Increment the bad_password_count
2380 *********************************************************************/
2382 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2384 uint32 account_policy_lockout;
2385 BOOL autolock_updated = False, badpw_updated = False;
2387 if (!sampass)
2388 return False;
2390 /* Retrieve the account lockout policy */
2391 if (!pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2392 &account_policy_lockout)) {
2393 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2394 return False;
2397 /* If there is no policy, we don't need to continue checking */
2398 if (!account_policy_lockout) {
2399 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2400 return True;
2403 /* Check if the autolock needs to be cleared */
2404 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2405 return False;
2407 /* Check if the badpw count needs to be reset */
2408 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2409 return False;
2412 Ok, now we can assume that any resetting that needs to be
2413 done has been done, and just get on with incrementing
2414 and autolocking if necessary
2417 pdb_set_bad_password_count(sampass,
2418 pdb_get_bad_password_count(sampass)+1,
2419 PDB_CHANGED);
2420 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2423 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2424 return True;
2426 if (!pdb_set_acct_ctrl(sampass,
2427 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2428 PDB_CHANGED)) {
2429 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2430 return False;
2433 return True;