r6303: Setting up for 3.0.15pre1
[Samba.git] / source / passdb / passdb.c
blob203fa2bf21e8b46f5ffac21978ef24a83a31a22a
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));
763 /* see if the passdb can help us with the name of the user */
764 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
765 return False;
768 /* BEING ROOT BLLOCK */
769 become_root();
770 if (pdb_getsampwsid(sam_account, sid)) {
771 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
772 fstrcpy(name, pdb_get_username(sam_account));
773 *psid_name_use = SID_NAME_USER;
775 pdb_free_sam(&sam_account);
777 return True;
779 pdb_free_sam(&sam_account);
781 ret = pdb_getgrsid(&map, *sid);
782 unbecome_root();
783 /* END BECOME_ROOT BLOCK */
785 if ( ret ) {
786 if (map.gid!=(gid_t)-1) {
787 DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
788 } else {
789 DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
792 fstrcpy(name, map.nt_name);
793 *psid_name_use = map.sid_name_use;
794 return True;
797 if (rid == DOMAIN_USER_RID_ADMIN) {
798 *psid_name_use = SID_NAME_USER;
799 fstrcpy(name, "Administrator");
800 return True;
803 if (algorithmic_pdb_rid_is_user(rid)) {
804 uid_t uid;
805 struct passwd *pw = NULL;
807 DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
809 uid = algorithmic_pdb_user_rid_to_uid(rid);
810 pw = sys_getpwuid( uid );
812 DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
813 pw ? "succeeded" : "failed" ));
815 if ( !pw )
816 fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
817 else
818 fstrcpy( name, pw->pw_name );
820 DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
821 (unsigned int)rid ));
823 *psid_name_use = SID_NAME_USER;
825 return ( pw != NULL );
826 } else {
827 gid_t gid;
828 struct group *gr;
830 DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
832 gid = pdb_group_rid_to_gid(rid);
833 gr = getgrgid(gid);
835 *psid_name_use = SID_NAME_ALIAS;
837 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
838 gr ? "succeeded" : "failed" ));
840 if( !gr )
841 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
842 else
843 fstrcpy( name, gr->gr_name);
845 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
846 (unsigned int)rid ));
848 /* assume algorithmic groups are domain global groups */
850 *psid_name_use = SID_NAME_DOM_GRP;
852 return ( gr != NULL );
856 /*******************************************************************
857 Convert a name into a SID. Used in the lookup name rpc.
858 ********************************************************************/
860 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
862 DOM_SID local_sid;
863 DOM_SID sid;
864 fstring user;
865 SAM_ACCOUNT *sam_account = NULL;
866 struct group *grp;
867 GROUP_MAP map;
869 *psid_name_use = SID_NAME_UNKNOWN;
872 * user may be quoted a const string, and map_username and
873 * friends can modify it. Make a modifiable copy. JRA.
876 fstrcpy(user, c_user);
878 sid_copy(&local_sid, get_global_sam_sid());
880 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
881 fstring sid_str;
882 sid_copy( psid, &sid);
883 sid_to_string(sid_str, &sid);
884 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
885 (unsigned int)*psid_name_use ));
886 return True;
889 (void)map_username(user);
891 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
892 return False;
895 /* BEGIN ROOT BLOCK */
897 become_root();
898 if (pdb_getsampwnam(sam_account, user)) {
899 unbecome_root();
900 sid_copy(psid, pdb_get_user_sid(sam_account));
901 *psid_name_use = SID_NAME_USER;
903 pdb_free_sam(&sam_account);
904 return True;
907 pdb_free_sam(&sam_account);
910 * Maybe it was a group ?
913 /* check if it's a mapped group */
914 if (pdb_getgrnam(&map, user)) {
915 /* yes it's a mapped group */
916 sid_copy(&local_sid, &map.sid);
917 *psid_name_use = map.sid_name_use;
918 } else {
919 /* it's not a mapped group */
920 grp = getgrnam(user);
921 if(!grp) {
922 unbecome_root(); /* ---> exit form block */
923 return False;
927 *check if it's mapped, if it is reply it doesn't exist
929 * that's to prevent this case:
931 * unix group ug is mapped to nt group ng
932 * someone does a lookup on ug
933 * we must not reply as it doesn't "exist" anymore
934 * for NT. For NT only ng exists.
935 * JFM, 30/11/2001
938 if (pdb_getgrgid(&map, grp->gr_gid)){
939 unbecome_root(); /* ---> exit form block */
940 return False;
943 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
944 *psid_name_use = SID_NAME_ALIAS;
946 unbecome_root();
947 /* END ROOT BLOCK */
949 sid_copy( psid, &local_sid);
951 return True;
954 /*************************************************************
955 Change a password entry in the local smbpasswd file.
956 *************************************************************/
958 BOOL local_password_change(const char *user_name, int local_flags,
959 const char *new_passwd,
960 char *err_str, size_t err_str_len,
961 char *msg_str, size_t msg_str_len)
963 SAM_ACCOUNT *sam_pass=NULL;
964 uint16 other_acb;
966 *err_str = '\0';
967 *msg_str = '\0';
969 /* Get the smb passwd entry for this user */
970 pdb_init_sam(&sam_pass);
972 become_root();
973 if(!pdb_getsampwnam(sam_pass, user_name)) {
974 unbecome_root();
975 pdb_free_sam(&sam_pass);
977 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
978 /* Might not exist in /etc/passwd. Use rid algorithm here */
979 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
980 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);
981 return False;
983 } else {
984 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
985 return False;
987 } else {
988 unbecome_root();
989 /* the entry already existed */
990 local_flags &= ~LOCAL_ADD_USER;
993 /* the 'other' acb bits not being changed here */
994 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
995 if (local_flags & LOCAL_TRUST_ACCOUNT) {
996 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
997 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
998 pdb_free_sam(&sam_pass);
999 return False;
1001 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
1002 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
1003 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
1004 pdb_free_sam(&sam_pass);
1005 return False;
1007 } else {
1008 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1009 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1010 pdb_free_sam(&sam_pass);
1011 return False;
1016 * We are root - just write the new password
1017 * and the valid last change time.
1020 if (local_flags & LOCAL_DISABLE_USER) {
1021 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1022 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1023 pdb_free_sam(&sam_pass);
1024 return False;
1026 } else if (local_flags & LOCAL_ENABLE_USER) {
1027 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1028 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1029 pdb_free_sam(&sam_pass);
1030 return False;
1034 if (local_flags & LOCAL_SET_NO_PASSWORD) {
1035 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1036 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1037 pdb_free_sam(&sam_pass);
1038 return False;
1040 } else if (local_flags & LOCAL_SET_PASSWORD) {
1042 * If we're dealing with setting a completely empty user account
1043 * ie. One with a password of 'XXXX', but not set disabled (like
1044 * an account created from scratch) then if the old password was
1045 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1046 * We remove that as we're giving this user their first password
1047 * and the decision hasn't really been made to disable them (ie.
1048 * don't create them disabled). JRA.
1050 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1051 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1052 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1053 pdb_free_sam(&sam_pass);
1054 return False;
1057 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1058 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1059 pdb_free_sam(&sam_pass);
1060 return False;
1063 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1064 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1065 pdb_free_sam(&sam_pass);
1066 return False;
1070 if (local_flags & LOCAL_ADD_USER) {
1071 if (pdb_add_sam_account(sam_pass)) {
1072 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1073 pdb_free_sam(&sam_pass);
1074 return True;
1075 } else {
1076 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1077 pdb_free_sam(&sam_pass);
1078 return False;
1080 } else if (local_flags & LOCAL_DELETE_USER) {
1081 if (!pdb_delete_sam_account(sam_pass)) {
1082 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1083 pdb_free_sam(&sam_pass);
1084 return False;
1086 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1087 } else {
1088 if(!pdb_update_sam_account(sam_pass)) {
1089 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1090 pdb_free_sam(&sam_pass);
1091 return False;
1093 if(local_flags & LOCAL_DISABLE_USER)
1094 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1095 else if (local_flags & LOCAL_ENABLE_USER)
1096 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1097 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1098 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1101 pdb_free_sam(&sam_pass);
1102 return True;
1105 /****************************************************************************
1106 Convert a uid to SID - algorithmic.
1107 ****************************************************************************/
1109 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1111 if ( !lp_enable_rid_algorithm() )
1112 return NULL;
1114 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1115 sid_copy( psid, get_global_sam_sid() );
1116 sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1117 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1118 (unsigned int)uid, sid_string_static(psid) ));
1120 return psid;
1123 /****************************************************************************
1124 Convert a uid to SID - locally.
1125 ****************************************************************************/
1127 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1129 SAM_ACCOUNT *sampw = NULL;
1130 struct passwd *unix_pw;
1131 BOOL ret;
1133 unix_pw = sys_getpwuid( uid );
1135 if ( !unix_pw ) {
1136 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1137 return algorithmic_uid_to_sid( psid, uid);
1140 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1141 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1142 return NULL;
1145 become_root();
1146 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1147 unbecome_root();
1149 if ( ret )
1150 sid_copy( psid, pdb_get_user_sid(sampw) );
1151 else {
1152 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1153 unix_pw->pw_name, (unsigned long)uid));
1155 algorithmic_uid_to_sid( psid, uid);
1158 pdb_free_sam(&sampw);
1160 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1161 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1163 return psid;
1166 /****************************************************************************
1167 Convert a SID to uid - locally.
1168 ****************************************************************************/
1170 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1172 SAM_ACCOUNT *sampw = NULL;
1173 struct passwd *unix_pw;
1174 const char *user_name;
1176 *name_type = SID_NAME_UNKNOWN;
1179 * We can only convert to a uid if this is our local
1180 * Domain SID (ie. we are the controling authority).
1182 if (!sid_check_is_in_our_domain(psid) ) {
1183 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1184 return False;
1187 /* lookup the user account */
1189 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1190 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1191 return False;
1194 become_root();
1195 if ( !pdb_getsampwsid(sampw, psid) ) {
1196 unbecome_root();
1197 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1198 sid_string_static(psid)));
1199 return False;
1201 unbecome_root();
1203 user_name = pdb_get_username(sampw);
1205 unix_pw = sys_getpwnam( user_name );
1207 if ( !unix_pw ) {
1208 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1209 user_name));
1210 pdb_free_sam( &sampw );
1211 return False;
1214 *puid = unix_pw->pw_uid;
1216 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1217 (unsigned int)*puid, user_name ));
1219 *name_type = SID_NAME_USER;
1221 return True;
1224 /****************************************************************************
1225 Convert a gid to SID - algorithmic.
1226 ****************************************************************************/
1228 DOM_SID *algorithmic_gid_to_sid(DOM_SID *psid, uid_t gid)
1230 if ( !lp_enable_rid_algorithm() )
1231 return NULL;
1233 DEBUG(8,("algorithmic_gid_to_sid: falling back to RID algorithm\n"));
1234 sid_copy( psid, get_global_sam_sid() );
1235 sid_append_rid( psid, pdb_gid_to_group_rid(gid) );
1236 DEBUG(10,("algorithmic_gid_to_sid: gid (%d) -> SID %s.\n",
1237 (unsigned int)gid, sid_string_static(psid) ));
1239 return psid;
1242 /****************************************************************************
1243 Convert a gid to SID - locally.
1244 ****************************************************************************/
1246 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1248 GROUP_MAP group;
1249 BOOL ret;
1251 /* we don't need to disable winbindd since the gid is stored in
1252 the GROUP_MAP object */
1254 /* done as root since ldap backend requires root to open a connection */
1256 become_root();
1257 ret = pdb_getgrgid( &group, gid );
1258 unbecome_root();
1260 if ( !ret ) {
1262 /* algorithmic to rid mapping if enabled */
1264 if ( lp_enable_rid_algorithm() ) {
1266 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1267 (unsigned int)gid, sid_string_static(psid)));
1269 return algorithmic_gid_to_sid(psid, gid);
1271 else
1272 return NULL;
1275 sid_copy( psid, &group.sid );
1277 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1278 (unsigned int)gid, sid_string_static(psid)));
1280 return psid;
1283 /****************************************************************************
1284 Convert a SID to gid - locally.
1285 ****************************************************************************/
1287 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1289 uint32 rid;
1290 GROUP_MAP group;
1291 BOOL ret;
1293 *name_type = SID_NAME_UNKNOWN;
1295 /* This call can enumerate group mappings for foreign sids as well.
1296 So don't check for a match against our domain SID */
1298 /* we don't need to disable winbindd since the gid is stored in
1299 the GROUP_MAP object */
1301 become_root();
1302 ret = pdb_getgrsid(&group, *psid);
1303 unbecome_root();
1305 if ( !ret ) {
1307 /* Fallback to algorithmic rid mapping if enabled */
1309 if ( lp_enable_rid_algorithm() ) {
1311 if (!sid_check_is_in_our_domain(psid) ) {
1312 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1313 return False;
1316 if (!sid_peek_rid(psid, &rid)) {
1317 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1318 return False;
1321 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1323 if (algorithmic_pdb_rid_is_user(rid)) {
1324 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1325 return False;
1326 } else {
1327 *pgid = pdb_group_rid_to_gid(rid);
1328 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1329 return True;
1333 return False;
1336 *pgid = group.gid;
1337 *name_type = group.sid_name_use;
1339 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1340 (unsigned int)*pgid));
1342 return True;
1345 /**********************************************************************
1346 Marshall/unmarshall SAM_ACCOUNT structs.
1347 *********************************************************************/
1349 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1350 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1351 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1353 /**********************************************************************
1354 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1355 *********************************************************************/
1357 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1359 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1362 /**********************************************************************
1363 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1364 *********************************************************************/
1366 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1368 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1372 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1375 /* times are stored as 32bit integer
1376 take care on system with 64bit wide time_t
1377 --SSS */
1378 uint32 logon_time,
1379 logoff_time,
1380 kickoff_time,
1381 pass_last_set_time,
1382 pass_can_change_time,
1383 pass_must_change_time;
1384 char *username = NULL;
1385 char *domain = NULL;
1386 char *nt_username = NULL;
1387 char *dir_drive = NULL;
1388 char *unknown_str = NULL;
1389 char *munged_dial = NULL;
1390 char *fullname = NULL;
1391 char *homedir = NULL;
1392 char *logon_script = NULL;
1393 char *profile_path = NULL;
1394 char *acct_desc = NULL;
1395 char *workstations = NULL;
1396 uint32 username_len, domain_len, nt_username_len,
1397 dir_drive_len, unknown_str_len, munged_dial_len,
1398 fullname_len, homedir_len, logon_script_len,
1399 profile_path_len, acct_desc_len, workstations_len;
1401 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1402 uint16 acct_ctrl, logon_divs;
1403 uint16 bad_password_count, logon_count;
1404 uint8 *hours = NULL;
1405 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1406 uint32 len = 0;
1407 uint32 lm_pw_len, nt_pw_len, hourslen;
1408 BOOL ret = True;
1410 if(sampass == NULL || buf == NULL) {
1411 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1412 return False;
1415 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1417 /* unpack the buffer into variables */
1418 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1419 &logon_time, /* d */
1420 &logoff_time, /* d */
1421 &kickoff_time, /* d */
1422 &pass_last_set_time, /* d */
1423 &pass_can_change_time, /* d */
1424 &pass_must_change_time, /* d */
1425 &username_len, &username, /* B */
1426 &domain_len, &domain, /* B */
1427 &nt_username_len, &nt_username, /* B */
1428 &fullname_len, &fullname, /* B */
1429 &homedir_len, &homedir, /* B */
1430 &dir_drive_len, &dir_drive, /* B */
1431 &logon_script_len, &logon_script, /* B */
1432 &profile_path_len, &profile_path, /* B */
1433 &acct_desc_len, &acct_desc, /* B */
1434 &workstations_len, &workstations, /* B */
1435 &unknown_str_len, &unknown_str, /* B */
1436 &munged_dial_len, &munged_dial, /* B */
1437 &user_rid, /* d */
1438 &group_rid, /* d */
1439 &lm_pw_len, &lm_pw_ptr, /* B */
1440 &nt_pw_len, &nt_pw_ptr, /* B */
1441 &acct_ctrl, /* w */
1442 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1443 &logon_divs, /* w */
1444 &hours_len, /* d */
1445 &hourslen, &hours, /* B */
1446 &bad_password_count, /* w */
1447 &logon_count, /* w */
1448 &unknown_6); /* d */
1450 if (len == (uint32) -1) {
1451 ret = False;
1452 goto done;
1455 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1456 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1457 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1458 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1459 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1460 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1462 pdb_set_username(sampass, username, PDB_SET);
1463 pdb_set_domain(sampass, domain, PDB_SET);
1464 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1465 pdb_set_fullname(sampass, fullname, PDB_SET);
1467 if (homedir) {
1468 pdb_set_homedir(sampass, homedir, PDB_SET);
1470 else {
1471 pdb_set_homedir(sampass,
1472 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1473 PDB_DEFAULT);
1476 if (dir_drive)
1477 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1478 else {
1479 pdb_set_dir_drive(sampass,
1480 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1481 PDB_DEFAULT);
1484 if (logon_script)
1485 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1486 else {
1487 pdb_set_logon_script(sampass,
1488 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1489 PDB_DEFAULT);
1492 if (profile_path) {
1493 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1494 } else {
1495 pdb_set_profile_path(sampass,
1496 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1497 PDB_DEFAULT);
1500 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1501 pdb_set_workstations(sampass, workstations, PDB_SET);
1502 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1504 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1505 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1506 ret = False;
1507 goto done;
1511 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1512 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1513 ret = False;
1514 goto done;
1518 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1519 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1520 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1521 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1522 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1523 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1524 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1525 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1526 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1527 pdb_set_hours(sampass, hours, PDB_SET);
1529 done:
1531 SAFE_FREE(username);
1532 SAFE_FREE(domain);
1533 SAFE_FREE(nt_username);
1534 SAFE_FREE(fullname);
1535 SAFE_FREE(homedir);
1536 SAFE_FREE(dir_drive);
1537 SAFE_FREE(logon_script);
1538 SAFE_FREE(profile_path);
1539 SAFE_FREE(acct_desc);
1540 SAFE_FREE(workstations);
1541 SAFE_FREE(munged_dial);
1542 SAFE_FREE(unknown_str);
1543 SAFE_FREE(lm_pw_ptr);
1544 SAFE_FREE(nt_pw_ptr);
1545 SAFE_FREE(hours);
1547 return ret;
1550 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1553 /* times are stored as 32bit integer
1554 take care on system with 64bit wide time_t
1555 --SSS */
1556 uint32 logon_time,
1557 logoff_time,
1558 kickoff_time,
1559 bad_password_time,
1560 pass_last_set_time,
1561 pass_can_change_time,
1562 pass_must_change_time;
1563 char *username = NULL;
1564 char *domain = NULL;
1565 char *nt_username = NULL;
1566 char *dir_drive = NULL;
1567 char *unknown_str = NULL;
1568 char *munged_dial = NULL;
1569 char *fullname = NULL;
1570 char *homedir = NULL;
1571 char *logon_script = NULL;
1572 char *profile_path = NULL;
1573 char *acct_desc = NULL;
1574 char *workstations = NULL;
1575 uint32 username_len, domain_len, nt_username_len,
1576 dir_drive_len, unknown_str_len, munged_dial_len,
1577 fullname_len, homedir_len, logon_script_len,
1578 profile_path_len, acct_desc_len, workstations_len;
1580 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1581 uint16 acct_ctrl, logon_divs;
1582 uint16 bad_password_count, logon_count;
1583 uint8 *hours = NULL;
1584 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1585 uint32 len = 0;
1586 uint32 lm_pw_len, nt_pw_len, hourslen;
1587 BOOL ret = True;
1589 if(sampass == NULL || buf == NULL) {
1590 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1591 return False;
1594 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1596 /* unpack the buffer into variables */
1597 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1598 &logon_time, /* d */
1599 &logoff_time, /* d */
1600 &kickoff_time, /* d */
1601 /* Change from V0 is addition of bad_password_time field. */
1602 &bad_password_time, /* d */
1603 &pass_last_set_time, /* d */
1604 &pass_can_change_time, /* d */
1605 &pass_must_change_time, /* d */
1606 &username_len, &username, /* B */
1607 &domain_len, &domain, /* B */
1608 &nt_username_len, &nt_username, /* B */
1609 &fullname_len, &fullname, /* B */
1610 &homedir_len, &homedir, /* B */
1611 &dir_drive_len, &dir_drive, /* B */
1612 &logon_script_len, &logon_script, /* B */
1613 &profile_path_len, &profile_path, /* B */
1614 &acct_desc_len, &acct_desc, /* B */
1615 &workstations_len, &workstations, /* B */
1616 &unknown_str_len, &unknown_str, /* B */
1617 &munged_dial_len, &munged_dial, /* B */
1618 &user_rid, /* d */
1619 &group_rid, /* d */
1620 &lm_pw_len, &lm_pw_ptr, /* B */
1621 &nt_pw_len, &nt_pw_ptr, /* B */
1622 &acct_ctrl, /* w */
1623 &remove_me, /* d */
1624 &logon_divs, /* w */
1625 &hours_len, /* d */
1626 &hourslen, &hours, /* B */
1627 &bad_password_count, /* w */
1628 &logon_count, /* w */
1629 &unknown_6); /* d */
1631 if (len == (uint32) -1) {
1632 ret = False;
1633 goto done;
1636 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1637 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1638 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1640 /* Change from V0 is addition of bad_password_time field. */
1641 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1642 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1643 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1644 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1646 pdb_set_username(sampass, username, PDB_SET);
1647 pdb_set_domain(sampass, domain, PDB_SET);
1648 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1649 pdb_set_fullname(sampass, fullname, PDB_SET);
1651 if (homedir) {
1652 pdb_set_homedir(sampass, homedir, PDB_SET);
1654 else {
1655 pdb_set_homedir(sampass,
1656 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1657 PDB_DEFAULT);
1660 if (dir_drive)
1661 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1662 else {
1663 pdb_set_dir_drive(sampass,
1664 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1665 PDB_DEFAULT);
1668 if (logon_script)
1669 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1670 else {
1671 pdb_set_logon_script(sampass,
1672 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1673 PDB_DEFAULT);
1676 if (profile_path) {
1677 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1678 } else {
1679 pdb_set_profile_path(sampass,
1680 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1681 PDB_DEFAULT);
1684 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1685 pdb_set_workstations(sampass, workstations, PDB_SET);
1686 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1688 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1689 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1690 ret = False;
1691 goto done;
1695 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1696 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1697 ret = False;
1698 goto done;
1702 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1704 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1705 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1706 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1707 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1708 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1709 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1710 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1711 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1712 pdb_set_hours(sampass, hours, PDB_SET);
1714 done:
1716 SAFE_FREE(username);
1717 SAFE_FREE(domain);
1718 SAFE_FREE(nt_username);
1719 SAFE_FREE(fullname);
1720 SAFE_FREE(homedir);
1721 SAFE_FREE(dir_drive);
1722 SAFE_FREE(logon_script);
1723 SAFE_FREE(profile_path);
1724 SAFE_FREE(acct_desc);
1725 SAFE_FREE(workstations);
1726 SAFE_FREE(munged_dial);
1727 SAFE_FREE(unknown_str);
1728 SAFE_FREE(lm_pw_ptr);
1729 SAFE_FREE(nt_pw_ptr);
1730 SAFE_FREE(hours);
1732 return ret;
1736 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1739 /* times are stored as 32bit integer
1740 take care on system with 64bit wide time_t
1741 --SSS */
1742 uint32 logon_time,
1743 logoff_time,
1744 kickoff_time,
1745 bad_password_time,
1746 pass_last_set_time,
1747 pass_can_change_time,
1748 pass_must_change_time;
1749 char *username = NULL;
1750 char *domain = NULL;
1751 char *nt_username = NULL;
1752 char *dir_drive = NULL;
1753 char *unknown_str = NULL;
1754 char *munged_dial = NULL;
1755 char *fullname = NULL;
1756 char *homedir = NULL;
1757 char *logon_script = NULL;
1758 char *profile_path = NULL;
1759 char *acct_desc = NULL;
1760 char *workstations = NULL;
1761 uint32 username_len, domain_len, nt_username_len,
1762 dir_drive_len, unknown_str_len, munged_dial_len,
1763 fullname_len, homedir_len, logon_script_len,
1764 profile_path_len, acct_desc_len, workstations_len;
1766 uint32 user_rid, group_rid, hours_len, unknown_6;
1767 uint16 acct_ctrl, logon_divs;
1768 uint16 bad_password_count, logon_count;
1769 uint8 *hours = NULL;
1770 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1771 uint32 len = 0;
1772 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1773 uint32 pwHistLen = 0;
1774 BOOL ret = True;
1775 fstring tmpstring;
1777 if(sampass == NULL || buf == NULL) {
1778 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1779 return False;
1782 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1784 /* unpack the buffer into variables */
1785 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1786 &logon_time, /* d */
1787 &logoff_time, /* d */
1788 &kickoff_time, /* d */
1789 &bad_password_time, /* d */
1790 &pass_last_set_time, /* d */
1791 &pass_can_change_time, /* d */
1792 &pass_must_change_time, /* d */
1793 &username_len, &username, /* B */
1794 &domain_len, &domain, /* B */
1795 &nt_username_len, &nt_username, /* B */
1796 &fullname_len, &fullname, /* B */
1797 &homedir_len, &homedir, /* B */
1798 &dir_drive_len, &dir_drive, /* B */
1799 &logon_script_len, &logon_script, /* B */
1800 &profile_path_len, &profile_path, /* B */
1801 &acct_desc_len, &acct_desc, /* B */
1802 &workstations_len, &workstations, /* B */
1803 &unknown_str_len, &unknown_str, /* B */
1804 &munged_dial_len, &munged_dial, /* B */
1805 &user_rid, /* d */
1806 &group_rid, /* d */
1807 &lm_pw_len, &lm_pw_ptr, /* B */
1808 &nt_pw_len, &nt_pw_ptr, /* B */
1809 /* Change from V1 is addition of password history field. */
1810 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1811 &acct_ctrl, /* w */
1812 /* Also "remove_me" field was removed. */
1813 &logon_divs, /* w */
1814 &hours_len, /* d */
1815 &hourslen, &hours, /* B */
1816 &bad_password_count, /* w */
1817 &logon_count, /* w */
1818 &unknown_6); /* d */
1820 if (len == (uint32) -1) {
1821 ret = False;
1822 goto done;
1825 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1826 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1827 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1828 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1829 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1830 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1831 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1833 pdb_set_username(sampass, username, PDB_SET);
1834 pdb_set_domain(sampass, domain, PDB_SET);
1835 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1836 pdb_set_fullname(sampass, fullname, PDB_SET);
1838 if (homedir) {
1839 fstrcpy( tmpstring, homedir );
1840 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1841 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1843 else {
1844 pdb_set_homedir(sampass,
1845 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1846 PDB_DEFAULT);
1849 if (dir_drive)
1850 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1851 else
1852 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1854 if (logon_script) {
1855 fstrcpy( tmpstring, logon_script );
1856 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1857 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1859 else {
1860 pdb_set_logon_script(sampass,
1861 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1862 PDB_DEFAULT);
1865 if (profile_path) {
1866 fstrcpy( tmpstring, profile_path );
1867 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1868 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1870 else {
1871 pdb_set_profile_path(sampass,
1872 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1873 PDB_DEFAULT);
1876 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1877 pdb_set_workstations(sampass, workstations, PDB_SET);
1878 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1880 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1881 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1882 ret = False;
1883 goto done;
1887 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1888 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1889 ret = False;
1890 goto done;
1894 /* Change from V1 is addition of password history field. */
1895 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
1896 if (pwHistLen) {
1897 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1898 if (!pw_hist) {
1899 ret = False;
1900 goto done;
1902 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1903 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1904 int i;
1905 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1906 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1907 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1908 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1909 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1910 PW_HISTORY_ENTRY_LEN);
1913 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1914 SAFE_FREE(pw_hist);
1915 ret = False;
1916 goto done;
1918 SAFE_FREE(pw_hist);
1919 } else {
1920 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1923 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1924 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1925 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1926 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1927 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1928 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1929 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1930 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1931 pdb_set_hours(sampass, hours, PDB_SET);
1933 done:
1935 SAFE_FREE(username);
1936 SAFE_FREE(domain);
1937 SAFE_FREE(nt_username);
1938 SAFE_FREE(fullname);
1939 SAFE_FREE(homedir);
1940 SAFE_FREE(dir_drive);
1941 SAFE_FREE(logon_script);
1942 SAFE_FREE(profile_path);
1943 SAFE_FREE(acct_desc);
1944 SAFE_FREE(workstations);
1945 SAFE_FREE(munged_dial);
1946 SAFE_FREE(unknown_str);
1947 SAFE_FREE(lm_pw_ptr);
1948 SAFE_FREE(nt_pw_ptr);
1949 SAFE_FREE(nt_pw_hist_ptr);
1950 SAFE_FREE(hours);
1952 return ret;
1955 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1957 size_t len, buflen;
1959 /* times are stored as 32bit integer
1960 take care on system with 64bit wide time_t
1961 --SSS */
1962 uint32 logon_time,
1963 logoff_time,
1964 kickoff_time,
1965 bad_password_time,
1966 pass_last_set_time,
1967 pass_can_change_time,
1968 pass_must_change_time;
1970 uint32 user_rid, group_rid;
1972 const char *username;
1973 const char *domain;
1974 const char *nt_username;
1975 const char *dir_drive;
1976 const char *unknown_str;
1977 const char *munged_dial;
1978 const char *fullname;
1979 const char *homedir;
1980 const char *logon_script;
1981 const char *profile_path;
1982 const char *acct_desc;
1983 const char *workstations;
1984 uint32 username_len, domain_len, nt_username_len,
1985 dir_drive_len, unknown_str_len, munged_dial_len,
1986 fullname_len, homedir_len, logon_script_len,
1987 profile_path_len, acct_desc_len, workstations_len;
1989 const uint8 *lm_pw;
1990 const uint8 *nt_pw;
1991 const uint8 *nt_pw_hist;
1992 uint32 lm_pw_len = 16;
1993 uint32 nt_pw_len = 16;
1994 uint32 nt_pw_hist_len;
1995 uint32 pwHistLen = 0;
1997 /* do we have a valid SAM_ACCOUNT pointer? */
1998 if (sampass == NULL) {
1999 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
2000 return -1;
2003 *buf = NULL;
2004 buflen = 0;
2006 logon_time = (uint32)pdb_get_logon_time(sampass);
2007 logoff_time = (uint32)pdb_get_logoff_time(sampass);
2008 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
2009 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
2010 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
2011 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
2012 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
2014 user_rid = pdb_get_user_rid(sampass);
2015 group_rid = pdb_get_group_rid(sampass);
2017 username = pdb_get_username(sampass);
2018 if (username) {
2019 username_len = strlen(username) +1;
2020 } else {
2021 username_len = 0;
2024 domain = pdb_get_domain(sampass);
2025 if (domain) {
2026 domain_len = strlen(domain) +1;
2027 } else {
2028 domain_len = 0;
2031 nt_username = pdb_get_nt_username(sampass);
2032 if (nt_username) {
2033 nt_username_len = strlen(nt_username) +1;
2034 } else {
2035 nt_username_len = 0;
2038 fullname = pdb_get_fullname(sampass);
2039 if (fullname) {
2040 fullname_len = strlen(fullname) +1;
2041 } else {
2042 fullname_len = 0;
2046 * Only updates fields which have been set (not defaults from smb.conf)
2049 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2050 dir_drive = pdb_get_dir_drive(sampass);
2051 } else {
2052 dir_drive = NULL;
2054 if (dir_drive) {
2055 dir_drive_len = strlen(dir_drive) +1;
2056 } else {
2057 dir_drive_len = 0;
2060 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2061 homedir = pdb_get_homedir(sampass);
2062 } else {
2063 homedir = NULL;
2065 if (homedir) {
2066 homedir_len = strlen(homedir) +1;
2067 } else {
2068 homedir_len = 0;
2071 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2072 logon_script = pdb_get_logon_script(sampass);
2073 } else {
2074 logon_script = NULL;
2076 if (logon_script) {
2077 logon_script_len = strlen(logon_script) +1;
2078 } else {
2079 logon_script_len = 0;
2082 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2083 profile_path = pdb_get_profile_path(sampass);
2084 } else {
2085 profile_path = NULL;
2087 if (profile_path) {
2088 profile_path_len = strlen(profile_path) +1;
2089 } else {
2090 profile_path_len = 0;
2093 lm_pw = pdb_get_lanman_passwd(sampass);
2094 if (!lm_pw) {
2095 lm_pw_len = 0;
2098 nt_pw = pdb_get_nt_passwd(sampass);
2099 if (!nt_pw) {
2100 nt_pw_len = 0;
2103 account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
2104 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2105 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2106 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2107 } else {
2108 nt_pw_hist_len = 0;
2111 acct_desc = pdb_get_acct_desc(sampass);
2112 if (acct_desc) {
2113 acct_desc_len = strlen(acct_desc) +1;
2114 } else {
2115 acct_desc_len = 0;
2118 workstations = pdb_get_workstations(sampass);
2119 if (workstations) {
2120 workstations_len = strlen(workstations) +1;
2121 } else {
2122 workstations_len = 0;
2125 unknown_str = NULL;
2126 unknown_str_len = 0;
2128 munged_dial = pdb_get_munged_dial(sampass);
2129 if (munged_dial) {
2130 munged_dial_len = strlen(munged_dial) +1;
2131 } else {
2132 munged_dial_len = 0;
2135 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2137 /* one time to get the size needed */
2138 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2139 logon_time, /* d */
2140 logoff_time, /* d */
2141 kickoff_time, /* d */
2142 bad_password_time, /* d */
2143 pass_last_set_time, /* d */
2144 pass_can_change_time, /* d */
2145 pass_must_change_time, /* d */
2146 username_len, username, /* B */
2147 domain_len, domain, /* B */
2148 nt_username_len, nt_username, /* B */
2149 fullname_len, fullname, /* B */
2150 homedir_len, homedir, /* B */
2151 dir_drive_len, dir_drive, /* B */
2152 logon_script_len, logon_script, /* B */
2153 profile_path_len, profile_path, /* B */
2154 acct_desc_len, acct_desc, /* B */
2155 workstations_len, workstations, /* B */
2156 unknown_str_len, unknown_str, /* B */
2157 munged_dial_len, munged_dial, /* B */
2158 user_rid, /* d */
2159 group_rid, /* d */
2160 lm_pw_len, lm_pw, /* B */
2161 nt_pw_len, nt_pw, /* B */
2162 nt_pw_hist_len, nt_pw_hist, /* B */
2163 pdb_get_acct_ctrl(sampass), /* w */
2164 pdb_get_logon_divs(sampass), /* w */
2165 pdb_get_hours_len(sampass), /* d */
2166 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2167 pdb_get_bad_password_count(sampass), /* w */
2168 pdb_get_logon_count(sampass), /* w */
2169 pdb_get_unknown_6(sampass)); /* d */
2171 if (size_only) {
2172 return buflen;
2175 /* malloc the space needed */
2176 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2177 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2178 return (-1);
2181 /* now for the real call to tdb_pack() */
2182 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2183 logon_time, /* d */
2184 logoff_time, /* d */
2185 kickoff_time, /* d */
2186 bad_password_time, /* d */
2187 pass_last_set_time, /* d */
2188 pass_can_change_time, /* d */
2189 pass_must_change_time, /* d */
2190 username_len, username, /* B */
2191 domain_len, domain, /* B */
2192 nt_username_len, nt_username, /* B */
2193 fullname_len, fullname, /* B */
2194 homedir_len, homedir, /* B */
2195 dir_drive_len, dir_drive, /* B */
2196 logon_script_len, logon_script, /* B */
2197 profile_path_len, profile_path, /* B */
2198 acct_desc_len, acct_desc, /* B */
2199 workstations_len, workstations, /* B */
2200 unknown_str_len, unknown_str, /* B */
2201 munged_dial_len, munged_dial, /* B */
2202 user_rid, /* d */
2203 group_rid, /* d */
2204 lm_pw_len, lm_pw, /* B */
2205 nt_pw_len, nt_pw, /* B */
2206 nt_pw_hist_len, nt_pw_hist, /* B */
2207 pdb_get_acct_ctrl(sampass), /* w */
2208 pdb_get_logon_divs(sampass), /* w */
2209 pdb_get_hours_len(sampass), /* d */
2210 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2211 pdb_get_bad_password_count(sampass), /* w */
2212 pdb_get_logon_count(sampass), /* w */
2213 pdb_get_unknown_6(sampass)); /* d */
2215 /* check to make sure we got it correct */
2216 if (buflen != len) {
2217 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2218 (unsigned long)buflen, (unsigned long)len));
2219 /* error */
2220 SAFE_FREE (*buf);
2221 return (-1);
2224 return (buflen);
2227 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2229 BOOL result;
2230 uint8 *buf;
2231 int len;
2233 if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2234 return False;
2236 len = init_buffer_from_sam_v2(&buf, src, False);
2238 if (len == -1)
2239 return False;
2241 result = init_sam_from_buffer_v2(*dst, buf, len);
2242 (*dst)->methods = src->methods;
2244 free(buf);
2246 return result;
2249 /**********************************************************************
2250 **********************************************************************/
2252 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2254 uid_t u_low, u_high;
2255 gid_t g_low, g_high;
2257 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2258 return False;
2261 *low = (u_low < g_low) ? u_low : g_low;
2262 *high = (u_high < g_high) ? u_high : g_high;
2264 return True;
2267 /******************************************************************
2268 Get the the non-algorithmic RID range if idmap range are defined
2269 ******************************************************************/
2271 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2273 uint32 id_low, id_high;
2275 if (!lp_enable_rid_algorithm()) {
2276 *low = BASE_RID;
2277 *high = (uint32)-1;
2280 if (!get_free_ugid_range(&id_low, &id_high)) {
2281 return False;
2284 *low = algorithmic_pdb_uid_to_user_rid(id_low);
2285 if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2286 *high = (uint32)-1;
2287 } else {
2288 *high = algorithmic_pdb_uid_to_user_rid(id_high);
2291 return True;
2294 /*********************************************************************
2295 Update the bad password count checking the AP_RESET_COUNT_TIME
2296 *********************************************************************/
2298 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2300 time_t LastBadPassword;
2301 uint16 BadPasswordCount;
2302 uint32 resettime;
2304 if (!sampass) return False;
2306 BadPasswordCount = pdb_get_bad_password_count(sampass);
2307 if (!BadPasswordCount) {
2308 DEBUG(9, ("No bad password attempts.\n"));
2309 return True;
2312 if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
2313 DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
2314 return False;
2317 /* First, check if there is a reset time to compare */
2318 if ((resettime == (uint32) -1) || (resettime == 0)) {
2319 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2320 return True;
2323 LastBadPassword = pdb_get_bad_password_time(sampass);
2324 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2325 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2326 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2327 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2328 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2329 if (updated) {
2330 *updated = True;
2334 return True;
2337 /*********************************************************************
2338 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2339 *********************************************************************/
2341 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2343 uint32 duration;
2344 time_t LastBadPassword;
2346 if (!sampass) return False;
2348 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2349 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2350 pdb_get_username(sampass)));
2351 return True;
2354 if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2355 DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
2356 return False;
2359 /* First, check if there is a duration to compare */
2360 if ((duration == (uint32) -1) || (duration == 0)) {
2361 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2362 return True;
2365 LastBadPassword = pdb_get_bad_password_time(sampass);
2366 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2367 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2369 if (LastBadPassword == (time_t)0) {
2370 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2371 bad password time. Leaving locked out.\n",
2372 pdb_get_username(sampass) ));
2373 return True;
2376 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2377 pdb_set_acct_ctrl(sampass,
2378 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2379 PDB_CHANGED);
2380 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2381 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2382 if (updated) {
2383 *updated = True;
2387 return True;
2390 /*********************************************************************
2391 Increment the bad_password_count
2392 *********************************************************************/
2394 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2396 uint32 account_policy_lockout;
2397 BOOL autolock_updated = False, badpw_updated = False;
2399 if (!sampass)
2400 return False;
2402 /* Retrieve the account lockout policy */
2403 if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
2404 &account_policy_lockout)) {
2405 DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
2406 return False;
2409 /* If there is no policy, we don't need to continue checking */
2410 if (!account_policy_lockout) {
2411 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2412 return True;
2415 /* Check if the autolock needs to be cleared */
2416 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2417 return False;
2419 /* Check if the badpw count needs to be reset */
2420 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2421 return False;
2424 Ok, now we can assume that any resetting that needs to be
2425 done has been done, and just get on with incrementing
2426 and autolocking if necessary
2429 pdb_set_bad_password_count(sampass,
2430 pdb_get_bad_password_count(sampass)+1,
2431 PDB_CHANGED);
2432 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2435 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2436 return True;
2438 if (!pdb_set_acct_ctrl(sampass,
2439 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2440 PDB_CHANGED)) {
2441 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2442 return False;
2445 return True;