diff options
Diffstat (limited to 'source/passdb/passdb.c')
-rw-r--r-- | source/passdb/passdb.c | 2954 |
1 files changed, 1166 insertions, 1788 deletions
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index e2e84436029..cf98f78ee28 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -1,11 +1,10 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 1.9. Password and authentication handling Copyright (C) Jeremy Allison 1996-2001 Copyright (C) Luke Kenneth Casson Leighton 1996-1998 Copyright (C) Gerald (Jerry) Carter 2000-2001 - Copyright (C) Andrew Bartlett 2001-2002 - Copyright (C) Simo Sorce 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,296 +23,103 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB +/* + * This is set on startup - it defines the SID for this + * machine, and therefore the SAM database for which it is + * responsible. + */ -/****************************************************************** - get the default domain/netbios name to be used when - testing authentication. For example, if you connect - to a Windows member server using a bogus domain name, the - Windows box will map the BOGUS\user to DOMAIN\user. A - standalone box will map to WKS\user. -******************************************************************/ +extern DOM_SID global_sam_sid; -const char *get_default_sam_name(void) -{ - /* standalone servers can only use the local netbios name */ - if ( lp_server_role() == ROLE_STANDALONE ) - return global_myname(); - - /* Windows domain members default to the DOMAIN - name when not specified */ - return lp_workgroup(); -} - -/************************************************************ - Fill the SAM_ACCOUNT with default values. - ***********************************************************/ - -void pdb_fill_default_sam(SAM_ACCOUNT *user) -{ - ZERO_STRUCT(user->private); /* Don't touch the talloc context */ - - /* no initial methods */ - user->methods = NULL; - - /* Don't change these timestamp settings without a good reason. - They are important for NT member server compatibility. */ - - user->private.logon_time = (time_t)0; - user->private.pass_last_set_time = (time_t)0; - user->private.pass_can_change_time = (time_t)0; - user->private.logoff_time = - user->private.kickoff_time = - user->private.pass_must_change_time = get_time_t_max(); - user->private.fields_present = 0x00ffffff; - user->private.logon_divs = 168; /* hours per week */ - user->private.hours_len = 21; /* 21 times 8 bits = 168 */ - memset(user->private.hours, 0xff, user->private.hours_len); /* available at all hours */ - user->private.bad_password_count = 0; - user->private.logon_count = 0; - user->private.unknown_6 = 0x000004ec; /* don't know */ - - /* Some parts of samba strlen their pdb_get...() returns, - so this keeps the interface unchanged for now. */ - - user->private.username = ""; - user->private.domain = ""; - user->private.nt_username = ""; - user->private.full_name = ""; - user->private.home_dir = ""; - user->private.logon_script = ""; - user->private.profile_path = ""; - user->private.acct_desc = ""; - user->private.workstations = ""; - user->private.unknown_str = ""; - user->private.munged_dial = ""; - - user->private.plaintext_pw = NULL; - - /* - Unless we know otherwise have a Account Control Bit - value of 'normal user'. This helps User Manager, which - asks for a filtered list of users. - */ - - user->private.acct_ctrl = ACB_NORMAL; -} - -static void destroy_pdb_talloc(SAM_ACCOUNT **user) -{ - if (*user) { - data_blob_clear_free(&((*user)->private.lm_pw)); - data_blob_clear_free(&((*user)->private.nt_pw)); - - if((*user)->private.plaintext_pw!=NULL) - memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw)); - talloc_destroy((*user)->mem_ctx); - *user = NULL; - } -} - - -/********************************************************************** - Allocates memory and initialises a struct sam_passwd on supplied mem_ctx. -***********************************************************************/ +struct passdb_ops *pdb_ops; -NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user) -{ - if (*user != NULL) { - DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n")); -#if 0 - smb_panic("non-NULL pointer passed to pdb_init_sam\n"); +#if 0 /* JERRY */ +static void* pdb_handle = NULL; #endif - return NT_STATUS_UNSUCCESSFUL; - } - - if (!mem_ctx) { - DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - *user=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(SAM_ACCOUNT)); - - if (*user==NULL) { - DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n")); - return NT_STATUS_NO_MEMORY; - } - - (*user)->mem_ctx = mem_ctx; - (*user)->free_fn = NULL; +/*************************************************************** + Initialize the password db operations. +***************************************************************/ - pdb_fill_default_sam(*user); +BOOL initialize_password_db(BOOL reload) +{ + /* + * This function is unfinished right now, so just + * ignore the details and always return True. It + * is here only as a placeholder --jerry + */ + return True; - return NT_STATUS_OK; } - /************************************************************* - Allocates memory and initialises a struct sam_passwd. - ************************************************************/ + Initialises a struct sam_disp_info. + **************************************************************/ -NTSTATUS pdb_init_sam(SAM_ACCOUNT **user) +static void pdb_init_dispinfo(struct sam_disp_info *user) { - TALLOC_CTX *mem_ctx; - NTSTATUS nt_status; - - mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation"); - - if (!mem_ctx) { - DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) { - talloc_destroy(mem_ctx); - return nt_status; - } - - (*user)->free_fn = destroy_pdb_talloc; - - return NT_STATUS_OK; + if (user == NULL) + return; + ZERO_STRUCTP(user); } -/************************************************************************** - * This function will take care of all the steps needed to correctly - * allocate and set the user SID, please do use this function to create new - * users, messing with SIDs is not good. - * - * account_data must be provided initialized, pwd may be null. - * SSS - ***************************************************************************/ -static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) -{ - const char *guest_account = lp_guestaccount(); - GROUP_MAP map; - BOOL ret; - - if (!account_data || !pwd) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* this is a hack this thing should not be set - this way --SSS */ - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return NT_STATUS_UNSUCCESSFUL; - } else { - /* Ensure this *must* be set right */ - if (strcmp(pwd->pw_name, guest_account) == 0) { - if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; - } - } +/************************************************************ + Fill the SAM_ACCOUNT with default values. + ***********************************************************/ - if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { - DEBUG(0,("Can't set User SID from RID!\n")); - return NT_STATUS_INVALID_PARAMETER; +static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user) +{ + if (user == NULL) { + DEBUG(0,("pdb_fill_default_sam: SAM_ACCOUNT was NULL\n")); + return False; } - /* call the mapping code here */ - become_root(); - ret = pdb_getgrgid(&map, pwd->pw_gid); - unbecome_root(); + ZERO_STRUCTP(user); - if( ret ) { - if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ - DEBUG(0,("Can't set Group SID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - else { - if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } + user->init_flag = FLAG_SAM_UNINIT; + user->uid = user->gid = -1; + user->logon_time = (time_t)0; + user->pass_last_set_time = (time_t)0; + user->pass_can_change_time = (time_t)0; + user->logoff_time = + user->kickoff_time = + user->pass_must_change_time = get_time_t_max(); /* Password never expires. */ + + user->unknown_3 = 0x00ffffff; /* don't know */ + user->logon_divs = 168; /* hours per week */ + user->hours_len = 21; /* 21 times 8 bits = 168 */ + memset(user->hours, 0xff, user->hours_len); /* available at all hours */ + user->unknown_5 = 0x00000000; /* don't know */ + user->unknown_6 = 0x000004ec; /* don't know */ + return True; +} - return NT_STATUS_OK; -} /************************************************************* - Initialises a struct sam_passwd with sane values. + Alloc memory and initialises a struct sam_passwd. ************************************************************/ -NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) +BOOL pdb_init_sam(SAM_ACCOUNT **user) { - NTSTATUS ret; - - if (!pwd) { - return NT_STATUS_UNSUCCESSFUL; + if (*user != NULL) { + DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n")); +#if 0 + smb_panic("NULL pointer passed to pdb_init_sam\n"); +#endif + return False; } - - pdb_fill_default_sam(sam_account); - - pdb_set_username(sam_account, pwd->pw_name, PDB_SET); - pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET); - - pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET); - - pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT); - /* When we get a proper uid -> SID and SID -> uid allocation - mechinism, we should call it here. - - We can't just set this to 0 or allow it only to be filled - in when added to the backend, because the user's SID - may already be in security descriptors etc. - - -- abartlet 11-May-02 - */ - - ret = pdb_set_sam_sids(sam_account, pwd); - if (!NT_STATUS_IS_OK(ret)) return ret; - - /* check if this is a user account or a machine account */ - if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$') - { - pdb_set_profile_path(sam_account, - talloc_sub_specified((sam_account)->mem_ctx, - lp_logon_path(), - pwd->pw_name, global_myname(), - pwd->pw_uid, pwd->pw_gid), - PDB_DEFAULT); - - pdb_set_homedir(sam_account, - talloc_sub_specified((sam_account)->mem_ctx, - lp_logon_home(), - pwd->pw_name, global_myname(), - pwd->pw_uid, pwd->pw_gid), - PDB_DEFAULT); - - pdb_set_dir_drive(sam_account, - talloc_sub_specified((sam_account)->mem_ctx, - lp_logon_drive(), - pwd->pw_name, global_myname(), - pwd->pw_uid, pwd->pw_gid), - PDB_DEFAULT); - - pdb_set_logon_script(sam_account, - talloc_sub_specified((sam_account)->mem_ctx, - lp_logon_script(), - pwd->pw_name, global_myname(), - pwd->pw_uid, pwd->pw_gid), - PDB_DEFAULT); - if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) { - DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name)); - return NT_STATUS_UNSUCCESSFUL; - } - } else { - if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) { - DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name)); - return NT_STATUS_UNSUCCESSFUL; - } + *user=(SAM_ACCOUNT *)malloc(sizeof(SAM_ACCOUNT)); + + if (*user==NULL) { + DEBUG(0,("pdb_init_sam: error while allocating memory\n")); + return False; } - return NT_STATUS_OK; + + pdb_fill_default_sam(*user); + + return True; } @@ -321,135 +127,121 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) Initialises a struct sam_passwd with sane values. ************************************************************/ -NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd) +BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd) { - NTSTATUS nt_status; - if (!pwd) { new_sam_acct = NULL; - return NT_STATUS_INVALID_PARAMETER; + return False; } - if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) { + if (!pdb_init_sam(new_sam_acct)) { new_sam_acct = NULL; - return nt_status; + return False; } - if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) { - pdb_free_sam(new_sam_acct); - new_sam_acct = NULL; - return nt_status; - } - return NT_STATUS_OK; + pdb_set_username(*new_sam_acct, pwd->pw_name); + pdb_set_fullname(*new_sam_acct, pwd->pw_gecos); + pdb_set_uid(*new_sam_acct, pwd->pw_uid); + pdb_set_gid(*new_sam_acct, pwd->pw_gid); + pdb_set_profile_path(*new_sam_acct, lp_logon_path(), False); + pdb_set_homedir(*new_sam_acct, lp_logon_home(), False); + pdb_set_dir_drive(*new_sam_acct, lp_logon_drive(), False); + pdb_set_logon_script(*new_sam_acct, lp_logon_script(), False); + return True; } -/************************************************************* - Initialises a SAM_ACCOUNT ready to add a new account, based - on the UNIX user. Pass in a RID if you have one - ************************************************************/ +/************************************************************ + Free the NT/LM hashes only. + ***********************************************************/ -NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username, - uint32 rid) +static BOOL pdb_free_sam_contents(SAM_ACCOUNT *user) { - NTSTATUS nt_status = NT_STATUS_NO_MEMORY; - struct passwd *pwd; - BOOL ret; - - pwd = Get_Pwnam(username); - - if (!pwd) - return NT_STATUS_NO_SUCH_USER; - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) { - *new_sam_acct = NULL; - return nt_status; - } - - /* see if we need to generate a new rid using the 2.2 algorithm */ - if ( rid == 0 && lp_enable_rid_algorithm() ) { - DEBUG(10,("pdb_init_sam_new: no RID specified. Generating one via old algorithm\n")); - rid = fallback_pdb_uid_to_user_rid(pwd->pw_uid); + if (user == NULL) { + DEBUG(0,("pdb_free_sam_contents: SAM_ACCOUNT was NULL\n")); +#if 0 + smb_panic("NULL pointer passed to pdb_free_sam\n"); +#endif + return False; } - - /* set the new SID */ - - ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET ); - - return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER); -} - - -/** - * Free the contets of the SAM_ACCOUNT, but not the structure. - * - * Also wipes the LM and NT hashes and plaintext password from - * memory. - * - * @param user SAM_ACCOUNT to free members of. - **/ - -static void pdb_free_sam_contents(SAM_ACCOUNT *user) -{ - - /* Kill off sensitive data. Free()ed by the - talloc mechinism */ - data_blob_clear_free(&(user->private.lm_pw)); - data_blob_clear_free(&(user->private.nt_pw)); - if (user->private.plaintext_pw!=NULL) - memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw)); + /* As we start mallocing more strings this is where + we should free them. */ - if (user->private.backend_private_data && user->private.backend_private_data_free_fn) { - user->private.backend_private_data_free_fn(&user->private.backend_private_data); - } + SAFE_FREE(user->nt_pw); + SAFE_FREE(user->lm_pw); + + return True; } /************************************************************ Reset the SAM_ACCOUNT and free the NT/LM hashes. + - note: they are not zero'ed out however. ***********************************************************/ -NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user) +BOOL pdb_reset_sam(SAM_ACCOUNT *user) { if (user == NULL) { DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n")); -#if 0 - smb_panic("NULL pointer passed to pdb_free_sam\n"); -#endif - return NT_STATUS_UNSUCCESSFUL; + return False; } - pdb_free_sam_contents(user); + if (!pdb_free_sam_contents(user)) { + return False; + } - pdb_fill_default_sam(user); + if (!pdb_fill_default_sam(user)) { + return False; + } - return NT_STATUS_OK; + return True; } /************************************************************ - Free the SAM_ACCOUNT and the member pointers. + Free the SAM_ACCOUNT and the NT/LM hashes. ***********************************************************/ -NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) +BOOL pdb_free_sam(SAM_ACCOUNT *user) { - if (*user == NULL) { + if (user == NULL) { DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n")); #if 0 smb_panic("NULL pointer passed to pdb_free_sam\n"); #endif - return NT_STATUS_UNSUCCESSFUL; + return False; } - pdb_free_sam_contents(*user); - - if ((*user)->free_fn) { - (*user)->free_fn(user); + if (!pdb_free_sam_contents(user)) { + return False; } - return NT_STATUS_OK; + SAFE_FREE(user); + + return True; +} + + +/************************************************************************* + Routine to return the next entry in the sam passwd list. + *************************************************************************/ + +struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user) +{ + static struct sam_disp_info disp_info; + + if (user == NULL) + return NULL; + + pdb_init_dispinfo(&disp_info); + + disp_info.smb_name = user->username; + disp_info.full_name = user->full_name; + disp_info.user_rid = user->user_rid; + + return &disp_info; } /********************************************************** @@ -461,11 +253,8 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length) { static fstring acct_str; - size_t i = 0; - SMB_ASSERT(length <= sizeof(acct_str)); - acct_str[i++] = '['; if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; @@ -536,7 +325,7 @@ uint16 pdb_decode_acct_ctrl(const char *p) Routine to set 32 hex password characters from a 16 byte array. **************************************************************/ -void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl) +void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl) { if (pwd != NULL) { int i; @@ -555,11 +344,11 @@ void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl) into a 16 byte array. **************************************************************/ -BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) +BOOL pdb_gethexpwd(char *p, unsigned char *pwd) { int i; unsigned char lonybble, hinybble; - const char *hexchars = "0123456789ABCDEF"; + const char *hexchars = "0123456789ABCDEF"; char *p1, *p2; if (!p) @@ -583,70 +372,66 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) return (True); } -int algorithmic_rid_base(void) -{ - static int rid_offset = 0; +/******************************************************************* + Group and User RID username mapping function + ********************************************************************/ - if (rid_offset != 0) - return rid_offset; +BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid) +{ + struct passwd *pw = Get_Pwnam(user_name, False); - rid_offset = lp_algorithmic_rid_base(); + if (u_rid == NULL || g_rid == NULL || user_name == NULL) + return False; - if (rid_offset < BASE_RID) { - /* Try to prevent admin foot-shooting, we can't put algorithmic - rids below 1000, that's the 'well known RIDs' on NT */ - DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID)); - rid_offset = BASE_RID; - } - if (rid_offset & 1) { - DEBUG(0, ("algorithmic rid base must be even\n")); - rid_offset += 1; + if (!pw) { + DEBUG(1,("Username %s is invalid on this system\n", user_name)); + return False; } - return rid_offset; + + /* turn the unix UID into a Domain RID. this is what the posix + sub-system does (adds 1000 to the uid) */ + *u_rid = pdb_uid_to_user_rid(pw->pw_uid); + + /* absolutely no idea what to do about the unix GID to Domain RID mapping */ + *g_rid = pdb_gid_to_group_rid(pw->pw_gid); + + return True; } /******************************************************************* Converts NT user RID to a UNIX uid. ********************************************************************/ -uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) +uid_t pdb_user_rid_to_uid(uint32 user_rid) { - int rid_offset = algorithmic_rid_base(); - return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER); + return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); } /******************************************************************* - converts UNIX uid to an NT User RID. + Converts NT user RID to a UNIX gid. ********************************************************************/ -uint32 fallback_pdb_uid_to_user_rid(uid_t uid) +gid_t pdb_user_rid_to_gid(uint32 user_rid) { - int rid_offset = algorithmic_rid_base(); - return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE); + return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER); } /******************************************************************* - Converts NT group RID to a UNIX gid. + converts UNIX uid to an NT User RID. ********************************************************************/ -gid_t pdb_group_rid_to_gid(uint32 group_rid) +uint32 pdb_uid_to_user_rid(uid_t uid) { - int rid_offset = algorithmic_rid_base(); - return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER); + return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); } /******************************************************************* converts NT Group RID to a UNIX uid. - - warning: you must not call that function only - you must do a call to the group mapping first. - there is not anymore a direct link between the gid and the rid. ********************************************************************/ uint32 pdb_gid_to_group_rid(gid_t gid) { - int rid_offset = algorithmic_rid_base(); - return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE); + return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE); } /******************************************************************* @@ -655,25 +440,19 @@ uint32 pdb_gid_to_group_rid(gid_t gid) static BOOL pdb_rid_is_well_known(uint32 rid) { - /* Not using rid_offset here, because this is the actual - NT fixed value (1000) */ - - return (rid < BASE_RID); + return (rid < 1000); } /******************************************************************* Decides if a RID is a user or group RID. ********************************************************************/ -BOOL fallback_pdb_rid_is_user(uint32 rid) +BOOL pdb_rid_is_user(uint32 rid) { /* lkcl i understand that NT attaches an enumeration to a RID * such that it can be identified as either a user, group etc * type. there are 5 such categories, and they are documented. */ - /* However, they are not in the RID, just somthing you can query - seperatly. Sorry luke :-) */ - if(pdb_rid_is_well_known(rid)) { /* * The only well known user RIDs are DOMAIN_USER_RID_ADMIN @@ -691,144 +470,127 @@ BOOL fallback_pdb_rid_is_user(uint32 rid) Convert a rid into a name. Used in the lookup SID rpc. ********************************************************************/ -BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use) +BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) { - uint32 rid; - SAM_ACCOUNT *sam_account = NULL; - GROUP_MAP map; - BOOL ret; + BOOL is_user = pdb_rid_is_user(rid); - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){ - DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n", - sid_string_static(&map.sid))); - return False; - } *psid_name_use = SID_NAME_UNKNOWN; - - DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid)); - - if (rid == DOMAIN_USER_RID_ADMIN) { - const char **admin_list = lp_admin_users(-1); - *psid_name_use = SID_NAME_USER; - if (admin_list) { - const char *p = *admin_list; + + DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" : + "group", (unsigned int)rid)); + + if(is_user) { + if(rid == DOMAIN_USER_RID_ADMIN) { + const char *p = lp_admin_users(-1); + *psid_name_use = SID_NAME_USER; if(!next_token(&p, name, NULL, sizeof(fstring))) fstrcpy(name, "Administrator"); + } else if (rid == DOMAIN_USER_RID_GUEST) { + const char *p = lp_guestaccount(-1); + *psid_name_use = SID_NAME_USER; + if(!next_token(&p, name, NULL, sizeof(fstring))) + fstrcpy(name, "Guest"); } else { - fstrcpy(name, "Administrator"); - } - return True; - } - - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { - return False; - } - - /* see if the passdb can help us with the name of the user */ + uid_t uid; + struct passwd *pass; + + /* + * Don't try to convert the rid to a name if + * running in appliance mode + */ + if (lp_hide_local_users()) + return False; + + uid = pdb_user_rid_to_uid(rid); + pass = sys_getpwuid(uid); - /* BEING ROOT BLLOCK */ - become_root(); - if (pdb_getsampwsid(sam_account, sid)) { - unbecome_root(); /* -----> EXIT BECOME_ROOT() */ - fstrcpy(name, pdb_get_username(sam_account)); - *psid_name_use = SID_NAME_USER; + *psid_name_use = SID_NAME_USER; - pdb_free_sam(&sam_account); - - return True; - } - pdb_free_sam(&sam_account); - - ret = pdb_getgrsid(&map, *sid); - unbecome_root(); - /* END BECOME_ROOT BLOCK */ - - if ( ret ) { - if (map.gid!=(gid_t)-1) { - DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); - } else { - DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name)); - } + DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid, + pass ? "succeeded" : "failed" )); - fstrcpy(name, map.nt_name); - *psid_name_use = map.sid_name_use; - return True; - } + if(!pass) { + slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid); + return True; + } - if (fallback_pdb_rid_is_user(rid)) { - uid_t uid; - struct passwd *pw = NULL; + fstrcpy(name, pass->pw_name); - DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid)); + DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name, + (unsigned int)rid )); + } - uid = fallback_pdb_user_rid_to_uid(rid); - pw = sys_getpwuid( uid ); - - DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid, - pw ? "succeeded" : "failed" )); - - if ( !pw ) - fstr_sprintf(name, "unix_user.%u", (unsigned int)uid); - else - fstrcpy( name, pw->pw_name ); - - DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name, - (unsigned int)rid )); - - *psid_name_use = SID_NAME_USER; - - return ( pw != NULL ); } else { gid_t gid; struct group *gr; - - DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid)); - gid = pdb_group_rid_to_gid(rid); - gr = getgrgid(gid); - - DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid, - gr ? "succeeded" : "failed" )); - - if( !gr ) - fstr_sprintf(name, "unix_group.%u", (unsigned int)gid); - else - fstrcpy( name, gr->gr_name); - - DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name, - (unsigned int)rid )); - - /* assume fallback groups aer domain global groups */ + /* + * Don't try to convert the rid to a name if running + * in appliance mode + */ - *psid_name_use = SID_NAME_DOM_GRP; + if (lp_hide_local_users()) + return False; - return ( gr != NULL ); + gid = pdb_user_rid_to_gid(rid); + gr = getgrgid(gid); + + *psid_name_use = SID_NAME_ALIAS; + + DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid, + gr ? "succeeded" : "failed" )); + + if(!gr) { + switch (rid) { + case DOMAIN_GROUP_RID_ADMINS: + fstrcpy(name, "Domain Admins"); + return True; + case DOMAIN_GROUP_RID_USERS: + fstrcpy(name, "Domain Users"); + return True; + case DOMAIN_GROUP_RID_GUESTS: + fstrcpy(name, "Domain Guests"); + return True; + case BUILTIN_ALIAS_RID_USERS: + fstrcpy(name, "Users"); + return True; + } + slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid); + return True; + } + + fstrcpy( name, gr->gr_name); + + DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name, + (unsigned int)rid )); } + + return True; } /******************************************************************* Convert a name into a SID. Used in the lookup name rpc. ********************************************************************/ -BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use) +BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use) { extern DOM_SID global_sid_World_Domain; + struct passwd *pass = NULL; DOM_SID local_sid; fstring user; - SAM_ACCOUNT *sam_account = NULL; - struct group *grp; - GROUP_MAP map; - + fstring domain; + *psid_name_use = SID_NAME_UNKNOWN; /* - * user may be quoted a const string, and map_username and - * friends can modify it. Make a modifiable copy. JRA. + * domain and user may be quoted const strings, and map_username and + * friends can modify them. Make a modifiable copy. JRA. */ + fstrcpy(domain, c_domain); fstrcpy(user, c_user); - sid_copy(&local_sid, get_global_sam_sid()); + sid_copy(&local_sid, &global_sam_sid); /* * Special case for MACHINE\Everyone. Map to the world_sid. @@ -841,73 +603,272 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi return True; } - (void)map_username(user); - - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { + /* + * Don't lookup local unix users if running in appliance mode + */ + if (lp_hide_local_users()) return False; - } - - /* BEGIN ROOT BLOCK */ - - become_root(); - if (pdb_getsampwnam(sam_account, user)) { - unbecome_root(); - sid_copy(psid, pdb_get_user_sid(sam_account)); - *psid_name_use = SID_NAME_USER; - - pdb_free_sam(&sam_account); - return True; - } - pdb_free_sam(&sam_account); - - /* - * Maybe it was a group ? - */ + (void)map_username(user); - /* check if it's a mapped group */ - if (pdb_getgrnam(&map, user)) { - /* yes it's a mapped group */ - sid_copy(&local_sid, &map.sid); - *psid_name_use = map.sid_name_use; + if((pass = Get_Pwnam(user, False))) { + sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid)); + *psid_name_use = SID_NAME_USER; } else { - /* it's not a mapped group */ - grp = getgrnam(user); - if(!grp) { - unbecome_root(); /* ---> exit form block */ - return False; - } - - /* - *check if it's mapped, if it is reply it doesn't exist - * - * that's to prevent this case: - * - * unix group ug is mapped to nt group ng - * someone does a lookup on ug - * we must not reply as it doesn't "exist" anymore - * for NT. For NT only ng exists. - * JFM, 30/11/2001 + /* + * Maybe it was a group ? */ - - if (pdb_getgrgid(&map, grp->gr_gid)){ - unbecome_root(); /* ---> exit form block */ + struct group *grp = getgrnam(user); + + if(!grp) return False; - } - + sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); *psid_name_use = SID_NAME_ALIAS; } - unbecome_root(); - /* END ROOT BLOCK */ sid_copy( psid, &local_sid); return True; } +/**************************************************************************** + Convert a uid to SID - locally. +****************************************************************************/ + +DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) +{ + extern DOM_SID global_sam_sid; + + sid_copy(psid, &global_sam_sid); + sid_append_rid(psid, pdb_uid_to_user_rid(uid)); + + return psid; +} + +/**************************************************************************** + Convert a SID to uid - locally. +****************************************************************************/ + +BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern DOM_SID global_sam_sid; + + DOM_SID dom_sid; + uint32 rid; + fstring str; + struct passwd *pass; + + *name_type = SID_NAME_UNKNOWN; + + sid_copy(&dom_sid, psid); + sid_split_rid(&dom_sid, &rid); + + if (!pdb_rid_is_user(rid)) + return False; + + /* + * We can only convert to a uid if this is our local + * Domain SID (ie. we are the controling authority). + */ + if (!sid_equal(&global_sam_sid, &dom_sid)) + return False; + + *puid = pdb_user_rid_to_uid(rid); + + /* + * Ensure this uid really does exist. + */ + if(!(pass = sys_getpwuid(*puid))) + return False; + + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), + (unsigned int)*puid, pass->pw_name )); + + *name_type = SID_NAME_USER; + return True; +} + +/**************************************************************************** + Convert a gid to SID - locally. +****************************************************************************/ + +DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) +{ + extern DOM_SID global_sam_sid; + + sid_copy(psid, &global_sam_sid); + sid_append_rid(psid, pdb_gid_to_group_rid(gid)); + + return psid; +} + +/**************************************************************************** + Convert a SID to gid - locally. +****************************************************************************/ + +BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern DOM_SID global_sam_sid; + DOM_SID dom_sid; + uint32 rid; + fstring str; + struct group *grp; + + *name_type = SID_NAME_UNKNOWN; + + sid_copy(&dom_sid, psid); + sid_split_rid(&dom_sid, &rid); + + /* + * We can only convert to a gid if this is our local + * Domain SID (ie. we are the controling authority). + */ + + if (!sid_equal(&global_sam_sid, &dom_sid)) + return False; + + if (pdb_rid_is_user(rid)) + return False; + + *pgid = pdb_user_rid_to_gid(rid); + + /* + * Ensure this gid really does exist. + */ + + if(!(grp = getgrgid(*pgid))) + return False; + + *name_type = SID_NAME_ALIAS; + + DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid), + (unsigned int)*pgid, grp->gr_name )); + + return True; +} + +static void select_name(pstring string, const UNISTR2 *from) +{ + if (from->buffer != 0) + unistr2_to_dos(string, from, sizeof(pstring)); +} + +/************************************************************* + Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT + **************************************************************/ + +void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) +{ + + if (from == NULL || to == NULL) + return; + + to->logon_time = nt_time_to_unix(&from->logon_time); + to->logoff_time = nt_time_to_unix(&from->logoff_time); + to->kickoff_time = nt_time_to_unix(&from->kickoff_time); + to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time); + to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time); + to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time); + + select_name(to->username , &from->uni_user_name ); + select_name(to->full_name , &from->uni_full_name ); + select_name(to->home_dir , &from->uni_home_dir ); + select_name(to->dir_drive , &from->uni_dir_drive ); + select_name(to->logon_script, &from->uni_logon_script); + select_name(to->profile_path, &from->uni_profile_path); + select_name(to->acct_desc , &from->uni_acct_desc ); + select_name(to->workstations, &from->uni_workstations); + select_name(to->unknown_str , &from->uni_unknown_str ); + select_name(to->munged_dial , &from->uni_munged_dial ); + + to->user_rid = from->user_rid; + to->group_rid = from->group_rid; + + to->acct_ctrl = from->acb_info; + to->unknown_3 = from->unknown_3; + + to->logon_divs = from->logon_divs; + to->hours_len = from->logon_hrs.len; + memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN); + + to->unknown_5 = from->unknown_5; + to->unknown_6 = from->unknown_6; +} + +/************************************************************* + Copies a sam passwd. + **************************************************************/ + +void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) +{ + if (from == NULL || to == NULL) + return; + + to->logon_time = nt_time_to_unix(&from->logon_time); + to->logoff_time = nt_time_to_unix(&from->logoff_time); + to->kickoff_time = nt_time_to_unix(&from->kickoff_time); + to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time); + to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time); + to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time); + + select_name(to->username , &from->uni_user_name ); + select_name(to->full_name , &from->uni_full_name ); + select_name(to->home_dir , &from->uni_home_dir ); + select_name(to->dir_drive , &from->uni_dir_drive ); + select_name(to->logon_script, &from->uni_logon_script); + select_name(to->profile_path, &from->uni_profile_path); + select_name(to->acct_desc , &from->uni_acct_desc ); + select_name(to->workstations, &from->uni_workstations); + select_name(to->unknown_str , &from->uni_unknown_str ); + select_name(to->munged_dial , &from->uni_munged_dial ); + + to->user_rid = from->user_rid; + to->group_rid = from->group_rid; + + /* FIXME!! Do we need to copy the passwords here as well? + I don't know. Need to figure this out --jerry */ + + to->acct_ctrl = from->acb_info; + to->unknown_3 = from->unknown_3; + + to->logon_divs = from->logon_divs; + to->hours_len = from->logon_hrs.len; + memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN); + + to->unknown_5 = from->unknown_5; + to->unknown_6 = from->unknown_6; +} + +#if 0 /* JERRY */ +/************************************************************* + Copies a SAM_ACCOUNT. + FIXME!!!! This is broken as SAM_ACCOUNT contains two + pointers. --jerry + **************************************************************/ + +void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from) +{ + if (!from || !to) + return; + + memcpy(to, from, sizeof(SAM_ACCOUNT)); + + +} +#endif + /************************************************************* Change a password entry in the local smbpasswd file. + + FIXME!! The function needs to be abstracted into the + passdb interface or something. It is currently being called + by _api_samr_create_user() in rpc_server/srv_samr.c + + --jerry + + FIXME ! The new password is in UNIX character set. Must be + changed to DOS codepage before hashing. *************************************************************/ BOOL local_password_change(const char *user_name, int local_flags, @@ -915,56 +876,84 @@ BOOL local_password_change(const char *user_name, int local_flags, char *err_str, size_t err_str_len, char *msg_str, size_t msg_str_len) { + struct passwd *pwd = NULL; SAM_ACCOUNT *sam_pass=NULL; - uint16 other_acb; *err_str = '\0'; *msg_str = '\0'; + if (local_flags & LOCAL_ADD_USER) { + + /* + * Check for a local account - if we're adding only. + */ + + if(!(pwd = sys_getpwnam(user_name))) { + slprintf(err_str, err_str_len - 1, "User %s does not \ +exist in system password file (usually /etc/passwd). Cannot add \ +account without a valid local system user.\n", user_name); + return False; + } + } + /* Get the smb passwd entry for this user */ pdb_init_sam(&sam_pass); - - become_root(); + if(local_flags & LOCAL_DELETE_USER) { + if (!pdb_delete_sam_account(user_name)) { + slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name); + pdb_free_sam(sam_pass); + return False; + } + slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name); + pdb_free_sam(sam_pass); + return True; + } if(!pdb_getsampwnam(sam_pass, user_name)) { - unbecome_root(); - pdb_free_sam(&sam_pass); + pdb_free_sam(sam_pass); - if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) { - /* Might not exist in /etc/passwd. Use rid algorithm here */ - if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) { - slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s.\n", user_name); - return False; - } - } else { + if(!(local_flags & LOCAL_ADD_USER)) { slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name); return False; } - } else { - unbecome_root(); - /* the entry already existed */ - local_flags &= ~LOCAL_ADD_USER; - } - /* the 'other' acb bits not being changed here */ - other_acb = (pdb_get_acct_ctrl(sam_pass) & (!(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL))); - if (local_flags & LOCAL_TRUST_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) { - slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); + sam_pass = NULL; + if (!pdb_init_sam_pw(&sam_pass, sys_getpwnam(user_name))) { return False; } - } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) { - if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; + + /* Set account flags. Note that the default is non-expiring accounts */ + pdb_set_acct_ctrl(sam_pass,(local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL|ACB_PWNOEXP); + + if (local_flags & LOCAL_DISABLE_USER) + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED); + + if (local_flags & LOCAL_SET_NO_PASSWORD) { + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ); + } else { + /* set the passwords here. if we get to here it means + we have a valid, active account */ + if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { + pdb_free_sam(sam_pass); + return False; + } } - } else { - if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) { - slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name); - pdb_free_sam(&sam_pass); + + /* Remember to set the "last changed time". */ + pdb_set_pass_last_set_time(sam_pass, time(NULL)); + + if (pdb_add_sam_account(sam_pass)) { + slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name); + pdb_free_sam(sam_pass); + return True; + } else { + slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name); + pdb_free_sam(sam_pass); return False; } + } else { + /* the entry already existed */ + local_flags &= ~LOCAL_ADD_USER; + slprintf(msg_str, msg_str_len-1, "Password changed for user %s.\n", user_name ); } /* @@ -972,27 +961,28 @@ BOOL local_password_change(const char *user_name, int local_flags, * and the valid last change time. */ - if (local_flags & LOCAL_DISABLE_USER) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } + if(local_flags & LOCAL_DISABLE_USER) { + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED); } else if (local_flags & LOCAL_ENABLE_USER) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name); - pdb_free_sam(&sam_pass); + if(pdb_get_lanman_passwd(sam_pass) == NULL) { + if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { + pdb_free_sam(sam_pass); + return False; + } + } + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED)); + } else if (local_flags & LOCAL_SET_NO_PASSWORD) { + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ); + /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */ + if (!pdb_set_lanman_passwd (sam_pass, NULL)) { + pdb_free_sam(sam_pass); return False; } - } - - if (local_flags & LOCAL_SET_NO_PASSWORD) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name); - pdb_free_sam(&sam_pass); + if (!pdb_set_nt_passwd(sam_pass, NULL)) { + pdb_free_sam(sam_pass); return False; } - } else if (local_flags & LOCAL_SET_PASSWORD) { + } else { /* * If we're dealing with setting a completely empty user account * ie. One with a password of 'XXXX', but not set disabled (like @@ -1002,1385 +992,773 @@ BOOL local_password_change(const char *user_name, int local_flags, * and the decision hasn't really been made to disable them (ie. * don't create them disabled). JRA. */ - if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) { - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } - if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) { - slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - + if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED)); + pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ)); if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) { - slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; + pdb_free_sam(sam_pass); + return False; } - } - - if (local_flags & LOCAL_ADD_USER) { - if (pdb_add_sam_account(sam_pass)) { - slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return True; - } else { - slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } else if (local_flags & LOCAL_DELETE_USER) { - if (!pdb_delete_sam_account(sam_pass)) { - slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name); - } else { - if(!pdb_update_sam_account(sam_pass)) { - slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - if(local_flags & LOCAL_DISABLE_USER) - slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name); - else if (local_flags & LOCAL_ENABLE_USER) - slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name); - else if (local_flags & LOCAL_SET_NO_PASSWORD) - slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name); } + + if(!pdb_update_sam_account(sam_pass, True)) { + slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name); + pdb_free_sam(sam_pass); + return False; + } + if(local_flags & LOCAL_DISABLE_USER) + slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name); + else if (local_flags & LOCAL_ENABLE_USER) + slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name); + else if (local_flags & LOCAL_SET_NO_PASSWORD) + slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name); - pdb_free_sam(&sam_pass); + pdb_free_sam(sam_pass); return True; } -/**************************************************************************** - Convert a uid to SID - algorithmic. -****************************************************************************/ +/********************************************************************* + Collection of get...() functions for SAM_ACCOUNT_INFO. + ********************************************************************/ -DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid) +uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass) { - if ( !lp_enable_rid_algorithm() ) - return NULL; + if (sampass) + return (sampass->acct_ctrl); + else + return (ACB_DISABLED); +} - DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n")); - sid_copy( psid, get_global_sam_sid() ); - sid_append_rid( psid, fallback_pdb_uid_to_user_rid(uid) ); - DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n", - (unsigned int)uid, sid_string_static(psid) )); +time_t pdb_get_logon_time (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->logon_time); + else + return (0); +} - return psid; +time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->logoff_time); + else + return (-1); } -/**************************************************************************** - Convert a uid to SID - locally. -****************************************************************************/ +time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->kickoff_time); + else + return (-1); +} -DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) +time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass) { - SAM_ACCOUNT *sampw = NULL; - struct passwd *unix_pw; - BOOL ret; - - unix_pw = sys_getpwuid( uid ); + if (sampass) + return (sampass->pass_last_set_time); + else + return (-1); +} - if ( !unix_pw ) { - DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid)); - return algorithmic_uid_to_sid( psid, uid); - } - - if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) { - DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n")); - return NULL; - } - - become_root(); - ret = pdb_getsampwnam( sampw, unix_pw->pw_name ); - unbecome_root(); - - if ( ret ) - sid_copy( psid, pdb_get_user_sid(sampw) ); - else { - DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n", - unix_pw->pw_name, (unsigned long)uid)); +time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->pass_can_change_time); + else + return (-1); +} - return algorithmic_uid_to_sid( psid, uid); - } +time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->pass_must_change_time); + else + return (-1); +} - DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n", - (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name)); - - return psid; +uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->logon_divs); + else + return (-1); } -/**************************************************************************** - Convert a SID to uid - locally. -****************************************************************************/ +uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->hours_len); + else + return (-1); +} -BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type) +uint8* pdb_get_hours (SAM_ACCOUNT *sampass) { - SAM_ACCOUNT *sampw = NULL; - struct passwd *unix_pw; - const char *user_name; + if (sampass) + return (sampass->hours); + else + return (NULL); +} - *name_type = SID_NAME_UNKNOWN; +uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->nt_pw); + else + return (NULL); +} - /* - * We can only convert to a uid if this is our local - * Domain SID (ie. we are the controling authority). - */ - if (!sid_check_is_in_our_domain(psid) ) { - DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid))); - return False; - } +uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->lm_pw); + else + return (NULL); +} - /* lookup the user account */ - - if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) { - DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n")); - return False; - } - - become_root(); - if ( !pdb_getsampwsid(sampw, psid) ) { - unbecome_root(); - DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n", - sid_string_static(psid))); - return False; - } - unbecome_root(); - - user_name = pdb_get_username(sampw); +uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->user_rid); + else + return (-1); +} - unix_pw = sys_getpwnam( user_name ); +uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->group_rid); + else + return (-1); +} - if ( !unix_pw ) { - DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n", - user_name)); - pdb_free_sam( &sampw ); - return False; - } - - *puid = unix_pw->pw_uid; - - DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid), - (unsigned int)*puid, user_name )); +uid_t pdb_get_uid (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->uid); + else + return ((uid_t)-1); +} - *name_type = SID_NAME_USER; - - return True; +gid_t pdb_get_gid (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->gid); + else + return ((gid_t)-1); } -/**************************************************************************** - Convert a gid to SID - locally. -****************************************************************************/ +char* pdb_get_username (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->username); + else + return (NULL); +} -DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) +char* pdb_get_domain (SAM_ACCOUNT *sampass) { - GROUP_MAP group; - BOOL ret; - - /* we don't need to disable winbindd since the gid is stored in - the GROUP_MAP object */ - - /* done as root since ldap backend requires root to open a connection */ - - become_root(); - ret = pdb_getgrgid( &group, gid ); - unbecome_root(); - - if ( !ret ) { + if (sampass) + return (sampass->domain); + else + return (NULL); +} - /* fallback to rid mapping if enabled */ +char* pdb_get_nt_username (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->nt_username); + else + return (NULL); +} - if ( lp_enable_rid_algorithm() ) { - sid_copy(psid, get_global_sam_sid()); - sid_append_rid(psid, pdb_gid_to_group_rid(gid)); +char* pdb_get_fullname (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->full_name); + else + return (NULL); +} - DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", - (unsigned int)gid, sid_string_static(psid))); - - return psid; - } - else - return NULL; - } - - sid_copy( psid, &group.sid ); - - DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n", - (unsigned int)gid, sid_string_static(psid))); - - return psid; +char* pdb_get_homedir (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->home_dir); + else + return (NULL); } -/**************************************************************************** - Convert a SID to gid - locally. -****************************************************************************/ +char* pdb_get_dirdrive (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->dir_drive); + else + return (NULL); +} -BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type) +char* pdb_get_logon_script (SAM_ACCOUNT *sampass) { - uint32 rid; - GROUP_MAP group; - BOOL ret; + if (sampass) + return (sampass->logon_script); + else + return (NULL); +} - *name_type = SID_NAME_UNKNOWN; +char* pdb_get_profile_path (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->profile_path); + else + return (NULL); +} - /* This call can enumerate group mappings for foreign sids as well. - So don't check for a match against our domain SID */ +char* pdb_get_acct_desc (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->acct_desc); + else + return (NULL); +} - /* we don't need to disable winbindd since the gid is stored in - the GROUP_MAP object */ - - become_root(); - ret = pdb_getgrsid(&group, *psid); - unbecome_root(); - - if ( !ret ) { +char* pdb_get_workstations (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->workstations); + else + return (NULL); +} - /* fallback to rid mapping if enabled */ +char* pdb_get_munged_dial (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->munged_dial); + else + return (NULL); +} - if ( lp_enable_rid_algorithm() ) { +uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->unknown_3); + else + return (-1); +} - if (!sid_check_is_in_our_domain(psid) ) { - DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid))); - return False; - } +uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->unknown_5); + else + return (-1); +} - if (!sid_peek_rid(psid, &rid)) { - DEBUG(10,("local_sid_to_uid: invalid SID!\n")); - return False; - } +uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->unknown_6); + else + return (-1); +} - DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n")); +/********************************************************************* + Collection of set...() functions for SAM_ACCOUNT_INFO. + ********************************************************************/ - if (fallback_pdb_rid_is_user(rid)) { - DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid))); - return False; - } else { - *pgid = pdb_group_rid_to_gid(rid); - DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid))); - return True; - } - } - +BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags) +{ + if (!sampass) return False; + + if (sampass) { + sampass->acct_ctrl = flags; + return True; } + + return False; +} - *pgid = group.gid; - - DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid), - (unsigned int)*pgid)); +BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime) +{ + if (!sampass) + return False; + sampass->logon_time = mytime; return True; } -/********************************************************************** - Marshall/unmarshall SAM_ACCOUNT structs. - *********************************************************************/ - -#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" -#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" +BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime) +{ + if (!sampass) + return False; -/********************************************************************** - Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len - *********************************************************************/ + sampass->logoff_time = mytime; + return True; +} -BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) +BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime) { - return(init_sam_from_buffer_v1(sampass, buf, buflen)); -} + if (!sampass) + return False; -/********************************************************************** - Intialize a BYTE buffer from a SAM_ACCOUNT struct - *********************************************************************/ + sampass->kickoff_time = mytime; + return True; +} -uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) +BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime) { - return(init_buffer_from_sam_v1(buf, sampass, size_only)); -} + if (!sampass) + return False; + sampass->pass_can_change_time = mytime; + return True; +} -BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) +BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime) { + if (!sampass) + return False; - /* times are stored as 32bit integer - take care on system with 64bit wide time_t - --SSS */ - uint32 logon_time, - logoff_time, - kickoff_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time; - char *username; - char *domain; - char *nt_username; - char *dir_drive; - char *unknown_str; - char *munged_dial; - char *fullname; - char *homedir; - char *logon_script; - char *profile_path; - char *acct_desc; - char *workstations; - uint32 username_len, domain_len, nt_username_len, - dir_drive_len, unknown_str_len, munged_dial_len, - fullname_len, homedir_len, logon_script_len, - profile_path_len, acct_desc_len, workstations_len; - - uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; - uint16 acct_ctrl, logon_divs; - uint16 bad_password_count, logon_count; - uint8 *hours; - static uint8 *lm_pw_ptr, *nt_pw_ptr; - uint32 len = 0; - uint32 lm_pw_len, nt_pw_len, hourslen; - BOOL ret = True; - - if(sampass == NULL || buf == NULL) { - DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n")); + sampass->pass_must_change_time = mytime; + return True; +} + +BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime) +{ + if (!sampass) return False; - } - - /* unpack the buffer into variables */ - len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0, - &logon_time, - &logoff_time, - &kickoff_time, - &pass_last_set_time, - &pass_can_change_time, - &pass_must_change_time, - &username_len, &username, - &domain_len, &domain, - &nt_username_len, &nt_username, - &fullname_len, &fullname, - &homedir_len, &homedir, - &dir_drive_len, &dir_drive, - &logon_script_len, &logon_script, - &profile_path_len, &profile_path, - &acct_desc_len, &acct_desc, - &workstations_len, &workstations, - &unknown_str_len, &unknown_str, - &munged_dial_len, &munged_dial, - &user_rid, - &group_rid, - &lm_pw_len, &lm_pw_ptr, - &nt_pw_len, &nt_pw_ptr, - &acct_ctrl, - &remove_me, /* remove on the next TDB_FORMAT upgarde */ - &logon_divs, - &hours_len, - &hourslen, &hours, - &bad_password_count, - &logon_count, - &unknown_6); - - if (len == (uint32) -1) { - ret = False; - goto done; - } - pdb_set_logon_time(sampass, logon_time, PDB_SET); - pdb_set_logoff_time(sampass, logoff_time, PDB_SET); - pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); - pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); - pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); - pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); + sampass->pass_last_set_time = mytime; + return True; +} - pdb_set_username(sampass, username, PDB_SET); - pdb_set_domain(sampass, domain, PDB_SET); - pdb_set_nt_username(sampass, nt_username, PDB_SET); - pdb_set_fullname(sampass, fullname, PDB_SET); +BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len) +{ + if (!sampass) + return False; - if (homedir) { - pdb_set_homedir(sampass, homedir, PDB_SET); - } - else { - pdb_set_homedir(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()), - PDB_DEFAULT); - } + sampass->hours_len = len; + return True; +} - if (dir_drive) - pdb_set_dir_drive(sampass, dir_drive, PDB_SET); - else { - pdb_set_dir_drive(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()), - PDB_DEFAULT); - } +BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours) +{ + if (!sampass) + return False; - if (logon_script) - pdb_set_logon_script(sampass, logon_script, PDB_SET); - else { - pdb_set_logon_script(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), - PDB_DEFAULT); - } + sampass->logon_divs = hours; + return True; +} + +BOOL pdb_set_init_flag (SAM_ACCOUNT *sampass, uint32 flag) +{ + if (!sampass) + return False; - if (profile_path) { - pdb_set_profile_path(sampass, profile_path, PDB_SET); - } else { - pdb_set_profile_path(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()), - PDB_DEFAULT); - } + sampass->init_flag |= flag; - pdb_set_acct_desc(sampass, acct_desc, PDB_SET); - pdb_set_workstations(sampass, workstations, PDB_SET); - pdb_set_munged_dial(sampass, munged_dial, PDB_SET); + return True; +} - if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { - if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { - ret = False; - goto done; - } - } +BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid) +{ + if (!sampass) + return False; - if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { - if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { - ret = False; - goto done; - } - } + sampass->uid = uid; + sampass->init_flag |= FLAG_SAM_UID; - pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); - pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - pdb_set_hours_len(sampass, hours_len, PDB_SET); - pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); - pdb_set_logon_count(sampass, logon_count, PDB_SET); - pdb_set_unknown_6(sampass, unknown_6, PDB_SET); - pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); - pdb_set_logon_divs(sampass, logon_divs, PDB_SET); - pdb_set_hours(sampass, hours, PDB_SET); - -done: - - SAFE_FREE(username); - SAFE_FREE(domain); - SAFE_FREE(nt_username); - SAFE_FREE(fullname); - SAFE_FREE(homedir); - SAFE_FREE(dir_drive); - SAFE_FREE(logon_script); - SAFE_FREE(profile_path); - SAFE_FREE(acct_desc); - SAFE_FREE(workstations); - SAFE_FREE(munged_dial); - SAFE_FREE(unknown_str); - SAFE_FREE(hours); - - return ret; -} - - -uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) -{ - size_t len, buflen; - - /* times are stored as 32bit integer - take care on system with 64bit wide time_t - --SSS */ - uint32 logon_time, - logoff_time, - kickoff_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time; - - uint32 user_rid, group_rid; - - const char *username; - const char *domain; - const char *nt_username; - const char *dir_drive; - const char *unknown_str; - const char *munged_dial; - const char *fullname; - const char *homedir; - const char *logon_script; - const char *profile_path; - const char *acct_desc; - const char *workstations; - uint32 username_len, domain_len, nt_username_len, - dir_drive_len, unknown_str_len, munged_dial_len, - fullname_len, homedir_len, logon_script_len, - profile_path_len, acct_desc_len, workstations_len; - - const uint8 *lm_pw; - const uint8 *nt_pw; - uint32 lm_pw_len = 16; - uint32 nt_pw_len = 16; - - /* do we have a valid SAM_ACCOUNT pointer? */ - if (sampass == NULL) { - DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n")); - return -1; - } - - *buf = NULL; - buflen = 0; - - logon_time = (uint32)pdb_get_logon_time(sampass); - logoff_time = (uint32)pdb_get_logoff_time(sampass); - kickoff_time = (uint32)pdb_get_kickoff_time(sampass); - pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); - pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); - pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); - - user_rid = pdb_get_user_rid(sampass); - group_rid = pdb_get_group_rid(sampass); - - username = pdb_get_username(sampass); - if (username) - username_len = strlen(username) +1; - else - username_len = 0; + return True; +} - domain = pdb_get_domain(sampass); - if (domain) - domain_len = strlen(domain) +1; - else - domain_len = 0; +BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid) +{ + if (!sampass) + return False; - nt_username = pdb_get_nt_username(sampass); - if (nt_username) - nt_username_len = strlen(nt_username) +1; - else - nt_username_len = 0; + sampass->gid = gid; + sampass->init_flag |= FLAG_SAM_GID; - fullname = pdb_get_fullname(sampass); - if (fullname) - fullname_len = strlen(fullname) +1; - else - fullname_len = 0; + return True; +} - /* - * Only updates fields which have been set (not defaults from smb.conf) - */ +BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid) +{ + if (!sampass) + return False; - if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) - dir_drive = pdb_get_dir_drive(sampass); - else - dir_drive = NULL; - if (dir_drive) - dir_drive_len = strlen(dir_drive) +1; - else - dir_drive_len = 0; + sampass->user_rid = rid; + return True; +} - if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) - homedir = pdb_get_homedir(sampass); - else - homedir = NULL; - if (homedir) - homedir_len = strlen(homedir) +1; - else - homedir_len = 0; +BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid) +{ + if (!sampass) + return False; - if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) - logon_script = pdb_get_logon_script(sampass); - else - logon_script = NULL; - if (logon_script) - logon_script_len = strlen(logon_script) +1; - else - logon_script_len = 0; + sampass->group_rid = grid; + return True; +} - if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) - profile_path = pdb_get_profile_path(sampass); - else - profile_path = NULL; - if (profile_path) - profile_path_len = strlen(profile_path) +1; - else - profile_path_len = 0; - - lm_pw = pdb_get_lanman_passwd(sampass); - if (!lm_pw) - lm_pw_len = 0; - - nt_pw = pdb_get_nt_passwd(sampass); - if (!nt_pw) - nt_pw_len = 0; - - acct_desc = pdb_get_acct_desc(sampass); - if (acct_desc) - acct_desc_len = strlen(acct_desc) +1; - else - acct_desc_len = 0; +/********************************************************************* + Set the user's UNIX name. + ********************************************************************/ - workstations = pdb_get_workstations(sampass); - if (workstations) - workstations_len = strlen(workstations) +1; - else - workstations_len = 0; +BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username) +{ + if (!sampass) + return False; + *sampass->username = '\0'; + if (!username) + return False; - unknown_str = NULL; - unknown_str_len = 0; + StrnCpy (sampass->username, username, sizeof(sampass->username)-1); - munged_dial = pdb_get_munged_dial(sampass); - if (munged_dial) - munged_dial_len = strlen(munged_dial) +1; - else - munged_dial_len = 0; - - /* one time to get the size needed */ - len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V0, - logon_time, - logoff_time, - kickoff_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time, - username_len, username, - domain_len, domain, - nt_username_len, nt_username, - fullname_len, fullname, - homedir_len, homedir, - dir_drive_len, dir_drive, - logon_script_len, logon_script, - profile_path_len, profile_path, - acct_desc_len, acct_desc, - workstations_len, workstations, - unknown_str_len, unknown_str, - munged_dial_len, munged_dial, - user_rid, - group_rid, - lm_pw_len, lm_pw, - nt_pw_len, nt_pw, - pdb_get_acct_ctrl(sampass), - 0, /* was: fileds_present, to be removed on format change */ - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_bad_password_count(sampass), - pdb_get_logon_count(sampass), - pdb_get_unknown_6(sampass)); - - - if (size_only) - return buflen; - - /* malloc the space needed */ - if ( (*buf=(uint8*)malloc(len)) == NULL) { - DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n")); - return (-1); - } - - /* now for the real call to tdb_pack() */ - buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V0, - logon_time, - logoff_time, - kickoff_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time, - username_len, username, - domain_len, domain, - nt_username_len, nt_username, - fullname_len, fullname, - homedir_len, homedir, - dir_drive_len, dir_drive, - logon_script_len, logon_script, - profile_path_len, profile_path, - acct_desc_len, acct_desc, - workstations_len, workstations, - unknown_str_len, unknown_str, - munged_dial_len, munged_dial, - user_rid, - group_rid, - lm_pw_len, lm_pw, - nt_pw_len, nt_pw, - pdb_get_acct_ctrl(sampass), - 0, /* was: fileds_present, to be removed on format change */ - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_bad_password_count(sampass), - pdb_get_logon_count(sampass), - pdb_get_unknown_6(sampass)); - - - /* check to make sure we got it correct */ - if (buflen != len) { - DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", - (unsigned long)buflen, (unsigned long)len)); - /* error */ - SAFE_FREE (*buf); - return (-1); - } + return True; +} - return (buflen); -} - - -BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) -{ - - /* times are stored as 32bit integer - take care on system with 64bit wide time_t - --SSS */ - uint32 logon_time, - logoff_time, - kickoff_time, - bad_password_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time; - char *username; - char *domain; - char *nt_username; - char *dir_drive; - char *unknown_str; - char *munged_dial; - char *fullname; - char *homedir; - char *logon_script; - char *profile_path; - char *acct_desc; - char *workstations; - uint32 username_len, domain_len, nt_username_len, - dir_drive_len, unknown_str_len, munged_dial_len, - fullname_len, homedir_len, logon_script_len, - profile_path_len, acct_desc_len, workstations_len; - - uint32 user_rid, group_rid, remove_me, hours_len, unknown_6; - uint16 acct_ctrl, logon_divs; - uint16 bad_password_count, logon_count; - uint8 *hours; - static uint8 *lm_pw_ptr, *nt_pw_ptr; - uint32 len = 0; - uint32 lm_pw_len, nt_pw_len, hourslen; - BOOL ret = True; - - if(sampass == NULL || buf == NULL) { - DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n")); +/********************************************************************* + Set the domain name. + ********************************************************************/ + +BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain) +{ + if (!sampass) + return False; + *sampass->domain = '\0'; + if (!domain) return False; - } - - /* unpack the buffer into variables */ - len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1, - &logon_time, - &logoff_time, - &kickoff_time, - &bad_password_time, - &pass_last_set_time, - &pass_can_change_time, - &pass_must_change_time, - &username_len, &username, - &domain_len, &domain, - &nt_username_len, &nt_username, - &fullname_len, &fullname, - &homedir_len, &homedir, - &dir_drive_len, &dir_drive, - &logon_script_len, &logon_script, - &profile_path_len, &profile_path, - &acct_desc_len, &acct_desc, - &workstations_len, &workstations, - &unknown_str_len, &unknown_str, - &munged_dial_len, &munged_dial, - &user_rid, - &group_rid, - &lm_pw_len, &lm_pw_ptr, - &nt_pw_len, &nt_pw_ptr, - &acct_ctrl, - &remove_me, - &logon_divs, - &hours_len, - &hourslen, &hours, - &bad_password_count, - &logon_count, - &unknown_6); - - if (len == (uint32) -1) { - ret = False; - goto done; - } - pdb_set_logon_time(sampass, logon_time, PDB_SET); - pdb_set_logoff_time(sampass, logoff_time, PDB_SET); - pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); - pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET); - pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); - pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); - pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); - - pdb_set_username(sampass, username, PDB_SET); - pdb_set_domain(sampass, domain, PDB_SET); - pdb_set_nt_username(sampass, nt_username, PDB_SET); - pdb_set_fullname(sampass, fullname, PDB_SET); - - if (homedir) { - pdb_set_homedir(sampass, homedir, PDB_SET); - } - else { - pdb_set_homedir(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()), - PDB_DEFAULT); - } + StrnCpy (sampass->domain, domain, sizeof(sampass->domain)-1); - if (dir_drive) - pdb_set_dir_drive(sampass, dir_drive, PDB_SET); - else { - pdb_set_dir_drive(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()), - PDB_DEFAULT); - } + return True; +} - if (logon_script) - pdb_set_logon_script(sampass, logon_script, PDB_SET); - else { - pdb_set_logon_script(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()), - PDB_DEFAULT); - } - - if (profile_path) { - pdb_set_profile_path(sampass, profile_path, PDB_SET); - } else { - pdb_set_profile_path(sampass, - talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()), - PDB_DEFAULT); - } +/********************************************************************* + Set the user's NT name. + ********************************************************************/ - pdb_set_acct_desc(sampass, acct_desc, PDB_SET); - pdb_set_workstations(sampass, workstations, PDB_SET); - pdb_set_munged_dial(sampass, munged_dial, PDB_SET); +BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username) +{ + if (!sampass) + return False; + *sampass->nt_username = '\0'; + if (!nt_username) + return False; - if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { - if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) { - ret = False; - goto done; - } - } + StrnCpy (sampass->nt_username, nt_username, sizeof(sampass->nt_username) -1); - if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { - if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) { - ret = False; - goto done; - } - } + return True; +} - pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); - pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - pdb_set_hours_len(sampass, hours_len, PDB_SET); - pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET); - pdb_set_logon_count(sampass, logon_count, PDB_SET); - pdb_set_unknown_6(sampass, unknown_6, PDB_SET); - pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); - pdb_set_logon_divs(sampass, logon_divs, PDB_SET); - pdb_set_hours(sampass, hours, PDB_SET); - -done: - - SAFE_FREE(lm_pw_ptr); - SAFE_FREE(nt_pw_ptr); - SAFE_FREE(username); - SAFE_FREE(domain); - SAFE_FREE(nt_username); - SAFE_FREE(fullname); - SAFE_FREE(homedir); - SAFE_FREE(dir_drive); - SAFE_FREE(logon_script); - SAFE_FREE(profile_path); - SAFE_FREE(acct_desc); - SAFE_FREE(workstations); - SAFE_FREE(munged_dial); - SAFE_FREE(unknown_str); - SAFE_FREE(hours); - - return ret; -} - - -uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only) -{ - size_t len, buflen; - - /* times are stored as 32bit integer - take care on system with 64bit wide time_t - --SSS */ - uint32 logon_time, - logoff_time, - kickoff_time, - bad_password_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time; - - uint32 user_rid, group_rid; - - const char *username; - const char *domain; - const char *nt_username; - const char *dir_drive; - const char *unknown_str; - const char *munged_dial; - const char *fullname; - const char *homedir; - const char *logon_script; - const char *profile_path; - const char *acct_desc; - const char *workstations; - uint32 username_len, domain_len, nt_username_len, - dir_drive_len, unknown_str_len, munged_dial_len, - fullname_len, homedir_len, logon_script_len, - profile_path_len, acct_desc_len, workstations_len; - - const uint8 *lm_pw; - const uint8 *nt_pw; - uint32 lm_pw_len = 16; - uint32 nt_pw_len = 16; - - /* do we have a valid SAM_ACCOUNT pointer? */ - if (sampass == NULL) { - DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n")); - return -1; - } - - *buf = NULL; - buflen = 0; - - logon_time = (uint32)pdb_get_logon_time(sampass); - logoff_time = (uint32)pdb_get_logoff_time(sampass); - kickoff_time = (uint32)pdb_get_kickoff_time(sampass); - bad_password_time = (uint32)pdb_get_bad_password_time(sampass); - pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass); - pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass); - pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass); - - user_rid = pdb_get_user_rid(sampass); - group_rid = pdb_get_group_rid(sampass); - - username = pdb_get_username(sampass); - if (username) - username_len = strlen(username) +1; - else - username_len = 0; +/********************************************************************* + Set the user's full name. + ********************************************************************/ - domain = pdb_get_domain(sampass); - if (domain) - domain_len = strlen(domain) +1; - else - domain_len = 0; +BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname) +{ + if (!sampass) + return False; + *sampass->full_name = '\0'; + if (!fullname) + return False; - nt_username = pdb_get_nt_username(sampass); - if (nt_username) - nt_username_len = strlen(nt_username) +1; - else - nt_username_len = 0; + StrnCpy (sampass->full_name, fullname, sizeof(sampass->full_name)-1); - fullname = pdb_get_fullname(sampass); - if (fullname) - fullname_len = strlen(fullname) +1; - else - fullname_len = 0; + return True; +} - /* - * Only updates fields which have been set (not defaults from smb.conf) - */ +/********************************************************************* + Set the user's logon script. + ********************************************************************/ - if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) - dir_drive = pdb_get_dir_drive(sampass); - else - dir_drive = NULL; - if (dir_drive) - dir_drive_len = strlen(dir_drive) +1; - else - dir_drive_len = 0; +BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script, BOOL store) +{ + if (!sampass) + return False; + *sampass->logon_script = '\0'; + if (!logon_script) + return False; - if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) - homedir = pdb_get_homedir(sampass); - else - homedir = NULL; - if (homedir) - homedir_len = strlen(homedir) +1; - else - homedir_len = 0; + StrnCpy (sampass->logon_script, logon_script, sizeof(sampass->logon_script)-1); - if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) - logon_script = pdb_get_logon_script(sampass); - else - logon_script = NULL; - if (logon_script) - logon_script_len = strlen(logon_script) +1; - else - logon_script_len = 0; + if (store) + pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT); - if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) - profile_path = pdb_get_profile_path(sampass); - else - profile_path = NULL; - if (profile_path) - profile_path_len = strlen(profile_path) +1; - else - profile_path_len = 0; + return True; +} + +/********************************************************************* + Set the user's profile path. + ********************************************************************/ + +BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path, BOOL store) +{ + if (!sampass) + return False; + *sampass->profile_path = '\0'; + if (!profile_path) + return False; - lm_pw = pdb_get_lanman_passwd(sampass); - if (!lm_pw) - lm_pw_len = 0; + StrnCpy (sampass->profile_path, profile_path, sizeof(sampass->profile_path)-1); + + if (store) + pdb_set_init_flag(sampass, FLAG_SAM_PROFILE); - nt_pw = pdb_get_nt_passwd(sampass); - if (!nt_pw) - nt_pw_len = 0; - - acct_desc = pdb_get_acct_desc(sampass); - if (acct_desc) - acct_desc_len = strlen(acct_desc) +1; - else - acct_desc_len = 0; + return True; +} - workstations = pdb_get_workstations(sampass); - if (workstations) - workstations_len = strlen(workstations) +1; - else - workstations_len = 0; +/********************************************************************* + Set the user's directory drive. + ********************************************************************/ - unknown_str = NULL; - unknown_str_len = 0; +BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive, BOOL store) +{ + if (!sampass) + return False; + *sampass->dir_drive = '\0'; + if (!dir_drive) + return False; - munged_dial = pdb_get_munged_dial(sampass); - if (munged_dial) - munged_dial_len = strlen(munged_dial) +1; - else - munged_dial_len = 0; - - /* one time to get the size needed */ - len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V1, - logon_time, - logoff_time, - kickoff_time, - bad_password_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time, - username_len, username, - domain_len, domain, - nt_username_len, nt_username, - fullname_len, fullname, - homedir_len, homedir, - dir_drive_len, dir_drive, - logon_script_len, logon_script, - profile_path_len, profile_path, - acct_desc_len, acct_desc, - workstations_len, workstations, - unknown_str_len, unknown_str, - munged_dial_len, munged_dial, - user_rid, - group_rid, - lm_pw_len, lm_pw, - nt_pw_len, nt_pw, - pdb_get_acct_ctrl(sampass), - 0, - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_bad_password_count(sampass), - pdb_get_logon_count(sampass), - pdb_get_unknown_6(sampass)); - - - if (size_only) - return buflen; - - /* malloc the space needed */ - if ( (*buf=(uint8*)malloc(len)) == NULL) { - DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n")); - return (-1); - } + StrnCpy (sampass->dir_drive, dir_drive, sizeof(sampass->dir_drive)-1); - /* now for the real call to tdb_pack() */ - buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V1, - logon_time, - logoff_time, - kickoff_time, - bad_password_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time, - username_len, username, - domain_len, domain, - nt_username_len, nt_username, - fullname_len, fullname, - homedir_len, homedir, - dir_drive_len, dir_drive, - logon_script_len, logon_script, - profile_path_len, profile_path, - acct_desc_len, acct_desc, - workstations_len, workstations, - unknown_str_len, unknown_str, - munged_dial_len, munged_dial, - user_rid, - group_rid, - lm_pw_len, lm_pw, - nt_pw_len, nt_pw, - pdb_get_acct_ctrl(sampass), - 0, - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_bad_password_count(sampass), - pdb_get_logon_count(sampass), - pdb_get_unknown_6(sampass)); - - - /* check to make sure we got it correct */ - if (buflen != len) { - DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n", - (unsigned long)buflen, (unsigned long)len)); - /* error */ - SAFE_FREE (*buf); - return (-1); - } + if (store) + pdb_set_init_flag(sampass, FLAG_SAM_DRIVE); - return (buflen); + return True; } +/********************************************************************* + Set the user's home directory. + ********************************************************************/ -/********************************************************************** -**********************************************************************/ - -static BOOL get_free_ugid_range(uint32 *low, uint32 *high) +BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir, BOOL store) { - uid_t u_low, u_high; - gid_t g_low, g_high; - - if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) { + if (!sampass) + return False; + *sampass->home_dir = '\0'; + if (!homedir) return False; - } - - *low = (u_low < g_low) ? u_low : g_low; - *high = (u_high < g_high) ? u_high : g_high; + StrnCpy (sampass->home_dir, homedir, sizeof(sampass->home_dir)-1); + + if (store) + pdb_set_init_flag(sampass, FLAG_SAM_SMBHOME); + return True; } -/****************************************************************** - Get the the non-algorithmic RID range if idmap range are defined -******************************************************************/ +/********************************************************************* + Set the user's account description. + ********************************************************************/ -BOOL get_free_rid_range(uint32 *low, uint32 *high) +BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc) { - uint32 id_low, id_high; + if (!sampass) + return False; + *sampass->acct_desc = '\0'; + if (!acct_desc) + return False; + + StrnCpy (sampass->acct_desc, acct_desc, sizeof(sampass->acct_desc)-1); - if (!lp_enable_rid_algorithm()) { - *low = BASE_RID; - *high = (uint32)-1; - } + return True; +} - if (!get_free_ugid_range(&id_low, &id_high)) { +/********************************************************************* + Set the user's workstation allowed list. + ********************************************************************/ + +BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations) +{ + if (!sampass) + return False; + *sampass->workstations = '\0'; + if (!workstations) return False; - } - *low = fallback_pdb_uid_to_user_rid(id_low); - if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) { - *high = (uint32)-1; - } else { - *high = fallback_pdb_uid_to_user_rid(id_high); - } + StrnCpy (sampass->workstations, workstations, sizeof(sampass->workstations)-1); return True; } /********************************************************************* - Update the bad password count checking the AP_RESET_COUNT_TIME -*********************************************************************/ + Set the user's dial string. + ********************************************************************/ -BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated) +BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial) { - time_t LastBadPassword; - uint16 BadPasswordCount; - uint32 resettime; - - if (!sampass) return False; - - BadPasswordCount = pdb_get_bad_password_count(sampass); - if (!BadPasswordCount) { - DEBUG(9, ("No bad password attempts.\n")); - return True; - } - - if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) { - DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n")); + if (!sampass) + return False; + *sampass->munged_dial = '\0'; + if (!munged_dial) return False; - } - - /* First, check if there is a reset time to compare */ - if ((resettime == (uint32) -1) || (resettime == 0)) { - DEBUG(9, ("No reset time, can't reset bad pw count\n")); - return True; - } - LastBadPassword = pdb_get_bad_password_time(sampass); - DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n", - (uint32) LastBadPassword, resettime, (uint32)time(NULL))); - if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){ - pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); - pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); - if (updated) *updated = True; - } + StrnCpy (sampass->munged_dial, munged_dial, sizeof(sampass->munged_dial)-1); return True; } /********************************************************************* - Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION -*********************************************************************/ + Set the user's NT hash. + ********************************************************************/ -BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated) +BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd) { - uint32 duration; - time_t LastBadPassword; + if (!sampass) + return False; + + /* Remember to set the "last changed time". */ + pdb_set_pass_last_set_time(sampass, time(NULL)); - if (!sampass) return False; - - if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) { - DEBUG(9, ("Account not autolocked, no check needed\n")); + if (!pwd) { + /* Allow setting to NULL */ + SAFE_FREE(sampass->nt_pw); return True; } - if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) { - DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n")); + if (sampass->nt_pw!=NULL) + DEBUG(4,("pdb_set_nt_passwd: NT hash non NULL overwritting ?\n")); + else + sampass->nt_pw=(unsigned char *)malloc(sizeof(unsigned char)*16); + + if (sampass->nt_pw==NULL) return False; - } - /* First, check if there is a duration to compare */ - if ((duration == (uint32) -1) || (duration == 0)) { - DEBUG(9, ("No reset duration, can't reset autolock\n")); - return True; - } - - LastBadPassword = pdb_get_bad_password_time(sampass); - DEBUG(7, ("LastBadPassword=%d, duration=%d, current time =%d.\n", - (uint32)LastBadPassword, duration*60, (uint32)time(NULL))); - if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) { - pdb_set_acct_ctrl(sampass, - pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK, - PDB_CHANGED); - pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); - pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); - if (updated) *updated = True; - } - + memcpy (sampass->nt_pw, pwd, 16); + return True; } /********************************************************************* - Increment the bad_password_count -*********************************************************************/ + Set the user's LM hash. + ********************************************************************/ -BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass) +BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd) { - uint32 account_policy_lockout; - BOOL autolock_updated = False, badpw_updated = False; - if (!sampass) return False; - /* Retrieve the account lockout policy */ - if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, - &account_policy_lockout)) { - DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n")); - return False; - } + /* Remember to set the "last changed time". */ + pdb_set_pass_last_set_time(sampass, time(NULL)); - /* If there is no policy, we don't need to continue checking */ - if (!account_policy_lockout) { - DEBUG(9, ("No lockout policy, don't track bad passwords\n")); + if (!pwd) { + /* Allow setting to NULL */ + SAFE_FREE(sampass->lm_pw); return True; } - - /* Check if the autolock needs to be cleared */ - if (!pdb_update_autolock_flag(sampass, &autolock_updated)) + + if (sampass->lm_pw!=NULL) + DEBUG(4,("pdb_set_lanman_passwd: LM hash non NULL overwritting ?\n")); + else + sampass->lm_pw=(unsigned char *)malloc(sizeof(unsigned char)*16); + + if (sampass->lm_pw==NULL) return False; - /* Check if the badpw count needs to be reset */ - if (!pdb_update_bad_password_count(sampass, &badpw_updated)) - return False; + memcpy (sampass->lm_pw, pwd, 16); - /* - Ok, now we can assume that any resetting that needs to be - done has been done, and just get on with incrementing - and autolocking if necessary - */ + return True; +} - pdb_set_bad_password_count(sampass, - pdb_get_bad_password_count(sampass)+1, - PDB_CHANGED); - pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED); +/********************************************************************* + Set the user's PLAINTEXT password. Used as an interface to the above. + NB. The plaintext is in UNIX character set. Must be converted to DOS + codepage. + ********************************************************************/ +BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) +{ + uchar new_lanman_p16[16]; + uchar new_nt_p16[16]; + fstring dos_plaintext; - if (pdb_get_bad_password_count(sampass) < account_policy_lockout) - return True; + if (!sampass || !plaintext) + return False; + + fstrcpy(dos_plaintext, unix_to_dos_static(plaintext)); + + nt_lm_owf_gen (dos_plaintext, new_nt_p16, new_lanman_p16); - if (!pdb_set_acct_ctrl(sampass, - pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK, - PDB_CHANGED)) { - DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n")); + if (!pdb_set_nt_passwd (sampass, new_nt_p16)) + return False; + + if (!pdb_set_lanman_passwd (sampass, new_lanman_p16)) return False; - } return True; } +BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn) +{ + if (!sampass) + return False; -/** - * Allocate and initialise buffer from SAM_TRUST_PASSWD - * - * @param trust trust structure's pointer address - * @return nt status code - **/ + sampass->unknown_3 = unkn; + return True; +} -size_t pdb_init_buffer_from_trustpw(TALLOC_CTX *mem_ctx, char** buf, const SAM_TRUST_PASSWD *trust) +BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn) { - size_t len, buflen; + if (!sampass) + return False; - if (!mem_ctx || !trust) - return 0; + sampass->unknown_5 = unkn; + return True; +} - /* flags must be defined (ie. not null) */ - if (!pdb_get_tp_flags(trust)) { - return 0; - } +BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn) +{ + if (!sampass) + return False; - /* calculate length of the storage buffer */ - len = tdb_trustpw_pack(trust, NULL, 0); + sampass->unknown_6 = unkn; + return True; +} - *buf = (char*)talloc(mem_ctx, len); - if (!(*buf)) { - return 0; - } +BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours) +{ + if (!sampass) + return False; - /* pack the structure in allocated buffer */ - buflen = tdb_trustpw_pack(trust, *buf, len); - - if (buflen != len) { - return 0; + if (!hours) { + memset ((char *)sampass->hours, 0, MAX_HOURS_LEN); + return True; } + + memcpy (sampass->hours, hours, MAX_HOURS_LEN); - return buflen; + return True; } +/*************************************************************************** + Search by uid. Wrapper around pdb_getsampwnam() + **************************************************************************/ -/** - * Allocate and initialise buffer from SAM_TRUST_PASSWD - * - * @param trust trust structure's pointer address (it's up to caller - * to free an allocated structure) - * @param buf - * @param buf_len - * @return nt status code - **/ - -BOOL pdb_init_trustpw_from_buffer(SAM_TRUST_PASSWD *trust, const char** buf, size_t buf_len) +BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid) { - if (!trust || !buf) + struct passwd *pw; + fstring name; + + if (user==NULL) { + DEBUG(0,("pdb_getsampwuid: SAM_ACCOUNT is NULL.\n")); + return False; + } + + /* + * Never trust the uid in the passdb. Lookup the username first + * and then lokup the user by name in the sam. + */ + + if ((pw=sys_getpwuid(uid)) == NULL) { + DEBUG(0,("pdb_getsampwuid: getpwuid(%u) return NULL. User does not exist in Unix accounts!\n", + (unsigned int)uid)); return False; + } - tdb_trustpw_unpack(trust, *buf, buf_len); - return True; + fstrcpy (name, pw->pw_name); + + return pdb_getsampwnam (user, name); + } + |