diff options
Diffstat (limited to 'source4/passdb')
-rw-r--r-- | source4/passdb/config.m4 | 18 | ||||
-rw-r--r-- | source4/passdb/machine_sid.c | 192 | ||||
-rw-r--r-- | source4/passdb/passdb.c | 948 | ||||
-rw-r--r-- | source4/passdb/passdb.h | 119 | ||||
-rw-r--r-- | source4/passdb/pdb_compat.c | 115 | ||||
-rw-r--r-- | source4/passdb/pdb_get_set.c | 1123 | ||||
-rw-r--r-- | source4/passdb/pdb_guest.c | 159 | ||||
-rw-r--r-- | source4/passdb/pdb_interface.c | 635 | ||||
-rw-r--r-- | source4/passdb/pdb_ldap.c | 2098 | ||||
-rw-r--r-- | source4/passdb/pdb_smbpasswd.c | 1615 | ||||
-rw-r--r-- | source4/passdb/pdb_tdb.c | 1021 | ||||
-rw-r--r-- | source4/passdb/pdb_unix.c | 131 | ||||
-rw-r--r-- | source4/passdb/util_sam_sid.c | 303 |
13 files changed, 0 insertions, 8477 deletions
diff --git a/source4/passdb/config.m4 b/source4/passdb/config.m4 deleted file mode 100644 index 78d827bf3a..0000000000 --- a/source4/passdb/config.m4 +++ /dev/null @@ -1,18 +0,0 @@ -dnl # PASSDB Server subsystem - -SMB_MODULE(passdb_smbpasswd,PASSDB,STATIC,[passdb/pdb_smbpasswd.o]) -SMB_MODULE(passdb_tdb,PASSDB,NOT,[passdb/pdb_tdb.o]) -SMB_MODULE(passdb_guest,PASSDB,STATIC,[passdb/pdb_guest.o]) -SMB_MODULE(passdb_unix,PASSDB,STATIC,[passdb/pdb_unix.o]) - -if test x"$with_ldap_support" = x"yes"; then - SMB_MODULE_DEFAULT(passdb_ldap,STATIC) -fi -SMB_MODULE(passdb_ldap,PASSDB,NOT,[passdb/pdb_ldap.o]) - -SMB_SUBSYSTEM(PASSDB,passdb/pdb_interface.o, - [passdb/passdb.o - passdb/machine_sid.o - passdb/util_sam_sid.o - passdb/pdb_get_set.o - passdb/pdb_compat.o]) diff --git a/source4/passdb/machine_sid.c b/source4/passdb/machine_sid.c deleted file mode 100644 index 41979c6526..0000000000 --- a/source4/passdb/machine_sid.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Jeremy Allison 1996-2002 - Copyright (C) Andrew Tridgell 2002 - Copyright (C) Gerald (Jerry) Carter 2000 - Copyright (C) Stefan (metze) Metzmacher 2002 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* NOTE! the global_sam_sid is the SID of our local SAM. This is only - equal to the domain SID when we are a DC, otherwise its our - workstation SID */ -static DOM_SID *global_sam_sid=NULL; - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -/**************************************************************************** - Read a SID from a file. This is for compatibility with the old MACHINE.SID - style of SID storage -****************************************************************************/ -static BOOL read_sid_from_file(const char *fname, DOM_SID *sid) -{ - char **lines; - int numlines; - BOOL ret; - - lines = file_lines_load(fname, &numlines); - - if (!lines || numlines < 1) { - if (lines) file_lines_free(lines); - return False; - } - - ret = string_to_sid(sid, lines[0]); - file_lines_free(lines); - return ret; -} - -/* - generate a random sid - used to build our own sid if we don't have one -*/ -static void generate_random_sid(DOM_SID *sid) -{ - int i; - uchar raw_sid_data[12]; - - memset((char *)sid, '\0', sizeof(*sid)); - sid->sid_rev_num = 1; - sid->id_auth[5] = 5; - sid->num_auths = 0; - sid->sub_auths[sid->num_auths++] = 21; - - generate_random_buffer(raw_sid_data, 12, True); - for (i = 0; i < 3; i++) - sid->sub_auths[sid->num_auths++] = IVAL(raw_sid_data, i*4); -} - -/**************************************************************************** - Generate the global machine sid. -****************************************************************************/ - -static BOOL pdb_generate_sam_sid(void) -{ - char *fname = NULL; - BOOL is_dc = False; - - if(global_sam_sid==NULL) - if(!(global_sam_sid=(DOM_SID *)malloc(sizeof(DOM_SID)))) - return False; - - generate_wellknown_sids(); - - switch (lp_server_role()) { - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - is_dc = True; - break; - default: - is_dc = False; - break; - } - - if (secrets_fetch_domain_sid(lp_netbios_name(), global_sam_sid)) { - DOM_SID domain_sid; - - /* We got our sid. If not a pdc/bdc, we're done. */ - if (!is_dc) - return True; - - if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { - - /* No domain sid and we're a pdc/bdc. Store it */ - - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc.\n")); - return False; - } - return True; - } - - if (!sid_equal(&domain_sid, global_sam_sid)) { - - /* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */ - - DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n")); - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n")); - return False; - } - return True; - } - - return True; - - } - - /* check for an old MACHINE.SID file for backwards compatibility */ - asprintf(&fname, "%s/MACHINE.SID", lp_private_dir()); - - if (read_sid_from_file(fname, global_sam_sid)) { - /* remember it for future reference and unlink the old MACHINE.SID */ - if (!secrets_store_domain_sid(lp_netbios_name(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Failed to store SID from file-1.\n")); - SAFE_FREE(fname); - return False; - } - unlink(fname); - if (is_dc) { - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file-2.\n")); - SAFE_FREE(fname); - return False; - } - } - - /* Stored the old sid from MACHINE.SID successfully.*/ - SAFE_FREE(fname); - return True; - } - - SAFE_FREE(fname); - - /* we don't have the SID in secrets.tdb, we will need to - generate one and save it */ - generate_random_sid(global_sam_sid); - - if (!secrets_store_domain_sid(lp_netbios_name(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Failed to store generated machine SID-3, nb name=%s.\n", lp_netbios_name())); - return False; - } - if (is_dc) { - if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) { - DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID-4, wg name=%s.\n", lp_workgroup())); - return False; - } - } - - return True; -} - -/* return our global_sam_sid */ -struct sid_info *get_global_sam_sid(void) -{ - if (global_sam_sid != NULL) - return global_sam_sid; - - /* memory for global_sam_sid is allocated in - pdb_generate_sam_sid() as needed */ - - if (!pdb_generate_sam_sid()) - global_sam_sid=NULL; - - return global_sam_sid; -} - diff --git a/source4/passdb/passdb.c b/source4/passdb/passdb.c deleted file mode 100644 index 8d41cc9227..0000000000 --- a/source4/passdb/passdb.c +++ /dev/null @@ -1,948 +0,0 @@ -/* - Unix SMB/CIFS implementation. - 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 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#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. - */ - -/************************************************************ - Fill the SAM_ACCOUNT with default values. - ***********************************************************/ - -static 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.uid = user->private.gid = -1; - - 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.unknown_3 = 0x00ffffff; /* don't know */ - 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.unknown_5 = 0x00000000; /* don't know */ - 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; - -} - -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; - } -} - - -/********************************************************************** - Alloc memory and initialises a struct sam_passwd on supplied mem_ctx. -***********************************************************************/ - -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"); -#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; - - pdb_fill_default_sam(*user); - - return NT_STATUS_OK; -} - - -/************************************************************* - Alloc memory and initialises a struct sam_passwd. - ************************************************************/ - -NTSTATUS pdb_init_sam(SAM_ACCOUNT **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; -} - - -/************************************************************* - Initialises a struct sam_passwd with sane values. - ************************************************************/ - -NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) -{ - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!pwd) { - return NT_STATUS_UNSUCCESSFUL; - } - - 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, lp_workgroup(), PDB_DEFAULT); - - pdb_set_uid(sam_account, pwd->pw_uid, PDB_SET); - pdb_set_gid(sam_account, pwd->pw_gid, PDB_SET); - - /* 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, becouse the user's SID - may already be in security descriptors etc. - - -- abartlet 11-May-02 - */ - - - /* Ensure this *must* be set right */ - if (strcmp(pwd->pw_name, guest_account) == 0) { - if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - } else { - - if (!pdb_set_user_sid_from_rid(sam_account, - 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; - } - - if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - - /* 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, lp_netbios_name(), - 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, lp_netbios_name(), - 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, lp_netbios_name(), - 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, lp_netbios_name(), - 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; - } - } - return NT_STATUS_OK; -} - - -/************************************************************* - Initialises a struct sam_passwd with sane values. - ************************************************************/ - -NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd) -{ - NTSTATUS nt_status; - - if (!pwd) { - new_sam_acct = NULL; - return NT_STATUS_INVALID_PARAMETER; - } - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) { - new_sam_acct = NULL; - return nt_status; - } - - 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; -} - - -/** - * 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)); -} - - -/************************************************************ - Reset the SAM_ACCOUNT and free the NT/LM hashes. - ***********************************************************/ - -NTSTATUS 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; - } - - pdb_free_sam_contents(user); - - pdb_fill_default_sam(user); - - return NT_STATUS_OK; -} - - -/************************************************************ - Free the SAM_ACCOUNT and the member pointers. - ***********************************************************/ - -NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) -{ - 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; - } - - pdb_free_sam_contents(*user); - - if ((*user)->free_fn) { - (*user)->free_fn(user); - } - - return NT_STATUS_OK; -} - - -/********************************************************** - Encode the account control bits into a string. - length = length of string to encode into (including terminating - null). length *MUST BE MORE THAN 2* ! - **********************************************************/ - -char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length) -{ - static fstring acct_str; - size_t i = 0; - - acct_str[i++] = '['; - - if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; - if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D'; - if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H'; - if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T'; - if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U'; - if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M'; - if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W'; - if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S'; - if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L'; - if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X'; - if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I'; - - for ( ; i < length - 2 ; i++ ) - acct_str[i] = ' '; - - i = length - 2; - acct_str[i++] = ']'; - acct_str[i++] = '\0'; - - return acct_str; -} - -/********************************************************** - Decode the account control bits from a string. - **********************************************************/ - -uint16 pdb_decode_acct_ctrl(const char *p) -{ - uint16 acct_ctrl = 0; - BOOL finished = False; - - /* - * Check if the account type bits have been encoded after the - * NT password (in the form [NDHTUWSLXI]). - */ - - if (*p != '[') - return 0; - - for (p++; *p && !finished; p++) { - switch (*p) { - case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } - case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } - case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ } - case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ } - case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ } - case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ } - case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ } - case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } - case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } - case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } - case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } - case ' ': { break; } - case ':': - case '\n': - case '\0': - case ']': - default: { finished = True; } - } - } - - return acct_ctrl; -} - -/************************************************************* - Routine to set 32 hex password characters from a 16 byte array. -**************************************************************/ - -void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl) -{ - if (pwd != NULL) { - int i; - for (i = 0; i < 16; i++) - slprintf(&p[i*2], 3, "%02X", pwd[i]); - } else { - if (acct_ctrl & ACB_PWNOTREQ) - safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33); - else - safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33); - } -} - -/************************************************************* - Routine to get the 32 hex characters and turn them - into a 16 byte array. -**************************************************************/ - -BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) -{ - int i; - unsigned char lonybble, hinybble; - const char *hexchars = "0123456789ABCDEF"; - char *p1, *p2; - - if (!p) - return (False); - - for (i = 0; i < 32; i += 2) { - hinybble = toupper(p[i]); - lonybble = toupper(p[i + 1]); - - p1 = strchr(hexchars, hinybble); - p2 = strchr(hexchars, lonybble); - - if (!p1 || !p2) - return (False); - - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - pwd[i / 2] = (hinybble << 4) | lonybble; - } - return (True); -} - -/******************************************************************* - Converts NT user RID to a UNIX uid. - ********************************************************************/ - -static int algorithmic_rid_base(void) -{ - static int rid_offset = 0; - - if (rid_offset != 0) - return rid_offset; - - rid_offset = lp_algorithmic_rid_base(); - - 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; - } - return rid_offset; -} - - -uid_t fallback_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); -} - - -/******************************************************************* - converts UNIX uid to an NT User RID. - ********************************************************************/ - -uint32 fallback_pdb_uid_to_user_rid(uid_t uid) -{ - int rid_offset = algorithmic_rid_base(); - return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE); -} - -/******************************************************************* - Converts NT group RID to a UNIX gid. - ********************************************************************/ - -gid_t pdb_group_rid_to_gid(uint32 group_rid) -{ - int rid_offset = algorithmic_rid_base(); - return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER); -} - -/******************************************************************* - 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); -} - -/******************************************************************* - Decides if a RID is a well known RID. - ********************************************************************/ - -static BOOL pdb_rid_is_well_known(uint32 rid) -{ - /* Not using rid_offset here, becouse this is the actual - NT fixed value (1000) */ - - return (rid < BASE_RID); -} - -/******************************************************************* - Decides if a RID is a user or group 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 - * and DOMAIN_USER_RID_GUEST. - */ - if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST) - return True; - } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) { - return True; - } - return False; -} - -/******************************************************************* - Convert a rid into a name. Used in the lookup SID rpc. - ********************************************************************/ - -BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use) -{ - uint32 rid; - SAM_ACCOUNT *sam_account = NULL; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("local_lookup_sid"); - if (!mem_ctx) { - DEBUG(0,("local_sid_to_gid: No memory\n")); - return False; - } - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){ - return False; - } - talloc_destroy(mem_ctx); - *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; - if(!next_token(&p, name, NULL, sizeof(fstring))) - fstrcpy(name, "Administrator"); - } else { - fstrcpy(name, "Administrator"); - } - return True; - } - - /* - * Don't try to convert the rid to a name if - * running in appliance mode - */ - - if (lp_hide_local_users()) - return False; - - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { - return False; - } - - /* This now does the 'generic' mapping in pdb_unix */ - /* 'guest' is also handled there */ - if (pdb_getsampwsid(sam_account, sid)) { - fstrcpy(name, pdb_get_username(sam_account)); - *psid_name_use = SID_NAME_USER; - - pdb_free_sam(&sam_account); - - return True; - } - - pdb_free_sam(&sam_account); - - if (pdb_rid_is_user(rid)) { - uid_t uid; - - DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid)); - - uid = fallback_pdb_user_rid_to_uid(rid); - slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid); - - return False; /* Indicates that this user was 'not mapped' */ - } 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); - - *psid_name_use = SID_NAME_ALIAS; - - DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid, - gr ? "succeeded" : "failed" )); - - if(!gr) { - slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid); - return False; /* Indicates that this group was 'not mapped' */ - } - - fstrcpy( name, gr->gr_name); - - DEBUG(5,("local_lookup_sid: 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) -{ - extern DOM_SID global_sid_World_Domain; - DOM_SID local_sid; - fstring user; - SAM_ACCOUNT *sam_account = NULL; - struct group *grp; - - *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. - */ - - fstrcpy(user, c_user); - - sid_copy(&local_sid, get_global_sam_sid()); - - /* - * Special case for MACHINE\Everyone. Map to the world_sid. - */ - - if(strequal(user, "Everyone")) { - sid_copy( psid, &global_sid_World_Domain); - sid_append_rid(psid, 0); - *psid_name_use = SID_NAME_ALIAS; - return True; - } - - /* - * Don't lookup local unix users if running in appliance mode - */ - if (lp_hide_local_users()) - return False; - - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) { - return False; - } - - if (pdb_getsampwnam(sam_account, user)) { - 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 ? - */ - - { - /* it's not a mapped group */ - grp = getgrnam(user); - if(!grp) - 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 - */ - - sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); - *psid_name_use = SID_NAME_ALIAS; - } - - sid_copy( psid, &local_sid); - - return True; -} - - -/************************************************************* - Change a password entry in the local smbpasswd file. - -It is currently being called by SWAT and by smbpasswd. - - --jerry - *************************************************************/ - -BOOL local_password_change(const char *user_name, int local_flags, - const char *new_passwd, - 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'; - - /* Get the smb passwd entry for this user */ - pdb_init_sam(&sam_pass); - if(!pdb_getsampwnam(sam_pass, user_name)) { - pdb_free_sam(&sam_pass); - - if (local_flags & LOCAL_ADD_USER) { - pwd = getpwnam_alloc(user_name); - } else if (local_flags & LOCAL_DELETE_USER) { - /* Might not exist in /etc/passwd */ - } else { - slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name); - return False; - } - - if (pwd) { - /* Local user found, so init from this */ - if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){ - slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name); - passwd_free(&pwd); - return False; - } - - passwd_free(&pwd); - } else { - if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_pass))){ - slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name); - return False; - } - - if (!pdb_set_username(sam_pass, user_name, PDB_CHANGED)) { - slprintf(err_str, err_str_len - 1, "Failed to set username for user %s.\n", user_name); - pdb_free_sam(&sam_pass); - return False; - } - } - } else { - /* 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); - 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; - } - } 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); - return False; - } - } - - /* - * We are root - just write the new password - * 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; - } - } 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); - 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); - return False; - } - } else if (local_flags & LOCAL_SET_PASSWORD) { - /* - * If we're dealing with setting a completely empty user account - * ie. One with a password of 'XXXX', but not set disabled (like - * an account created from scratch) then if the old password was - * 'XX's then getsmbpwent will have set the ACB_DISABLED flag. - * We remove that as we're giving this user their first password - * 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_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; - } - } - - 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); - } - - pdb_free_sam(&sam_pass); - return True; -} diff --git a/source4/passdb/passdb.h b/source4/passdb/passdb.h deleted file mode 100644 index 7b7f221065..0000000000 --- a/source4/passdb/passdb.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Unix SMB/CIFS implementation. - passdb structures and parameters - Copyright (C) Gerald Carter 2001 - Copyright (C) Luke Kenneth Casson Leighton 1998 - 2000 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _SAMBA_PASSDB_H -#define _SAMBA_PASSDB_H - -/* - * This next constant specifies the version number of the PASSDB interface - * this SAMBA will load. Increment this with a comment if *ANY* changes are made - * to the interface and maybe update struct auth_critical_sizes - */ -/* version 2 - init versioning of the interface - metze */ -/* version 3 - value states of SAM_ACCOUNT entries - metze */ -/* version 4 - add group mapping api - vlendec */ -#define PASSDB_INTERFACE_VERSION 4 - -typedef struct pdb_context -{ - struct pdb_methods *pdb_methods; - struct pdb_methods *pwent_methods; - - /* These functions are wrappers for the functions listed above. - They may do extra things like re-reading a SAM_ACCOUNT on update */ - - NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update); - - void (*pdb_endsampwent)(struct pdb_context *); - - NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user); - - NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username); - - NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid); - - NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - - NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - - NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); - - NTSTATUS (*pdb_delete_group_mapping_entry)(struct pdb_context *context, - DOM_SID sid); - - void (*free_fn)(struct pdb_context **); - - TALLOC_CTX *mem_ctx; - -} PDB_CONTEXT; - -typedef struct pdb_methods -{ - const char *name; /* What name got this module */ - struct pdb_context *parent; - - /* Use macros from dlinklist.h on these two */ - struct pdb_methods *next; - struct pdb_methods *prev; - - NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update); - - void (*endsampwent)(struct pdb_methods *); - - NTSTATUS (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user); - - NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username); - - NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid); - - NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); - - NTSTATUS (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); - - NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username); - - NTSTATUS (*delete_group_mapping_entry)(struct pdb_methods *methods, - DOM_SID sid); - - void *private_data; /* Private data of some kind */ - - void (*free_private_data)(void **); - -} PDB_METHODS; - -struct passdb_ops { - /* the name of the backend */ - const char *name; - - /* Function to create a member of the pdb_methods list */ - NTSTATUS (*init)(struct pdb_context *, struct pdb_methods **, const char *); -}; - -/* this structure is used by modules to determine the size of some critical types */ -struct passdb_critical_sizes { - int interface_version; - int sizeof_passdb_ops; - int sizeof_pdb_methods; - int sizeof_pdb_context; - int sizeof_SAM_ACCOUNT; -}; - -#endif /* _SAMBA_PASSDB_H */ diff --git a/source4/passdb/pdb_compat.c b/source4/passdb/pdb_compat.c deleted file mode 100644 index 0bd003f1e9..0000000000 --- a/source4/passdb/pdb_compat.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SAM_ACCOUNT access routines - 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) Stefan (metze) Metzmacher 2002 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass) -{ - uint32 u_rid; - - if (sampass) - if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_user_sid(sampass),&u_rid)) - return u_rid; - - return (0); -} - -uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass) -{ - uint32 g_rid; - - if (sampass) - if (sid_peek_check_rid(get_global_sam_sid(), pdb_get_group_sid(sampass),&g_rid)) - return g_rid; - return (0); -} - -BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid, enum pdb_value_state flag) -{ - DOM_SID u_sid; - const DOM_SID *global_sam_sid; - TALLOC_CTX *mem_ctx; - - if (!sampass) - return False; - - if (!(global_sam_sid = get_global_sam_sid())) { - DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n")); - return False; - } - - sid_copy(&u_sid, global_sam_sid); - - if (!sid_append_rid(&u_sid, rid)) - return False; - - if (!pdb_set_user_sid(sampass, &u_sid, flag)) - return False; - mem_ctx = talloc_init("pdb_set_user_sid_from_rid"); - if (!mem_ctx) { - DEBUG(1, ("pdb_set_user_sid_from_rid: No memory\n")); - return False; - } - DEBUG(10, ("pdb_set_user_sid_from_rid:\n\tsetting user sid %s from rid %d\n", - sid_string_talloc(mem_ctx, &u_sid),rid)); - talloc_destroy(mem_ctx); - return True; -} - -BOOL pdb_set_group_sid_from_rid (SAM_ACCOUNT *sampass, uint32 grid, enum pdb_value_state flag) -{ - DOM_SID g_sid; - const DOM_SID *global_sam_sid; - TALLOC_CTX *mem_ctx; - - if (!sampass) - return False; - - if (!(global_sam_sid = get_global_sam_sid())) { - DEBUG(1, ("pdb_set_user_sid_from_rid: Could not read global sam sid!\n")); - return False; - } - - sid_copy(&g_sid, global_sam_sid); - - if (!sid_append_rid(&g_sid, grid)) - return False; - - if (!pdb_set_group_sid(sampass, &g_sid, flag)) - return False; - - mem_ctx = talloc_init("pdb_set_user_sid_from_rid"); - if (!mem_ctx) { - DEBUG(1, ("pdb_set_user_sid_from_rid: No memory\n")); - return False; - } - DEBUG(10, ("pdb_set_group_sid_from_rid:\n\tsetting group sid %s from rid %d\n", - sid_string_talloc(mem_ctx, &g_sid), grid)); - talloc_destroy(mem_ctx); - return True; -} - diff --git a/source4/passdb/pdb_get_set.c b/source4/passdb/pdb_get_set.c deleted file mode 100644 index 27aa5923e4..0000000000 --- a/source4/passdb/pdb_get_set.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SAM_ACCOUNT access routines - 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) Stefan (metze) Metzmacher 2002 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -/** - * @todo Redefine this to NULL, but this changes the API becouse - * much of samba assumes that the pdb_get...() funtions - * return pstrings. (ie not null-pointers). - * See also pdb_fill_default_sam(). - */ - -#define PDB_NOT_QUITE_NULL "" - -/********************************************************************* - Collection of get...() functions for SAM_ACCOUNT. - ********************************************************************/ - -uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.acct_ctrl); - else - return (ACB_DISABLED); -} - -time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.logon_time); - else - return (0); -} - -time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.logoff_time); - else - return (-1); -} - -time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.kickoff_time); - else - return (-1); -} - -time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.pass_last_set_time); - else - return (-1); -} - -time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.pass_can_change_time); - else - return (-1); -} - -time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.pass_must_change_time); - else - return (-1); -} - -uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.logon_divs); - else - return (-1); -} - -uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.hours_len); - else - return (-1); -} - -const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.hours); - else - return (NULL); -} - -const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass) -{ - if (sampass) { - SMB_ASSERT((!sampass->private.nt_pw.data) - || sampass->private.nt_pw.length == NT_HASH_LEN); - return ((uint8*)sampass->private.nt_pw.data); - } - else - return (NULL); -} - -const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) -{ - if (sampass) { - SMB_ASSERT((!sampass->private.lm_pw.data) - || sampass->private.lm_pw.length == LM_HASH_LEN); - return ((uint8*)sampass->private.lm_pw.data); - } - else - return (NULL); -} - -/* Return the plaintext password if known. Most of the time - it isn't, so don't assume anything magic about this function. - - Used to pass the plaintext to passdb backends that might - want to store more than just the NTLM hashes. -*/ -const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) -{ - if (sampass) { - return (sampass->private.plaintext_pw); - } - else - return (NULL); -} -const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass) -{ - if (sampass) - return &sampass->private.user_sid; - else - return (NULL); -} - -const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass) -{ - if (sampass) - return &sampass->private.group_sid; - else - return (NULL); -} - -/** - * Get flags showing what is initalised in the SAM_ACCOUNT - * @param sampass the SAM_ACCOUNT in question - * @return the flags indicating the members initialised in the struct. - **/ - -enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element) -{ - enum pdb_value_state ret = PDB_DEFAULT; - - if (!sampass || !sampass->private.change_flags || !sampass->private.set_flags) - return ret; - - if (bitmap_query(sampass->private.set_flags, element)) { - DEBUG(10, ("element %d: SET\n", element)); - ret = PDB_SET; - } - - if (bitmap_query(sampass->private.change_flags, element)) { - DEBUG(10, ("element %d: CHANGED\n", element)); - ret = PDB_CHANGED; - } - - if (ret == PDB_DEFAULT) { - DEBUG(10, ("element %d: DEFAULT\n", element)); - } - - return ret; -} - -uid_t pdb_get_uid (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.uid); - else - return (-1); -} - -gid_t pdb_get_gid (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.gid); - else - return (-1); -} - -const char* pdb_get_username (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.username); - else - return (NULL); -} - -const char* pdb_get_domain (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.domain); - else - return (NULL); -} - -const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.nt_username); - else - return (NULL); -} - -const char* pdb_get_fullname (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.full_name); - else - return (NULL); -} - -const char* pdb_get_homedir (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.home_dir); - else - return (NULL); -} - -const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unix_home_dir); - else - return (NULL); -} - -const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.dir_drive); - else - return (NULL); -} - -const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.logon_script); - else - return (NULL); -} - -const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.profile_path); - else - return (NULL); -} - -const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.acct_desc); - else - return (NULL); -} - -const char* pdb_get_workstations (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.workstations); - else - return (NULL); -} - -const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unknown_str); - else - return (NULL); -} - -const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.munged_dial); - else - return (NULL); -} - -uint32 pdb_get_unknown_3 (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unknown_3); - else - return (-1); -} - -uint32 pdb_get_unknown_5 (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unknown_5); - else - return (-1); -} - -uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass) -{ - if (sampass) - return (sampass->private.unknown_6); - else - return (-1); -} - -/********************************************************************* - Collection of set...() functions for SAM_ACCOUNT. - ********************************************************************/ - -BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.acct_ctrl = acct_ctrl; - - return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag); -} - -BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.logon_time = mytime; - - return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag); -} - -BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.logoff_time = mytime; - - return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag); -} - -BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.kickoff_time = mytime; - - return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag); -} - -BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.pass_can_change_time = mytime; - - return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag); -} - -BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.pass_must_change_time = mytime; - - return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag); -} - -BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.pass_last_set_time = mytime; - - return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag); -} - -BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.hours_len = len; - - return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag); -} - -BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.logon_divs = hours; - - return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag); -} - -/** - * Set flags showing what is initalised in the SAM_ACCOUNT - * @param sampass the SAM_ACCOUNT in question - * @param flag The *new* flag to be set. Old flags preserved - * this flag is only added. - **/ - -BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag) -{ - if (!sampass || !sampass->mem_ctx) - return False; - - if (!sampass->private.set_flags) { - if ((sampass->private.set_flags = - bitmap_talloc(sampass->mem_ctx, - PDB_COUNT))==NULL) { - DEBUG(0,("bitmap_talloc failed\n")); - return False; - } - } - if (!sampass->private.change_flags) { - if ((sampass->private.change_flags = - bitmap_talloc(sampass->mem_ctx, - PDB_COUNT))==NULL) { - DEBUG(0,("bitmap_talloc failed\n")); - return False; - } - } - - switch(value_flag) { - case PDB_CHANGED: - if (!bitmap_set(sampass->private.change_flags, element)) { - DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); - return False; - } - if (!bitmap_set(sampass->private.set_flags, element)) { - DEBUG(0,("Can't set flag: %d in set_falgs.\n",element)); - return False; - } - DEBUG(10, ("element %d -> now CHANGED\n", element)); - break; - case PDB_SET: - if (!bitmap_clear(sampass->private.change_flags, element)) { - DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); - return False; - } - if (!bitmap_set(sampass->private.set_flags, element)) { - DEBUG(0,("Can't set flag: %d in set_falgs.\n",element)); - return False; - } - DEBUG(10, ("element %d -> now SET\n", element)); - break; - case PDB_DEFAULT: - default: - if (!bitmap_clear(sampass->private.change_flags, element)) { - DEBUG(0,("Can't set flag: %d in change_flags.\n",element)); - return False; - } - if (!bitmap_clear(sampass->private.set_flags, element)) { - DEBUG(0,("Can't set flag: %d in set_falgs.\n",element)); - return False; - } - DEBUG(10, ("element %d -> now DEFAULT\n", element)); - break; - } - - return True; -} - -BOOL pdb_set_uid (SAM_ACCOUNT *sampass, const uid_t uid, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - DEBUG(10, ("pdb_set_uid: setting uid %d, was %d\n", - (int)uid, (int)sampass->private.uid)); - - sampass->private.uid = uid; - - return pdb_set_init_flags(sampass, PDB_UID, flag); -} - -BOOL pdb_set_gid (SAM_ACCOUNT *sampass, const gid_t gid, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - DEBUG(10, ("pdb_set_gid: setting gid %d, was %d\n", - (int)gid, (int)sampass->private.gid)); - - sampass->private.gid = gid; - - return pdb_set_init_flags(sampass, PDB_GID, flag); -} - -BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid, enum pdb_value_state flag) -{ - TALLOC_CTX *mem_ctx; - if (!sampass || !u_sid) - return False; - - sid_copy(&sampass->private.user_sid, u_sid); - - mem_ctx = talloc_init("pdb_set_group_sid"); - if (!mem_ctx) return False; - DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", - sid_string_talloc(mem_ctx, &sampass->private.user_sid))); - - talloc_destroy(mem_ctx); - return pdb_set_init_flags(sampass, PDB_USERSID, flag); -} - -BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag) -{ - DOM_SID new_sid; - - if (!sampass || !u_sid) - return False; - - DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n", - u_sid)); - - if (!string_to_sid(&new_sid, u_sid)) { - DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid)); - return False; - } - - if (!pdb_set_user_sid(sampass, &new_sid, flag)) { - DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid)); - return False; - } - - return True; -} - -BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, DOM_SID *g_sid, enum pdb_value_state flag) -{ - TALLOC_CTX *mem_ctx; - if (!sampass || !g_sid) - return False; - - sid_copy(&sampass->private.group_sid, g_sid); - - mem_ctx = talloc_init("pdb_set_group_sid"); - if (!mem_ctx) return False; - DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", - sid_string_talloc(mem_ctx, &sampass->private.group_sid))); - talloc_destroy(mem_ctx); - return pdb_set_init_flags(sampass, PDB_GROUPSID, flag); -} - -BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag) -{ - DOM_SID new_sid; - if (!sampass || !g_sid) - return False; - - DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n", - g_sid)); - - if (!string_to_sid(&new_sid, g_sid)) { - DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid)); - return False; - } - - if (!pdb_set_group_sid(sampass, &new_sid, flag)) { - DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid)); - return False; - } - return True; -} - -/********************************************************************* - Set the user's UNIX name. - ********************************************************************/ - -BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (username) { - DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username, - (sampass->private.username)?(sampass->private.username):"NULL")); - - sampass->private.username = talloc_strdup(sampass->mem_ctx, username); - - if (!sampass->private.username) { - DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.username = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_USERNAME, flag); -} - -/********************************************************************* - Set the domain name. - ********************************************************************/ - -BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (domain) { - DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain, - (sampass->private.domain)?(sampass->private.domain):"NULL")); - - sampass->private.domain = talloc_strdup(sampass->mem_ctx, domain); - - if (!sampass->private.domain) { - DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.domain = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_DOMAIN, flag); -} - -/********************************************************************* - Set the user's NT name. - ********************************************************************/ - -BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (nt_username) { - DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username, - (sampass->private.nt_username)?(sampass->private.nt_username):"NULL")); - - sampass->private.nt_username = talloc_strdup(sampass->mem_ctx, nt_username); - - if (!sampass->private.nt_username) { - DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.nt_username = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag); -} - -/********************************************************************* - Set the user's full name. - ********************************************************************/ - -BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (full_name) { - DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name, - (sampass->private.full_name)?(sampass->private.full_name):"NULL")); - - sampass->private.full_name = talloc_strdup(sampass->mem_ctx, full_name); - - if (!sampass->private.full_name) { - DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.full_name = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_FULLNAME, flag); -} - -/********************************************************************* - Set the user's logon script. - ********************************************************************/ - -BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (logon_script) { - DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script, - (sampass->private.logon_script)?(sampass->private.logon_script):"NULL")); - - sampass->private.logon_script = talloc_strdup(sampass->mem_ctx, logon_script); - - if (!sampass->private.logon_script) { - DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.logon_script = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag); -} - -/********************************************************************* - Set the user's profile path. - ********************************************************************/ - -BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (profile_path) { - DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path, - (sampass->private.profile_path)?(sampass->private.profile_path):"NULL")); - - sampass->private.profile_path = talloc_strdup(sampass->mem_ctx, profile_path); - - if (!sampass->private.profile_path) { - DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.profile_path = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_PROFILE, flag); -} - -/********************************************************************* - Set the user's directory drive. - ********************************************************************/ - -BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (dir_drive) { - DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive, - (sampass->private.dir_drive)?(sampass->private.dir_drive):"NULL")); - - sampass->private.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive); - - if (!sampass->private.dir_drive) { - DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.dir_drive = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_DRIVE, flag); -} - -/********************************************************************* - Set the user's home directory. - ********************************************************************/ - -BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (home_dir) { - DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir, - (sampass->private.home_dir)?(sampass->private.home_dir):"NULL")); - - sampass->private.home_dir = talloc_strdup(sampass->mem_ctx, home_dir); - - if (!sampass->private.home_dir) { - DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.home_dir = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_SMBHOME, flag); -} - -/********************************************************************* - Set the user's unix home directory. - ********************************************************************/ - -BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (unix_home_dir) { - DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir, - (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL")); - - sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx, - unix_home_dir); - - if (!sampass->private.unix_home_dir) { - DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag); -} - -/********************************************************************* - Set the user's account description. - ********************************************************************/ - -BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (acct_desc) { - sampass->private.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc); - - if (!sampass->private.acct_desc) { - DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.acct_desc = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag); -} - -/********************************************************************* - Set the user's workstation allowed list. - ********************************************************************/ - -BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (workstations) { - DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations, - (sampass->private.workstations)?(sampass->private.workstations):"NULL")); - - sampass->private.workstations = talloc_strdup(sampass->mem_ctx, workstations); - - if (!sampass->private.workstations) { - DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.workstations = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag); -} - -/********************************************************************* - Set the user's 'unknown_str', whatever the heck this actually is... - ********************************************************************/ - -BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (unknown_str) { - sampass->private.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str); - - if (!sampass->private.unknown_str) { - DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.unknown_str = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag); -} - -/********************************************************************* - Set the user's dial string. - ********************************************************************/ - -BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (munged_dial) { - sampass->private.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial); - - if (!sampass->private.munged_dial) { - DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.munged_dial = PDB_NOT_QUITE_NULL; - } - - return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag); -} - -/********************************************************************* - Set the user's NT hash. - ********************************************************************/ - -BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag) -{ - if (!sampass) - return False; - - data_blob_clear_free(&sampass->private.nt_pw); - - sampass->private.nt_pw = data_blob(pwd, NT_HASH_LEN); - - return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag); -} - -/********************************************************************* - Set the user's LM hash. - ********************************************************************/ - -BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag) -{ - if (!sampass) - return False; - - data_blob_clear_free(&sampass->private.lm_pw); - - sampass->private.lm_pw = data_blob(pwd, LM_HASH_LEN); - - return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag); -} - -/********************************************************************* - Set the user's plaintext password only (base procedure, see helper - below) - ********************************************************************/ - -BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (password) { - if (sampass->private.plaintext_pw!=NULL) - memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1); - - sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); - - if (!sampass->private.plaintext_pw) { - DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); - return False; - } - - } else { - sampass->private.plaintext_pw = NULL; - } - - return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag); -} - -BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.unknown_3 = unkn; - - return pdb_set_init_flags(sampass, PDB_UNKNOWN3, flag); -} - -BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.unknown_5 = unkn; - - return pdb_set_init_flags(sampass, PDB_UNKNOWN5, flag); -} - -BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - sampass->private.unknown_6 = unkn; - - return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag); -} - -BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag) -{ - if (!sampass) - return False; - - if (!hours) { - memset ((char *)sampass->private.hours, 0, MAX_HOURS_LEN); - return True; - } - - memcpy (sampass->private.hours, hours, MAX_HOURS_LEN); - - return pdb_set_init_flags(sampass, PDB_HOURS, flag); -} - - -/* Helpful interfaces to the above */ - -/********************************************************************* - Sets the last changed times and must change times for a normal - password change. - ********************************************************************/ - -BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass) -{ - uint32 expire; - - if (!sampass) - return False; - - if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) - return False; - - if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) - || (expire==(uint32)-1)) { - if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED)) - return False; - } else { - if (!pdb_set_pass_must_change_time (sampass, - pdb_get_pass_last_set_time(sampass) - + expire, PDB_CHANGED)) - return False; - } - - return True; -} - -/********************************************************************* - Set the user's PLAINTEXT password. Used as an interface to the above. - Also sets the last change time to NOW. - ********************************************************************/ - -BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) -{ - uchar new_lanman_p16[16]; - uchar new_nt_p16[16]; - - if (!sampass || !plaintext) - return False; - - nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16); - - if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) - return False; - - if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) - return False; - - if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) - return False; - - if (!pdb_set_pass_changed_now (sampass)) - return False; - - return True; -} diff --git a/source4/passdb/pdb_guest.c b/source4/passdb/pdb_guest.c deleted file mode 100644 index 036ff8d46b..0000000000 --- a/source4/passdb/pdb_guest.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 'Guest' password backend for samba - * Copyright (C) Jelmer Vernooij 2002 - * Copyright (C) Andrew Bartlett 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/****************************************************************** - Lookup a name in the SAM database - ******************************************************************/ - -static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) -{ - NTSTATUS nt_status; - struct passwd *pass; - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!methods) { - DEBUG(0,("invalid methods\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (!sname) { - DEBUG(0,("invalid name specified")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!strequal(guest_account, sname)) { - return NT_STATUS_NO_SUCH_USER; - } - - pass = getpwnam_alloc(guest_account); - - nt_status = pdb_fill_sam_pw(user, pass); - - passwd_free(&pass); - return nt_status; -} - - -/*************************************************************************** - Search by rid - **************************************************************************/ - -static NTSTATUS guestsam_getsampwrid (struct pdb_methods *methods, - SAM_ACCOUNT *user, uint32 rid) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct passwd *pass = NULL; - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return nt_status; - } - - if (!methods) { - DEBUG(0,("invalid methods\n")); - return nt_status; - } - - if (rid == DOMAIN_USER_RID_GUEST) { - pass = getpwnam_alloc(guest_account); - if (!pass) { - DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account)); - return NT_STATUS_NO_SUCH_USER; - } - } else { - return NT_STATUS_NO_SUCH_USER; - } - - nt_status = pdb_fill_sam_pw(user, pass); - passwd_free(&pass); - - return nt_status; -} - -static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_NO_SUCH_USER; - return guestsam_getsampwrid(my_methods, user, rid); -} - -static NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - - if (!pdb_context) { - DEBUG(0, ("invalid pdb_context specified\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "guestsam"; - - (*pdb_method)->getsampwnam = guestsam_getsampwnam; - (*pdb_method)->getsampwsid = guestsam_getsampwsid; - - /* There's not very much to initialise here */ - return NT_STATUS_OK; -} - -NTSTATUS passdb_guest_init(void) -{ - NTSTATUS ret; - struct passdb_ops ops; - - ZERO_STRUCT(ops); - - /* fill in our name */ - ops.name = "guestsam"; - /* fill in all the operations */ - ops.init = pdb_init_guestsam; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - /* fill in our name */ - ops.name = "guest"; - /* fill in all the operations */ - ops.init = pdb_init_guestsam; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/passdb/pdb_interface.c b/source4/passdb/pdb_interface.c deleted file mode 100644 index ecdd7b6486..0000000000 --- a/source4/passdb/pdb_interface.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -/* the list of currently registered AUTH backends */ -static struct { - const struct passdb_ops *ops; -} *backends = NULL; -static int num_backends; - -/* - register a AUTH backend. - - The 'name' can be later used by other backends to find the operations - structure for this backend. -*/ -static NTSTATUS passdb_register(void *_ops) -{ - const struct passdb_ops *ops = _ops; - struct passdb_ops *new_ops; - - if (passdb_backend_byname(ops->name) != NULL) { - /* its already registered! */ - DEBUG(0,("PASSDB backend '%s' already registered\n", - ops->name)); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); - if (!backends) { - smb_panic("out of memory in passdb_register"); - } - - new_ops = smb_xmemdup(ops, sizeof(*ops)); - new_ops->name = smb_xstrdup(ops->name); - - backends[num_backends].ops = new_ops; - - num_backends++; - - DEBUG(3,("PASSDB backend '%s' registered\n", - ops->name)); - - return NT_STATUS_OK; -} - -/* - return the operations structure for a named backend of the specified type -*/ -const struct passdb_ops *passdb_backend_byname(const char *name) -{ - int i; - - for (i=0;i<num_backends;i++) { - if (strcmp(backends[i].ops->name, name) == 0) { - return backends[i].ops; - } - } - - return NULL; -} - -/* - return the PASSDB interface version, and the size of some critical types - This can be used by backends to either detect compilation errors, or provide - multiple implementations for different smbd compilation options in one module -*/ -const struct passdb_critical_sizes *passdb_interface_version(void) -{ - static const struct passdb_critical_sizes critical_sizes = { - PASSDB_INTERFACE_VERSION, - sizeof(struct passdb_ops), - sizeof(struct pdb_methods), - sizeof(struct pdb_context), - sizeof(SAM_ACCOUNT) - }; - - return &critical_sizes; -} - -/* - initialise the PASSDB subsystem -*/ -BOOL passdb_init(void) -{ - NTSTATUS status; - - status = register_subsystem("passdb", passdb_register); - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - /* FIXME: Perhaps panic if a basic backend, such as SAM, fails to initialise? */ - static_init_passdb; - - DEBUG(3,("PASSDB subsystem version %d initialised\n", PASSDB_INTERFACE_VERSION)); - return True; -} - -static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if (!context) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - - context->pwent_methods = context->pdb_methods; - - if (!context->pwent_methods) { - /* No passdbs at all */ - return ret; - } - - while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) { - context->pwent_methods = context->pwent_methods->next; - if (context->pwent_methods == NULL) - return NT_STATUS_UNSUCCESSFUL; - } - return ret; -} - -static void context_endsampwent(struct pdb_context *context) -{ - if ((!context)){ - DEBUG(0, ("invalid pdb_context specified!\n")); - return; - } - - if (context->pwent_methods && context->pwent_methods->endsampwent) - context->pwent_methods->endsampwent(context->pwent_methods); - - /* So we won't get strange data when calling getsampwent now */ - context->pwent_methods = NULL; -} - -static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if ((!context) || (!context->pwent_methods)) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - /* Loop until we find something useful */ - while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) { - - context->pwent_methods->endsampwent(context->pwent_methods); - - context->pwent_methods = context->pwent_methods->next; - - /* All methods are checked now. There are no more entries */ - if (context->pwent_methods == NULL) - return ret; - - context->pwent_methods->setsampwent(context->pwent_methods, False); - } - user->methods = context->pwent_methods; - return ret; -} - -static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - struct pdb_methods *curmethods; - if ((!context)) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - curmethods = context->pdb_methods; - while (curmethods){ - if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) { - sam_acct->methods = curmethods; - return ret; - } - curmethods = curmethods->next; - } - - return ret; -} - -static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - struct pdb_methods *curmethods; - if ((!context)) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - - curmethods = context->pdb_methods; - - while (curmethods){ - if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) { - sam_acct->methods = curmethods; - return ret; - } - curmethods = curmethods->next; - } - - return ret; -} - -static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if ((!context) || (!context->pdb_methods)) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - - /** @todo This is where a 're-read on add' should be done */ - /* We now add a new account to the first database listed. - * Should we? */ - - return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct); -} - -static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - if (!context) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - - if (!sam_acct || !sam_acct->methods){ - DEBUG(0, ("invalid sam_acct specified\n")); - return ret; - } - - /** @todo This is where a 're-read on update' should be done */ - - return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct); -} - -static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - - struct pdb_methods *pdb_selected; - if (!context) { - DEBUG(0, ("invalid pdb_context specified!\n")); - return ret; - } - - if (!sam_acct->methods){ - pdb_selected = context->pdb_methods; - /* There's no passdb backend specified for this account. - * Try to delete it in every passdb available - * Needed to delete accounts in smbpasswd that are not - * in /etc/passwd. - */ - while (pdb_selected){ - if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) { - return ret; - } - pdb_selected = pdb_selected->next; - } - return ret; - } - - if (!sam_acct->methods->delete_sam_account){ - DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n")); - return ret; - } - - return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct); -} - -/****************************************************************** - Free and cleanup a pdb context, any associated data and anything - that the attached modules might have associated. - *******************************************************************/ - -static void free_pdb_context(struct pdb_context **context) -{ - struct pdb_methods *pdb_selected = (*context)->pdb_methods; - - while (pdb_selected){ - if(pdb_selected->free_private_data) - pdb_selected->free_private_data(&(pdb_selected->private_data)); - pdb_selected = pdb_selected->next; - } - - talloc_destroy((*context)->mem_ctx); - *context = NULL; -} - -/****************************************************************** - Make a pdb_methods from scratch - *******************************************************************/ - -static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected) -{ - char *module_name = smb_xstrdup(selected); - char *module_param = NULL, *p; - const struct passdb_ops *ops; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - p = strchr(module_name, ':'); - - if (p) { - *p = 0; - module_param = p+1; - trim_string(module_param, " ", " "); - } - - trim_string(module_name, " ", " "); - - - DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name)); - - ops = passdb_backend_byname(module_name); - /* No such backend found */ - if(!ops) { - SAFE_FREE(module_name); - return NT_STATUS_INVALID_PARAMETER; - } - DEBUG(5,("Found PASSDB backend %s\n", module_name)); - nt_status = ops->init(context, methods, module_param); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5,("PASSDB backend %s has a valid init\n", selected)); - } else { - DEBUG(0,("PASSDB backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); - } - SAFE_FREE(module_name); - return nt_status; -} - -/****************************************************************** - Make a pdb_context from scratch. - *******************************************************************/ - -static NTSTATUS make_pdb_context(struct pdb_context **context) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("pdb_context internal allocation context"); - - if (!mem_ctx) { - DEBUG(0, ("make_pdb_context: talloc init failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - *context = talloc(mem_ctx, sizeof(**context)); - if (!*context) { - DEBUG(0, ("make_pdb_context: talloc failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*context); - - (*context)->mem_ctx = mem_ctx; - - (*context)->pdb_setsampwent = context_setsampwent; - (*context)->pdb_endsampwent = context_endsampwent; - (*context)->pdb_getsampwent = context_getsampwent; - (*context)->pdb_getsampwnam = context_getsampwnam; - (*context)->pdb_getsampwsid = context_getsampwsid; - (*context)->pdb_add_sam_account = context_add_sam_account; - (*context)->pdb_update_sam_account = context_update_sam_account; - (*context)->pdb_delete_sam_account = context_delete_sam_account; - - (*context)->free_fn = free_pdb_context; - - return NT_STATUS_OK; -} - - -/****************************************************************** - Make a pdb_context, given an array of strings - *******************************************************************/ - -NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **selected) -{ - int i = 0; - struct pdb_methods *curmethods; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) { - return nt_status; - } - - while (selected[i]){ - /* Try to initialise pdb */ - DEBUG(5,("Trying to load: %s\n", selected[i])); - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) { - DEBUG(1, ("Loading %s failed!\n", selected[i])); - free_pdb_context(context); - return nt_status; - } - curmethods->parent = *context; - DLIST_ADD_END((*context)->pdb_methods, curmethods, struct pdb_methods *); - i++; - } - - return NT_STATUS_OK; -} - -/****************************************************************** - Make a pdb_context, given a text string. - *******************************************************************/ - -NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) -{ - NTSTATUS ret; - char **newsel = str_list_make(selected, NULL); - ret = make_pdb_context_list(context, (const char **)newsel); - str_list_free(&newsel); - return ret; -} - -/****************************************************************** - Return an already initialised pdb_context, to facilitate backward - compatibility (see functions below). -*******************************************************************/ - -static struct pdb_context *pdb_get_static_context(BOOL reload) -{ - static struct pdb_context *pdb_context = NULL; - - if ((pdb_context) && (reload)) { - pdb_context->free_fn(&pdb_context); - if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { - return NULL; - } - } - - if (!pdb_context) { - if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { - return NULL; - } - } - - return pdb_context; -} - -/****************************************************************** - Backward compatibility functions for the original passdb interface -*******************************************************************/ - -BOOL pdb_setsampwent(BOOL update) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update)); -} - -void pdb_endsampwent(void) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return; - } - - pdb_context->pdb_endsampwent(pdb_context); -} - -BOOL pdb_getsampwent(SAM_ACCOUNT *user) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user)); -} - -BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username)); -} - -BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid)); -} - -BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct)); -} - -BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct)); -} - -BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) -{ - struct pdb_context *pdb_context = pdb_get_static_context(False); - - if (!pdb_context) { - return False; - } - - return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct)); -} - -/*************************************************************** - Initialize the static context (at smbd startup etc). - - If uninitialised, context will auto-init on first use. - ***************************************************************/ - -BOOL initialize_password_db(BOOL reload) -{ - return (pdb_get_static_context(reload) != NULL); -} - - -/*************************************************************************** - Default implementations of some functions. - ****************************************************************************/ - -static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) -{ - return NT_STATUS_NO_SUCH_USER; -} - -static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - return NT_STATUS_NO_SUCH_USER; -} - -static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) -{ - DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name)); - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static void pdb_default_endsampwent(struct pdb_methods *methods) -{ - return; /* NT_STATUS_NOT_IMPLEMENTED; */ -} - -NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) -{ - *methods = talloc(mem_ctx, sizeof(struct pdb_methods)); - - if (!*methods) { - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*methods); - - (*methods)->setsampwent = pdb_default_setsampwent; - (*methods)->endsampwent = pdb_default_endsampwent; - (*methods)->getsampwent = pdb_default_getsampwent; - (*methods)->getsampwnam = pdb_default_getsampwnam; - (*methods)->getsampwsid = pdb_default_getsampwsid; - (*methods)->add_sam_account = pdb_default_add_sam_account; - (*methods)->update_sam_account = pdb_default_update_sam_account; - (*methods)->delete_sam_account = pdb_default_delete_sam_account; - - return NT_STATUS_OK; -} diff --git a/source4/passdb/pdb_ldap.c b/source4/passdb/pdb_ldap.c deleted file mode 100644 index d15ead85d2..0000000000 --- a/source4/passdb/pdb_ldap.c +++ /dev/null @@ -1,2098 +0,0 @@ -/* - Unix SMB/CIFS implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Jean François Micouleau 1998 - Copyright (C) Gerald Carter 2001 - Copyright (C) Shahms King 2001 - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Stefan (metze) Metzmacher 2002 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -/* TODO: -* persistent connections: if using NSS LDAP, many connections are made -* however, using only one within Samba would be nice -* -* Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK -* -* Other LDAP based login attributes: accountExpires, etc. -* (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT -* structures don't have fields for some of these attributes) -* -* SSL is done, but can't get the certificate based authentication to work -* against on my test platform (Linux 2.4, OpenLDAP 2.x) -*/ - -/* NOTE: this will NOT work against an Active Directory server -* due to the fact that the two password fields cannot be retrieved -* from a server; recommend using security = domain in this situation -* and/or winbind -*/ - -#include <lber.h> -#include <ldap.h> - -#ifndef SAM_ACCOUNT -#define SAM_ACCOUNT struct sam_passwd -#endif - -struct ldapsam_privates { - - /* Former statics */ - LDAP *ldap_struct; - LDAPMessage *result; - LDAPMessage *entry; - int index; - - time_t last_ping; - /* retrive-once info */ - const char *uri; - - BOOL permit_non_unix_accounts; - - uint32 low_nua_rid; - uint32 high_nua_rid; - - char *bind_dn; - char *bind_secret; -}; - -#define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */ - -static struct ldapsam_privates *static_ldap_state; - -static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state); - -/******************************************************************* - find the ldap password -******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) -{ - char *key = NULL; - size_t size; - - *dn = smb_xstrdup(lp_ldap_admin_dn()); - - if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) { - SAFE_FREE(*dn); - DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n")); - } - - *pw=secrets_fetch(key, &size); - if (!size) { - /* Upgrade 2.2 style entry */ - char *p; - char* old_style_key = strdup(*dn); - char *data; - fstring old_style_pw; - - if (!old_style_key) { - DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n")); - return False; - } - - for (p=old_style_key; *p; p++) - if (*p == ',') *p = '/'; - - data=secrets_fetch(old_style_key, &size); - if (!size && size < sizeof(old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - - strncpy(old_style_pw, data, size); - old_style_pw[size] = 0; - - SAFE_FREE(data); - - if (!secrets_store_ldap_pw(*dn, old_style_pw)) { - DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n")); - SAFE_FREE(old_style_key); - SAFE_FREE(*dn); - return False; - } - if (!secrets_delete(old_style_key)) { - DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n")); - } - - SAFE_FREE(old_style_key); - - *pw = smb_xstrdup(old_style_pw); - } - - return True; -} - -static const char * const attr[] = {"uid", "pwdLastSet", "logonTime", - "logoffTime", "kickoffTime", "cn", - "pwdCanChange", "pwdMustChange", - "displayName", "homeDrive", - "smbHome", "scriptPath", - "profilePath", "description", - "userWorkstations", "rid", - "primaryGroupID", "lmPassword", - "ntPassword", "acctFlags", - "domain", "objectClass", - "uidNumber", "gidNumber", - "homeDirectory", NULL }; - -/******************************************************************* - open a connection to the ldap server. -******************************************************************/ -static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct) -{ - int rc = LDAP_SUCCESS; - int version; - BOOL ldap_v3 = False; - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) - DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri)); - - if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) { - DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc))); - return rc; - } - -#else - - /* Parse the string manually */ - - { - int port = 0; - fstring protocol; - fstring host; - const char *p = ldap_state->uri; - SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254); - - /* skip leading "URL:" (if any) */ - if ( strncasecmp( p, "URL:", 4 ) == 0 ) { - p += 4; - } - - sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port); - - if (port == 0) { - if (strequal(protocol, "ldap")) { - port = LDAP_PORT; - } else if (strequal(protocol, "ldaps")) { - port = LDAPS_PORT; - } else { - DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); - } - } - - if ((*ldap_struct = ldap_init(host, port)) == NULL) { - DEBUG(0, ("ldap_init failed !\n")); - return LDAP_OPERATIONS_ERROR; - } - - if (strequal(protocol, "ldaps")) { -#ifdef LDAP_OPT_X_TLS - int tls = LDAP_OPT_X_TLS_HARD; - if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) - { - DEBUG(0, ("Failed to setup a TLS session\n")); - } - - DEBUG(3,("LDAPS option set...!\n")); -#else - DEBUG(0,("ldapsam_open_connection: Secure connection not supported by LDAP client libraries!\n")); - return LDAP_OPERATIONS_ERROR; -#endif - } - } -#endif - - if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) - { - if (version != LDAP_VERSION3) - { - version = LDAP_VERSION3; - if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - ldap_v3 = True; - } - } else { - ldap_v3 = True; - } - } - - if (lp_ldap_ssl() == LDAP_SSL_START_TLS) { -#ifdef LDAP_OPT_X_TLS - if (ldap_v3) { - if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS) - { - DEBUG(0,("Failed to issue the StartTLS instruction: %s\n", - ldap_err2string(rc))); - return rc; - } - DEBUG (3, ("StartTLS issued: using a TLS connection\n")); - } else { - - DEBUG(0, ("Need LDAPv3 for Start TLS\n")); - return LDAP_OPERATIONS_ERROR; - } -#else - DEBUG(0,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n")); - return LDAP_OPERATIONS_ERROR; -#endif - } - - DEBUG(2, ("ldapsam_open_connection: connection opened\n")); - return rc; -} - - -/******************************************************************* - a rebind function for authenticated referrals - This version takes a void* that we can shove useful stuff in :-) -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#else -static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, - int *methodp, int freeit, void *arg) -{ - struct ldapsam_privates *ldap_state = arg; - - /** @TODO Should we be doing something to check what servers we rebind to? - Could we get a referral to a machine that we don't want to give our - username and password to? */ - - if (freeit) { - SAFE_FREE(*whop); - memset(*credp, '\0', strlen(*credp)); - SAFE_FREE(*credp); - } else { - DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", - ldap_state->bind_dn)); - - *whop = strdup(ldap_state->bind_dn); - if (!*whop) { - return LDAP_NO_MEMORY; - } - *credp = strdup(ldap_state->bind_secret); - if (!*credp) { - SAFE_FREE(*whop); - return LDAP_NO_MEMORY; - } - *methodp = LDAP_AUTH_SIMPLE; - } - return 0; -} -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - a rebind function for authenticated referrals - This version takes a void* that we can shove useful stuff in :-) - and actually does the connection. -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -static int rebindproc_connect_with_state (LDAP *ldap_struct, - LDAP_CONST char *url, - ber_tag_t request, - ber_int_t msgid, void *arg) -{ - struct ldapsam_privates *ldap_state = arg; - int rc; - DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", - ldap_state->bind_dn)); - - /** @TODO Should we be doing something to check what servers we rebind to? - Could we get a referral to a machine that we don't want to give our - username and password to? */ - - rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); - - return rc; -} -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - Add a rebind function for authenticated referrals -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -#else -# if LDAP_SET_REBIND_PROC_ARGS == 2 -static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, - int *method, int freeit ) -{ - return rebindproc_with_state(ldap_struct, whop, credp, - method, freeit, static_ldap_state); - -} -# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - a rebind function for authenticated referrals - this also does the connection, but no void*. -******************************************************************/ -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -# if LDAP_SET_REBIND_PROC_ARGS == 2 -static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, - ber_int_t msgid) -{ - return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, - static_ldap_state); -} -# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - -/******************************************************************* - connect to the ldap server under system privilege. -******************************************************************/ -static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct) -{ - int rc; - char *ldap_dn; - char *ldap_secret; - - /* The rebind proc needs this *HACK*. We are not multithreaded, so - this will work, but it's not nice. */ - static_ldap_state = ldap_state; - - /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) - { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); - return LDAP_INVALID_CREDENTIALS; - } - - ldap_state->bind_dn = ldap_dn; - ldap_state->bind_secret = ldap_secret; - - /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite - (OpenLDAP) doesnt' seem to support it */ - - DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n", - ldap_state->uri, ldap_dn)); - -#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) -# if LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); -# endif -# if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state); -# endif -#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ -# if LDAP_SET_REBIND_PROC_ARGS == 2 - ldap_set_rebind_proc(ldap_struct, &rebindproc); -# endif -# if LDAP_SET_REBIND_PROC_ARGS == 3 - ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state); -# endif -#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ - - rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - - if (rc != LDAP_SUCCESS) { - char *ld_error; - ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0, - ("failed to bind to server with dn= %s Error: %s\n\t%s\n", - ldap_dn, ldap_err2string(rc), - ld_error)); - free(ld_error); - return rc; - } - - DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n")); - return rc; -} - -/********************************************************************** -Connect to LDAP server -*********************************************************************/ -static int ldapsam_open(struct ldapsam_privates *ldap_state) -{ - int rc; - SMB_ASSERT(ldap_state); - -#ifndef NO_LDAP_SECURITY - if (geteuid() != 0) { - DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n")); - return LDAP_INSUFFICIENT_ACCESS; - } -#endif - - if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) { - struct sockaddr_un addr; - socklen_t len; - int sd; - if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 && - getpeername(sd, (struct sockaddr *) &addr, &len) < 0) { - /* the other end has died. reopen. */ - ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); - ldap_state->ldap_struct = NULL; - ldap_state->last_ping = (time_t)0; - } else { - ldap_state->last_ping = time(NULL); - } - } - - if (ldap_state->ldap_struct != NULL) { - DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n")); - return LDAP_SUCCESS; - } - - if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) { - return rc; - } - - if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) { - ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); - ldap_state->ldap_struct = NULL; - return rc; - } - - - ldap_state->last_ping = time(NULL); - DEBUG(4,("The LDAP server is succesful connected\n")); - - return LDAP_SUCCESS; -} - -/********************************************************************** -Disconnect from LDAP server -*********************************************************************/ -static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state) -{ - if (!ldap_state) - return NT_STATUS_INVALID_PARAMETER; - - if (ldap_state->ldap_struct != NULL) { - ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL); - ldap_state->ldap_struct = NULL; - } - - DEBUG(5,("The connection to the LDAP server was closed\n")); - /* maybe free the results here --metze */ - - return NT_STATUS_OK; -} - -static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts) -{ - int rc; - - SMB_ASSERT(ldap_state && attempts); - - if (*attempts != 0) { - /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */ - msleep((((*attempts)*(*attempts))/2)*1000); - } - (*attempts)++; - - if ((rc = ldapsam_open(ldap_state))) { - DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts)); - return rc; - } - - return LDAP_SUCCESS; -} - - -static int ldapsam_search(struct ldapsam_privates *ldap_state, - const char *base, int scope, const char *filter, - const char *attrs[], int attrsonly, - LDAPMessage **res) -{ - int rc = LDAP_SERVER_DOWN; - int attempts = 0; - - SMB_ASSERT(ldap_state); - - while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { - - if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) - continue; - - rc = ldap_search_s(ldap_state->ldap_struct, base, scope, - filter, attrs, attrsonly, res); - } - - if (rc == LDAP_SERVER_DOWN) { - DEBUG(0,("ldapsam_seacrh: LDAP server is down!\n")); - ldapsam_close(ldap_state); - } - - return rc; -} - -static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[]) -{ - int rc = LDAP_SERVER_DOWN; - int attempts = 0; - - if (!ldap_state) - return (-1); - - while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { - - if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) - continue; - - rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs); - } - - if (rc == LDAP_SERVER_DOWN) { - DEBUG(0,("ldapsam_modify: LDAP server is down!\n")); - ldapsam_close(ldap_state); - } - - return rc; -} - -static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[]) -{ - int rc = LDAP_SERVER_DOWN; - int attempts = 0; - - if (!ldap_state) - return (-1); - - while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { - - if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) - continue; - - rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs); - } - - if (rc == LDAP_SERVER_DOWN) { - DEBUG(0,("ldapsam_add: LDAP server is down!\n")); - ldapsam_close(ldap_state); - } - - return rc; -} - -static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn) -{ - int rc = LDAP_SERVER_DOWN; - int attempts = 0; - - if (!ldap_state) - return (-1); - - while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { - - if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) - continue; - - rc = ldap_delete_s(ldap_state->ldap_struct, dn); - } - - if (rc == LDAP_SERVER_DOWN) { - DEBUG(0,("ldapsam_delete: LDAP server is down!\n")); - ldapsam_close(ldap_state); - } - - return rc; -} - -static int ldapsam_extended_operation(struct ldapsam_privates *ldap_state, LDAP_CONST char *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap) -{ - int rc = LDAP_SERVER_DOWN; - int attempts = 0; - - if (!ldap_state) - return (-1); - - while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) { - - if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS) - continue; - - rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap); - } - - if (rc == LDAP_SERVER_DOWN) { - DEBUG(0,("ldapsam_extended_operation: LDAP server is down!\n")); - ldapsam_close(ldap_state); - } - - return rc; -} - -/******************************************************************* - run the search by name. -******************************************************************/ -static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result) -{ - int scope = LDAP_SCOPE_SUBTREE; - int rc; - - DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); - - rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result); - - if (rc != LDAP_SUCCESS) { - DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", - ldap_err2string (rc))); - DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(), - filter)); - } - - return rc; -} - -/******************************************************************* - run the search by name. -******************************************************************/ -static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user, - LDAPMessage ** result) -{ - pstring filter; - char *escape_user = escape_ldap_string_alloc(user); - - if (!escape_user) { - return LDAP_NO_MEMORY; - } - - /* - * in the filter expression, replace %u with the real name - * so in ldap filter, %u MUST exist :-) - */ - pstrcpy(filter, lp_ldap_filter()); - - /* - * have to use this here because $ is filtered out - * in pstring_sub - */ - - - all_string_sub(filter, "%u", escape_user, sizeof(pstring)); - SAFE_FREE(escape_user); - - return ldapsam_search_one_user(ldap_state, filter, result); -} - -/******************************************************************* - run the search by uid. -******************************************************************/ -static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, - int uid, - LDAPMessage ** result) -{ - struct passwd *user; - pstring filter; - char *escape_user; - - /* Get the username from the system and look that up in the LDAP */ - - if ((user = getpwuid_alloc(uid)) == NULL) { - DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid)); - return LDAP_NO_SUCH_OBJECT; - } - - pstrcpy(filter, lp_ldap_filter()); - - escape_user = escape_ldap_string_alloc(user->pw_name); - if (!escape_user) { - passwd_free(&user); - return LDAP_NO_MEMORY; - } - - all_string_sub(filter, "%u", escape_user, sizeof(pstring)); - - passwd_free(&user); - SAFE_FREE(escape_user); - - return ldapsam_search_one_user(ldap_state, filter, result); -} - -/******************************************************************* - run the search by rid. -******************************************************************/ -static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, - uint32 rid, - LDAPMessage ** result) -{ - pstring filter; - int rc; - - /* check if the user rid exsists, if not, try searching on the uid */ - - snprintf(filter, sizeof(filter) - 1, "rid=%i", rid); - rc = ldapsam_search_one_user(ldap_state, filter, result); - - if (rc != LDAP_SUCCESS) - rc = ldapsam_search_one_user_by_uid(ldap_state, - fallback_pdb_user_rid_to_uid(rid), - result); - - return rc; -} - -/******************************************************************* -search an attribute and return the first value found. -******************************************************************/ -static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, - const char *attribute, pstring value) -{ - char **values; - - if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) { - value = NULL; - DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute)); - - return False; - } - - pstrcpy(value, values[0]); - ldap_value_free(values); -#ifdef DEBUG_PASSWORDS - DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value)); -#endif - return True; -} - -/************************************************************************ -Routine to manage the LDAPMod structure array -manage memory used by the array, by each struct, and values - -************************************************************************/ -static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value) -{ - LDAPMod **mods; - int i; - int j; - - mods = *modlist; - - if (attribute == NULL || *attribute == '\0') - return; - - if (value == NULL || *value == '\0') - return; - - if (mods == NULL) - { - mods = (LDAPMod **) malloc(sizeof(LDAPMod *)); - if (mods == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[0] = NULL; - } - - for (i = 0; mods[i] != NULL; ++i) { - if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute)) - break; - } - - if (mods[i] == NULL) - { - mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *)); - if (mods == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod)); - if (mods[i] == NULL) - { - DEBUG(0, ("make_a_mod: out of memory!\n")); - return; - } - mods[i]->mod_op = modop; - mods[i]->mod_values = NULL; - mods[i]->mod_type = strdup(attribute); - mods[i + 1] = NULL; - } - - if (value != NULL) - { - j = 0; - if (mods[i]->mod_values != NULL) { - for (; mods[i]->mod_values[j] != NULL; j++); - } - mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values, - (j + 2) * sizeof (char *)); - - if (mods[i]->mod_values == NULL) { - DEBUG (0, ("make_a_mod: Memory allocation failure!\n")); - return; - } - mods[i]->mod_values[j] = strdup(value); - mods[i]->mod_values[j + 1] = NULL; - } - *modlist = mods; -} - -/* New Interface is being implemented here */ - -/********************************************************************** -Initialize SAM_ACCOUNT from an LDAP query (unix attributes only) -*********************************************************************/ -static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, - SAM_ACCOUNT * sampass, - LDAPMessage * entry) -{ - pstring homedir; - pstring temp; - uid_t uid; - gid_t gid; - char **ldap_values; - char **values; - - if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) { - DEBUG (1, ("get_unix_attributes: no objectClass! \n")); - return False; - } - - for (values=ldap_values;*values;values++) { - if (strcasecmp(*values, "posixAccount") == 0) { - break; - } - } - - if (!*values) { /*end of array, no posixAccount */ - DEBUG(10, ("user does not have posixAcccount attributes\n")); - ldap_value_free(ldap_values); - return False; - } - ldap_value_free(ldap_values); - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir)) - return False; - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp)) - return False; - - uid = (uid_t)atol(temp); - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp)) - return False; - - gid = (gid_t)atol(temp); - - pdb_set_unix_homedir(sampass, homedir, PDB_SET); - pdb_set_uid(sampass, uid, PDB_SET); - pdb_set_gid(sampass, gid, PDB_SET); - - DEBUG(10, ("user has posixAcccount attributes\n")); - return True; -} - - -/********************************************************************** -Initialize SAM_ACCOUNT from an LDAP query -(Based on init_sam_from_buffer in pdb_tdb.c) -*********************************************************************/ -static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, - SAM_ACCOUNT * sampass, - LDAPMessage * entry) -{ - time_t logon_time, - logoff_time, - kickoff_time, - pass_last_set_time, - pass_can_change_time, - pass_must_change_time; - pstring username, - domain, - nt_username, - fullname, - homedir, - dir_drive, - logon_script, - profile_path, - acct_desc, - munged_dial, - workstations; - struct passwd *pw; - uint32 user_rid, - group_rid; - uint8 smblmpwd[LM_HASH_LEN], - smbntpwd[NT_HASH_LEN]; - uint16 acct_ctrl = 0, - logon_divs; - uint32 hours_len; - uint8 hours[MAX_HOURS_LEN]; - pstring temp; - uid_t uid = -1; - gid_t gid = getegid(); - - - /* - * do a little initialization - */ - username[0] = '\0'; - domain[0] = '\0'; - nt_username[0] = '\0'; - fullname[0] = '\0'; - homedir[0] = '\0'; - dir_drive[0] = '\0'; - logon_script[0] = '\0'; - profile_path[0] = '\0'; - acct_desc[0] = '\0'; - munged_dial[0] = '\0'; - workstations[0] = '\0'; - - - if (sampass == NULL || ldap_state == NULL || entry == NULL) { - DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n")); - return False; - } - - if (ldap_state->ldap_struct == NULL) { - DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n")); - return False; - } - - get_single_attribute(ldap_state->ldap_struct, entry, "uid", username); - DEBUG(2, ("Entry found for user: %s\n", username)); - - pstrcpy(nt_username, username); - - pstrcpy(domain, lp_workgroup()); - - pdb_set_username(sampass, username, PDB_SET); - - pdb_set_domain(sampass, domain, PDB_DEFAULT); - pdb_set_nt_username(sampass, nt_username, PDB_SET); - - get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp); - user_rid = (uint32)atol(temp); - - pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) { - group_rid = 0; - } else { - group_rid = (uint32)atol(temp); - pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - } - - - /* - * If so configured, try and get the values from LDAP - */ - - if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) { - - /* - * Otherwise just ask the system getpw() calls. - */ - - pw = getpwnam_alloc(username); - if (pw == NULL) { - if (! ldap_state->permit_non_unix_accounts) { - DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username)); - return False; - } - } else { - uid = pw->pw_uid; - pdb_set_uid(sampass, uid, PDB_SET); - gid = pw->pw_gid; - pdb_set_gid(sampass, gid, PDB_SET); - - pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET); - - passwd_free(&pw); - } - } - - if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) { - gid = pdb_get_gid(sampass); - /* call the mapping code here */ - pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) { - /* leave as default */ - } else { - pass_last_set_time = (time_t) atol(temp); - pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) { - /* leave as default */ - } else { - logon_time = (time_t) atol(temp); - pdb_set_logon_time(sampass, logon_time, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) { - /* leave as default */ - } else { - logoff_time = (time_t) atol(temp); - pdb_set_logoff_time(sampass, logoff_time, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) { - /* leave as default */ - } else { - kickoff_time = (time_t) atol(temp); - pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) { - /* leave as default */ - } else { - pass_can_change_time = (time_t) atol(temp); - pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) { - /* leave as default */ - } else { - pass_must_change_time = (time_t) atol(temp); - pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET); - } - - /* recommend that 'gecos' and 'displayName' should refer to the same - * attribute OID. userFullName depreciated, only used by Samba - * primary rules of LDAP: don't make a new attribute when one is already defined - * that fits your needs; using cn then displayName rather than 'userFullName' - */ - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) { - if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) { - /* leave as default */ - } else { - pdb_set_fullname(sampass, fullname, PDB_SET); - } - } else { - pdb_set_fullname(sampass, fullname, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) { - pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_drive(), - username, domain, - uid, gid), - PDB_DEFAULT); - } else { - pdb_set_dir_drive(sampass, dir_drive, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) { - pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_home(), - username, domain, - uid, gid), - PDB_DEFAULT); - } else { - pdb_set_homedir(sampass, homedir, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) { - pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_script(), - username, domain, - uid, gid), - PDB_DEFAULT); - } else { - pdb_set_logon_script(sampass, logon_script, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) { - pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx, - lp_logon_path(), - username, domain, - uid, gid), - PDB_DEFAULT); - } else { - pdb_set_profile_path(sampass, profile_path, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) { - /* leave as default */ - } else { - pdb_set_acct_desc(sampass, acct_desc, PDB_SET); - } - - if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) { - /* leave as default */; - } else { - pdb_set_workstations(sampass, workstations, PDB_SET); - } - - /* FIXME: hours stuff should be cleaner */ - - logon_divs = 168; - hours_len = 21; - memset(hours, 0xff, hours_len); - - if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) { - /* leave as default */ - } else { - pdb_gethexpwd(temp, smblmpwd); - memset((char *)temp, '\0', strlen(temp)+1); - if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) - return False; - ZERO_STRUCT(smblmpwd); - } - - if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) { - /* leave as default */ - } else { - pdb_gethexpwd(temp, smbntpwd); - memset((char *)temp, '\0', strlen(temp)+1); - if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) - return False; - ZERO_STRUCT(smbntpwd); - } - - if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) { - acct_ctrl |= ACB_NORMAL; - } else { - acct_ctrl = pdb_decode_acct_ctrl(temp); - - if (acct_ctrl == 0) - acct_ctrl |= ACB_NORMAL; - - pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET); - } - - pdb_set_hours_len(sampass, hours_len, PDB_SET); - pdb_set_logon_divs(sampass, logon_divs, PDB_SET); - - pdb_set_munged_dial(sampass, munged_dial, PDB_SET); - - /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */ - /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */ - /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */ - - pdb_set_hours(sampass, hours, PDB_SET); - - return True; -} - -static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) { - if (pdb_add) { - return (!IS_SAM_DEFAULT(sampass, element)); - } else { - return IS_SAM_CHANGED(sampass, element); - } -} - -/********************************************************************** -Initialize SAM_ACCOUNT from an LDAP query -(Based on init_buffer_from_sam in pdb_tdb.c) -*********************************************************************/ -static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, - LDAPMod *** mods, int ldap_op, - BOOL pdb_add, - const SAM_ACCOUNT * sampass) -{ - pstring temp; - uint32 rid; - - if (mods == NULL || sampass == NULL) { - DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n")); - return False; - } - - *mods = NULL; - - /* - * took out adding "objectclass: sambaAccount" - * do this on a per-mod basis - */ - if (need_ldap_mod(pdb_add, sampass, PDB_USERNAME)) { - make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass)); - DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass))); - } - - if ((rid = pdb_get_user_rid(sampass))!=0 ) { - if (need_ldap_mod(pdb_add, sampass, PDB_USERSID)) { - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "rid", temp); - } - } else if (!IS_SAM_DEFAULT(sampass, PDB_UID)) { - rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass)); - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "rid", temp); - } else if (ldap_state->permit_non_unix_accounts) { - rid = ldapsam_get_next_available_nua_rid(ldap_state); - if (rid == 0) { - DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass))); - return False; - } - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "rid", temp); - } else { - DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass))); - return False; - } - - - - if ((rid = pdb_get_group_rid(sampass))!=0 ) { - if (need_ldap_mod(pdb_add, sampass, PDB_GROUPSID)) { - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "primaryGroupID", temp); - } - } else if (!IS_SAM_DEFAULT(sampass, PDB_GID)) { - rid = pdb_gid_to_group_rid(pdb_get_gid(sampass)); - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "primaryGroupID", temp); - } else if (ldap_state->permit_non_unix_accounts) { - rid = DOMAIN_GROUP_RID_USERS; - slprintf(temp, sizeof(temp) - 1, "%i", rid); - make_a_mod(mods, ldap_op, "primaryGroupID", temp); - } else { - DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass))); - return False; - } - - - /* displayName, cn, and gecos should all be the same - * most easily accomplished by giving them the same OID - * gecos isn't set here b/c it should be handled by the - * add-user script - */ - if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) { - make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass)); - make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass)); - } - if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) { - make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass)); - } - if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) { - make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass)); - } - /* - * Only updates fields which have been set (not defaults from smb.conf) - */ - - if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) { - make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass)); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) { - make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass)); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) { - make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass)); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE)) - make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass)); - - if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) { - slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass)); - make_a_mod(mods, ldap_op, "logonTime", temp); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) { - slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass)); - make_a_mod(mods, ldap_op, "logoffTime", temp); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass)); - make_a_mod(mods, ldap_op, "kickoffTime", temp); - } - - - if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); - make_a_mod(mods, ldap_op, "pwdCanChange", temp); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass)); - make_a_mod(mods, ldap_op, "pwdMustChange", temp); - } - - if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))|| - (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { - - if (need_ldap_mod(pdb_add, sampass, PDB_LMPASSWD)) { - pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "lmPassword", temp); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_NTPASSWD)) { - pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "ntPassword", temp); - } - - if (need_ldap_mod(pdb_add, sampass, PDB_PASSLASTSET)) { - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - make_a_mod(mods, ldap_op, "pwdLastSet", temp); - } - } - - /* FIXME: Hours stuff goes in LDAP */ - if (need_ldap_mod(pdb_add, sampass, PDB_ACCTCTRL)) { - make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), - NEW_PW_FORMAT_SPACE_PADDED_LEN)); - } - - return True; -} - - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid) -{ - LDAPMessage *result; - uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER; - if (top_rid == 0) { - return 0; - } - - if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) { - return 0; - } - - if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) { - DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid)); - return 0; - } - - if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) { - DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid)); - ldap_msgfree(result); - return 0; - } - - DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid)); - ldap_msgfree(result); - return final_rid; -} - -/********************************************************************** -Extract the RID from an LDAP entry -*********************************************************************/ -static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) { - uint32 rid; - SAM_ACCOUNT *user = NULL; - if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) { - return 0; - } - - if (init_sam_from_ldap(ldap_state, user, entry)) { - rid = pdb_get_user_rid(user); - } else { - rid =0; - } - pdb_free_sam(&user); - if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) { - return rid; - } - return 0; -} - - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state) -{ - int rc; - pstring filter; - LDAPMessage *result; - LDAPMessage *entry; - char *final_filter = NULL; - uint32 top_rid = 0; - uint32 count; - uint32 rid; - - pstrcpy(filter, lp_ldap_filter()); - all_string_sub(filter, "%u", "*", sizeof(pstring)); - -#if 0 - asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid); -#else - final_filter = strdup(filter); -#endif - DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); - - rc = ldapsam_search(ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, final_filter, attr, 0, - &result); - - if (rc != LDAP_SUCCESS) { - DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc))); - DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); - - free(final_filter); - result = NULL; - return 0; - } - - count = ldap_count_entries(ldap_state->ldap_struct, result); - DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count)); - - if (count == 0) { - DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc))); - DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); - free(final_filter); - ldap_msgfree(result); - result = NULL; - return ldap_state->low_nua_rid; - } - - free(final_filter); - entry = ldap_first_entry(ldap_state->ldap_struct,result); - - top_rid = entry_to_user_rid(ldap_state, entry); - - while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) { - - rid = entry_to_user_rid(ldap_state, entry); - if (rid > top_rid) { - top_rid = rid; - } - } - - ldap_msgfree(result); - - if (top_rid < ldap_state->low_nua_rid) - top_rid = ldap_state->low_nua_rid; - - return top_rid; -} - -/********************************************************************** -Connect to LDAP server and find the next available RID. -*********************************************************************/ -static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) { - uint32 next_nua_rid; - uint32 top_nua_rid; - - top_nua_rid = search_top_nua_rid(ldap_state); - - next_nua_rid = check_nua_rid_is_avail(ldap_state, - top_nua_rid); - - return next_nua_rid; -} - -/********************************************************************** -Connect to LDAP server for password enumeration -*********************************************************************/ -static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) -{ - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - int rc; - pstring filter; - - pstrcpy(filter, lp_ldap_filter()); - all_string_sub(filter, "%u", "*", sizeof(pstring)); - - rc = ldapsam_search(ldap_state, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attr, 0, - &ldap_state->result); - - if (rc != LDAP_SUCCESS) { - DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); - DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); - ldap_msgfree(ldap_state->result); - ldap_state->result = NULL; - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n", - ldap_count_entries(ldap_state->ldap_struct, - ldap_state->result))); - - ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct, - ldap_state->result); - ldap_state->index = 0; - - return NT_STATUS_OK; -} - -/********************************************************************** -End enumeration of the LDAP password list -*********************************************************************/ -static void ldapsam_endsampwent(struct pdb_methods *my_methods) -{ - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - if (ldap_state->result) { - ldap_msgfree(ldap_state->result); - ldap_state->result = NULL; - } -} - -/********************************************************************** -Get the next entry in the LDAP password database -*********************************************************************/ -static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - BOOL bret = False; - - /* The rebind proc needs this *HACK*. We are not multithreaded, so - this will work, but it's not nice. */ - static_ldap_state = ldap_state; - - while (!bret) { - if (!ldap_state->entry) - return ret; - - ldap_state->index++; - bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry); - - ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct, - ldap_state->entry); - } - - return NT_STATUS_OK; -} - -/********************************************************************** -Get SAM_ACCOUNT entry from LDAP by username -*********************************************************************/ -static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - LDAPMessage *result; - LDAPMessage *entry; - int count; - - if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) { - return NT_STATUS_NO_SUCH_USER; - } - - count = ldap_count_entries(ldap_state->ldap_struct, result); - - if (count < 1) { - DEBUG(4, - ("We don't find this user [%s] count=%d\n", sname, - count)); - return NT_STATUS_NO_SUCH_USER; - } else if (count > 1) { - DEBUG(1, - ("Duplicate entries for this user [%s] Failing. count=%d\n", sname, - count)); - return NT_STATUS_NO_SUCH_USER; - } - - entry = ldap_first_entry(ldap_state->ldap_struct, result); - if (entry) { - if (!init_sam_from_ldap(ldap_state, user, entry)) { - DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); - ldap_msgfree(result); - return NT_STATUS_NO_SUCH_USER; - } - ldap_msgfree(result); - ret = NT_STATUS_OK; - } else { - ldap_msgfree(result); - } - return ret; -} - -/********************************************************************** -Get SAM_ACCOUNT entry from LDAP by rid -*********************************************************************/ -static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = - (struct ldapsam_privates *)my_methods->private_data; - LDAPMessage *result; - LDAPMessage *entry; - int count; - - if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) { - return NT_STATUS_NO_SUCH_USER; - } - - count = ldap_count_entries(ldap_state->ldap_struct, result); - - if (count < 1) { - DEBUG(4, - ("We don't find this rid [%i] count=%d\n", rid, - count)); - return NT_STATUS_NO_SUCH_USER; - } else if (count > 1) { - DEBUG(1, - ("More than one user with rid [%i]. Failing. count=%d\n", rid, - count)); - return NT_STATUS_NO_SUCH_USER; - } - - entry = ldap_first_entry(ldap_state->ldap_struct, result); - if (entry) { - if (!init_sam_from_ldap(ldap_state, user, entry)) { - DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); - ldap_msgfree(result); - return NT_STATUS_NO_SUCH_USER; - } - ldap_msgfree(result); - ret = NT_STATUS_OK; - } else { - ldap_msgfree(result); - } - return ret; -} - -static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_NO_SUCH_USER; - return ldapsam_getsampwrid(my_methods, user, rid); -} - -/******************************************************************** -Do the actual modification - also change a plaittext passord if -it it set. -**********************************************************************/ - -static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, - SAM_ACCOUNT *newpwd, char *dn, - LDAPMod **mods, int ldap_op, BOOL pdb_add) -{ - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - int rc; - - if (!my_methods || !newpwd || !dn) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (!mods) { - DEBUG(5,("mods is empty: nothing to modify\n")); - /* may be password change below however */ - } else { - switch(ldap_op) - { - case LDAP_MOD_ADD: - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); - rc = ldapsam_add(ldap_state, dn, mods); - break; - case LDAP_MOD_REPLACE: - rc = ldapsam_modify(ldap_state, dn ,mods); - break; - default: - DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op)); - return NT_STATUS_UNSUCCESSFUL; - } - - if (rc!=LDAP_SUCCESS) { - char *ld_error; - ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(1, - ("failed to %s user dn= %s with: %s\n\t%s\n", - ldap_op == LDAP_MOD_ADD ? "add" : "modify", - dn, ldap_err2string(rc), - ld_error)); - free(ld_error); - return NT_STATUS_UNSUCCESSFUL; - } - } - -#ifdef LDAP_EXOP_X_MODIFY_PASSWD - if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&& - (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&& - need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&& - (pdb_get_plaintext_passwd(newpwd)!=NULL)) { - BerElement *ber; - struct berval *bv; - char *retoid; - struct berval *retdata; - - if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { - DEBUG(0,("ber_alloc_t returns NULL\n")); - return NT_STATUS_UNSUCCESSFUL; - } - ber_printf (ber, "{"); - ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn); - ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd)); - ber_printf (ber, "N}"); - - if ((rc = ber_flatten (ber, &bv))<0) { - DEBUG(0,("ber_flatten returns a value <0\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - ber_free(ber,1); - - if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD, - bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) { - DEBUG(0,("LDAP Password could not be changed for user %s: %s\n", - pdb_get_username(newpwd),ldap_err2string(rc))); - } else { - DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd))); - - ber_bvfree(retdata); - ber_memfree(retoid); - } - ber_bvfree(bv); - } -#else - DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n")); -#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ - return NT_STATUS_OK; -} - -/********************************************************************** -Delete entry from LDAP for username -*********************************************************************/ -static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct) -{ - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - const char *sname; - int rc; - char *dn; - LDAPMessage *entry; - LDAPMessage *result; - - if (!sam_acct) { - DEBUG(0, ("sam_acct was NULL!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - sname = pdb_get_username(sam_acct); - - DEBUG (3, ("Deleting user %s from LDAP.\n", sname)); - - rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result); - if (rc != LDAP_SUCCESS) { - return NT_STATUS_NO_SUCH_USER; - } - - if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) { - DEBUG (0, ("User doesn't exit!\n")); - ldap_msgfree (result); - return NT_STATUS_NO_SUCH_USER; - } - - entry = ldap_first_entry (ldap_state->ldap_struct, result); - dn = ldap_get_dn (ldap_state->ldap_struct, entry); - ldap_msgfree(result); - - rc = ldapsam_delete(ldap_state, dn); - - ldap_memfree (dn); - if (rc != LDAP_SUCCESS) { - char *ld_error; - ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n", - sname, ldap_err2string (rc), ld_error)); - free (ld_error); - return NT_STATUS_CANNOT_DELETE; - } - - DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname)); - return NT_STATUS_OK; -} - -/********************************************************************** -Update SAM_ACCOUNT -*********************************************************************/ -static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - int rc; - char *dn; - LDAPMessage *result; - LDAPMessage *entry; - LDAPMod **mods; - - if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) { - DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (mods == NULL) { - DEBUG(4,("mods is empty: nothing to update for user: %s\n",pdb_get_username(newpwd))); - return NT_STATUS_OK; - } - - rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result); - if (rc != LDAP_SUCCESS) { - return NT_STATUS_UNSUCCESSFUL; - } - - if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) { - DEBUG(0, ("No user to modify!\n")); - ldap_msgfree(result); - return NT_STATUS_UNSUCCESSFUL; - } - - entry = ldap_first_entry(ldap_state->ldap_struct, result); - dn = ldap_get_dn(ldap_state->ldap_struct, entry); - ldap_msgfree(result); - - ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False); - if (NT_STATUS_IS_ERR(ret)) { - DEBUG(0,("failed to modify user with uid = %s\n", - pdb_get_username(newpwd))); - ldap_mods_free(mods,1); - return ret; - } - - - DEBUG(2, - ("successfully modified uid = %s in the LDAP database\n", - pdb_get_username(newpwd))); - ldap_mods_free(mods, 1); - return NT_STATUS_OK; -} - -/********************************************************************** -Add SAM_ACCOUNT to LDAP -*********************************************************************/ -static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - int rc; - pstring filter; - LDAPMessage *result = NULL; - pstring dn; - LDAPMod **mods = NULL; - int ldap_op; - uint32 num_result; - - const char *username = pdb_get_username(newpwd); - if (!username || !*username) { - DEBUG(0, ("Cannot add user without a username!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - rc = ldapsam_search_one_user_by_name (ldap_state, username, &result); - if (rc != LDAP_SUCCESS) { - return NT_STATUS_UNSUCCESSFUL; - } - - if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) { - DEBUG(0,("User '%s' already in the base, with samba properties\n", - username)); - ldap_msgfree(result); - return NT_STATUS_UNSUCCESSFUL; - } - ldap_msgfree(result); - - slprintf (filter, sizeof (filter) - 1, "uid=%s", username); - rc = ldapsam_search_one_user(ldap_state, filter, &result); - if (rc != LDAP_SUCCESS) { - return NT_STATUS_UNSUCCESSFUL; - } - - num_result = ldap_count_entries(ldap_state->ldap_struct, result); - - if (num_result > 1) { - DEBUG (0, ("More than one user with that uid exists: bailing out!\n")); - ldap_msgfree(result); - return NT_STATUS_UNSUCCESSFUL; - } - - /* Check if we need to update an existing entry */ - if (num_result == 1) { - char *tmp; - LDAPMessage *entry; - - DEBUG(3,("User exists without samba properties: adding them\n")); - ldap_op = LDAP_MOD_REPLACE; - entry = ldap_first_entry (ldap_state->ldap_struct, result); - tmp = ldap_get_dn (ldap_state->ldap_struct, entry); - slprintf (dn, sizeof (dn) - 1, "%s", tmp); - ldap_memfree (tmp); - } else { - /* Check if we need to add an entry */ - DEBUG(3,("Adding new user\n")); - ldap_op = LDAP_MOD_ADD; - if (username[strlen(username)-1] == '$') { - slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ()); - } else { - slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ()); - } - } - - ldap_msgfree(result); - - if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) { - DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n")); - ldap_mods_free(mods, 1); - return NT_STATUS_UNSUCCESSFUL; - } - - if (mods == NULL) { - DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd))); - return NT_STATUS_UNSUCCESSFUL; - } - - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount"); - - ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True); - if (NT_STATUS_IS_ERR(ret)) { - DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", - pdb_get_username(newpwd),dn)); - ldap_mods_free(mods,1); - return ret; - } - - DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); - ldap_mods_free(mods, 1); - return NT_STATUS_OK; -} - -static void free_private_data(void **vp) -{ - struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp; - - ldapsam_close(*ldap_state); - - if ((*ldap_state)->bind_secret) { - memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret)); - } - - ldapsam_close(*ldap_state); - - SAFE_FREE((*ldap_state)->bind_dn); - SAFE_FREE((*ldap_state)->bind_secret); - - *ldap_state = NULL; - - /* No need to free any further, as it is talloc()ed */ -} - -static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct ldapsam_privates *ldap_state; - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "ldapsam"; - - (*pdb_method)->setsampwent = ldapsam_setsampwent; - (*pdb_method)->endsampwent = ldapsam_endsampwent; - (*pdb_method)->getsampwent = ldapsam_getsampwent; - (*pdb_method)->getsampwnam = ldapsam_getsampwnam; - (*pdb_method)->getsampwsid = ldapsam_getsampwsid; - (*pdb_method)->add_sam_account = ldapsam_add_sam_account; - (*pdb_method)->update_sam_account = ldapsam_update_sam_account; - (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account; - - /* TODO: Setup private data and free */ - - ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates)); - - if (!ldap_state) { - DEBUG(0, ("talloc() failed for ldapsam private_data!\n")); - return NT_STATUS_NO_MEMORY; - } - - if (location) { - ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location); -#ifdef WITH_LDAP_SAMCONFIG - } else { - int ldap_port = lp_ldap_port(); - - /* remap default port if not using SSL (ie clear or TLS) */ - if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) { - ldap_port = 389; - } - - ldap_state->uri = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port); - if (!ldap_state->uri) { - return NT_STATUS_NO_MEMORY; - } -#else - } else { - ldap_state->uri = "ldap://localhost"; -#endif - } - - (*pdb_method)->private_data = ldap_state; - - (*pdb_method)->free_private_data = free_private_data; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct ldapsam_privates *ldap_state; - uint32 low_nua_uid, high_nua_uid; - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) { - return nt_status; - } - - (*pdb_method)->name = "ldapsam_nua"; - - ldap_state = (*pdb_method)->private_data; - - ldap_state->permit_non_unix_accounts = True; - - if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) { - DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); - - ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); - - return NT_STATUS_OK; -} - -NTSTATUS passdb_ldap_init(void) -{ - NTSTATUS ret; - struct passdb_ops ops; - - /* fill in our name */ - ops.name = "ldapsam"; - /* fill in all the operations */ - ops.init = pdb_init_ldapsam; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - /* fill in our name */ - ops.name = "ldapsam_nua"; - /* fill in all the operations */ - ops.init = pdb_init_ldapsam_nua; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/passdb/pdb_smbpasswd.c b/source4/passdb/pdb_smbpasswd.c deleted file mode 100644 index abb37c4bd7..0000000000 --- a/source4/passdb/pdb_smbpasswd.c +++ /dev/null @@ -1,1615 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * SMB parameters and setup - * Copyright (C) Andrew Tridgell 1992-1998 - * Modified by Jeremy Allison 1995. - * Modified by Gerald (Jerry) Carter 2000-2001 - * Modified by Andrew Bartlett 2002. - * - * 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -/* - smb_passwd is analogous to sam_passwd used everywhere - else. However, smb_passwd is limited to the information - stored by an smbpasswd entry - */ - -struct smb_passwd -{ - BOOL smb_userid_set; /* this is actually the unix uid_t */ - uint32 smb_userid; /* this is actually the unix uid_t */ - const char *smb_name; /* username string */ - - const unsigned char *smb_passwd; /* Null if no password */ - const unsigned char *smb_nt_passwd; /* Null if no password */ - - uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ - time_t pass_last_set_time; /* password last set time */ -}; - -struct smbpasswd_privates -{ - /* used for maintain locks on the smbpasswd file */ - int pw_file_lock_depth; - - /* Global File pointer */ - FILE *pw_file; - - /* formerly static variables */ - struct smb_passwd pw_buf; - pstring user_name; - unsigned char smbpwd[16]; - unsigned char smbntpwd[16]; - - /* retrive-once info */ - const char *smbpasswd_file; - - BOOL permit_non_unix_accounts; - - uint32 low_nua_userid; - uint32 high_nua_userid; - -}; - -enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE }; - -/*************************************************************** - Lock an fd. Abandon after waitsecs seconds. -****************************************************************/ - -static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth) -{ - if (fd < 0) - return False; - - if(*plock_depth == 0) { - if (!do_file_lock(fd, secs, type)) { - DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n", - strerror(errno))); - return False; - } - } - - (*plock_depth)++; - - return True; -} - -/*************************************************************** - Unlock an fd. Abandon after waitsecs seconds. -****************************************************************/ - -static BOOL pw_file_unlock(int fd, int *plock_depth) -{ - BOOL ret=True; - - if (fd == 0 || *plock_depth == 0) { - return True; - } - - if(*plock_depth == 1) - ret = do_file_lock(fd, 5, F_UNLCK); - - if (*plock_depth > 0) - (*plock_depth)--; - - if(!ret) - DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n", - strerror(errno))); - return ret; -} - - -/************************************************************** - Intialize a smb_passwd struct - *************************************************************/ - -static void pdb_init_smb(struct smb_passwd *user) -{ - if (user == NULL) - return; - ZERO_STRUCTP (user); - - user->pass_last_set_time = (time_t)0; -} - -/*************************************************************** - Internal fn to enumerate the smbpasswd list. Returns a void pointer - to ensure no modification outside this module. Checks for atomic - rename of smbpasswd file on update or create once the lock has - been granted to prevent race conditions. JRA. -****************************************************************/ - -static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth) -{ - FILE *fp = NULL; - const char *open_mode = NULL; - int race_loop = 0; - int lock_type = F_RDLCK; - - if (!*pfile) { - DEBUG(0, ("startsmbfilepwent: No SMB password file set\n")); - return (NULL); - } - - switch(type) { - case PWF_READ: - open_mode = "rb"; - lock_type = F_RDLCK; - break; - case PWF_UPDATE: - open_mode = "r+b"; - lock_type = F_WRLCK; - break; - case PWF_CREATE: - /* - * Ensure atomic file creation. - */ - { - int i, fd = -1; - - for(i = 0; i < 5; i++) { - if((fd = sys_open(pfile, O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600))!=-1) - break; - sys_usleep(200); /* Spin, spin... */ - } - if(fd == -1) { - DEBUG(0,("startsmbfilepwent_internal: too many race conditions creating file %s\n", pfile)); - return NULL; - } - close(fd); - open_mode = "r+b"; - lock_type = F_WRLCK; - break; - } - } - - for(race_loop = 0; race_loop < 5; race_loop++) { - DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile)); - - if((fp = sys_fopen(pfile, open_mode)) == NULL) { - DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) )); - return NULL; - } - - if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) { - DEBUG(0, ("startsmbfilepwent_internal: unable to lock file %s. Error was %s\n", pfile, strerror(errno) )); - fclose(fp); - return NULL; - } - - /* - * Only check for replacement races on update or create. - * For read we don't mind if the data is one record out of date. - */ - - if(type == PWF_READ) { - break; - } else { - SMB_STRUCT_STAT sbuf1, sbuf2; - - /* - * Avoid the potential race condition between the open and the lock - * by doing a stat on the filename and an fstat on the fd. If the - * two inodes differ then someone did a rename between the open and - * the lock. Back off and try the open again. Only do this 5 times to - * prevent infinate loops. JRA. - */ - - if (sys_stat(pfile,&sbuf1) != 0) { - DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. Error was %s\n", pfile, strerror(errno))); - pw_file_unlock(fileno(fp), lock_depth); - fclose(fp); - return NULL; - } - - if (sys_fstat(fileno(fp),&sbuf2) != 0) { - DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. Error was %s\n", pfile, strerror(errno))); - pw_file_unlock(fileno(fp), lock_depth); - fclose(fp); - return NULL; - } - - if( sbuf1.st_ino == sbuf2.st_ino) { - /* No race. */ - break; - } - - /* - * Race occurred - back off and try again... - */ - - pw_file_unlock(fileno(fp), lock_depth); - fclose(fp); - } - } - - if(race_loop == 5) { - DEBUG(0, ("startsmbfilepwent_internal: too many race conditions opening file %s\n", pfile)); - return NULL; - } - - /* Set a buffer to do more efficient reads */ - setvbuf(fp, (char *)NULL, _IOFBF, 1024); - - /* Make sure it is only rw by the owner */ - if(fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) { - DEBUG(0, ("startsmbfilepwent_internal: failed to set 0600 permissions on password file %s. \ -Error was %s\n.", pfile, strerror(errno) )); - pw_file_unlock(fileno(fp), lock_depth); - fclose(fp); - return NULL; - } - - /* We have a lock on the file. */ - return fp; -} - -/*************************************************************** - End enumeration of the smbpasswd list. -****************************************************************/ -static void endsmbfilepwent(FILE *fp, int *lock_depth) -{ - if (!fp) { - return; - } - - pw_file_unlock(fileno(fp), lock_depth); - fclose(fp); - DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n")); -} - -/************************************************************************* - Routine to return the next entry in the smbpasswd list. - *************************************************************************/ - -static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_state, FILE *fp) -{ - /* Static buffers we will return. */ - struct smb_passwd *pw_buf = &smbpasswd_state->pw_buf; - char *user_name = smbpasswd_state->user_name; - unsigned char *smbpwd = smbpasswd_state->smbpwd; - unsigned char *smbntpwd = smbpasswd_state->smbntpwd; - char linebuf[256]; - unsigned char c; - unsigned char *p; - long uidval; - size_t linebuf_len; - - if(fp == NULL) { - DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n")); - return NULL; - } - - pdb_init_smb(pw_buf); - - pw_buf->acct_ctrl = ACB_NORMAL; - - /* - * Scan the file, a line at a time and check if the name matches. - */ - while (!feof(fp)) { - linebuf[0] = '\0'; - - fgets(linebuf, 256, fp); - if (ferror(fp)) { - return NULL; - } - - /* - * Check if the string is terminated with a newline - if not - * then we must keep reading and discard until we get one. - */ - if ((linebuf_len = strlen(linebuf)) == 0) - continue; - - if (linebuf[linebuf_len - 1] != '\n') { - c = '\0'; - while (!ferror(fp) && !feof(fp)) { - c = fgetc(fp); - if (c == '\n') - break; - } - } else - linebuf[linebuf_len - 1] = '\0'; - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("getsmbfilepwent: got line |%s|\n", linebuf)); -#endif - if ((linebuf[0] == 0) && feof(fp)) { - DEBUG(4, ("getsmbfilepwent: end of file reached\n")); - break; - } - /* - * The line we have should be of the form :- - * - * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently - * ignored.... - * - * or, - * - * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored.... - * - * if Windows NT compatible passwords are also present. - * [Account type] is an ascii encoding of the type of account. - * LCT-(8 hex digits) is the time_t value of the last change time. - */ - - if (linebuf[0] == '#' || linebuf[0] == '\0') { - DEBUG(6, ("getsmbfilepwent: skipping comment or blank line\n")); - continue; - } - p = (unsigned char *) strchr_m(linebuf, ':'); - if (p == NULL) { - DEBUG(0, ("getsmbfilepwent: malformed password entry (no :)\n")); - continue; - } - /* - * As 256 is shorter than a pstring we don't need to check - * length here - if this ever changes.... - */ - SMB_ASSERT(sizeof(pstring) > sizeof(linebuf)); - - strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); - user_name[PTR_DIFF(p, linebuf)] = '\0'; - - /* Get smb uid. */ - - p++; /* Go past ':' */ - - if(*p == '-') { - DEBUG(0, ("getsmbfilepwent: uids in the smbpasswd file must not be negative.\n")); - continue; - } - - if (!isdigit(*p)) { - DEBUG(0, ("getsmbfilepwent: malformed password entry (uid not number)\n")); - continue; - } - - uidval = atoi((char *) p); - - while (*p && isdigit(*p)) - p++; - - if (*p != ':') { - DEBUG(0, ("getsmbfilepwent: malformed password entry (no : after uid)\n")); - continue; - } - - pw_buf->smb_name = user_name; - pw_buf->smb_userid = uidval; - - /* - * Now get the password value - this should be 32 hex digits - * which are the ascii representations of a 16 byte string. - * Get two at a time and put them into the password. - */ - - /* Skip the ':' */ - p++; - - if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { - DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n")); - continue; - } - - if (p[32] != ':') { - DEBUG(0, ("getsmbfilepwent: malformed password entry (no terminating :)\n")); - continue; - } - - if (!strncasecmp((char *) p, "NO PASSWORD", 11)) { - pw_buf->smb_passwd = NULL; - pw_buf->acct_ctrl |= ACB_PWNOTREQ; - } else { - if (*p == '*' || *p == 'X') { - /* NULL LM password */ - pw_buf->smb_passwd = NULL; - DEBUG(10, ("getsmbfilepwent: LM password for user %s invalidated\n", user_name)); - } else if (pdb_gethexpwd((char *)p, smbpwd)) { - pw_buf->smb_passwd = smbpwd; - } else { - pw_buf->smb_passwd = NULL; - DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n")); - } - } - - /* - * Now check if the NT compatible password is - * available. - */ - pw_buf->smb_nt_passwd = NULL; - - p += 33; /* Move to the first character of the line after - the lanman password. */ - if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) { - if (*p != '*' && *p != 'X') { - if(pdb_gethexpwd((char *)p,smbntpwd)) - pw_buf->smb_nt_passwd = smbntpwd; - } - p += 33; /* Move to the first character of the line after - the NT password. */ - } - - DEBUG(5,("getsmbfilepwent: returning passwd entry for user %s, uid %ld\n", - user_name, uidval)); - - if (*p == '[') - { - unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']'); - pw_buf->acct_ctrl = pdb_decode_acct_ctrl((char*)p); - - /* Must have some account type set. */ - if(pw_buf->acct_ctrl == 0) - pw_buf->acct_ctrl = ACB_NORMAL; - - /* Now try and get the last change time. */ - if(end_p) - p = end_p + 1; - if(*p == ':') { - p++; - if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) { - int i; - p += 4; - for(i = 0; i < 8; i++) { - if(p[i] == '\0' || !isxdigit(p[i])) - break; - } - if(i == 8) { - /* - * p points at 8 characters of hex digits - - * read into a time_t as the seconds since - * 1970 that the password was last changed. - */ - pw_buf->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16); - } - } - } - } else { - /* 'Old' style file. Fake up based on user name. */ - /* - * Currently trust accounts are kept in the same - * password file as 'normal accounts'. If this changes - * we will have to fix this code. JRA. - */ - if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') { - pw_buf->acct_ctrl &= ~ACB_NORMAL; - pw_buf->acct_ctrl |= ACB_WSTRUST; - } - } - - return pw_buf; - } - - DEBUG(5,("getsmbfilepwent: end of file reached.\n")); - return NULL; -} - -/************************************************************************ - Create a new smbpasswd entry - malloced space returned. -*************************************************************************/ - -static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd) -{ - int new_entry_length; - char *new_entry; - char *p; - - new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2; - - if((new_entry = (char *)malloc( new_entry_length )) == NULL) { - DEBUG(0, ("format_new_smbpasswd_entry: Malloc failed adding entry for user %s.\n", newpwd->smb_name )); - return NULL; - } - - slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid); - - p = new_entry+strlen(new_entry); - - pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl); - - p+=strlen(p); *p = ':'; p++; - - pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl); - - p+=strlen(p); *p = ':'; p++; - - /* Add the account encoding and the last change time. */ - slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", - pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), - (uint32)newpwd->pass_last_set_time); - - return new_entry; -} - -/************************************************************************ - Routine to add an entry to the smbpasswd file. -*************************************************************************/ - -static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd) -{ - const char *pfile = smbpasswd_state->smbpasswd_file; - struct smb_passwd *pwd = NULL; - FILE *fp = NULL; - int wr_len; - int fd; - size_t new_entry_length; - char *new_entry; - SMB_OFF_T offpos; - uint32 max_found_uid = 0; - - /* Open the smbpassword file - for update. */ - fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth)); - - if (fp == NULL && errno == ENOENT) { - /* Try again - create. */ - fp = startsmbfilepwent(pfile, PWF_CREATE, &(smbpasswd_state->pw_file_lock_depth)); - } - - if (fp == NULL) { - DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n")); - return False; - } - - /* - * Scan the file, a line at a time and check if the name matches. - */ - - while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) - { - if (strequal(newpwd->smb_name, pwd->smb_name)) - { - DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name)); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } - - /* Look for a free uid for use in non-unix accounts */ - if (pwd->smb_userid > max_found_uid) { - max_found_uid = pwd->smb_userid; - } - } - - /* Ok - entry doesn't exist. We can add it */ - - /* Account not in /etc/passwd hack!!! */ - if (!newpwd->smb_userid_set) { - if (!smbpasswd_state->permit_non_unix_accounts) { - DEBUG(0, ("add_smbfilepwd_entry: cannot add account %s without unix identity\n", newpwd->smb_name)); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } - - if (max_found_uid < smbpasswd_state->low_nua_userid) { - newpwd->smb_userid = smbpasswd_state->low_nua_userid; - newpwd->smb_userid_set = True; - } else if (max_found_uid >= smbpasswd_state->high_nua_userid) { - DEBUG(0, ("add_smbfilepwd_entry: cannot add machine %s, no uids are free! \n", newpwd->smb_name)); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } else { - newpwd->smb_userid = max_found_uid + 1; - newpwd->smb_userid_set = True; - } - } - - - /* Create a new smb passwd entry and set it to the given password. */ - /* - * The add user write needs to be atomic - so get the fd from - * the fp and do a raw write() call. - */ - fd = fileno(fp); - - if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) - { - DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \ -Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } - - if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) - { - DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \ -Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } - - new_entry_length = strlen(new_entry); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|", - fd, new_entry_length, new_entry)); -#endif - - if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) - { - DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \ -Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno))); - - /* Remove the entry we just wrote. */ - if(sys_ftruncate(fd, offpos) == -1) - { - DEBUG(0, ("add_smbfilepwd_entry: ERROR failed to ftruncate file %s. \ -Error was %s. Password file may be corrupt ! Please examine by hand !\n", - newpwd->smb_name, strerror(errno))); - } - - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - free(new_entry); - return False; - } - - free(new_entry); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return True; -} - -/************************************************************************ - Routine to search the smbpasswd file for an entry matching the username. - and then modify its password entry. We can't use the startsmbpwent()/ - getsmbpwent()/endsmbpwent() interfaces here as we depend on looking - in the actual file to decide how much room we have to write data. - override = False, normal - override = True, override XXXXXXXX'd out password or NO PASS -************************************************************************/ - -static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd) -{ - /* Static buffers we will return. */ - pstring user_name; - - char linebuf[256]; - char readbuf[1024]; - unsigned char c; - fstring ascii_p16; - fstring encode_bits; - unsigned char *p = NULL; - size_t linebuf_len = 0; - FILE *fp; - int lockfd; - const char *pfile = smbpasswd_state->smbpasswd_file; - BOOL found_entry = False; - BOOL got_pass_last_set_time = False; - - SMB_OFF_T pwd_seekpos = 0; - - int i; - int wr_len; - int fd; - - if (!*pfile) { - DEBUG(0, ("No SMB password file set\n")); - return False; - } - DEBUG(10, ("mod_smbfilepwd_entry: opening file %s\n", pfile)); - - fp = sys_fopen(pfile, "r+"); - - if (fp == NULL) { - DEBUG(0, ("mod_smbfilepwd_entry: unable to open file %s\n", pfile)); - return False; - } - /* Set a buffer to do more efficient reads */ - setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf)); - - lockfd = fileno(fp); - - if (!pw_file_lock(lockfd, F_WRLCK, 5, &(smbpasswd_state->pw_file_lock_depth))) { - DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile)); - fclose(fp); - return False; - } - - /* Make sure it is only rw by the owner */ - chmod(pfile, 0600); - - /* We have a write lock on the file. */ - /* - * Scan the file, a line at a time and check if the name matches. - */ - while (!feof(fp)) { - pwd_seekpos = sys_ftell(fp); - - linebuf[0] = '\0'; - - fgets(linebuf, sizeof(linebuf), fp); - if (ferror(fp)) { - pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - /* - * Check if the string is terminated with a newline - if not - * then we must keep reading and discard until we get one. - */ - linebuf_len = strlen(linebuf); - if (linebuf[linebuf_len - 1] != '\n') { - c = '\0'; - while (!ferror(fp) && !feof(fp)) { - c = fgetc(fp); - if (c == '\n') { - break; - } - } - } else { - linebuf[linebuf_len - 1] = '\0'; - } - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("mod_smbfilepwd_entry: got line |%s|\n", linebuf)); -#endif - - if ((linebuf[0] == 0) && feof(fp)) { - DEBUG(4, ("mod_smbfilepwd_entry: end of file reached\n")); - break; - } - - /* - * The line we have should be of the form :- - * - * username:uid:[32hex bytes]:....other flags presently - * ignored.... - * - * or, - * - * username:uid:[32hex bytes]:[32hex bytes]:[attributes]:LCT-XXXXXXXX:...ignored. - * - * if Windows NT compatible passwords are also present. - */ - - if (linebuf[0] == '#' || linebuf[0] == '\0') { - DEBUG(6, ("mod_smbfilepwd_entry: skipping comment or blank line\n")); - continue; - } - - p = (unsigned char *) strchr_m(linebuf, ':'); - - if (p == NULL) { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no :)\n")); - continue; - } - - /* - * As 256 is shorter than a pstring we don't need to check - * length here - if this ever changes.... - */ - - SMB_ASSERT(sizeof(user_name) > sizeof(linebuf)); - - strncpy(user_name, linebuf, PTR_DIFF(p, linebuf)); - user_name[PTR_DIFF(p, linebuf)] = '\0'; - if (strequal(user_name, pwd->smb_name)) { - found_entry = True; - break; - } - } - - if (!found_entry) { - pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - - DEBUG(2, ("Cannot update entry for user %s, as they don't exist in the smbpasswd file!\n", - pwd->smb_name)); - return False; - } - - DEBUG(6, ("mod_smbfilepwd_entry: entry exists\n")); - - /* User name matches - get uid and password */ - p++; /* Go past ':' */ - - if (!isdigit(*p)) { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n")); - pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - while (*p && isdigit(*p)) - p++; - if (*p != ':') { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n")); - pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - /* - * Now get the password value - this should be 32 hex digits - * which are the ascii representations of a 16 byte string. - * Get two at a time and put them into the password. - */ - p++; - - /* Record exact password position */ - pwd_seekpos += PTR_DIFF(p, linebuf); - - if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n")); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return (False); - } - - if (p[32] != ':') { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n")); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - /* Now check if the NT compatible password is - available. */ - p += 33; /* Move to the first character of the line after - the lanman password. */ - if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n")); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return (False); - } - - if (p[32] != ':') { - DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n")); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - /* - * Now check if the account info and the password last - * change time is available. - */ - p += 33; /* Move to the first character of the line after - the NT password. */ - - if (*p == '[') { - - i = 0; - encode_bits[i++] = *p++; - while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']')) - encode_bits[i++] = *p++; - - encode_bits[i++] = ']'; - encode_bits[i++] = '\0'; - - if(i == NEW_PW_FORMAT_SPACE_PADDED_LEN) { - /* - * We are using a new format, space padded - * acct ctrl field. Encode the given acct ctrl - * bits into it. - */ - fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN)); - } else { - DEBUG(0,("mod_smbfilepwd_entry: Using old smbpasswd format. This is no longer supported.!\n")); - DEBUG(0,("mod_smbfilepwd_entry: No changes made, failing.!\n")); - return False; - } - - /* Go past the ']' */ - if(linebuf_len > PTR_DIFF(p, linebuf)) - p++; - - if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) { - p++; - - /* We should be pointing at the LCT entry. */ - if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && (StrnCaseCmp((char *)p, "LCT-", 4) == 0)) { - - p += 4; - for(i = 0; i < 8; i++) { - if(p[i] == '\0' || !isxdigit(p[i])) - break; - } - if(i == 8) { - /* - * p points at 8 characters of hex digits - - * read into a time_t as the seconds since - * 1970 that the password was last changed. - */ - got_pass_last_set_time = True; - } /* i == 8 */ - } /* *p && StrnCaseCmp() */ - } /* p == ':' */ - } /* p == '[' */ - - /* Entry is correctly formed. */ - - /* Create the 32 byte representation of the new p16 */ - pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl); - - /* Add on the NT md4 hash */ - ascii_p16[32] = ':'; - wr_len = 66; - pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl); - ascii_p16[65] = ':'; - ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */ - - /* Add on the account info bits and the time of last - password change. */ - - if(got_pass_last_set_time) { - slprintf(&ascii_p16[strlen(ascii_p16)], - sizeof(ascii_p16)-(strlen(ascii_p16)+1), - "%s:LCT-%08X:", - encode_bits, (uint32)pwd->pass_last_set_time ); - wr_len = strlen(ascii_p16); - } - -#ifdef DEBUG_PASSWORD - DEBUG(100,("mod_smbfilepwd_entry: ")); - dump_data(100, ascii_p16, wr_len); -#endif - - if(wr_len > sizeof(linebuf)) { - DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return (False); - } - - /* - * Do an atomic write into the file at the position defined by - * seekpos. - */ - - /* The mod user write needs to be atomic - so get the fd from - the fp and do a raw write() call. - */ - - fd = fileno(fp); - - if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) { - DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - /* Sanity check - ensure the areas we are writing are framed by ':' */ - if (read(fd, linebuf, wr_len+1) != wr_len+1) { - DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) { - DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) { - DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - if (write(fd, ascii_p16, wr_len) != wr_len) { - DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile)); - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return False; - } - - pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth)); - fclose(fp); - return True; -} - -/************************************************************************ - Routine to delete an entry in the smbpasswd file by name. -*************************************************************************/ - -static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name) -{ - const char *pfile = smbpasswd_state->smbpasswd_file; - pstring pfile2; - struct smb_passwd *pwd = NULL; - FILE *fp = NULL; - FILE *fp_write = NULL; - int pfile2_lockdepth = 0; - - slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)getpid() ); - - /* - * Open the smbpassword file - for update. It needs to be update - * as we need any other processes to wait until we have replaced - * it. - */ - - if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth))) == NULL) { - DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile)); - return False; - } - - /* - * Create the replacement password file. - */ - if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) { - DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile)); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - return False; - } - - /* - * Scan the file, a line at a time and check if the name matches. - */ - - while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) { - char *new_entry; - size_t new_entry_length; - - if (strequal(name, pwd->smb_name)) { - DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name)); - continue; - } - - /* - * We need to copy the entry out into the second file. - */ - - if((new_entry = format_new_smbpasswd_entry(pwd)) == NULL) - { - DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \ -Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); - unlink(pfile2); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - endsmbfilepwent(fp_write, &pfile2_lockdepth); - return False; - } - - new_entry_length = strlen(new_entry); - - if(fwrite(new_entry, 1, new_entry_length, fp_write) != new_entry_length) - { - DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \ -Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); - unlink(pfile2); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - endsmbfilepwent(fp_write, &pfile2_lockdepth); - free(new_entry); - return False; - } - - free(new_entry); - } - - /* - * Ensure pfile2 is flushed before rename. - */ - - if(fflush(fp_write) != 0) - { - DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno))); - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - endsmbfilepwent(fp_write,&pfile2_lockdepth); - return False; - } - - /* - * Do an atomic rename - then release the locks. - */ - - if(rename(pfile2,pfile) != 0) { - unlink(pfile2); - } - - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - endsmbfilepwent(fp_write,&pfile2_lockdepth); - return True; -} - -/********************************************************************* - Create a smb_passwd struct from a SAM_ACCOUNT. - We will not allocate any new memory. The smb_passwd struct - should only stay around as long as the SAM_ACCOUNT does. - ********************************************************************/ -static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass) -{ - uid_t uid; - - if (sampass == NULL) - return False; - - ZERO_STRUCTP(smb_pw); - - if (!IS_SAM_UNIX_USER(sampass)) { - smb_pw->smb_userid_set = False; - DEBUG(5,("build_smb_pass: storing user without a UNIX uid or gid. \n")); - } else { - uint32 rid = pdb_get_user_rid(sampass); - smb_pw->smb_userid_set = True; - uid = pdb_get_uid(sampass); - - /* If the user specified a RID, make sure its able to be both stored and retreived */ - if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) { - DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); - return False; - } - - smb_pw->smb_userid=uid; - } - - smb_pw->smb_name=(const char*)pdb_get_username(sampass); - - smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass); - smb_pw->smb_nt_passwd=pdb_get_nt_passwd(sampass); - - smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass); - smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass); - -#if 0 - /* - * ifdef'out by JFM on 11/29/2001. - * this assertion is no longer valid - * and I don't understand the goal - * and doing the same thing with the group mapping code - * is hairy ! - * - * We just have the RID, in which SID is it valid ? - * our domain SID ? well known SID ? local SID ? - */ - - if (gid != pdb_group_rid_to_gid(pdb_get_group_rid(sampass))) { - DEBUG(0,("build_sam_pass: Failing attempt to store user with non-gid based primary group RID. \n")); - DEBUG(0,("build_sam_pass: %d %d %d. \n", *gid, pdb_group_rid_to_gid(pdb_get_group_rid(sampass)), pdb_get_group_rid(sampass))); - return False; - } -#endif - - return True; -} - -/********************************************************************* - Create a SAM_ACCOUNT from a smb_passwd struct - ********************************************************************/ -static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, - SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf) -{ - struct passwd *pwfile; - - if (sam_pass==NULL) { - DEBUG(5,("build_sam_account: SAM_ACCOUNT is NULL\n")); - return False; - } - - pwfile = getpwnam_alloc(pw_buf->smb_name); - if (pwfile == NULL) { - if ((smbpasswd_state->permit_non_unix_accounts) - && (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid) - && (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) { - - pdb_set_user_sid_from_rid(sam_pass, fallback_pdb_uid_to_user_rid (pw_buf->smb_userid), PDB_SET); - - /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. - - This was down the bottom for machines, but it looks pretty good as - a general default for non-unix users. --abartlet 2002-01-08 - */ - pdb_set_group_sid_from_rid (sam_pass, DOMAIN_GROUP_RID_USERS, PDB_SET); - pdb_set_username (sam_pass, pw_buf->smb_name, PDB_SET); - pdb_set_domain (sam_pass, lp_workgroup(), PDB_DEFAULT); - - } else { - DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid %u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid)); - return False; - } - } else { - if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) { - return False; - } - - passwd_free(&pwfile); - } - - pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET); - pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET); - pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET); - pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET); - pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET); - -#if 0 /* JERRY */ - /* the smbpasswd format doesn't have a must change time field, so - we can't get this right. The best we can do is to set this to - some time in the future. 21 days seems as reasonable as any other value :) - */ - pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE, PDB_DEFAULT); -#endif - return True; -} - -/***************************************************************** - Functions to be implemented by the new passdb API - ****************************************************************/ -static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update) -{ - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - - smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, - update ? PWF_UPDATE : PWF_READ, - &(smbpasswd_state->pw_file_lock_depth)); - - /* did we fail? Should we try to create it? */ - if (!smbpasswd_state->pw_file && update && errno == ENOENT) - { - FILE *fp; - /* slprintf(msg_str,msg_str_len-1, - "smbpasswd file did not exist - attempting to create it.\n"); */ - DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n")); - fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w"); - if (fp) - { - fprintf(fp, "# Samba SMB password file\n"); - fclose(fp); - } - - smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, - update ? PWF_UPDATE : PWF_READ, - &(smbpasswd_state->pw_file_lock_depth)); - } - - if (smbpasswd_state->pw_file != NULL) - return NT_STATUS_OK; - else - return NT_STATUS_UNSUCCESSFUL; -} - -static void smbpasswd_endsampwent (struct pdb_methods *my_methods) -{ - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth)); -} - -/***************************************************************** - ****************************************************************/ -static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - struct smb_passwd *pw_buf=NULL; - BOOL done = False; - DEBUG(5,("pdb_getsampwent\n")); - - if (user==NULL) { - DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n")); -#if 0 - smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n"); -#endif - return nt_status; - } - - while (!done) - { - /* do we have an entry? */ - pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file); - if (pw_buf == NULL) - return nt_status; - - /* build the SAM_ACCOUNT entry from the smb_passwd struct. - We loop in case the user in the pdb does not exist in - the local system password file */ - if (build_sam_account(smbpasswd_state, user, pw_buf)) - done = True; - } - - DEBUG(5,("getsampwent (smbpasswd): done\n")); - - /* success */ - return NT_STATUS_OK; -} - - -/**************************************************************** - Search smbpasswd file by iterating over the entries. Do not - call getpwnam() for unix account information until we have found - the correct entry - ***************************************************************/ -static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods, - SAM_ACCOUNT *sam_acct, const char *username) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - struct smb_passwd *smb_pw; - void *fp = NULL; - - DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username)); - - /* startsmbfilepwent() is used here as we don't want to lookup - the UNIX account in the local system password file until - we have a match. */ - fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth)); - - if (fp == NULL) { - DEBUG(0, ("unable to open passdb database.\n")); - return nt_status; - } - - while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) ) - /* do nothing....another loop */ ; - - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - - - /* did we locate the username in smbpasswd */ - if (smb_pw == NULL) - return nt_status; - - DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name)); - - if (!sam_acct) { - DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n")); -#if 0 - smb_panic("NULL pointer passed to pdb_getsampwnam\n"); -#endif - return nt_status; - } - - /* now build the SAM_ACCOUNT */ - if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw)) - return nt_status; - - /* success */ - return NT_STATUS_OK; -} - -static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const DOM_SID *sid) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - struct smb_passwd *smb_pw; - void *fp = NULL; - fstring sid_str; - uint32 rid; - - DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid))); - - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_UNSUCCESSFUL; - - /* More special case 'guest account' hacks... */ - if (rid == DOMAIN_USER_RID_GUEST) { - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("Guest account not specfied!\n")); - return nt_status; - } - return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account); - } - - /* Open the sam password file - not for update. */ - fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth)); - - if (fp == NULL) { - DEBUG(0, ("unable to open passdb database.\n")); - return nt_status; - } - - while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (fallback_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) ) - /* do nothing */ ; - - endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); - - - /* did we locate the username in smbpasswd */ - if (smb_pw == NULL) - return nt_status; - - DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name)); - - if (!sam_acct) { - DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n")); -#if 0 - smb_panic("NULL pointer passed to pdb_getsampwrid\n"); -#endif - return nt_status; - } - - /* now build the SAM_ACCOUNT */ - if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw)) - return nt_status; - - /* build_sam_account might change the SID on us, if the name was for the guest account */ - if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) { - fstring sid_string1, sid_string2; - DEBUG(1, ("looking for user with sid %s instead returned %s for account %s!?!\n", - sid_to_string(sid_string1, sid), sid_to_string(sid_string2, pdb_get_user_sid(sam_acct)), pdb_get_username(sam_acct))); - return NT_STATUS_NO_SUCH_USER; - } - - /* success */ - return NT_STATUS_OK; -} - -static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass) -{ - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - struct smb_passwd smb_pw; - - /* convert the SAM_ACCOUNT */ - if (!build_smb_pass(&smb_pw, sampass)) { - return NT_STATUS_UNSUCCESSFUL; - } - - /* add the entry */ - if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) { - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass) -{ - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - struct smb_passwd smb_pw; - - /* convert the SAM_ACCOUNT */ - if (!build_smb_pass(&smb_pw, sampass)) { - DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - /* update the entry */ - if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) { - DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass) -{ - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; - - const char *username = pdb_get_username(sampass); - - if (del_smbfilepwd_entry(smbpasswd_state, username)) - return NT_STATUS_OK; - - return NT_STATUS_UNSUCCESSFUL; -} - -static void free_private_data(void **vp) -{ - struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp; - - endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth)); - - *privates = NULL; - /* No need to free any further, as it is talloc()ed */ -} - - -static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct smbpasswd_privates *privates; - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "smbpasswd"; - - (*pdb_method)->setsampwent = smbpasswd_setsampwent; - (*pdb_method)->endsampwent = smbpasswd_endsampwent; - (*pdb_method)->getsampwent = smbpasswd_getsampwent; - (*pdb_method)->getsampwnam = smbpasswd_getsampwnam; - (*pdb_method)->getsampwsid = smbpasswd_getsampwsid; - (*pdb_method)->add_sam_account = smbpasswd_add_sam_account; - (*pdb_method)->update_sam_account = smbpasswd_update_sam_account; - (*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account; - - /* Setup private data and free function */ - - privates = talloc_zero(pdb_context->mem_ctx, sizeof(struct smbpasswd_privates)); - - if (!privates) { - DEBUG(0, ("talloc() failed for smbpasswd private_data!\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Store some config details */ - - if (location) { - privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location); - } else { - privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file()); - } - - if (!privates->smbpasswd_file) { - DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n")); - return NT_STATUS_NO_MEMORY; - } - - (*pdb_method)->private_data = privates; - - (*pdb_method)->free_private_data = free_private_data; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct smbpasswd_privates *privates; - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_smbpasswd(pdb_context, pdb_method, location))) { - return nt_status; - } - - (*pdb_method)->name = "smbpasswd_nua"; - - privates = (*pdb_method)->private_data; - - privates->permit_non_unix_accounts = True; - - if (!lp_non_unix_account_range(&privates->low_nua_userid, &privates->high_nua_userid)) { - DEBUG(0, ("cannot use smbpasswd_nua without 'non unix account range' in smb.conf!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -NTSTATUS passdb_smbpasswd_init(void) -{ - NTSTATUS ret; - struct passdb_ops ops; - - /* fill in our name */ - ops.name = "smbpasswd"; - /* fill in all the operations */ - ops.init = pdb_init_smbpasswd; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - /* fill in our name */ - ops.name = "smbpasswd_nua"; - /* fill in all the operations */ - ops.init = pdb_init_smbpasswd_nua; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/passdb/pdb_tdb.c b/source4/passdb/pdb_tdb.c deleted file mode 100644 index 8d699c281e..0000000000 --- a/source4/passdb/pdb_tdb.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * SMB parameters and setup - * Copyright (C) Andrew Tridgell 1992-1998 - * Copyright (C) Simo Sorce 2000-2002 - * Copyright (C) Gerald Carter 2000 - * Copyright (C) Jeremy Allison 2001 - * Copyright (C) Andrew Bartlett 2002 - * - * 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -#if 0 /* when made a module use this */ - -static int tdbsam_debug_level = DBGC_ALL; -#undef DBGC_CLASS -#define DBGC_CLASS tdbsam_debug_level - -#else - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -#endif - -#define PDB_VERSION "20010830" -#define PASSDB_FILE_NAME "passdb.tdb" -#define TDB_FORMAT_STRING "ddddddBBBBBBBBBBBBddBBwdwdBdd" -#define USERPREFIX "USER_" -#define RIDPREFIX "RID_" - -struct tdbsam_privates { - TDB_CONTEXT *passwd_tdb; - TDB_DATA key; - - /* retrive-once info */ - const char *tdbsam_location; - - BOOL permit_non_unix_accounts; - - BOOL algorithmic_rids; - - uint32 low_nua_rid; - uint32 high_nua_rid; -}; - -/********************************************************************** - Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len - *********************************************************************/ - -static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, - 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, - 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, unknown_3, hours_len, unknown_5, unknown_6; - uint16 acct_ctrl, logon_divs; - uint8 *hours; - static uint8 *lm_pw_ptr, *nt_pw_ptr; - uint32 len = 0; - uint32 lm_pw_len, nt_pw_len, hourslen; - BOOL ret = True; - struct passwd *pw; - uid_t uid = -1; - gid_t gid = -1; /* This is what standard sub advanced expects if no gid is known */ - - if(sampass == NULL || buf == NULL) { - DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n")); - return False; - } - - /* unpack the buffer into variables */ - len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING, - &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, - &unknown_3, - &logon_divs, - &hours_len, - &hourslen, &hours, - &unknown_5, - &unknown_6); - - if (len == -1) { - ret = False; - goto done; - } - - /* validate the account and fill in UNIX uid and gid. Standard - * getpwnam() is used instead of Get_Pwnam() as we do not need - * to try case permutations - */ - if (!username || !(pw = getpwnam_alloc(username))) { - if (!(tdb_state->permit_non_unix_accounts)) { - DEBUG(0,("tdbsam: getpwnam_alloc(%s) return NULL. User does not exist!\n", username)); - ret = False; - goto done; - } - } - - if (pw) { - uid = pw->pw_uid; - gid = pw->pw_gid; - - pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET); - - passwd_free(&pw); - - pdb_set_uid(sampass, uid, PDB_SET); - pdb_set_gid(sampass, gid, PDB_SET); - } - - 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); - - 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_specified(sampass->mem_ctx, - lp_logon_home(), - username, domain, - uid, gid), - PDB_DEFAULT); - } - - if (dir_drive) - pdb_set_dir_drive(sampass, dir_drive, PDB_SET); - else { - pdb_set_dir_drive(sampass, - talloc_sub_specified(sampass->mem_ctx, - lp_logon_drive(), - username, domain, - uid, gid), - PDB_DEFAULT); - } - - if (logon_script) - pdb_set_logon_script(sampass, logon_script, PDB_SET); - else { - pdb_set_logon_script(sampass, - talloc_sub_specified(sampass->mem_ctx, - lp_logon_script(), - username, domain, - uid, gid), - PDB_DEFAULT); - } - - if (profile_path) { - pdb_set_profile_path(sampass, profile_path, PDB_SET); - } else { - pdb_set_profile_path(sampass, - talloc_sub_specified(sampass->mem_ctx, - lp_logon_path(), - username, domain, - uid, gid), - PDB_DEFAULT); - } - - 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); - - 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; - } - } - - 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; - } - } - - pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET); - pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET); - pdb_set_unknown_3(sampass, unknown_3, PDB_SET); - pdb_set_hours_len(sampass, hours_len, PDB_SET); - pdb_set_unknown_5(sampass, unknown_5, 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); - - return ret; -} - -/********************************************************************** - Intialize a BYTE buffer from a SAM_ACCOUNT struct - *********************************************************************/ -static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state, - uint8 **buf, const SAM_ACCOUNT *sampass) -{ - 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; - - domain = pdb_get_domain(sampass); - if (domain) domain_len = strlen(domain) +1; - else domain_len = 0; - - nt_username = pdb_get_nt_username(sampass); - if (nt_username) nt_username_len = strlen(nt_username) +1; - else nt_username_len = 0; - - fullname = pdb_get_fullname(sampass); - if (fullname) fullname_len = strlen(fullname) +1; - else fullname_len = 0; - - /* - * Only updates fields which have been set (not defaults from smb.conf) - */ - - 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; - - 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; - - 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 (!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; - - workstations = pdb_get_workstations(sampass); - if (workstations) workstations_len = strlen(workstations) +1; - else workstations_len = 0; - - unknown_str = NULL; - unknown_str_len = 0; - - 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, - 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), - pdb_get_unknown_3(sampass), - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_unknown_5(sampass), - pdb_get_unknown_6(sampass)); - - - /* 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(*buf, len, TDB_FORMAT_STRING, - 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), - pdb_get_unknown_3(sampass), - pdb_get_logon_divs(sampass), - pdb_get_hours_len(sampass), - MAX_HOURS_LEN, pdb_get_hours(sampass), - pdb_get_unknown_5(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 (%d) != len (%d) in tdb_pack operations!\n", - buflen, len)); - /* error */ - SAFE_FREE (*buf); - return (-1); - } - - return (buflen); -} - -/*************************************************************** - Open the TDB passwd database for SAM account enumeration. -****************************************************************/ - -static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update) -{ - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - - /* Open tdb passwd */ - if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600))) - { - DEBUG(0, ("Unable to open/create TDB passwd\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb); - - return NT_STATUS_OK; -} - -static void close_tdb(struct tdbsam_privates *tdb_state) -{ - if (tdb_state->passwd_tdb) { - tdb_close(tdb_state->passwd_tdb); - tdb_state->passwd_tdb = NULL; - } -} - -/*************************************************************** - End enumeration of the TDB passwd list. -****************************************************************/ - -static void tdbsam_endsampwent(struct pdb_methods *my_methods) -{ - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - close_tdb(tdb_state); - - DEBUG(7, ("endtdbpwent: closed sam database.\n")); -} - -/***************************************************************** - Get one SAM_ACCOUNT from the TDB (next in line) -*****************************************************************/ - -static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_DATA data; - const char *prefix = USERPREFIX; - int prefixlen = strlen (prefix); - - - if (user==NULL) { - DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n")); - return nt_status; - } - - /* skip all non-USER entries (eg. RIDs) */ - while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen))) - /* increment to next in line */ - tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); - - /* do we have an valid iteration pointer? */ - if(tdb_state->passwd_tdb == NULL) { - DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n")); - return nt_status; - } - - data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key); - if (!data.dptr) { - DEBUG(5,("pdb_getsampwent: database entry not found.\n")); - return nt_status; - } - - /* unpack the buffer */ - if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) { - DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); - SAFE_FREE(data.dptr); - return nt_status; - } - SAFE_FREE(data.dptr); - - /* increment to next in line */ - tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key); - - return NT_STATUS_OK; -} - -/****************************************************************** - Lookup a name in the SAM TDB -******************************************************************/ - -static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb; - TDB_DATA data, key; - fstring keystr; - fstring name; - - if (user==NULL) { - DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n")); - return nt_status; - } - - /* Data is stored in all lower-case */ - unix_strlower(sname, -1, name, sizeof(name)); - - /* set search key */ - slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - /* open the accounts TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) { - DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); - return nt_status; - } - - /* get the record */ - data = tdb_fetch(pwd_tdb, key); - if (!data.dptr) { - DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); - DEBUGADD(5, (" Key: %s\n", keystr)); - tdb_close(pwd_tdb); - return nt_status; - } - - /* unpack the buffer */ - if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) { - DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n")); - SAFE_FREE(data.dptr); - tdb_close(pwd_tdb); - return nt_status; - } - SAFE_FREE(data.dptr); - - /* no further use for database, close it now */ - tdb_close(pwd_tdb); - - return NT_STATUS_OK; -} - -/*************************************************************************** - Search by rid - **************************************************************************/ - -static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb; - TDB_DATA data, key; - fstring keystr; - fstring name; - - if (user==NULL) { - DEBUG(0,("pdb_getsampwrid: SAM_ACCOUNT is NULL.\n")); - return nt_status; - } - - /* set search key */ - slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - /* open the accounts TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) { - DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n")); - return nt_status; - } - - /* get the record */ - data = tdb_fetch (pwd_tdb, key); - if (!data.dptr) { - DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr)); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); - tdb_close (pwd_tdb); - return nt_status; - } - - fstrcpy (name, data.dptr); - SAFE_FREE(data.dptr); - - tdb_close (pwd_tdb); - - return tdbsam_getsampwnam (my_methods, user, name); -} - -static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_UNSUCCESSFUL; - return tdbsam_getsampwrid(my_methods, user, rid); -} - -/*************************************************************************** - Delete a SAM_ACCOUNT -****************************************************************************/ - -static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb; - TDB_DATA key; - fstring keystr; - uint32 rid; - fstring name; - - unix_strlower(pdb_get_username(sam_pass), -1, name, sizeof(name)); - - /* open the TDB */ - if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR, 0600))) { - DEBUG(0, ("Unable to open TDB passwd!")); - return nt_status; - } - - /* set the search key */ - slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - rid = pdb_get_user_rid(sam_pass); - - /* it's outaa here! 8^) */ - if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) { - DEBUG(5, ("Error deleting entry from tdb passwd database!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); - tdb_close(pwd_tdb); - return nt_status; - } - - /* delete also the RID key */ - - /* set the search key */ - slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - /* it's outaa here! 8^) */ - if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) { - DEBUG(5, ("Error deleting entry from tdb rid database!\n")); - DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); - tdb_close(pwd_tdb); - return nt_status; - } - - tdb_close(pwd_tdb); - - return NT_STATUS_OK; -} - -/*************************************************************************** - Update the TDB SAM -****************************************************************************/ - -static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) -{ - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb = NULL; - TDB_DATA key, data; - uint8 *buf = NULL; - fstring keystr; - fstring name; - BOOL ret = True; - uint32 user_rid; - BOOL tdb_ret; - - /* invalidate the existing TDB iterator if it is open */ - if (tdb_state->passwd_tdb) { - tdb_close(tdb_state->passwd_tdb); - tdb_state->passwd_tdb = NULL; - } - - /* open the account TDB passwd*/ - pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600); - if (!pwd_tdb) - { - DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); - return False; - } - - /* if flag == TDB_INSERT then make up a new RID else throw an error. */ - if (!(user_rid = pdb_get_user_rid(newpwd))) { - if (flag & TDB_INSERT) { - if (IS_SAM_UNIX_USER(newpwd)) { - if (tdb_state->algorithmic_rids) { - user_rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(newpwd)); - } else { - user_rid = BASE_RID; - tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER); - if (!tdb_ret) { - ret = False; - goto done; - } - } - pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED); - } else { - user_rid = tdb_state->low_nua_rid; - tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "NUA_RID_COUNTER", &user_rid, RID_MULTIPLIER); - if (!tdb_ret) { - ret = False; - goto done; - } - if (user_rid > tdb_state->high_nua_rid) { - DEBUG(0, ("tdbsam: no NUA rids available, cannot add user %s!\n", pdb_get_username(newpwd))); - ret = False; - goto done; - } - pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED); - } - } else { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd))); - ret = False; - goto done; - } - } - - if (!pdb_get_group_rid(newpwd)) { - if (flag & TDB_INSERT) { - if (!tdb_state->permit_non_unix_accounts) { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); - ret = False; - goto done; - } else { - /* This seems like a good default choice for non-unix users */ - pdb_set_group_sid_from_rid(newpwd, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT); - } - } else { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); - ret = False; - goto done; - } - } - - /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */ - if ((data.dsize=init_buffer_from_sam (tdb_state, &buf, newpwd)) == -1) { - DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n")); - ret = False; - goto done; - } - data.dptr = buf; - - unix_strlower(pdb_get_username(newpwd), -1, name, sizeof(name)); - - DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid)); - - /* setup the USER index key */ - slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - /* add the account */ - if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { - DEBUG(0, ("Unable to modify passwd TDB!")); - DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); - DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); - ret = False; - goto done; - } - - /* setup RID data */ - data.dsize = sizeof(fstring); - data.dptr = name; - - /* setup the RID index key */ - slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid); - key.dptr = keystr; - key.dsize = strlen (keystr) + 1; - - /* add the reference */ - if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { - DEBUG(0, ("Unable to modify TDB passwd !")); - DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb))); - DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr)); - ret = False; - goto done; - } - -done: - /* cleanup */ - tdb_close (pwd_tdb); - SAFE_FREE(buf); - - return (ret); -} - -/*************************************************************************** - Modifies an existing SAM_ACCOUNT -****************************************************************************/ - -static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd) -{ - if (tdb_update_sam(my_methods, newpwd, TDB_MODIFY)) - return NT_STATUS_OK; - else - return NT_STATUS_UNSUCCESSFUL; -} - -/*************************************************************************** - Adds an existing SAM_ACCOUNT -****************************************************************************/ - -static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd) -{ - if (tdb_update_sam(my_methods, newpwd, TDB_INSERT)) - return NT_STATUS_OK; - else - return NT_STATUS_UNSUCCESSFUL; -} - -static void free_private_data(void **vp) -{ - struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp; - close_tdb(*tdb_state); - *tdb_state = NULL; - - /* No need to free any further, as it is talloc()ed */ -} - - -static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct tdbsam_privates *tdb_state; - -#if 0 /* when made a module use this */ - tdbsam_debug_level = debug_add_class("tdbsam"); - if(tdbsam_debug_level == -1) { - tdbsam_debug_level = DBGC_ALL; - DEBUG(0, ("tdbsam: Couldn't register custom debugging class!\n")); - } -#endif - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "tdbsam"; - - (*pdb_method)->setsampwent = tdbsam_setsampwent; - (*pdb_method)->endsampwent = tdbsam_endsampwent; - (*pdb_method)->getsampwent = tdbsam_getsampwent; - (*pdb_method)->getsampwnam = tdbsam_getsampwnam; - (*pdb_method)->getsampwsid = tdbsam_getsampwsid; - (*pdb_method)->add_sam_account = tdbsam_add_sam_account; - (*pdb_method)->update_sam_account = tdbsam_update_sam_account; - (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; - - tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates)); - - if (!tdb_state) { - DEBUG(0, ("talloc() failed for tdbsam private_data!\n")); - return NT_STATUS_NO_MEMORY; - } - - if (location) { - tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location); - } else { - pstring tdbfile; - get_private_directory(tdbfile); - pstrcat(tdbfile, "/"); - pstrcat(tdbfile, PASSDB_FILE_NAME); - tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile); - } - - tdb_state->algorithmic_rids = True; - - (*pdb_method)->private_data = tdb_state; - - (*pdb_method)->free_private_data = free_private_data; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - struct tdbsam_privates *tdb_state; - uint32 low_nua_uid, high_nua_uid; - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_tdbsam(pdb_context, pdb_method, location))) { - return nt_status; - } - - (*pdb_method)->name = "tdbsam_nua"; - - tdb_state = (*pdb_method)->private_data; - - tdb_state->permit_non_unix_accounts = True; - - if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) { - DEBUG(0, ("cannot use tdbsam_nua without 'non unix account range' in smb.conf!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); - - tdb_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); - - return NT_STATUS_OK; -} - -NTSTATUS passdb_tdb_init(void) -{ - NTSTATUS ret; - struct passdb_ops ops; - - /* fill in our name */ - ops.name = "tdbsam"; - /* fill in all the operations */ - ops.init = pdb_init_tdbsam; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - /* fill in our name */ - ops.name = "tdbsam_nua"; - /* fill in all the operations */ - ops.init = pdb_init_tdbsam_nua; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/passdb/pdb_unix.c b/source4/passdb/pdb_unix.c deleted file mode 100644 index 0a4ab68574..0000000000 --- a/source4/passdb/pdb_unix.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Unix password backend for samba - * Copyright (C) Jelmer Vernooij 2002 - * - * 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 the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/****************************************************************** - Lookup a name in the SAM database - ******************************************************************/ - -static NTSTATUS unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) -{ - struct passwd *pass; - if (!methods) { - DEBUG(0,("invalid methods\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (!sname) { - DEBUG(0,("invalid name specified")); - return NT_STATUS_UNSUCCESSFUL; - } - pass = Get_Pwnam(sname); - - return pdb_fill_sam_pw(user, pass); -} - - -/*************************************************************************** - Search by rid - **************************************************************************/ - -static NTSTATUS unixsam_getsampwrid (struct pdb_methods *methods, - SAM_ACCOUNT *user, uint32 rid) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct passwd *pass = NULL; - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return nt_status; - } - - if (!methods) { - DEBUG(0,("invalid methods\n")); - return nt_status; - } - - if (rid == DOMAIN_USER_RID_GUEST) { - pass = getpwnam_alloc(guest_account); - if (!pass) { - DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account)); - return nt_status; - } - } else if (pdb_rid_is_user(rid)) { - pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid)); - } - - if (pass == NULL) { - return nt_status; - } - - nt_status = pdb_fill_sam_pw(user, pass); - passwd_free(&pass); - - return nt_status; -} - -static NTSTATUS unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_UNSUCCESSFUL; - return unixsam_getsampwrid(my_methods, user, rid); -} - -static NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - - if (!pdb_context) { - DEBUG(0, ("invalid pdb_context specified\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "unixsam"; - (*pdb_method)->getsampwnam = unixsam_getsampwnam; - (*pdb_method)->getsampwsid = unixsam_getsampwsid; - - /* There's not very much to initialise here */ - return NT_STATUS_OK; -} - -NTSTATUS passdb_unix_init(void) -{ - NTSTATUS ret; - struct passdb_ops ops; - - /* fill in our name */ - ops.name = "unixsam"; - /* fill in all the operations */ - ops.init = pdb_init_unixsam; - - /* register ourselves with the PASSDB subsystem. */ - ret = register_backend("passdb", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register '%s' PASSDB backend!\n", - ops.name)); - return ret; - } - - return ret; -} diff --git a/source4/passdb/util_sam_sid.c b/source4/passdb/util_sam_sid.c deleted file mode 100644 index e18386801c..0000000000 --- a/source4/passdb/util_sam_sid.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Luke Kenneth Caseson Leighton 1998-1999 - Copyright (C) Jeremy Allison 1999 - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#define MAX_SID_NAMES 7 - -typedef struct _known_sid_users { - uint32 rid; - enum SID_NAME_USE sid_name_use; - const char *known_user_name; -} known_sid_users; - -static struct sid_name_map_info -{ - DOM_SID *sid; - const char *name; - const known_sid_users *known_users; -} sid_name_map[MAX_SID_NAMES]; - -extern DOM_SID global_sid_Builtin; /* Local well-known domain */ -extern DOM_SID global_sid_World_Domain; /* Everyone domain */ -extern DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */ -extern DOM_SID global_sid_NT_Authority; /* NT Authority */ - - -static BOOL sid_name_map_initialized = False; -/* static known_sid_users no_users[] = {{0, 0, NULL}}; */ - -static const known_sid_users everyone_users[] = { - { 0, SID_NAME_WKN_GRP, "Everyone" }, - {0, (enum SID_NAME_USE)0, NULL}}; - -static const known_sid_users creator_owner_users[] = { - { 0, SID_NAME_WKN_GRP, "Creator Owner" }, - { 1, SID_NAME_WKN_GRP, "Creator Group" }, - {0, (enum SID_NAME_USE)0, NULL}}; - -static const known_sid_users nt_authority_users[] = { - { 1, SID_NAME_ALIAS, "Dialup" }, - { 2, SID_NAME_ALIAS, "Network"}, - { 3, SID_NAME_ALIAS, "Batch"}, - { 4, SID_NAME_ALIAS, "Interactive"}, - { 6, SID_NAME_ALIAS, "Service"}, - { 7, SID_NAME_ALIAS, "AnonymousLogon"}, - { 8, SID_NAME_ALIAS, "Proxy"}, - { 9, SID_NAME_ALIAS, "ServerLogon"}, - { 11, SID_NAME_ALIAS, "Authenticated Users"}, - { 18, SID_NAME_ALIAS, "SYSTEM"}, - { 0, (enum SID_NAME_USE)0, NULL}}; - -static const known_sid_users builtin_groups[] = { - { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" }, - { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" }, - { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" }, - { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" }, - { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" }, - { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" }, - { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" }, - { 0, (enum SID_NAME_USE)0, NULL}}; - -/************************************************************************** - Quick init function. -*************************************************************************/ - -static void init_sid_name_map (void) -{ - int i = 0; - - if (sid_name_map_initialized) return; - - generate_wellknown_sids(); - - if ((lp_security() == SEC_USER) && lp_domain_logons()) { - sid_name_map[i].sid = get_global_sam_sid(); - /* This is not lp_workgroup() for good reason: - it must stay around longer than the lp_*() - strings do */ - sid_name_map[i].name = strdup(lp_workgroup()); - sid_name_map[i].known_users = NULL; - i++; - sid_name_map[i].sid = get_global_sam_sid(); - sid_name_map[i].name = strdup(lp_netbios_name()); - sid_name_map[i].known_users = NULL; - i++; - } else { - sid_name_map[i].sid = get_global_sam_sid(); - sid_name_map[i].name = strdup(lp_netbios_name()); - sid_name_map[i].known_users = NULL; - i++; - } - - sid_name_map[i].sid = &global_sid_Builtin; - sid_name_map[i].name = "BUILTIN"; - sid_name_map[i].known_users = &builtin_groups[0]; - i++; - - sid_name_map[i].sid = &global_sid_World_Domain; - sid_name_map[i].name = ""; - sid_name_map[i].known_users = &everyone_users[0]; - i++; - - sid_name_map[i].sid = &global_sid_Creator_Owner_Domain; - sid_name_map[i].name = ""; - sid_name_map[i].known_users = &creator_owner_users[0]; - i++; - - sid_name_map[i].sid = &global_sid_NT_Authority; - sid_name_map[i].name = "NT Authority"; - sid_name_map[i].known_users = &nt_authority_users[0]; - i++; - - /* End of array. */ - sid_name_map[i].sid = NULL; - sid_name_map[i].name = NULL; - sid_name_map[i].known_users = NULL; - - sid_name_map_initialized = True; - - return; -} - -/************************************************************************** - Turns a domain SID into a name, returned in the nt_domain argument. -***************************************************************************/ - -BOOL map_domain_sid_to_name(DOM_SID *sid, fstring nt_domain) -{ - fstring sid_str; - int i = 0; - - sid_to_string(sid_str, sid); - - if (!sid_name_map_initialized) - init_sid_name_map(); - - DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str)); - - if (nt_domain == NULL) - return False; - - while (sid_name_map[i].sid != NULL) { - sid_to_string(sid_str, sid_name_map[i].sid); - DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str)); - if (sid_equal(sid_name_map[i].sid, sid)) { - fstrcpy(nt_domain, sid_name_map[i].name); - DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain)); - return True; - } - i++; - } - - DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str)); - - return False; -} - -/************************************************************************** - Looks up a known username from one of the known domains. -***************************************************************************/ - -BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use) -{ - int i = 0; - struct sid_name_map_info *psnm; - - if (!sid_name_map_initialized) - init_sid_name_map(); - - for(i = 0; sid_name_map[i].sid != NULL; i++) { - psnm = &sid_name_map[i]; - if(sid_equal(psnm->sid, sid)) { - int j; - for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) { - if(rid == psnm->known_users[j].rid) { - DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n", - (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name )); - fstrcpy( name, psnm->known_users[j].known_user_name); - *psid_name_use = psnm->known_users[j].sid_name_use; - return True; - } - } - } - } - - return False; -} - -/************************************************************************** - Turns a domain name into a SID. - *** side-effect: if the domain name is NULL, it is set to our domain *** -***************************************************************************/ - -BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain) -{ - int i = 0; - - if (nt_domain == NULL) { - DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n")); - sid_copy(sid, get_global_sam_sid()); - return True; - } - - if (nt_domain[0] == 0) { - fstrcpy(nt_domain, lp_netbios_name()); - DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain)); - sid_copy(sid, get_global_sam_sid()); - return True; - } - - DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain)); - - if (!sid_name_map_initialized) - init_sid_name_map(); - - while (sid_name_map[i].name != NULL) { - DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name)); - if (strequal(sid_name_map[i].name, nt_domain)) { - fstring sid_str; - sid_copy(sid, sid_name_map[i].sid); - sid_to_string(sid_str, sid_name_map[i].sid); - DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str)); - return True; - } - i++; - } - - DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain)); - return False; -} - -/***************************************************************** - Check if the SID is our domain SID (S-1-5-21-x-y-z). -*****************************************************************/ - -BOOL sid_check_is_domain(const DOM_SID *sid) -{ - return sid_equal(sid, get_global_sam_sid()); -} - -/***************************************************************** - Check if the SID is our domain SID (S-1-5-21-x-y-z). -*****************************************************************/ - -BOOL sid_check_is_in_our_domain(const DOM_SID *sid) -{ - DOM_SID dom_sid; - uint32 rid; - - sid_copy(&dom_sid, sid); - sid_split_rid(&dom_sid, &rid); - - return sid_equal(&dom_sid, get_global_sam_sid()); -} - -/************************************************************************** - Try and map a name to one of the well known SIDs. -***************************************************************************/ - -BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name) -{ - int i, j; - - if (!sid_name_map_initialized) - init_sid_name_map(); - - for (i=0; sid_name_map[i].sid != NULL; i++) { - const known_sid_users *users = sid_name_map[i].known_users; - - if (users == NULL) - continue; - - for (j=0; users[j].known_user_name != NULL; j++) { - if (strequal(users[j].known_user_name, name) == 0) { - sid_copy(sid, sid_name_map[i].sid); - sid_append_rid(sid, users[j].rid); - *use = users[j].sid_name_use; - return True; - } - } - } - - return False; -} |