r10656: BIG merge from trunk. Features not copied over
[Samba/nascimento.git] / source3 / passdb / passdb.c
bloba7ff3a04f7e8939f755afc1ada7f19cce1601c17
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 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 DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
836 gr ? "succeeded" : "failed" ));
838 if( !gr )
839 fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
840 else
841 fstrcpy( name, gr->gr_name);
843 DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
844 (unsigned int)rid ));
846 /* assume algorithmic groups are domain global groups */
848 *psid_name_use = SID_NAME_DOM_GRP;
850 return ( gr != NULL );
854 /*******************************************************************
855 Convert a name into a SID. Used in the lookup name rpc.
856 ********************************************************************/
858 BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
860 DOM_SID local_sid;
861 DOM_SID sid;
862 fstring user;
863 SAM_ACCOUNT *sam_account = NULL;
864 struct group *grp;
865 GROUP_MAP map;
867 *psid_name_use = SID_NAME_UNKNOWN;
870 * user may be quoted a const string, and map_username and
871 * friends can modify it. Make a modifiable copy. JRA.
874 fstrcpy(user, c_user);
876 sid_copy(&local_sid, get_global_sam_sid());
878 if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
879 fstring sid_str;
880 sid_copy( psid, &sid);
881 sid_to_string(sid_str, &sid);
882 DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
883 (unsigned int)*psid_name_use ));
884 return True;
887 (void)map_username(user);
889 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
890 return False;
893 /* BEGIN ROOT BLOCK */
895 become_root();
896 if (pdb_getsampwnam(sam_account, user)) {
897 unbecome_root();
898 sid_copy(psid, pdb_get_user_sid(sam_account));
899 *psid_name_use = SID_NAME_USER;
901 pdb_free_sam(&sam_account);
902 return True;
905 pdb_free_sam(&sam_account);
908 * Maybe it was a group ?
911 /* check if it's a mapped group */
912 if (pdb_getgrnam(&map, user)) {
913 /* yes it's a mapped group */
914 sid_copy(&local_sid, &map.sid);
915 *psid_name_use = map.sid_name_use;
916 } else {
917 /* it's not a mapped group */
918 grp = getgrnam(user);
919 if(!grp) {
920 unbecome_root(); /* ---> exit form block */
921 return False;
925 *check if it's mapped, if it is reply it doesn't exist
927 * that's to prevent this case:
929 * unix group ug is mapped to nt group ng
930 * someone does a lookup on ug
931 * we must not reply as it doesn't "exist" anymore
932 * for NT. For NT only ng exists.
933 * JFM, 30/11/2001
936 if (pdb_getgrgid(&map, grp->gr_gid)){
937 unbecome_root(); /* ---> exit form block */
938 return False;
941 sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
942 *psid_name_use = SID_NAME_ALIAS;
944 unbecome_root();
945 /* END ROOT BLOCK */
947 sid_copy( psid, &local_sid);
949 return True;
952 /*************************************************************
953 Change a password entry in the local smbpasswd file.
954 *************************************************************/
956 BOOL local_password_change(const char *user_name, int local_flags,
957 const char *new_passwd,
958 char *err_str, size_t err_str_len,
959 char *msg_str, size_t msg_str_len)
961 SAM_ACCOUNT *sam_pass=NULL;
962 uint16 other_acb;
964 *err_str = '\0';
965 *msg_str = '\0';
967 /* Get the smb passwd entry for this user */
968 pdb_init_sam(&sam_pass);
970 become_root();
971 if(!pdb_getsampwnam(sam_pass, user_name)) {
972 unbecome_root();
973 pdb_free_sam(&sam_pass);
975 if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
976 /* Might not exist in /etc/passwd. Use rid algorithm here */
977 if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
978 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);
979 return False;
981 } else {
982 slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
983 return False;
985 } else {
986 unbecome_root();
987 /* the entry already existed */
988 local_flags &= ~LOCAL_ADD_USER;
991 /* the 'other' acb bits not being changed here */
992 other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
993 if (local_flags & LOCAL_TRUST_ACCOUNT) {
994 if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
995 slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
996 pdb_free_sam(&sam_pass);
997 return False;
999 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
1000 if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
1001 slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
1002 pdb_free_sam(&sam_pass);
1003 return False;
1005 } else {
1006 if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
1007 slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
1008 pdb_free_sam(&sam_pass);
1009 return False;
1014 * We are root - just write the new password
1015 * and the valid last change time.
1018 if (local_flags & LOCAL_DISABLE_USER) {
1019 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
1020 slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
1021 pdb_free_sam(&sam_pass);
1022 return False;
1024 } else if (local_flags & LOCAL_ENABLE_USER) {
1025 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1026 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1027 pdb_free_sam(&sam_pass);
1028 return False;
1032 if (local_flags & LOCAL_SET_NO_PASSWORD) {
1033 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
1034 slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
1035 pdb_free_sam(&sam_pass);
1036 return False;
1038 } else if (local_flags & LOCAL_SET_PASSWORD) {
1040 * If we're dealing with setting a completely empty user account
1041 * ie. One with a password of 'XXXX', but not set disabled (like
1042 * an account created from scratch) then if the old password was
1043 * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
1044 * We remove that as we're giving this user their first password
1045 * and the decision hasn't really been made to disable them (ie.
1046 * don't create them disabled). JRA.
1048 if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
1049 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
1050 slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
1051 pdb_free_sam(&sam_pass);
1052 return False;
1055 if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
1056 slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
1057 pdb_free_sam(&sam_pass);
1058 return False;
1061 if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
1062 slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
1063 pdb_free_sam(&sam_pass);
1064 return False;
1068 if (local_flags & LOCAL_ADD_USER) {
1069 if (pdb_add_sam_account(sam_pass)) {
1070 slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
1071 pdb_free_sam(&sam_pass);
1072 return True;
1073 } else {
1074 slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
1075 pdb_free_sam(&sam_pass);
1076 return False;
1078 } else if (local_flags & LOCAL_DELETE_USER) {
1079 if (!pdb_delete_sam_account(sam_pass)) {
1080 slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
1081 pdb_free_sam(&sam_pass);
1082 return False;
1084 slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
1085 } else {
1086 if(!pdb_update_sam_account(sam_pass)) {
1087 slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
1088 pdb_free_sam(&sam_pass);
1089 return False;
1091 if(local_flags & LOCAL_DISABLE_USER)
1092 slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
1093 else if (local_flags & LOCAL_ENABLE_USER)
1094 slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
1095 else if (local_flags & LOCAL_SET_NO_PASSWORD)
1096 slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
1099 pdb_free_sam(&sam_pass);
1100 return True;
1103 /****************************************************************************
1104 Convert a uid to SID - algorithmic.
1105 ****************************************************************************/
1107 DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
1109 if ( !lp_enable_rid_algorithm() )
1110 return NULL;
1112 DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
1113 sid_copy( psid, get_global_sam_sid() );
1114 sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
1115 DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
1116 (unsigned int)uid, sid_string_static(psid) ));
1118 return psid;
1121 /****************************************************************************
1122 Convert a uid to SID - locally.
1123 ****************************************************************************/
1125 DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
1127 SAM_ACCOUNT *sampw = NULL;
1128 struct passwd *unix_pw;
1129 BOOL ret;
1131 unix_pw = sys_getpwuid( uid );
1133 if ( !unix_pw ) {
1134 DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
1135 return algorithmic_uid_to_sid( psid, uid);
1138 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1139 DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
1140 return NULL;
1143 become_root();
1144 ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
1145 unbecome_root();
1147 if ( ret )
1148 sid_copy( psid, pdb_get_user_sid(sampw) );
1149 else {
1150 DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
1151 unix_pw->pw_name, (unsigned long)uid));
1153 algorithmic_uid_to_sid( psid, uid);
1156 pdb_free_sam(&sampw);
1158 DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
1159 (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
1161 return psid;
1164 /****************************************************************************
1165 Convert a SID to uid - locally.
1166 ****************************************************************************/
1168 BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1170 SAM_ACCOUNT *sampw = NULL;
1171 struct passwd *unix_pw;
1172 const char *user_name;
1174 *name_type = SID_NAME_UNKNOWN;
1177 * We can only convert to a uid if this is our local
1178 * Domain SID (ie. we are the controling authority).
1180 if (!sid_check_is_in_our_domain(psid) ) {
1181 DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
1182 return False;
1185 /* lookup the user account */
1187 if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
1188 DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
1189 return False;
1192 become_root();
1193 if ( !pdb_getsampwsid(sampw, psid) ) {
1194 unbecome_root();
1195 pdb_free_sam(&sampw);
1196 DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
1197 sid_string_static(psid)));
1198 return False;
1200 unbecome_root();
1202 user_name = pdb_get_username(sampw);
1204 unix_pw = sys_getpwnam( user_name );
1206 if ( !unix_pw ) {
1207 DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
1208 user_name));
1209 pdb_free_sam( &sampw );
1210 return False;
1213 *puid = unix_pw->pw_uid;
1215 DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
1216 (unsigned int)*puid, user_name ));
1218 *name_type = SID_NAME_USER;
1219 pdb_free_sam( &sampw );
1220 return True;
1223 /****************************************************************************
1224 Convert a gid to SID - locally.
1225 ****************************************************************************/
1227 DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
1229 GROUP_MAP group;
1230 BOOL ret;
1232 /* we don't need to disable winbindd since the gid is stored in
1233 the GROUP_MAP object */
1235 /* done as root since ldap backend requires root to open a connection */
1237 become_root();
1238 ret = pdb_getgrgid( &group, gid );
1239 unbecome_root();
1241 if ( !ret ) {
1243 /* fallback to rid mapping if enabled */
1245 if ( lp_enable_rid_algorithm() ) {
1246 sid_copy(psid, get_global_sam_sid());
1247 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
1249 DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
1250 (unsigned int)gid, sid_string_static(psid)));
1252 return psid;
1254 else
1255 return NULL;
1258 sid_copy( psid, &group.sid );
1260 DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
1261 (unsigned int)gid, sid_string_static(psid)));
1263 return psid;
1266 /****************************************************************************
1267 Convert a SID to gid - locally.
1268 ****************************************************************************/
1270 BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
1272 uint32 rid;
1273 GROUP_MAP group;
1274 BOOL ret;
1276 *name_type = SID_NAME_UNKNOWN;
1278 /* This call can enumerate group mappings for foreign sids as well.
1279 So don't check for a match against our domain SID */
1281 /* we don't need to disable winbindd since the gid is stored in
1282 the GROUP_MAP object */
1284 become_root();
1285 ret = pdb_getgrsid(&group, *psid);
1286 unbecome_root();
1288 if ( !ret ) {
1290 /* Fallback to algorithmic rid mapping if enabled */
1292 if ( lp_enable_rid_algorithm() ) {
1294 if (!sid_check_is_in_our_domain(psid) ) {
1295 DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
1296 return False;
1299 if (!sid_peek_rid(psid, &rid)) {
1300 DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
1301 return False;
1304 DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
1306 if (algorithmic_pdb_rid_is_user(rid)) {
1307 DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
1308 return False;
1309 } else {
1310 *pgid = pdb_group_rid_to_gid(rid);
1311 DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
1312 return True;
1316 return False;
1319 *pgid = group.gid;
1320 *name_type = group.sid_name_use;
1322 DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
1323 (unsigned int)*pgid));
1325 return True;
1328 /**********************************************************************
1329 Marshall/unmarshall SAM_ACCOUNT structs.
1330 *********************************************************************/
1332 #define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
1333 #define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
1334 #define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
1336 /**********************************************************************
1337 Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
1338 *********************************************************************/
1340 BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1342 return(init_sam_from_buffer_v2(sampass, buf, buflen));
1345 /**********************************************************************
1346 Intialize a BYTE buffer from a SAM_ACCOUNT struct
1347 *********************************************************************/
1349 uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1351 return(init_buffer_from_sam_v2(buf, sampass, size_only));
1355 BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1358 /* times are stored as 32bit integer
1359 take care on system with 64bit wide time_t
1360 --SSS */
1361 uint32 logon_time,
1362 logoff_time,
1363 kickoff_time,
1364 pass_last_set_time,
1365 pass_can_change_time,
1366 pass_must_change_time;
1367 char *username = NULL;
1368 char *domain = NULL;
1369 char *nt_username = NULL;
1370 char *dir_drive = NULL;
1371 char *unknown_str = NULL;
1372 char *munged_dial = NULL;
1373 char *fullname = NULL;
1374 char *homedir = NULL;
1375 char *logon_script = NULL;
1376 char *profile_path = NULL;
1377 char *acct_desc = NULL;
1378 char *workstations = NULL;
1379 uint32 username_len, domain_len, nt_username_len,
1380 dir_drive_len, unknown_str_len, munged_dial_len,
1381 fullname_len, homedir_len, logon_script_len,
1382 profile_path_len, acct_desc_len, workstations_len;
1384 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1385 uint16 acct_ctrl, logon_divs;
1386 uint16 bad_password_count, logon_count;
1387 uint8 *hours = NULL;
1388 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1389 uint32 len = 0;
1390 uint32 lm_pw_len, nt_pw_len, hourslen;
1391 BOOL ret = True;
1393 if(sampass == NULL || buf == NULL) {
1394 DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
1395 return False;
1398 /* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1400 /* unpack the buffer into variables */
1401 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
1402 &logon_time, /* d */
1403 &logoff_time, /* d */
1404 &kickoff_time, /* d */
1405 &pass_last_set_time, /* d */
1406 &pass_can_change_time, /* d */
1407 &pass_must_change_time, /* d */
1408 &username_len, &username, /* B */
1409 &domain_len, &domain, /* B */
1410 &nt_username_len, &nt_username, /* B */
1411 &fullname_len, &fullname, /* B */
1412 &homedir_len, &homedir, /* B */
1413 &dir_drive_len, &dir_drive, /* B */
1414 &logon_script_len, &logon_script, /* B */
1415 &profile_path_len, &profile_path, /* B */
1416 &acct_desc_len, &acct_desc, /* B */
1417 &workstations_len, &workstations, /* B */
1418 &unknown_str_len, &unknown_str, /* B */
1419 &munged_dial_len, &munged_dial, /* B */
1420 &user_rid, /* d */
1421 &group_rid, /* d */
1422 &lm_pw_len, &lm_pw_ptr, /* B */
1423 &nt_pw_len, &nt_pw_ptr, /* B */
1424 &acct_ctrl, /* w */
1425 &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
1426 &logon_divs, /* w */
1427 &hours_len, /* d */
1428 &hourslen, &hours, /* B */
1429 &bad_password_count, /* w */
1430 &logon_count, /* w */
1431 &unknown_6); /* d */
1433 if (len == (uint32) -1) {
1434 ret = False;
1435 goto done;
1438 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1439 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1440 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1441 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1442 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1443 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1445 pdb_set_username(sampass, username, PDB_SET);
1446 pdb_set_domain(sampass, domain, PDB_SET);
1447 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1448 pdb_set_fullname(sampass, fullname, PDB_SET);
1450 if (homedir) {
1451 pdb_set_homedir(sampass, homedir, PDB_SET);
1453 else {
1454 pdb_set_homedir(sampass,
1455 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1456 PDB_DEFAULT);
1459 if (dir_drive)
1460 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1461 else {
1462 pdb_set_dir_drive(sampass,
1463 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1464 PDB_DEFAULT);
1467 if (logon_script)
1468 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1469 else {
1470 pdb_set_logon_script(sampass,
1471 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1472 PDB_DEFAULT);
1475 if (profile_path) {
1476 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1477 } else {
1478 pdb_set_profile_path(sampass,
1479 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1480 PDB_DEFAULT);
1483 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1484 pdb_set_workstations(sampass, workstations, PDB_SET);
1485 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1487 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1488 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1489 ret = False;
1490 goto done;
1494 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1495 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1496 ret = False;
1497 goto done;
1501 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1502 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1503 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1504 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1505 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1506 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1507 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1508 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1509 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1510 pdb_set_hours(sampass, hours, PDB_SET);
1512 done:
1514 SAFE_FREE(username);
1515 SAFE_FREE(domain);
1516 SAFE_FREE(nt_username);
1517 SAFE_FREE(fullname);
1518 SAFE_FREE(homedir);
1519 SAFE_FREE(dir_drive);
1520 SAFE_FREE(logon_script);
1521 SAFE_FREE(profile_path);
1522 SAFE_FREE(acct_desc);
1523 SAFE_FREE(workstations);
1524 SAFE_FREE(munged_dial);
1525 SAFE_FREE(unknown_str);
1526 SAFE_FREE(lm_pw_ptr);
1527 SAFE_FREE(nt_pw_ptr);
1528 SAFE_FREE(hours);
1530 return ret;
1533 BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1536 /* times are stored as 32bit integer
1537 take care on system with 64bit wide time_t
1538 --SSS */
1539 uint32 logon_time,
1540 logoff_time,
1541 kickoff_time,
1542 bad_password_time,
1543 pass_last_set_time,
1544 pass_can_change_time,
1545 pass_must_change_time;
1546 char *username = NULL;
1547 char *domain = NULL;
1548 char *nt_username = NULL;
1549 char *dir_drive = NULL;
1550 char *unknown_str = NULL;
1551 char *munged_dial = NULL;
1552 char *fullname = NULL;
1553 char *homedir = NULL;
1554 char *logon_script = NULL;
1555 char *profile_path = NULL;
1556 char *acct_desc = NULL;
1557 char *workstations = NULL;
1558 uint32 username_len, domain_len, nt_username_len,
1559 dir_drive_len, unknown_str_len, munged_dial_len,
1560 fullname_len, homedir_len, logon_script_len,
1561 profile_path_len, acct_desc_len, workstations_len;
1563 uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
1564 uint16 acct_ctrl, logon_divs;
1565 uint16 bad_password_count, logon_count;
1566 uint8 *hours = NULL;
1567 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1568 uint32 len = 0;
1569 uint32 lm_pw_len, nt_pw_len, hourslen;
1570 BOOL ret = True;
1572 if(sampass == NULL || buf == NULL) {
1573 DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
1574 return False;
1577 /* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1579 /* unpack the buffer into variables */
1580 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
1581 &logon_time, /* d */
1582 &logoff_time, /* d */
1583 &kickoff_time, /* d */
1584 /* Change from V0 is addition of bad_password_time field. */
1585 &bad_password_time, /* d */
1586 &pass_last_set_time, /* d */
1587 &pass_can_change_time, /* d */
1588 &pass_must_change_time, /* d */
1589 &username_len, &username, /* B */
1590 &domain_len, &domain, /* B */
1591 &nt_username_len, &nt_username, /* B */
1592 &fullname_len, &fullname, /* B */
1593 &homedir_len, &homedir, /* B */
1594 &dir_drive_len, &dir_drive, /* B */
1595 &logon_script_len, &logon_script, /* B */
1596 &profile_path_len, &profile_path, /* B */
1597 &acct_desc_len, &acct_desc, /* B */
1598 &workstations_len, &workstations, /* B */
1599 &unknown_str_len, &unknown_str, /* B */
1600 &munged_dial_len, &munged_dial, /* B */
1601 &user_rid, /* d */
1602 &group_rid, /* d */
1603 &lm_pw_len, &lm_pw_ptr, /* B */
1604 &nt_pw_len, &nt_pw_ptr, /* B */
1605 &acct_ctrl, /* w */
1606 &remove_me, /* d */
1607 &logon_divs, /* w */
1608 &hours_len, /* d */
1609 &hourslen, &hours, /* B */
1610 &bad_password_count, /* w */
1611 &logon_count, /* w */
1612 &unknown_6); /* d */
1614 if (len == (uint32) -1) {
1615 ret = False;
1616 goto done;
1619 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1620 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1621 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1623 /* Change from V0 is addition of bad_password_time field. */
1624 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1625 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1626 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1627 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1629 pdb_set_username(sampass, username, PDB_SET);
1630 pdb_set_domain(sampass, domain, PDB_SET);
1631 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1632 pdb_set_fullname(sampass, fullname, PDB_SET);
1634 if (homedir) {
1635 pdb_set_homedir(sampass, homedir, PDB_SET);
1637 else {
1638 pdb_set_homedir(sampass,
1639 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1640 PDB_DEFAULT);
1643 if (dir_drive)
1644 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1645 else {
1646 pdb_set_dir_drive(sampass,
1647 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
1648 PDB_DEFAULT);
1651 if (logon_script)
1652 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1653 else {
1654 pdb_set_logon_script(sampass,
1655 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1656 PDB_DEFAULT);
1659 if (profile_path) {
1660 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1661 } else {
1662 pdb_set_profile_path(sampass,
1663 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1664 PDB_DEFAULT);
1667 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1668 pdb_set_workstations(sampass, workstations, PDB_SET);
1669 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1671 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1672 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1673 ret = False;
1674 goto done;
1678 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1679 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1680 ret = False;
1681 goto done;
1685 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1687 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1688 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1689 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1690 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1691 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1692 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1693 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1694 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1695 pdb_set_hours(sampass, hours, PDB_SET);
1697 done:
1699 SAFE_FREE(username);
1700 SAFE_FREE(domain);
1701 SAFE_FREE(nt_username);
1702 SAFE_FREE(fullname);
1703 SAFE_FREE(homedir);
1704 SAFE_FREE(dir_drive);
1705 SAFE_FREE(logon_script);
1706 SAFE_FREE(profile_path);
1707 SAFE_FREE(acct_desc);
1708 SAFE_FREE(workstations);
1709 SAFE_FREE(munged_dial);
1710 SAFE_FREE(unknown_str);
1711 SAFE_FREE(lm_pw_ptr);
1712 SAFE_FREE(nt_pw_ptr);
1713 SAFE_FREE(hours);
1715 return ret;
1719 BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
1722 /* times are stored as 32bit integer
1723 take care on system with 64bit wide time_t
1724 --SSS */
1725 uint32 logon_time,
1726 logoff_time,
1727 kickoff_time,
1728 bad_password_time,
1729 pass_last_set_time,
1730 pass_can_change_time,
1731 pass_must_change_time;
1732 char *username = NULL;
1733 char *domain = NULL;
1734 char *nt_username = NULL;
1735 char *dir_drive = NULL;
1736 char *unknown_str = NULL;
1737 char *munged_dial = NULL;
1738 char *fullname = NULL;
1739 char *homedir = NULL;
1740 char *logon_script = NULL;
1741 char *profile_path = NULL;
1742 char *acct_desc = NULL;
1743 char *workstations = NULL;
1744 uint32 username_len, domain_len, nt_username_len,
1745 dir_drive_len, unknown_str_len, munged_dial_len,
1746 fullname_len, homedir_len, logon_script_len,
1747 profile_path_len, acct_desc_len, workstations_len;
1749 uint32 user_rid, group_rid, hours_len, unknown_6;
1750 uint16 acct_ctrl, logon_divs;
1751 uint16 bad_password_count, logon_count;
1752 uint8 *hours = NULL;
1753 uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1754 uint32 len = 0;
1755 uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1756 uint32 pwHistLen = 0;
1757 BOOL ret = True;
1758 fstring tmpstring;
1760 if(sampass == NULL || buf == NULL) {
1761 DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
1762 return False;
1765 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1767 /* unpack the buffer into variables */
1768 len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
1769 &logon_time, /* d */
1770 &logoff_time, /* d */
1771 &kickoff_time, /* d */
1772 &bad_password_time, /* d */
1773 &pass_last_set_time, /* d */
1774 &pass_can_change_time, /* d */
1775 &pass_must_change_time, /* d */
1776 &username_len, &username, /* B */
1777 &domain_len, &domain, /* B */
1778 &nt_username_len, &nt_username, /* B */
1779 &fullname_len, &fullname, /* B */
1780 &homedir_len, &homedir, /* B */
1781 &dir_drive_len, &dir_drive, /* B */
1782 &logon_script_len, &logon_script, /* B */
1783 &profile_path_len, &profile_path, /* B */
1784 &acct_desc_len, &acct_desc, /* B */
1785 &workstations_len, &workstations, /* B */
1786 &unknown_str_len, &unknown_str, /* B */
1787 &munged_dial_len, &munged_dial, /* B */
1788 &user_rid, /* d */
1789 &group_rid, /* d */
1790 &lm_pw_len, &lm_pw_ptr, /* B */
1791 &nt_pw_len, &nt_pw_ptr, /* B */
1792 /* Change from V1 is addition of password history field. */
1793 &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
1794 &acct_ctrl, /* w */
1795 /* Also "remove_me" field was removed. */
1796 &logon_divs, /* w */
1797 &hours_len, /* d */
1798 &hourslen, &hours, /* B */
1799 &bad_password_count, /* w */
1800 &logon_count, /* w */
1801 &unknown_6); /* d */
1803 if (len == (uint32) -1) {
1804 ret = False;
1805 goto done;
1808 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1809 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1810 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1811 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1812 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1813 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1814 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1816 pdb_set_username(sampass, username, PDB_SET);
1817 pdb_set_domain(sampass, domain, PDB_SET);
1818 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1819 pdb_set_fullname(sampass, fullname, PDB_SET);
1821 if (homedir) {
1822 fstrcpy( tmpstring, homedir );
1823 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1824 pdb_set_homedir(sampass, tmpstring, PDB_SET);
1826 else {
1827 pdb_set_homedir(sampass,
1828 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
1829 PDB_DEFAULT);
1832 if (dir_drive)
1833 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1834 else
1835 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1837 if (logon_script) {
1838 fstrcpy( tmpstring, logon_script );
1839 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1840 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
1842 else {
1843 pdb_set_logon_script(sampass,
1844 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
1845 PDB_DEFAULT);
1848 if (profile_path) {
1849 fstrcpy( tmpstring, profile_path );
1850 standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
1851 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
1853 else {
1854 pdb_set_profile_path(sampass,
1855 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
1856 PDB_DEFAULT);
1859 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1860 pdb_set_workstations(sampass, workstations, PDB_SET);
1861 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1863 if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1864 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1865 ret = False;
1866 goto done;
1870 if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1871 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1872 ret = False;
1873 goto done;
1877 /* Change from V1 is addition of password history field. */
1878 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1879 if (pwHistLen) {
1880 uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1881 if (!pw_hist) {
1882 ret = False;
1883 goto done;
1885 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1886 if (nt_pw_hist_ptr && nt_pw_hist_len) {
1887 int i;
1888 SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1889 nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1890 for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1891 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1892 &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1893 PW_HISTORY_ENTRY_LEN);
1896 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1897 SAFE_FREE(pw_hist);
1898 ret = False;
1899 goto done;
1901 SAFE_FREE(pw_hist);
1902 } else {
1903 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1906 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1907 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1908 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1909 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1910 pdb_set_logon_count(sampass, logon_count, PDB_SET);
1911 pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1912 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1913 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1914 pdb_set_hours(sampass, hours, PDB_SET);
1916 done:
1918 SAFE_FREE(username);
1919 SAFE_FREE(domain);
1920 SAFE_FREE(nt_username);
1921 SAFE_FREE(fullname);
1922 SAFE_FREE(homedir);
1923 SAFE_FREE(dir_drive);
1924 SAFE_FREE(logon_script);
1925 SAFE_FREE(profile_path);
1926 SAFE_FREE(acct_desc);
1927 SAFE_FREE(workstations);
1928 SAFE_FREE(munged_dial);
1929 SAFE_FREE(unknown_str);
1930 SAFE_FREE(lm_pw_ptr);
1931 SAFE_FREE(nt_pw_ptr);
1932 SAFE_FREE(nt_pw_hist_ptr);
1933 SAFE_FREE(hours);
1935 return ret;
1938 uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
1940 size_t len, buflen;
1942 /* times are stored as 32bit integer
1943 take care on system with 64bit wide time_t
1944 --SSS */
1945 uint32 logon_time,
1946 logoff_time,
1947 kickoff_time,
1948 bad_password_time,
1949 pass_last_set_time,
1950 pass_can_change_time,
1951 pass_must_change_time;
1953 uint32 user_rid, group_rid;
1955 const char *username;
1956 const char *domain;
1957 const char *nt_username;
1958 const char *dir_drive;
1959 const char *unknown_str;
1960 const char *munged_dial;
1961 const char *fullname;
1962 const char *homedir;
1963 const char *logon_script;
1964 const char *profile_path;
1965 const char *acct_desc;
1966 const char *workstations;
1967 uint32 username_len, domain_len, nt_username_len,
1968 dir_drive_len, unknown_str_len, munged_dial_len,
1969 fullname_len, homedir_len, logon_script_len,
1970 profile_path_len, acct_desc_len, workstations_len;
1972 const uint8 *lm_pw;
1973 const uint8 *nt_pw;
1974 const uint8 *nt_pw_hist;
1975 uint32 lm_pw_len = 16;
1976 uint32 nt_pw_len = 16;
1977 uint32 nt_pw_hist_len;
1978 uint32 pwHistLen = 0;
1980 /* do we have a valid SAM_ACCOUNT pointer? */
1981 if (sampass == NULL) {
1982 DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
1983 return -1;
1986 *buf = NULL;
1987 buflen = 0;
1989 logon_time = (uint32)pdb_get_logon_time(sampass);
1990 logoff_time = (uint32)pdb_get_logoff_time(sampass);
1991 kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
1992 bad_password_time = (uint32)pdb_get_bad_password_time(sampass);
1993 pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
1994 pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
1995 pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
1997 user_rid = pdb_get_user_rid(sampass);
1998 group_rid = pdb_get_group_rid(sampass);
2000 username = pdb_get_username(sampass);
2001 if (username) {
2002 username_len = strlen(username) +1;
2003 } else {
2004 username_len = 0;
2007 domain = pdb_get_domain(sampass);
2008 if (domain) {
2009 domain_len = strlen(domain) +1;
2010 } else {
2011 domain_len = 0;
2014 nt_username = pdb_get_nt_username(sampass);
2015 if (nt_username) {
2016 nt_username_len = strlen(nt_username) +1;
2017 } else {
2018 nt_username_len = 0;
2021 fullname = pdb_get_fullname(sampass);
2022 if (fullname) {
2023 fullname_len = strlen(fullname) +1;
2024 } else {
2025 fullname_len = 0;
2029 * Only updates fields which have been set (not defaults from smb.conf)
2032 if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
2033 dir_drive = pdb_get_dir_drive(sampass);
2034 } else {
2035 dir_drive = NULL;
2037 if (dir_drive) {
2038 dir_drive_len = strlen(dir_drive) +1;
2039 } else {
2040 dir_drive_len = 0;
2043 if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
2044 homedir = pdb_get_homedir(sampass);
2045 } else {
2046 homedir = NULL;
2048 if (homedir) {
2049 homedir_len = strlen(homedir) +1;
2050 } else {
2051 homedir_len = 0;
2054 if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
2055 logon_script = pdb_get_logon_script(sampass);
2056 } else {
2057 logon_script = NULL;
2059 if (logon_script) {
2060 logon_script_len = strlen(logon_script) +1;
2061 } else {
2062 logon_script_len = 0;
2065 if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
2066 profile_path = pdb_get_profile_path(sampass);
2067 } else {
2068 profile_path = NULL;
2070 if (profile_path) {
2071 profile_path_len = strlen(profile_path) +1;
2072 } else {
2073 profile_path_len = 0;
2076 lm_pw = pdb_get_lanman_passwd(sampass);
2077 if (!lm_pw) {
2078 lm_pw_len = 0;
2081 nt_pw = pdb_get_nt_passwd(sampass);
2082 if (!nt_pw) {
2083 nt_pw_len = 0;
2086 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
2087 nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
2088 if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
2089 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
2090 } else {
2091 nt_pw_hist_len = 0;
2094 acct_desc = pdb_get_acct_desc(sampass);
2095 if (acct_desc) {
2096 acct_desc_len = strlen(acct_desc) +1;
2097 } else {
2098 acct_desc_len = 0;
2101 workstations = pdb_get_workstations(sampass);
2102 if (workstations) {
2103 workstations_len = strlen(workstations) +1;
2104 } else {
2105 workstations_len = 0;
2108 unknown_str = NULL;
2109 unknown_str_len = 0;
2111 munged_dial = pdb_get_munged_dial(sampass);
2112 if (munged_dial) {
2113 munged_dial_len = strlen(munged_dial) +1;
2114 } else {
2115 munged_dial_len = 0;
2118 /* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
2120 /* one time to get the size needed */
2121 len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
2122 logon_time, /* d */
2123 logoff_time, /* d */
2124 kickoff_time, /* d */
2125 bad_password_time, /* d */
2126 pass_last_set_time, /* d */
2127 pass_can_change_time, /* d */
2128 pass_must_change_time, /* d */
2129 username_len, username, /* B */
2130 domain_len, domain, /* B */
2131 nt_username_len, nt_username, /* B */
2132 fullname_len, fullname, /* B */
2133 homedir_len, homedir, /* B */
2134 dir_drive_len, dir_drive, /* B */
2135 logon_script_len, logon_script, /* B */
2136 profile_path_len, profile_path, /* B */
2137 acct_desc_len, acct_desc, /* B */
2138 workstations_len, workstations, /* B */
2139 unknown_str_len, unknown_str, /* B */
2140 munged_dial_len, munged_dial, /* B */
2141 user_rid, /* d */
2142 group_rid, /* d */
2143 lm_pw_len, lm_pw, /* B */
2144 nt_pw_len, nt_pw, /* B */
2145 nt_pw_hist_len, nt_pw_hist, /* B */
2146 pdb_get_acct_ctrl(sampass), /* w */
2147 pdb_get_logon_divs(sampass), /* w */
2148 pdb_get_hours_len(sampass), /* d */
2149 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2150 pdb_get_bad_password_count(sampass), /* w */
2151 pdb_get_logon_count(sampass), /* w */
2152 pdb_get_unknown_6(sampass)); /* d */
2154 if (size_only) {
2155 return buflen;
2158 /* malloc the space needed */
2159 if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
2160 DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
2161 return (-1);
2164 /* now for the real call to tdb_pack() */
2165 buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
2166 logon_time, /* d */
2167 logoff_time, /* d */
2168 kickoff_time, /* d */
2169 bad_password_time, /* d */
2170 pass_last_set_time, /* d */
2171 pass_can_change_time, /* d */
2172 pass_must_change_time, /* d */
2173 username_len, username, /* B */
2174 domain_len, domain, /* B */
2175 nt_username_len, nt_username, /* B */
2176 fullname_len, fullname, /* B */
2177 homedir_len, homedir, /* B */
2178 dir_drive_len, dir_drive, /* B */
2179 logon_script_len, logon_script, /* B */
2180 profile_path_len, profile_path, /* B */
2181 acct_desc_len, acct_desc, /* B */
2182 workstations_len, workstations, /* B */
2183 unknown_str_len, unknown_str, /* B */
2184 munged_dial_len, munged_dial, /* B */
2185 user_rid, /* d */
2186 group_rid, /* d */
2187 lm_pw_len, lm_pw, /* B */
2188 nt_pw_len, nt_pw, /* B */
2189 nt_pw_hist_len, nt_pw_hist, /* B */
2190 pdb_get_acct_ctrl(sampass), /* w */
2191 pdb_get_logon_divs(sampass), /* w */
2192 pdb_get_hours_len(sampass), /* d */
2193 MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2194 pdb_get_bad_password_count(sampass), /* w */
2195 pdb_get_logon_count(sampass), /* w */
2196 pdb_get_unknown_6(sampass)); /* d */
2198 /* check to make sure we got it correct */
2199 if (buflen != len) {
2200 DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2201 (unsigned long)buflen, (unsigned long)len));
2202 /* error */
2203 SAFE_FREE (*buf);
2204 return (-1);
2207 return (buflen);
2210 BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
2212 BOOL result;
2213 uint8 *buf;
2214 int len;
2216 if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
2217 return False;
2219 len = init_buffer_from_sam_v2(&buf, src, False);
2221 if (len == -1)
2222 return False;
2224 result = init_sam_from_buffer_v2(*dst, buf, len);
2225 (*dst)->methods = src->methods;
2227 free(buf);
2229 return result;
2232 /**********************************************************************
2233 **********************************************************************/
2235 static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
2237 uid_t u_low, u_high;
2238 gid_t g_low, g_high;
2240 if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
2241 return False;
2244 *low = (u_low < g_low) ? u_low : g_low;
2245 *high = (u_high < g_high) ? u_high : g_high;
2247 return True;
2250 /******************************************************************
2251 Get the the non-algorithmic RID range if idmap range are defined
2252 ******************************************************************/
2254 BOOL get_free_rid_range(uint32 *low, uint32 *high)
2256 uint32 id_low, id_high;
2258 if (!lp_enable_rid_algorithm()) {
2259 *low = BASE_RID;
2260 *high = (uint32)-1;
2263 if (!get_free_ugid_range(&id_low, &id_high)) {
2264 return False;
2267 *low = algorithmic_pdb_uid_to_user_rid(id_low);
2268 if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
2269 *high = (uint32)-1;
2270 } else {
2271 *high = algorithmic_pdb_uid_to_user_rid(id_high);
2274 return True;
2277 /*********************************************************************
2278 Update the bad password count checking the AP_RESET_COUNT_TIME
2279 *********************************************************************/
2281 BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
2283 time_t LastBadPassword;
2284 uint16 BadPasswordCount;
2285 uint32 resettime;
2287 if (!sampass) return False;
2289 BadPasswordCount = pdb_get_bad_password_count(sampass);
2290 if (!BadPasswordCount) {
2291 DEBUG(9, ("No bad password attempts.\n"));
2292 return True;
2295 if (!pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime)) {
2296 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2297 return False;
2300 /* First, check if there is a reset time to compare */
2301 if ((resettime == (uint32) -1) || (resettime == 0)) {
2302 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2303 return True;
2306 LastBadPassword = pdb_get_bad_password_time(sampass);
2307 DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
2308 (uint32) LastBadPassword, resettime, (uint32)time(NULL)));
2309 if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
2310 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2311 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2312 if (updated) {
2313 *updated = True;
2317 return True;
2320 /*********************************************************************
2321 Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
2322 *********************************************************************/
2324 BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
2326 uint32 duration;
2327 time_t LastBadPassword;
2329 if (!sampass) return False;
2331 if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2332 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2333 pdb_get_username(sampass)));
2334 return True;
2337 if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
2338 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2339 return False;
2342 /* First, check if there is a duration to compare */
2343 if ((duration == (uint32) -1) || (duration == 0)) {
2344 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2345 return True;
2348 LastBadPassword = pdb_get_bad_password_time(sampass);
2349 DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
2350 pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
2352 if (LastBadPassword == (time_t)0) {
2353 DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
2354 bad password time. Leaving locked out.\n",
2355 pdb_get_username(sampass) ));
2356 return True;
2359 if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
2360 pdb_set_acct_ctrl(sampass,
2361 pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2362 PDB_CHANGED);
2363 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2364 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2365 if (updated) {
2366 *updated = True;
2370 return True;
2373 /*********************************************************************
2374 Increment the bad_password_count
2375 *********************************************************************/
2377 BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
2379 uint32 account_policy_lockout;
2380 BOOL autolock_updated = False, badpw_updated = False;
2382 if (!sampass)
2383 return False;
2385 /* Retrieve the account lockout policy */
2386 if (!pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
2387 &account_policy_lockout)) {
2388 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2389 return False;
2392 /* If there is no policy, we don't need to continue checking */
2393 if (!account_policy_lockout) {
2394 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2395 return True;
2398 /* Check if the autolock needs to be cleared */
2399 if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2400 return False;
2402 /* Check if the badpw count needs to be reset */
2403 if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2404 return False;
2407 Ok, now we can assume that any resetting that needs to be
2408 done has been done, and just get on with incrementing
2409 and autolocking if necessary
2412 pdb_set_bad_password_count(sampass,
2413 pdb_get_bad_password_count(sampass)+1,
2414 PDB_CHANGED);
2415 pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2418 if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2419 return True;
2421 if (!pdb_set_acct_ctrl(sampass,
2422 pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2423 PDB_CHANGED)) {
2424 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2425 return False;
2428 return True;