diff options
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/machine_sid.c | 53 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 513 | ||||
-rw-r--r-- | source3/passdb/passgrp.c | 3 | ||||
-rw-r--r-- | source3/passdb/pdb_get_set.c | 168 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 335 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 279 | ||||
-rw-r--r-- | source3/passdb/pdb_nisplus.c | 22 | ||||
-rw-r--r-- | source3/passdb/pdb_plugin.c | 21 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 272 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 224 | ||||
-rw-r--r-- | source3/passdb/secrets.c | 192 |
11 files changed, 857 insertions, 1225 deletions
diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index e1f7dec2a9..6436a2cd05 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -4,7 +4,6 @@ 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 @@ -23,13 +22,6 @@ #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 @@ -76,17 +68,13 @@ static void generate_random_sid(DOM_SID *sid) Generate the global machine sid. ****************************************************************************/ -static BOOL pdb_generate_sam_sid(void) +BOOL pdb_generate_sam_sid(void) { char *fname = NULL; extern pstring global_myname; extern fstring global_myworkgroup; 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()) { @@ -99,7 +87,7 @@ static BOOL pdb_generate_sam_sid(void) break; } - if (secrets_fetch_domain_sid(global_myname, global_sam_sid)) { + if (secrets_fetch_domain_sid(global_myname, &global_sam_sid)) { DOM_SID domain_sid; /* We got our sid. If not a pdc/bdc, we're done. */ @@ -110,19 +98,19 @@ static BOOL pdb_generate_sam_sid(void) /* No domain sid and we're a pdc/bdc. Store it */ - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myworkgroup, &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)) { + 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(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n")); return False; } @@ -136,23 +124,24 @@ static BOOL pdb_generate_sam_sid(void) /* 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)) { + 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(global_myname, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store SID from file.\n")); SAFE_FREE(fname); return False; } unlink(fname); if (is_dc) { - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file.\n")); SAFE_FREE(fname); return False; } } - /* Stored the old sid from MACHINE.SID successfully.*/ + /* Stored the old sid from MACHINE.SID successfully. + Patch from Stefan "metze" Metzmacher <metze@metzemix.de>*/ SAFE_FREE(fname); return True; } @@ -161,14 +150,14 @@ static BOOL pdb_generate_sam_sid(void) /* we don't have the SID in secrets.tdb, we will need to generate one and save it */ - generate_random_sid(global_sam_sid); + generate_random_sid(&global_sam_sid); - if (!secrets_store_domain_sid(global_myname, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store generated machine SID.\n")); return False; } if (is_dc) { - if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) { + if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) { DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID.\n")); return False; } @@ -176,19 +165,3 @@ static BOOL pdb_generate_sam_sid(void) return True; } - -/* return our global_sam_sid */ -DOM_SID *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/source3/passdb/passdb.c b/source3/passdb/passdb.c index 2bf3eccfb7..17aefe1159 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -23,16 +23,13 @@ #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. */ -extern pstring global_myname; +extern DOM_SID global_sam_sid; /************************************************************ Fill the SAM_ACCOUNT with default values. @@ -93,7 +90,7 @@ static void destroy_pdb_talloc(SAM_ACCOUNT **user) 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")); + DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n")); #if 0 smb_panic("non-NULL pointer passed to pdb_init_sam\n"); #endif @@ -108,7 +105,7 @@ NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user) *user=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(SAM_ACCOUNT)); if (*user==NULL) { - DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n")); + DEBUG(0,("pdb_init_sam: error while allocating memory\n")); return NT_STATUS_NO_MEMORY; } @@ -153,115 +150,59 @@ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user) Initialises a struct sam_passwd with sane values. ************************************************************/ -NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) +NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd) { + pstring str; GROUP_MAP map; + uint32 rid; + NTSTATUS nt_status; if (!pwd) { + new_sam_acct = NULL; return NT_STATUS_UNSUCCESSFUL; } - pdb_fill_default_sam(sam_account); - - pdb_set_username(sam_account, pwd->pw_name); - pdb_set_fullname(sam_account, pwd->pw_gecos); - - pdb_set_unix_homedir(sam_account, pwd->pw_dir); + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) { + new_sam_acct = NULL; + return nt_status; + } - pdb_set_domain (sam_account, lp_workgroup()); + pdb_set_username(*new_sam_acct, pwd->pw_name); + pdb_set_fullname(*new_sam_acct, pwd->pw_gecos); - pdb_set_uid(sam_account, pwd->pw_uid); - pdb_set_gid(sam_account, pwd->pw_gid); + pdb_set_uid(*new_sam_acct, pwd->pw_uid); + pdb_set_gid(*new_sam_acct, pwd->pw_gid); - /* 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 - */ - - if (!pdb_set_user_sid_from_rid(sam_account, - fallback_pdb_uid_to_user_rid(pwd->pw_uid))) { - DEBUG(0,("Can't set User SID from RID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } + /* let the backends set the rid!! + pdb_set_user_rid(*new_sam_acct, pdb_uid_to_user_rid(pwd->pw_uid)); + -- simo */ /* call the mapping code here */ if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { - if (!pdb_set_group_sid(sam_account,&map.sid)){ - DEBUG(0,("Can't set Group SID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } + sid_peek_rid(&map.sid, &rid); } else { - if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } + rid=pdb_gid_to_group_rid(pwd->pw_gid); } - - /* 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, - standard_sub_specified((sam_account)->mem_ctx, - lp_logon_path(), - pwd->pw_name, global_myname, - pwd->pw_uid, pwd->pw_gid), - False); - - pdb_set_homedir(sam_account, - standard_sub_specified((sam_account)->mem_ctx, - lp_logon_home(), - pwd->pw_name, global_myname, - pwd->pw_uid, pwd->pw_gid), - False); - - pdb_set_dir_drive(sam_account, - standard_sub_specified((sam_account)->mem_ctx, - lp_logon_drive(), - pwd->pw_name, global_myname, - pwd->pw_uid, pwd->pw_gid), - False); - pdb_set_logon_script(sam_account, - standard_sub_specified((sam_account)->mem_ctx, - lp_logon_script(), - pwd->pw_name, global_myname, - pwd->pw_uid, pwd->pw_gid), - False); - } - 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_UNSUCCESSFUL; - } - - if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) { - new_sam_acct = NULL; - return nt_status; - } + pdb_set_group_rid(*new_sam_acct, rid); - 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; - } + pstrcpy(str, lp_logon_path()); + standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str); + pdb_set_profile_path(*new_sam_acct, str, False); + + pstrcpy(str, lp_logon_home()); + standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str); + pdb_set_homedir(*new_sam_acct, str, False); + + pstrcpy(str, lp_logon_drive()); + standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str); + pdb_set_dir_drive(*new_sam_acct, str, False); + pstrcpy(str, lp_logon_script()); + standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str); + pdb_set_logon_script(*new_sam_acct, str, False); + return NT_STATUS_OK; } @@ -269,21 +210,18 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd) /** * Free the contets of the SAM_ACCOUNT, but not the structure. * - * Also wipes the LM and NT hashes and plaintext passwrod from - * memory. + * Also wipes the LM and NT hashes 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 */ + /* As we start mallocing more strings this is where + we should free them. */ data_blob_clear_free(&(user->private.lm_pw)); data_blob_clear_free(&(user->private.nt_pw)); - data_blob_clear_free(&(user->private.plaintext_pw)); } @@ -461,14 +399,46 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) return (True); } +#if 0 /* seem it is not used by anyone */ +/******************************************************************* + Group and User RID username mapping function + ********************************************************************/ + +BOOL pdb_name_to_rid(const char *user_name, uint32 *u_rid, uint32 *g_rid) +{ + GROUP_MAP map; + struct passwd *pw = Get_Pwnam(user_name); + + if (u_rid == NULL || g_rid == NULL || user_name == NULL) + return False; + + if (!pw) { + DEBUG(1,("Username %s is invalid on this system\n", user_name)); + return False; + } + + /* turn the unix UID into a Domain RID. this is what the posix + sub-system does (adds 1000 to the uid) */ + *u_rid = fallback_pdb_uid_to_user_rid(pw->pw_uid); + + /* absolutely no idea what to do about the unix GID to Domain RID mapping */ + /* map it ! */ + if (get_group_map_from_gid(pw->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { + sid_peek_rid(&map.sid, g_rid); + } else + *g_rid = pdb_gid_to_group_rid(pw->pw_gid); + + return True; +} +#endif /* seem it is not used by anyone */ + /******************************************************************* Converts NT user RID to a UNIX uid. ********************************************************************/ -uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) +static uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) { - int rid_offset = lp_algorithmic_rid_base(); - return (uid_t)(((user_rid & (~USER_RID_TYPE))- rid_offset)/RID_MULTIPLIER); + return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); } @@ -476,10 +446,9 @@ uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) converts UNIX uid to an NT User RID. ********************************************************************/ -uint32 fallback_pdb_uid_to_user_rid(uid_t uid) +static uint32 fallback_pdb_uid_to_user_rid(uid_t uid) { - int rid_offset = lp_algorithmic_rid_base(); - return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE); + return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); } /******************************************************************* @@ -488,8 +457,7 @@ uint32 fallback_pdb_uid_to_user_rid(uid_t uid) gid_t pdb_group_rid_to_gid(uint32 group_rid) { - int rid_offset = lp_algorithmic_rid_base(); - return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER); + return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER); } /******************************************************************* @@ -502,8 +470,7 @@ gid_t pdb_group_rid_to_gid(uint32 group_rid) uint32 pdb_gid_to_group_rid(gid_t gid) { - int rid_offset = lp_algorithmic_rid_base(); - return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE); + return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE); } /******************************************************************* @@ -512,10 +479,7 @@ uint32 pdb_gid_to_group_rid(gid_t gid) 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); + return (rid < 1000); } /******************************************************************* @@ -548,14 +512,14 @@ BOOL pdb_rid_is_user(uint32 rid) BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use) { uint32 rid; + BOOL is_user; SAM_ACCOUNT *sam_account = NULL; + uid_t uid; + struct passwd *pass; GROUP_MAP map; + - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){ - DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n", - sid_string_static(&map.sid))); - return False; - } + sid_peek_rid(sid, &rid); *psid_name_use = SID_NAME_UNKNOWN; DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid)); @@ -593,8 +557,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use return False; } - /* This now does the 'generic' mapping in pdb_unix */ - if (pdb_getsampwsid(sam_account, sid)) { + if (pdb_getsampwrid(sam_account, rid)) { fstrcpy(name, pdb_get_username(sam_account)); *psid_name_use = SID_NAME_USER; @@ -602,36 +565,47 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use return True; } - + pdb_free_sam(&sam_account); if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) { if (map.gid!=-1) { DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid)); - } else { - DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name)); + fstrcpy(name, map.nt_name); + *psid_name_use = map.sid_name_use; + return True; } - - fstrcpy(name, map.nt_name); - *psid_name_use = map.sid_name_use; - return True; } + + is_user = pdb_rid_is_user(rid); - 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); + DEBUG(5, ("assuming RID %u is a %s\n", (unsigned)rid, is_user ? "user" : "group")); - return False; /* Indicates that this user was 'not mapped' */ + if (pdb_rid_is_user(rid)) { + uid = fallback_pdb_user_rid_to_uid(rid); + pass = getpwuid_alloc(uid); + + *psid_name_use = SID_NAME_USER; + + DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid, + pass ? "succeeded" : "failed" )); + + if(!pass) { + slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid); + return True; + } + + fstrcpy(name, pass->pw_name); + + DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name, + (unsigned int)rid )); + + passwd_free(&pass); + } 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); @@ -642,15 +616,15 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use if(!gr) { slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid); - return False; /* Indicates that this group was 'not mapped' */ + return False; } fstrcpy( name, gr->gr_name); DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name, (unsigned int)rid )); - return True; } + return True; } /******************************************************************* @@ -660,12 +634,11 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use 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; + struct passwd *pass = NULL; DOM_SID local_sid; fstring user; SAM_ACCOUNT *sam_account = NULL; - struct group *grp; - GROUP_MAP map; - + *psid_name_use = SID_NAME_UNKNOWN; /* @@ -675,7 +648,7 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi fstrcpy(user, c_user); - sid_copy(&local_sid, get_global_sam_sid()); + sid_copy(&local_sid, &global_sam_sid); /* * Special case for MACHINE\Everyone. Map to the world_sid. @@ -701,54 +674,62 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi } if (pdb_getsampwnam(sam_account, user)) { - sid_copy(psid, pdb_get_user_sid(sam_account)); + sid_append_rid( &local_sid, pdb_get_user_rid(sam_account)); *psid_name_use = SID_NAME_USER; + sid_copy( psid, &local_sid); pdb_free_sam(&sam_account); return True; } pdb_free_sam(&sam_account); - /* - * Maybe it was a group ? - */ + if ((pass = Get_Pwnam(user))) { + sid_append_rid( &local_sid, fallback_pdb_uid_to_user_rid(pass->pw_uid)); + *psid_name_use = SID_NAME_USER; - /* check if it's a mapped group */ - if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { - if (map.gid!=-1) { - /* yes it's a mapped group to a valid unix group */ - sid_copy(&local_sid, &map.sid); - *psid_name_use = map.sid_name_use; - } - else { - /* it's a correct name but not mapped so it points to nothing*/ - return False; - } } else { - /* 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 + /* + * Maybe it was a group ? */ + struct group *grp; + GROUP_MAP map; - if (get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){ - return False; + /* check if it's a mapped group */ + if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) { + if (map.gid!=-1) { + /* yes it's a mapped group to a valid unix group */ + sid_copy(&local_sid, &map.sid); + *psid_name_use = map.sid_name_use; + } + else + /* it's a correct name but not mapped so it points to nothing*/ + return False; + } else { + /* 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 + */ + + if(get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){ + return False; + } + + sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); + *psid_name_use = SID_NAME_ALIAS; } - - sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid)); - *psid_name_use = SID_NAME_ALIAS; } sid_copy( psid, &local_sid); @@ -762,11 +743,12 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) { + extern DOM_SID global_sam_sid; struct passwd *pass; SAM_ACCOUNT *sam_user = NULL; fstring str; /* sid string buffer */ - sid_copy(psid, get_global_sam_sid()); + sid_copy(psid, &global_sam_sid); if((pass = getpwuid_alloc(uid))) { @@ -776,7 +758,7 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) } if (pdb_getsampwnam(sam_user, pass->pw_name)) { - sid_copy(psid, pdb_get_user_sid(sam_user)); + sid_append_rid(psid, pdb_get_user_rid(sam_user)); } else { sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); } @@ -804,6 +786,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) { + extern DOM_SID global_sam_sid; + DOM_SID dom_sid; uint32 rid; fstring str; @@ -818,13 +802,13 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) * We can only convert to a uid if this is our local * Domain SID (ie. we are the controling authority). */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) + if (!sid_equal(&global_sam_sid, &dom_sid)) return False; if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) return False; - if (pdb_getsampwsid(sam_user, psid)) { + if (pdb_getsampwrid(sam_user, rid)) { *puid = pdb_get_uid(sam_user); if (*puid == -1) { pdb_free_sam(&sam_user); @@ -833,9 +817,14 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), (unsigned int)*puid, pdb_get_username(sam_user))); } else { - DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid))); - pdb_free_sam(&sam_user); - return False; + if (pdb_rid_is_user(rid)) { + *puid = fallback_pdb_user_rid_to_uid(rid); + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (non-passdb user).\n", sid_to_string( str, psid), + (unsigned int)*puid)); + } else { + pdb_free_sam(&sam_user); + return False; + } } pdb_free_sam(&sam_user); @@ -850,13 +839,14 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) { + extern DOM_SID global_sam_sid; GROUP_MAP map; - sid_copy(psid, get_global_sam_sid()); + sid_copy(psid, &global_sam_sid); if (get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) { sid_copy(psid, &map.sid); - } + } else { sid_append_rid(psid, pdb_gid_to_group_rid(gid)); } @@ -870,9 +860,11 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) { + extern DOM_SID global_sam_sid; DOM_SID dom_sid; uint32 rid; fstring str; + struct group *grp; GROUP_MAP map; *name_type = SID_NAME_UNKNOWN; @@ -887,7 +879,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) * Or in the Builtin SID too. JFM, 11/30/2001 */ - if (!sid_equal(get_global_sam_sid(), &dom_sid)) + if (!sid_equal(&global_sam_sid, &dom_sid)) return False; if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) { @@ -896,26 +888,27 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) if (map.gid==-1) return False; - if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){ - DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n", - sid_string_static(&map.sid))); - return False; - } + sid_peek_rid(&map.sid, &rid); *pgid = map.gid; *name_type = map.sid_name_use; - DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid), - map.nt_name, (unsigned int)*pgid)); - } else { if (pdb_rid_is_user(rid)) return False; *pgid = pdb_group_rid_to_gid(rid); *name_type = SID_NAME_ALIAS; - DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid), - (unsigned int)*pgid)); } + /* + * Ensure this gid really does exist. + */ + + if(!(grp = getgrgid(*pgid))) + return False; + + DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid), + (unsigned int)*pgid, grp->gr_name )); + return True; } @@ -924,7 +917,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type) * @return static buffer containing the converted string **/ -const char *pdb_unistr2_convert(const UNISTR2 *from) +static char *pdb_convert(const UNISTR2 *from) { static pstring convert_buffer; *convert_buffer = 0; @@ -937,6 +930,122 @@ const char *pdb_unistr2_convert(const UNISTR2 *from) } /************************************************************* + Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT + **************************************************************/ + +void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) +{ + + if (from == NULL || to == NULL) + return; + + pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True); + pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True); + pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True); + pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True); + pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True); + + pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time)); + + if (from->uni_user_name.buffer) + pdb_set_username(to , pdb_convert(&from->uni_user_name )); + if (from->uni_full_name.buffer) + pdb_set_fullname(to , pdb_convert(&from->uni_full_name )); + if (from->uni_home_dir.buffer) + pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True); + if (from->uni_dir_drive.buffer) + pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True); + if (from->uni_logon_script.buffer) + pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True); + if (from->uni_profile_path.buffer) + pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True); + if (from->uni_acct_desc.buffer) + pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc )); + if (from->uni_workstations.buffer) + pdb_set_workstations(to , pdb_convert(&from->uni_workstations)); + if (from->uni_unknown_str.buffer) + pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str )); + if (from->uni_munged_dial.buffer) + pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial )); + + if (from->user_rid) + pdb_set_user_rid(to, from->user_rid); + if (from->group_rid) + pdb_set_group_rid(to, from->group_rid); + + pdb_set_acct_ctrl(to, from->acb_info); + pdb_set_unknown_3(to, from->unknown_3); + + pdb_set_logon_divs(to, from->logon_divs); + pdb_set_hours_len(to, from->logon_hrs.len); + pdb_set_hours(to, from->logon_hrs.hours); + + pdb_set_unknown_5(to, from->unknown_5); + pdb_set_unknown_6(to, from->unknown_6); +} + + +/************************************************************* + Copies a sam passwd. + **************************************************************/ + +void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) +{ + if (from == NULL || to == NULL) + return; + + pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True); + pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True); + pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True); + pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True); + pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True); + + pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time)); + + if (from->uni_user_name.buffer) + pdb_set_username(to , pdb_convert(&from->uni_user_name )); + if (from->uni_full_name.buffer) + pdb_set_fullname(to , pdb_convert(&from->uni_full_name )); + if (from->uni_home_dir.buffer) + pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True); + if (from->uni_dir_drive.buffer) + pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True); + if (from->uni_logon_script.buffer) + pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True); + if (from->uni_profile_path.buffer) + pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True); + if (from->uni_acct_desc.buffer) + pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc )); + if (from->uni_workstations.buffer) + pdb_set_workstations(to , pdb_convert(&from->uni_workstations)); + if (from->uni_unknown_str.buffer) + pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str )); + if (from->uni_munged_dial.buffer) + pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial )); + + if (from->user_rid) + pdb_set_user_rid(to, from->user_rid); + if (from->group_rid) + pdb_set_group_rid(to, from->group_rid); + + /* FIXME!! Do we need to copy the passwords here as well? + I don't know. Need to figure this out --jerry */ + + /* Passwords dealt with in caller --abartlet */ + + pdb_set_acct_ctrl(to, from->acb_info); + pdb_set_unknown_3(to, from->unknown_3); + + pdb_set_logon_divs(to, from->logon_divs); + pdb_set_hours_len(to, from->logon_hrs.len); + pdb_set_hours(to, from->logon_hrs.hours); + + pdb_set_unknown_5(to, from->unknown_5); + pdb_set_unknown_6(to, from->unknown_6); +} + + +/************************************************************* Change a password entry in the local smbpasswd file. FIXME!! The function needs to be abstracted into the diff --git a/source3/passdb/passgrp.c b/source3/passdb/passgrp.c index f73591793f..d7ed965648 100644 --- a/source3/passdb/passgrp.c +++ b/source3/passdb/passgrp.c @@ -21,9 +21,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - /* * NOTE. All these functions are abstracted into a structure * that points to the correct function for the selected database. JRA. diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index dff4b40f4d..cf77efd38f 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -5,7 +5,6 @@ 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 @@ -24,9 +23,6 @@ #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 @@ -142,35 +138,21 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) 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) +uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass) { - if (sampass) { - return ((char*)sampass->private.plaintext_pw.data); - } - else - return (NULL); -} -const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass) -{ - if (sampass) - return &sampass->private.user_sid; + if (sampass) + return (sampass->private.user_rid); else - return (NULL); + return (-1); } -const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass) +uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass) { if (sampass) - return &sampass->private.group_sid; - else - return (NULL); -} + return (sampass->private.group_rid); + else + return (-1); +} /** * Get flags showing what is initalised in the SAM_ACCOUNT @@ -242,14 +224,6 @@ const char* pdb_get_homedir (const SAM_ACCOUNT *sampass) 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_dirdrive (const SAM_ACCOUNT *sampass) { if (sampass) @@ -487,72 +461,27 @@ BOOL pdb_set_gid (SAM_ACCOUNT *sampass, const gid_t gid) } -BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid) -{ - if (!sampass || !u_sid) - return False; - - sid_copy(&sampass->private.user_sid, u_sid); - - DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", - sid_string_static(&sampass->private.user_sid))); - - return True; -} - -BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid) -{ - 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)) { - 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) +BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid) { - if (!sampass || !g_sid) + if (!sampass) return False; - sid_copy(&sampass->private.group_sid, g_sid); - - DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", - sid_string_static(&sampass->private.group_sid))); - + DEBUG(10, ("pdb_set_rid: setting user rid %d, was %d\n", + rid, sampass->private.user_rid)); + + sampass->private.user_rid = rid; return True; } -BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid) +BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid) { - DOM_SID new_sid; - if (!sampass || !g_sid) + if (!sampass) 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)) { - DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid)); - return False; - } + DEBUG(10, ("pdb_set_group_rid: setting group rid %d, was %d\n", + grid, sampass->private.group_rid)); + + sampass->private.group_rid = grid; return True; } @@ -689,7 +618,7 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, BOOL s } if (store) { - DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!\n")); + DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!")); pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT); } @@ -721,7 +650,7 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, BOOL } if (store) { - DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!\n")); + DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!")); pdb_set_init_flag(sampass, FLAG_SAM_PROFILE); } @@ -753,7 +682,7 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, BOOL store) } if (store) { - DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!\n")); + DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!")); pdb_set_init_flag(sampass, FLAG_SAM_DRIVE); } @@ -785,7 +714,7 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, BOOL store) } if (store) { - DEBUG(10, ("pdb_set_homedir: setting home dir sam flag!\n")); + DEBUG(10, ("pdb_set_homedir: setting home dir sam flag!")); pdb_set_init_flag(sampass, FLAG_SAM_SMBHOME); } @@ -793,34 +722,6 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, BOOL store) } /********************************************************************* - Set the user's unix home directory. - ********************************************************************/ - -BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir) -{ - 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 True; -} - -/********************************************************************* Set the user's account description. ********************************************************************/ @@ -939,7 +840,7 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd) Set the user's LM hash. ********************************************************************/ -BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16]) +BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd) { if (!sampass) return False; @@ -951,23 +852,6 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16]) return True; } -/********************************************************************* - Set the user's plaintext password only (base procedure, see helper - below) - ********************************************************************/ - -BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const uint8 *password, size_t len) -{ - if (!sampass) - return False; - - data_blob_clear_free(&sampass->private.plaintext_pw); - - sampass->private.plaintext_pw = data_blob(password, len); - - return True; -} - BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn) { if (!sampass) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 3b0f54b2b3..435b627da6 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1,19 +1,18 @@ /* Unix SMB/CIFS implementation. Password and authentication handling - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - + 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. @@ -21,9 +20,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - /** List of various built-in passdb modules */ const struct pdb_init_function_entry builtin_pdb_init_functions[] = { @@ -33,199 +29,102 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = { { "tdbsam_nua", pdb_init_tdbsam_nua }, { "ldapsam", pdb_init_ldapsam }, { "ldapsam_nua", pdb_init_ldapsam_nua }, - { "unixsam", pdb_init_unixsam }, +#if 0 + { "nisplus", pdb_init_nisplus }, + { "unix", pdb_init_unix }, +#endif { "plugin", pdb_init_plugin }, { NULL, NULL} }; static BOOL context_setsampwent(struct pdb_context *context, BOOL update) { - if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->setsampwent)) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - - context->pwent_methods = context->pdb_methods; - - if (!context->pwent_methods) { - /* No passdbs at all */ - return True; - } - - while (!(context->pwent_methods->setsampwent(context->pwent_methods, update))) { - context->pwent_methods = context->pwent_methods->next; - if (context->pwent_methods == NULL) - return False; - } - return True; + + return context->pdb_selected->setsampwent(context, update); } static void context_endsampwent(struct pdb_context *context) { - if ((!context)){ + if ((!context) || (!context->pdb_selected)) { 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; + + context->pdb_selected->endsampwent(context); } static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user) { - if ((!context) || (!context->pwent_methods)) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - /* Loop until we find something useful */ - while ((!context->pwent_methods->getsampwent) || - context->pwent_methods->getsampwent(context->pwent_methods, user) == False){ - - if (context->pwent_methods->endsampwent) - 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 False; - if (!context->pwent_methods->setsampwent){ - DEBUG(5, ("next backend does not implment setsampwent\n")); - return False; - } - - context->pwent_methods->setsampwent(context->pwent_methods, False); - } - user->methods = context->pwent_methods; - return True; + return context->pdb_selected->getsampwent(context, user); } static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username) { - struct pdb_methods *curmethods; - if ((!context)) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - curmethods = context->pdb_methods; - while (curmethods){ - if (curmethods->getsampwnam && curmethods->getsampwnam(curmethods, sam_acct, username) == True){ - sam_acct->methods = curmethods; - return True; - } - curmethods = curmethods->next; - } - - return False; + + return context->pdb_selected->getsampwnam(context, sam_acct, username); } -static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid) +static BOOL context_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, uint32 rid) { - struct pdb_methods *curmethods; - if ((!context)) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - curmethods = context->pdb_methods; - - while (curmethods){ - if (curmethods->getsampwsid && curmethods->getsampwsid(curmethods, sam_acct, sid) == True){ - sam_acct->methods = curmethods; - return True; - } - curmethods = curmethods->next; - } - - return False; + return context->pdb_selected->getsampwrid(context, sam_acct, rid); } static BOOL context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) { - if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->add_sam_account)) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - + /** @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); + + return context->pdb_selected->add_sam_account(context, sam_acct); } static BOOL context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) { - if (!context) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - - if (!sam_acct || !sam_acct->methods){ - DEBUG(0, ("invalid sam_acct specified\n")); - return False; - } - - if (!sam_acct->methods->update_sam_account){ - DEBUG(0, ("invalid sam_acct->methods\n")); - return False; - } - + /** @todo This is where a 're-read on update' should be done */ - - return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct); + + return context->pdb_selected->update_sam_account(context, sam_acct); } static BOOL context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) { - struct pdb_methods *pdb_selected; - if (!context) { + if ((!context) || (!context->pdb_selected)) { DEBUG(0, ("invalid pdb_context specified!\n")); return False; } - - 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 (pdb_selected->delete_sam_account && pdb_selected->delete_sam_account(pdb_selected, sam_acct)){ - return True; - } - pdb_selected = pdb_selected->next; - } - return False; - } - - if (!sam_acct->methods->delete_sam_account){ - DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n")); - return False; - } - return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct); + return context->pdb_selected->delete_sam_account(context, 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; + if (((*context)->pdb_selected) && ((*context)->pdb_selected->free_private_data)) { + (*context)->pdb_selected->free_private_data((*context)->pdb_selected->private_data); } talloc_destroy((*context)->mem_ctx); @@ -233,57 +132,13 @@ static void free_pdb_context(struct pdb_context **context) } /****************************************************************** - 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_location = NULL, *p; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - int i; - - p = strchr(module_name, ':'); - - if (p) { - *p = 0; - module_location = p+1; - trim_string(module_location, " ", " "); - } - - trim_string(module_name, " ", " "); - - DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name)); - for (i = 0; builtin_pdb_init_functions[i].name; i++) - { - if (strequal(builtin_pdb_init_functions[i].name, module_name)) - { - DEBUG(5,("Found pdb backend %s (at pos %d)\n", module_name, i)); - nt_status = builtin_pdb_init_functions[i].init(context, methods, module_location); - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5,("pdb backend %s has a valid init\n", selected)); - } else { - DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); - } - SAFE_FREE(module_name); - return nt_status; - break; /* unreached */ - } - } - - /* No such backend found */ - SAFE_FREE(module_name); - return NT_STATUS_INVALID_PARAMETER; -} - -/****************************************************************** - Make a pdb_context from scratch. - *******************************************************************/ + Make a pdb_context from scratch. +*******************************************************************/ static NTSTATUS make_pdb_context(struct pdb_context **context) { TALLOC_CTX *mem_ctx; - + mem_ctx = talloc_init_named("pdb_context internal allocation context"); if (!mem_ctx) { @@ -305,60 +160,82 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_endsampwent = context_endsampwent; (*context)->pdb_getsampwent = context_getsampwent; (*context)->pdb_getsampwnam = context_getsampwnam; - (*context)->pdb_getsampwsid = context_getsampwsid; + (*context)->pdb_getsampwrid = context_getsampwrid; (*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 - *******************************************************************/ + Make a pdb_context, given a text string. +*******************************************************************/ -NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected) +NTSTATUS make_pdb_context_name(struct pdb_context **context, const char *selected) { - int i = 0; - struct pdb_methods *curmethods, *tmpmethods; + /* HINT: Don't store 'selected' becouse its often an lp_ string and + will 'go away' */ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + int i; + char *module_name = smb_xstrdup(selected); + char *module_location = NULL; + char *p; - if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) { - return nt_status; + p = strchr(module_name, ':'); + + if (p) { + *p = 0; + + module_location = p+1; + + trim_string(module_location, " ", " "); } - 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; + trim_string(module_name, " ", " "); + + if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) + goto done; + + DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", + selected, module_name)); + + for (i = 0; builtin_pdb_init_functions[i].name; i++) { + if (strequal(builtin_pdb_init_functions[i].name, + module_name)) { + + DEBUG(5,("Found pdb backend %s (at pos %d)\n", + module_name, i)); + + if (NT_STATUS_IS_OK(nt_status = builtin_pdb_init_functions[i].init(*context, &(*context)->pdb_selected, module_location))) { + DEBUG(5,("pdb backend %s has a valid init\n", selected)); + } else { + DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); + (*context)->pdb_selected = NULL; + } + break; } - curmethods->parent = *context; - DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods); - i++; + } + + if (!(*context)->pdb_selected) { + DEBUG(0,("failed to select passdb backed!\n")); + talloc_destroy((*context)->mem_ctx); + *context = NULL; + goto done; } - return NT_STATUS_OK; -} + nt_status = NT_STATUS_OK; -/****************************************************************** - Make a pdb_context, given a text string. - *******************************************************************/ + done: + SAFE_FREE(module_name); -NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) -{ - NTSTATUS ret; - char **newsel = str_list_make(selected); - ret = make_pdb_context_list(context, newsel); - str_list_free(&newsel); - return ret; + return nt_status; } + /****************************************************************** Return an already initialised pdb_context, to facilitate backward compatibility (see functions below). @@ -367,20 +244,20 @@ NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selec 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_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { + if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) { return NULL; } } - + if (!pdb_context) { - if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { + if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) { return NULL; } } - + return pdb_context; } @@ -434,7 +311,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username); } -BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid) +BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid) { struct pdb_context *pdb_context = pdb_get_static_context(False); @@ -442,7 +319,7 @@ BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid) return False; } - return pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid); + return pdb_context->pdb_getsampwrid(pdb_context, sam_acct, rid); } BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) @@ -470,21 +347,21 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *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 pdb_context->pdb_delete_sam_account(pdb_context, sam_acct); } #endif /* !defined(WITH_NISPLUS_SAM) */ /*************************************************************** - Initialize the static context (at smbd startup etc). + Initialize the static context (at smbd startup etc). - If uninitialised, context will auto-init on first use. - ***************************************************************/ + If uninitialised, context will auto-init on first use. +***************************************************************/ BOOL initialize_password_db(BOOL reload) { @@ -504,3 +381,11 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) return NT_STATUS_OK; } + + + + + + + + diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index fd5ad7ee12..02bb43b7ff 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -24,10 +24,7 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - -#ifdef HAVE_LDAP +#ifdef WITH_LDAP_SAM /* TODO: * persistent connections: if using NSS LDAP, many connections are made * however, using only one within Samba would be nice @@ -75,77 +72,55 @@ struct ldapsam_privates { static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state); /******************************************************************* + Converts NT user RID to a UNIX uid. + ********************************************************************/ + +static uid_t pdb_user_rid_to_uid(uint32 user_rid) +{ + return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); +} + +/******************************************************************* + converts UNIX uid to an NT User RID. + ********************************************************************/ + +static uint32 pdb_uid_to_user_rid(uid_t uid) +{ + return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); +} + +/******************************************************************* find the ldap password ******************************************************************/ -static BOOL fetch_ldapsam_pw(char **dn, char** pw) +static BOOL fetch_ldapsam_pw(char *dn, char* pw, int len) { - char *key = NULL; + fstring key; + char *p; + void *data = 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")); - } + pstrcpy(key, dn); + for (p=key; *p; p++) + if (*p == ',') *p = '/'; - *pw=secrets_fetch(key, &size); + data=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 = '/'; + DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n")); + return False; + } - 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); + if (size > len-1) + { + DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1)); + return False; } + + memcpy(pw, data, size); + pw[size] = '\0'; return True; } -static const char *attr[] = {"uid", "pwdLastSet", "logonTime", - "logoffTime", "kickoffTime", "cn", - "pwdCanChange", "pwdMustChange", - "displayName", "homeDrive", - "smbHome", "scriptPath", - "profilePath", "description", - "userWorkstations", "rid", - "primaryGroupID", "lmPassword", - "ntPassword", "acctFlags", - "domain", "description", NULL }; /******************************************************************* open a connection to the ldap server. @@ -250,57 +225,20 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * return True; } - -/******************************************************************* - Add a rebind function for authenticated referrals -******************************************************************/ - -static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, - int *method, int freeit ) -{ - int rc; - char *ldap_dn; - char *ldap_secret; - - /** @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 != 0) - { - - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) - { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); - return LDAP_OPERATIONS_ERROR; /* No idea what to return */ - } - - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", - ldap_dn)); - - rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - - SAFE_FREE(ldap_dn); - SAFE_FREE(ldap_secret); - - return rc; - } - return 0; -} - /******************************************************************* connect to the ldap server under system privilege. ******************************************************************/ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct) { int rc; - char *ldap_dn; - char *ldap_secret; + static BOOL got_pw = False; + static pstring ldap_secret; - /* get the password */ - if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) + /* get the password if we don't have it already */ + if (!got_pw && !(got_pw=fetch_ldapsam_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring)))) { - DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); + DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n", + lp_ldap_admin_dn())); return False; } @@ -308,16 +246,10 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l (OpenLDAP) doesnt' seem to support it */ DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n", - ldap_dn)); - - ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc)); - - rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - - SAFE_FREE(ldap_dn); - SAFE_FREE(ldap_secret); - - if (rc != LDAP_SUCCESS) + lp_ldap_admin_dn())); + + if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(), + ldap_secret)) != LDAP_SUCCESS) { DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); return False; @@ -337,7 +269,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result); + rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, NULL, 0, result); if (rc != LDAP_SUCCESS) { DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", @@ -415,7 +347,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, if (rc != LDAP_SUCCESS) rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct, - fallback_pdb_user_rid_to_uid(rid), + pdb_user_rid_to_uid(rid), result); return rc; @@ -425,7 +357,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state, search an attribute and return the first value found. ******************************************************************/ static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry, - char *attribute, pstring value) + char *attribute, char *value) { char **values; @@ -589,14 +521,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, get_single_attribute(ldap_struct, entry, "rid", temp); user_rid = (uint32)atol(temp); - - pdb_set_user_sid_from_rid(sampass, user_rid); - if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) { group_rid = 0; } else { group_rid = (uint32)atol(temp); - pdb_set_group_sid_from_rid(sampass, group_rid); } if ((ldap_state->permit_non_unix_accounts) @@ -611,14 +539,12 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pw = getpwnam_alloc(username); if (pw == NULL) { - DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username)); + DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username)); return False; } uid = pw->pw_uid; gid = pw->pw_gid; - pdb_set_unix_homedir(sampass, pw->pw_dir); - passwd_free(&pw); pdb_set_uid(sampass, uid); @@ -628,10 +554,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, GROUP_MAP map; /* call the mapping code here */ if(get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) { - pdb_set_group_sid(sampass, &map.sid); + sid_peek_rid(&map.sid, &group_rid); } else { - pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid)); + group_rid=pdb_gid_to_group_rid(gid); } } } @@ -695,41 +621,37 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, } if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) { - pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx, - lp_logon_drive(), - username, domain, - uid, gid), - False); + pstrcpy(dir_drive, lp_logon_drive()); + standard_sub_advanced(-1, username, "", gid, username, dir_drive); + DEBUG(5,("homeDrive fell back to %s\n",dir_drive)); + pdb_set_dir_drive(sampass, dir_drive, False); } else { pdb_set_dir_drive(sampass, dir_drive, True); } if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) { - pdb_set_homedir(sampass, standard_sub_specified(sampass->mem_ctx, - lp_logon_home(), - username, domain, - uid, gid), - False); + pstrcpy(homedir, lp_logon_home()); + standard_sub_advanced(-1, username, "", gid, username, homedir); + DEBUG(5,("smbHome fell back to %s\n",homedir)); + pdb_set_homedir(sampass, homedir, False); } else { pdb_set_homedir(sampass, homedir, True); } if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) { - pdb_set_logon_script(sampass, standard_sub_specified(sampass->mem_ctx, - lp_logon_script(), - username, domain, - uid, gid), - False); + pstrcpy(logon_script, lp_logon_script()); + standard_sub_advanced(-1, username, "", gid, username, logon_script); + DEBUG(5,("scriptPath fell back to %s\n",logon_script)); + pdb_set_logon_script(sampass, logon_script, False); } else { pdb_set_logon_script(sampass, logon_script, True); } if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) { - pdb_set_profile_path(sampass, standard_sub_specified(sampass->mem_ctx, - lp_logon_path(), - username, domain, - uid, gid), - False); + pstrcpy(profile_path, lp_logon_path()); + standard_sub_advanced(-1, username, "", gid, username, profile_path); + DEBUG(5,("profilePath fell back to %s\n",profile_path)); + pdb_set_profile_path(sampass, profile_path, False); } else { pdb_set_profile_path(sampass, profile_path, True); } @@ -784,6 +706,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, pdb_set_hours_len(sampass, hours_len); pdb_set_logon_divs(sampass, logon_divs); + pdb_set_user_rid(sampass, user_rid); + pdb_set_group_rid(sampass, group_rid); + pdb_set_username(sampass, username); pdb_set_domain(sampass, domain); @@ -829,7 +754,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, if ( pdb_get_user_rid(sampass) ) { rid = pdb_get_user_rid(sampass); } else if (IS_SAM_SET(sampass, FLAG_SAM_UID)) { - rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass)); + rid = pdb_uid_to_user_rid(pdb_get_uid(sampass)); } else if (ldap_state->permit_non_unix_accounts) { rid = ldapsam_get_next_available_nua_rid(ldap_state); if (rid == 0) { @@ -1007,7 +932,7 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, final_filter, attr, 0, + LDAP_SCOPE_SUBTREE, final_filter, NULL, 0, &result); if (rc != LDAP_SUCCESS) @@ -1048,10 +973,6 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap } ldap_msgfree(result); - - if (top_rid < ldap_state->low_nua_rid) - top_rid = ldap_state->low_nua_rid; - return top_rid; } @@ -1085,9 +1006,9 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s /********************************************************************** Connect to LDAP server for password enumeration *********************************************************************/ -static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) +static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; int rc; pstring filter; @@ -1105,7 +1026,7 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) all_string_sub(filter, "%u", "*", sizeof(pstring)); rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attr, 0, + LDAP_SCOPE_SUBTREE, filter, NULL, 0, &ldap_state->result); if (rc != LDAP_SUCCESS) @@ -1133,9 +1054,9 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) /********************************************************************** End enumeration of the LDAP password list *********************************************************************/ -static void ldapsam_endsampwent(struct pdb_methods *my_methods) +static void ldapsam_endsampwent(struct pdb_context *context) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; if (ldap_state->ldap_struct && ldap_state->result) { ldap_msgfree(ldap_state->result); @@ -1148,9 +1069,9 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods) /********************************************************************** Get the next entry in the LDAP password database *********************************************************************/ -static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user) +static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; BOOL ret = False; while (!ret) { @@ -1172,9 +1093,9 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by username *********************************************************************/ -static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname) +static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user, const char *sname) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; @@ -1223,9 +1144,9 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by rid *********************************************************************/ -static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid) +static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user, uint32 rid) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; LDAP *ldap_struct; LDAPMessage *result; LDAPMessage *entry; @@ -1275,20 +1196,12 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us } } -static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return False; - return ldapsam_getsampwrid(my_methods, user, rid); -} - /********************************************************************** Delete entry from LDAP for username *********************************************************************/ -static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct) +static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT * sam_acct) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; const char *sname; int rc; char *dn; @@ -1346,9 +1259,9 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOU /********************************************************************** Update SAM_ACCOUNT *********************************************************************/ -static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) +static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; int rc; char *dn; LDAP *ldap_struct; @@ -1413,9 +1326,9 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU /********************************************************************** Add SAM_ACCOUNT to LDAP *********************************************************************/ -static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd) +static BOOL ldapsam_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd) { - struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; + struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data; int rc; pstring filter; LDAP *ldap_struct = NULL; @@ -1550,7 +1463,7 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co (*pdb_method)->endsampwent = ldapsam_endsampwent; (*pdb_method)->getsampwent = ldapsam_getsampwent; (*pdb_method)->getsampwnam = ldapsam_getsampwnam; - (*pdb_method)->getsampwsid = ldapsam_getsampwsid; + (*pdb_method)->getsampwrid = ldapsam_getsampwrid; (*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; @@ -1598,9 +1511,9 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method return NT_STATUS_UNSUCCESSFUL; } - ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); + ldap_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid); - ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); + ldap_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid); return NT_STATUS_OK; } @@ -1610,13 +1523,13 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { - DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n")); + DEBUG(0, ("ldapsam not compiled in!\n")); return NT_STATUS_UNSUCCESSFUL; } NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { - DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n")); + DEBUG(0, ("ldapsam_nua not compiled in!\n")); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c index 9c5b2e1171..145e1d4f0c 100644 --- a/source3/passdb/pdb_nisplus.c +++ b/source3/passdb/pdb_nisplus.c @@ -56,7 +56,7 @@ struct nisp_enum_info }; static struct nisp_enum_info global_nisp_ent; -static SIG_ATOMIC_T gotalarm; +static VOLATILE sig_atomic_t gotalarm; /*************************************************************** @@ -339,8 +339,8 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID))); pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID))); - pdb_set_user_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID))); - pdb_set_group_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID))); + pdb_set_user_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID))); + pdb_set_group_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID))); /* values, must exist for user */ if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) { @@ -381,7 +381,7 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj else { /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ - pdb_set_group_sid_from_rid (pw_buf, DOMAIN_GROUP_RID_USERS); + pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS); } /* Check the lanman password column. */ @@ -538,8 +538,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass, if (rid==0) { if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) { - if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)) - return False; + sid_peek_rid(&map.sid, &rid); } else rid=pdb_gid_to_group_rid(pdb_get_gid(sampass)); } @@ -1031,16 +1030,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname) /************************************************************************* Routine to search the nisplus passwd file for an entry matching the username *************************************************************************/ - -BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return False; - return pdb_getsampwrid(user, rid); -} - -static BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid) +BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid) { nis_result *result; char *nisname; diff --git a/source3/passdb/pdb_plugin.c b/source3/passdb/pdb_plugin.c index 1a246631fe..1de61abd5f 100644 --- a/source3/passdb/pdb_plugin.c +++ b/source3/passdb/pdb_plugin.c @@ -21,15 +21,11 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { void * dl_handle; char *plugin_location, *plugin_name, *p; pdb_init_function plugin_init; - int (*plugin_version)(void); if (location == NULL) { DEBUG(0, ("The plugin module needs an argument!\n")); @@ -52,23 +48,8 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con return NT_STATUS_UNSUCCESSFUL; } - plugin_version = sys_dlsym(dl_handle, "pdb_version"); - if (!plugin_version) { - sys_dlclose(dl_handle); - DEBUG(0, ("Failed to find function 'pdb_version' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); - return NT_STATUS_UNSUCCESSFUL; - } - - if (plugin_version()!=PASSDB_INTERFACE_VERSION) { - sys_dlclose(dl_handle); - DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n", - plugin_version(),PASSDB_INTERFACE_VERSION)); - return NT_STATUS_UNSUCCESSFUL; - } - plugin_init = sys_dlsym(dl_handle, "pdb_init"); - if (!plugin_init) { - sys_dlclose(dl_handle); + if (!plugin_init){ DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 8c7ba364b8..89a4217c3b 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -23,8 +23,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB /* smb_passwd is analogous to sam_passwd used everywhere @@ -71,6 +69,24 @@ struct smbpasswd_privates enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE }; +/******************************************************************* + Converts NT user RID to a UNIX uid. + ********************************************************************/ + +static uid_t pdb_user_rid_to_uid(uint32 user_rid) +{ + return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); +} + +/******************************************************************* + converts UNIX uid to an NT User RID. + ********************************************************************/ + +static uint32 pdb_uid_to_user_rid(uid_t uid) +{ + return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); +} + /*************************************************************** Lock an fd. Abandon after waitsecs seconds. ****************************************************************/ @@ -101,10 +117,6 @@ 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); @@ -186,7 +198,7 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int 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) )); + DEBUG(2, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) )); return NULL; } @@ -268,13 +280,10 @@ Error was %s\n.", pfile, strerror(errno) )); ****************************************************************/ 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")); + pw_file_unlock(fileno(fp), lock_depth); + fclose(fp); + DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n")); } /************************************************************************* @@ -366,8 +375,6 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s * 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'; @@ -407,6 +414,15 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s /* Skip the ':' */ p++; + if (*p == '*' || *p == 'X') { + /* Password deliberately invalid - end here. */ + DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name)); + pw_buf->smb_nt_passwd = NULL; + pw_buf->smb_passwd = NULL; + pw_buf->acct_ctrl |= ACB_DISABLED; + return pw_buf; + } + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) { DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n")); continue; @@ -421,16 +437,11 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s 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")); - } + if (!pdb_gethexpwd((char *)p, smbpwd)) { + DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n")); + continue; + } + pw_buf->smb_passwd = smbpwd; } /* @@ -513,6 +524,7 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd) int new_entry_length; char *new_entry; char *p; + int i; new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2; @@ -522,16 +534,38 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd) } slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid); + p = &new_entry[strlen(new_entry)]; - p = new_entry+strlen(new_entry); + if(newpwd->smb_passwd != NULL) { + for( i = 0; i < 16; i++) { + slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]); + } + } else { + i=0; + if(newpwd->acct_ctrl & ACB_PWNOTREQ) + safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + else + safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + } - pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl); + p += 32; - p+=strlen(p); *p = ':'; p++; + *p++ = ':'; - pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl); + if(newpwd->smb_nt_passwd != NULL) { + for( i = 0; i < 16; i++) { + slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]); + } + } else { + if(newpwd->acct_ctrl & ACB_PWNOTREQ) + safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + else + safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + } - p+=strlen(p); *p = ':'; p++; + p += 32; + + *p++ = ':'; /* Add the account encoding and the last change time. */ slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", @@ -678,7 +712,7 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd) { /* Static buffers we will return. */ - pstring user_name; + char * user_name = smbpasswd_state->user_name; char linebuf[256]; char readbuf[1024]; @@ -796,9 +830,6 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con * 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)) { @@ -810,9 +841,6 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con 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; } @@ -939,12 +967,30 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con /* Entry is correctly formed. */ /* Create the 32 byte representation of the new p16 */ - pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl); + if(pwd->smb_passwd != NULL) { + for (i = 0; i < 16; i++) { + slprintf(&ascii_p16[i*2], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_passwd[i]); + } + } else { + if(pwd->acct_ctrl & ACB_PWNOTREQ) + fstrcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); + else + fstrcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } /* Add on the NT md4 hash */ ascii_p16[32] = ':'; wr_len = 66; - pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl); + if (pwd->smb_nt_passwd != NULL) { + for (i = 0; i < 16; i++) { + slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]); + } + } else { + if(pwd->acct_ctrl & ACB_PWNOTREQ) + fstrcpy(&ascii_p16[33], "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); + else + fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } ascii_p16[65] = ':'; ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */ @@ -1138,18 +1184,18 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas if (sampass == NULL) return False; - ZERO_STRUCTP(smb_pw); + 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")); + DEBUG(5,("build_sam_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 && uid != fallback_pdb_user_rid_to_uid(rid)) { + if (rid && uid != 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; } @@ -1190,8 +1236,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas /********************************************************************* 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) +static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf) { struct passwd *pwfile; @@ -1204,37 +1249,84 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, && (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_user_rid(sam_pass, pdb_uid_to_user_rid (pw_buf->smb_userid)); /* 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_username (sam_pass, pw_buf->smb_name); - pdb_set_domain (sam_pass, lp_workgroup()); + pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); + } else { + uint32 grid; + GROUP_MAP map; + + /* Verify in system password file... + FIXME!!! This is where we should look up an internal + mapping of allocated uid for machine accounts as well + --jerry */ pwfile = getpwnam_alloc(pw_buf->smb_name); if (pwfile == NULL) { - 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)); + DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s not in unix passwd database!\n", pw_buf->smb_name)); return False; } - if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) { - return False; + pdb_set_uid (sam_pass, pwfile->pw_uid); + pdb_set_gid (sam_pass, pwfile->pw_gid); + + pdb_set_fullname(sam_pass, pwfile->pw_gecos); + + pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid)); + + if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) { + sid_peek_rid(&map.sid, &grid); + } else { + grid=pdb_gid_to_group_rid(pwfile->pw_gid); + } + + pdb_set_group_rid(sam_pass, grid); + + /* check if this is a user account or a machine account */ + if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$') + { + pstring str; + + pstrcpy(str, lp_logon_path()); + standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str); + pdb_set_profile_path(sam_pass, str, False); + + pstrcpy(str, lp_logon_home()); + standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str); + pdb_set_homedir(sam_pass, str, False); + + pstrcpy(str, lp_logon_drive()); + standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str); + pdb_set_dir_drive(sam_pass, str, False); + + pstrcpy(str, lp_logon_script()); + standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str); + pdb_set_logon_script(sam_pass, str, False); + + } else { + /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ + /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */ } passwd_free(&pwfile); } + pdb_set_username (sam_pass, pw_buf->smb_name); pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd); pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd); pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl); pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time); pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, True); + pdb_set_domain (sam_pass, lp_workgroup()); + pdb_set_dir_drive (sam_pass, lp_logon_drive(), False); + #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 @@ -1248,9 +1340,9 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, /***************************************************************** Functions to be implemented by the new passdb API ****************************************************************/ -static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update) +static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, update ? PWF_UPDATE : PWF_READ, @@ -1278,17 +1370,17 @@ static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update) return (smbpasswd_state->pw_file != NULL); } -static void smbpasswd_endsampwent (struct pdb_methods *my_methods) +static void smbpasswd_endsampwent (struct pdb_context *context) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth)); } /***************************************************************** ****************************************************************/ -static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) +static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; struct smb_passwd *pw_buf=NULL; BOOL done = False; DEBUG(5,("pdb_getsampwent\n")); @@ -1327,14 +1419,32 @@ static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *u call getpwnam() for unix account information until we have found the correct entry ***************************************************************/ -static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const char *username) +static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; struct smb_passwd *smb_pw; void *fp = NULL; + char *domain = NULL; + char *user = NULL; + fstring name; DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username)); + + /* break the username from the domain if we have + been given a string in the form 'DOMAIN\user' */ + fstrcpy (name, username); + if ((user=strchr_m(name, '\\')) != NULL) { + domain = name; + *user = '\0'; + user++; + } + + /* if a domain was specified and it wasn't ours + then there is no chance of matching */ + if ( domain && !StrCaseCmp(domain, lp_workgroup()) ) + return False; + /* 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. */ @@ -1345,6 +1455,11 @@ static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *s return False; } + /* if we have a domain name, then we should map it to a UNIX + username first */ + if ( domain ) + map_username(user); + while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) ) /* do nothing....another loop */ ; @@ -1373,9 +1488,10 @@ static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *s return True; } -static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct,uint32 rid) + +static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct,uint32 rid) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; struct smb_passwd *smb_pw; void *fp = NULL; @@ -1389,7 +1505,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s return False; } - while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (fallback_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) ) + while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) ) /* do nothing */ ; endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth)); @@ -1417,17 +1533,9 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s return True; } -static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) +static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass) { - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return False; - return smbpasswd_getsampwrid(my_methods, user, rid); -} - -static BOOL 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 smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; struct smb_passwd smb_pw; /* convert the SAM_ACCOUNT */ @@ -1443,29 +1551,25 @@ static BOOL smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUN return True; } -static BOOL smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass) +static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->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")); + if (!build_smb_pass(&smb_pw, sampass)) return False; - } /* update the entry */ - if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) { - DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n")); + if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) return False; - } - + return True; } -static BOOL smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass) +static BOOL smbpasswd_delete_sam_account (struct pdb_context *context, const SAM_ACCOUNT *sampass) { - struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data; + struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data; const char *username = pdb_get_username(sampass); @@ -1498,7 +1602,7 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, (*pdb_method)->endsampwent = smbpasswd_endsampwent; (*pdb_method)->getsampwent = smbpasswd_getsampwent; (*pdb_method)->getsampwnam = smbpasswd_getsampwnam; - (*pdb_method)->getsampwsid = smbpasswd_getsampwsid; + (*pdb_method)->getsampwrid = smbpasswd_getsampwrid; (*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; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index b309f675b3..a8edac917e 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * SMB parameters and setup * Copyright (C) Andrew Tridgell 1992-1998 - * Copyright (C) Simo Sorce 2000-2002 + * Copyright (C) Simo Sorce 2000 * Copyright (C) Gerald Carter 2000 * Copyright (C) Jeremy Allison 2001 * Copyright (C) Andrew Bartlett 2002 @@ -24,19 +24,6 @@ #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 - #ifdef WITH_TDB_SAM #define PDB_VERSION "20010830" @@ -54,10 +41,8 @@ struct tdbsam_privates { BOOL permit_non_unix_accounts; - BOOL algorithmic_rids; - - uint32 low_nua_rid; - uint32 high_nua_rid; +/* uint32 low_nua_rid; + uint32 high_nua_rid; */ }; /********************************************************************** @@ -99,10 +84,12 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, uint8 *hours; static uint8 *lm_pw_ptr, *nt_pw_ptr; uint32 len = 0; - uint32 lm_pw_len, nt_pw_len, hourslen; + uint32 lmpwlen, ntpwlen, hourslen; BOOL ret = True; + BOOL setflag; + pstring sub_buffer; struct passwd *pw; - uid_t uid = -1; + uid_t uid; gid_t gid = -1; /* This is what standard sub advanced expects if no gid is known */ if(sampass == NULL || buf == NULL) { @@ -132,8 +119,8 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, &munged_dial_len, &munged_dial, &user_rid, &group_rid, - &lm_pw_len, &lm_pw_ptr, - &nt_pw_len, &nt_pw_ptr, + &lmpwlen, &lm_pw_ptr, + &ntpwlen, &nt_pw_ptr, &acct_ctrl, &unknown_3, &logon_divs, @@ -163,8 +150,6 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, uid = pw->pw_uid; gid = pw->pw_gid; - pdb_set_unix_homedir(sampass, pw->pw_dir); - passwd_free(&pw); pdb_set_uid(sampass, uid); @@ -178,76 +163,70 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, pdb_set_pass_must_change_time(sampass, pass_must_change_time, True); pdb_set_pass_last_set_time(sampass, pass_last_set_time); - pdb_set_username (sampass, username); + pdb_set_username (sampass, username); pdb_set_domain (sampass, domain); pdb_set_nt_username (sampass, nt_username); pdb_set_fullname (sampass, fullname); - if (homedir) { - pdb_set_homedir(sampass, homedir, True); - } + if (homedir) setflag = True; else { - pdb_set_homedir(sampass, - standard_sub_specified(sampass->mem_ctx, - lp_logon_home(), - username, domain, - uid, gid), - False); + setflag = False; + pstrcpy(sub_buffer, lp_logon_home()); + /* standard_sub_advanced() assumes pstring is passed!! */ + standard_sub_advanced(-1, username, "", gid, username, sub_buffer); + homedir = strdup(sub_buffer); + if(!homedir) { ret = False; goto done; } + DEBUG(5,("Home directory set back to %s\n", homedir)); } + pdb_set_homedir(sampass, homedir, setflag); - if (dir_drive) - pdb_set_dir_drive(sampass, dir_drive, True); + if (dir_drive) setflag = True; else { - pdb_set_dir_drive(sampass, - standard_sub_specified(sampass->mem_ctx, - lp_logon_drive(), - username, domain, - uid, gid), - False); + setflag = False; + pstrcpy(sub_buffer, lp_logon_drive()); + standard_sub_advanced(-1, username, "", gid, username, sub_buffer); + dir_drive = strdup(sub_buffer); + if(!dir_drive) { ret = False; goto done; } + DEBUG(5,("Drive set back to %s\n", dir_drive)); } + pdb_set_dir_drive(sampass, dir_drive, setflag); - if (logon_script) - pdb_set_logon_script(sampass, logon_script, True); + if (logon_script) setflag = True; else { - pdb_set_logon_script(sampass, - standard_sub_specified(sampass->mem_ctx, - lp_logon_script(), - username, domain, - uid, gid), - False); + setflag = False; + pstrcpy(sub_buffer, lp_logon_script()); + standard_sub_advanced(-1, username, "", gid, username, sub_buffer); + logon_script = strdup(sub_buffer); + if(!logon_script) { ret = False; goto done; } + DEBUG(5,("Logon script set back to %s\n", logon_script)); } + pdb_set_logon_script(sampass, logon_script, setflag); - if (profile_path) { - pdb_set_profile_path(sampass, profile_path, True); - } else { - pdb_set_profile_path(sampass, - standard_sub_specified(sampass->mem_ctx, - lp_logon_path(), - username, domain, - uid, gid), - False); + if (profile_path) setflag = True; + else { + setflag = False; + pstrcpy(sub_buffer, lp_logon_path()); + standard_sub_advanced(-1, username, "", gid, username, sub_buffer); + profile_path = strdup(sub_buffer); + if(!profile_path) { ret = False; goto done; } + DEBUG(5,("Profile path set back to %s\n", profile_path)); } + pdb_set_profile_path(sampass, profile_path, setflag); pdb_set_acct_desc (sampass, acct_desc); pdb_set_workstations (sampass, workstations); pdb_set_munged_dial (sampass, munged_dial); - - if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) { - if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) { - ret = False; - goto done; - } + if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) { + ret = False; + goto done; } - - if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) { - if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) { - ret = False; - goto done; - } + if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) { + ret = False; + goto done; } - pdb_set_user_sid_from_rid(sampass, user_rid); - pdb_set_group_sid_from_rid(sampass, group_rid); + pdb_set_user_rid(sampass, user_rid); + pdb_set_group_rid(sampass, group_rid); pdb_set_unknown_3(sampass, unknown_3); pdb_set_hours_len(sampass, hours_len); pdb_set_unknown_5(sampass, unknown_5); @@ -483,9 +462,9 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state, Open the TDB passwd database for SAM account enumeration. ****************************************************************/ -static BOOL tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update) +static BOOL tdbsam_setsampwent(struct pdb_context *context, BOOL update) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->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))) @@ -511,9 +490,9 @@ static void close_tdb(struct tdbsam_privates *tdb_state) End enumeration of the TDB passwd list. ****************************************************************/ -static void tdbsam_endsampwent(struct pdb_methods *my_methods) +static void tdbsam_endsampwent(struct pdb_context *context) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; close_tdb(tdb_state); DEBUG(7, ("endtdbpwent: closed sam database.\n")); @@ -523,9 +502,9 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods) Get one SAM_ACCOUNT from the TDB (next in line) *****************************************************************/ -static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) +static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; TDB_DATA data; char *prefix = USERPREFIX; int prefixlen = strlen (prefix); @@ -571,9 +550,9 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user Lookup a name in the SAM TDB ******************************************************************/ -static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) +static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user, const char *sname) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; TDB_CONTEXT *pwd_tdb; TDB_DATA data, key; fstring keystr; @@ -627,9 +606,9 @@ static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *use Search by rid **************************************************************************/ -static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) +static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user, uint32 rid) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; TDB_CONTEXT *pwd_tdb; TDB_DATA data, key; fstring keystr; @@ -665,24 +644,16 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use tdb_close (pwd_tdb); - return tdbsam_getsampwnam (my_methods, user, name); -} - -static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return False; - return tdbsam_getsampwrid(my_methods, user, rid); + return tdbsam_getsampwnam (context, user, name); } /*************************************************************************** Delete a SAM_ACCOUNT ****************************************************************************/ -static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass) +static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sam_pass) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; TDB_CONTEXT *pwd_tdb; TDB_DATA key; fstring keystr; @@ -736,9 +707,9 @@ static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUN Update the TDB SAM ****************************************************************************/ -static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) +static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpwd, int flag) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data; TDB_CONTEXT *pwd_tdb = NULL; TDB_DATA key, data; uint8 *buf = NULL; @@ -746,7 +717,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, fstring name; BOOL ret = True; uint32 user_rid; - BOOL tdb_ret; + int32 tdb_ret; /* invalidate the existing TDB iterator if it is open */ if (tdb_state->passwd_tdb) { @@ -765,32 +736,13 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, /* 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); - } 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); + user_rid = BASE_RID; + tdb_ret = tdb_change_int32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER); + if (tdb_ret == -1) { + ret = False; + goto done; } + pdb_set_user_rid(newpwd, user_rid); } else { DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd))); ret = False; @@ -806,7 +758,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, 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_set_group_rid(newpwd, DOMAIN_GROUP_RID_USERS); } } else { DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); @@ -871,18 +823,18 @@ done: Modifies an existing SAM_ACCOUNT ****************************************************************************/ -static BOOL tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd) +static BOOL tdbsam_update_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd) { - return (tdb_update_sam(my_methods, newpwd, TDB_MODIFY)); + return (tdb_update_sam(context, newpwd, TDB_MODIFY)); } /*************************************************************************** Adds an existing SAM_ACCOUNT ****************************************************************************/ -static BOOL tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd) +static BOOL tdbsam_add_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd) { - return (tdb_update_sam(my_methods, newpwd, TDB_INSERT)); + return (tdb_update_sam(context, newpwd, TDB_INSERT)); } static void free_private_data(void **vp) @@ -900,14 +852,6 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con 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; } @@ -918,7 +862,7 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con (*pdb_method)->endsampwent = tdbsam_endsampwent; (*pdb_method)->getsampwent = tdbsam_getsampwent; (*pdb_method)->getsampwnam = tdbsam_getsampwnam; - (*pdb_method)->getsampwsid = tdbsam_getsampwsid; + (*pdb_method)->getsampwrid = tdbsam_getsampwrid; (*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; @@ -940,8 +884,6 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con 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; @@ -962,7 +904,7 @@ NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, (*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)) { @@ -970,10 +912,10 @@ NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, return NT_STATUS_UNSUCCESSFUL; } - tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); +/* 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; } diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 3ecaf52e58..b3507a1392 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -1,8 +1,6 @@ /* Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 1992-2001 - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Rafal Szczesniak 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 @@ -24,9 +22,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_PASSDB - static TDB_CONTEXT *tdb; /* open up the secrets database */ @@ -52,7 +47,7 @@ BOOL secrets_init(void) /* read a entry from the secrets database - the caller must free the result if size is non-null then the size of the entry is put in there */ -void *secrets_fetch(const char *key, size_t *size) +void *secrets_fetch(char *key, size_t *size) { TDB_DATA kbuf, dbuf; secrets_init(); @@ -68,7 +63,7 @@ void *secrets_fetch(const char *key, size_t *size) /* store a secrets entry */ -BOOL secrets_store(const char *key, void *data, size_t size) +BOOL secrets_store(char *key, void *data, size_t size) { TDB_DATA kbuf, dbuf; secrets_init(); @@ -84,7 +79,7 @@ BOOL secrets_store(const char *key, void *data, size_t size) /* delete a secets database entry */ -BOOL secrets_delete(const char *key) +BOOL secrets_delete(char *key) { TDB_DATA kbuf; secrets_init(); @@ -129,14 +124,10 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid) } -/** - * Form a key for fetching the machine trust account password - * - * @param domain domain name - * - * @return stored password's key - **/ -const char *trust_keystr(const char *domain) +/************************************************************************ +form a key for fetching the machine trust account password +************************************************************************/ +char *trust_keystr(char *domain) { static fstring keystr; @@ -150,11 +141,11 @@ const char *trust_keystr(const char *domain) /** * Form a key for fetching a trusted domain password * - * @param domain trusted domain name + * @param domain domain name * * @return stored password's key **/ -char *trustdom_keystr(const char *domain) +char *trustdom_keystr(char *domain) { static char* keystr; @@ -203,23 +194,21 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16], Routine to get account password to trusted domain ************************************************************************/ BOOL secrets_fetch_trusted_domain_password(char *domain, char** pwd, - DOM_SID *sid, time_t *pass_last_set_time) + DOM_SID *sid, time_t *pass_last_set_time) { struct trusted_dom_pass *pass; size_t size; - /* fetching trusted domain password structure */ if (!(pass = secrets_fetch(trustdom_keystr(domain), &size))) { DEBUG(5, ("secrets_fetch failed!\n")); return False; } - + if (size != sizeof(*pass)) { DEBUG(0, ("secrets were of incorrect size!\n")); return False; } - - /* the trust's password */ + if (pwd) { *pwd = strdup(pass->pass); if (!*pwd) { @@ -227,12 +216,9 @@ BOOL secrets_fetch_trusted_domain_password(char *domain, char** pwd, } } - /* last change time */ if (pass_last_set_time) *pass_last_set_time = pass->mod_time; - /* domain sid */ memcpy(&sid, &(pass->domain_sid), sizeof(sid)); - SAFE_FREE(pass); return True; @@ -261,30 +247,19 @@ BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16]) * @return true if succeeded **/ -BOOL secrets_store_trusted_domain_password(char* domain, smb_ucs2_t *uni_dom_name, - size_t uni_name_len, char* pwd, +BOOL secrets_store_trusted_domain_password(char* domain, char* pwd, DOM_SID sid) { struct trusted_dom_pass pass; ZERO_STRUCT(pass); - /* unicode domain name and its length */ - if (!uni_dom_name) - return False; - - strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1); - pass.uni_name_len = uni_name_len; - - /* last change time */ pass.mod_time = time(NULL); - /* password of the trust */ pass.pass_len = strlen(pwd); fstrcpy(pass.pass, pwd); - /* domain sid */ memcpy(&(pass.domain_sid), &sid, sizeof(sid)); - + return secrets_store(trustdom_keystr(domain), (void *)&pass, sizeof(pass)); } @@ -325,7 +300,7 @@ char *secrets_fetch_machine_password(void) Routine to delete the machine trust account password file for a domain. ************************************************************************/ -BOOL trust_password_delete(const char *domain) +BOOL trust_password_delete(char *domain) { return secrets_delete(trust_keystr(domain)); } @@ -333,7 +308,7 @@ BOOL trust_password_delete(const char *domain) /************************************************************************ Routine to delete the password for trusted domain ************************************************************************/ -BOOL trusted_domain_password_delete(const char *domain) +BOOL trusted_domain_password_delete(char *domain) { return secrets_delete(trustdom_keystr(domain)); } @@ -370,136 +345,15 @@ void reset_globals_after_fork(void) generate_random_buffer( &dummy, 1, True); } -BOOL secrets_store_ldap_pw(const char* dn, char* pw) +BOOL secrets_store_ldap_pw(char* dn, char* pw) { - char *key = NULL; - BOOL ret; - - if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) { - DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n")); - return False; - } - - ret = secrets_store(key, pw, strlen(pw)+1); + fstring key; + char *p; - SAFE_FREE(key); - return ret; -} - - -/** - * The linked list is allocated on the supplied talloc context, caller gets to destory - * when done. - * - * @param ctx Allocation context - * @param enum_ctx Starting index, eg. we can start fetching at third - * or sixth trusted domain entry. Zero is the first index. - * Value it is set to is the enum context for the next enumeration. - * @param num_domains Number of domain entries to fetch at one call - * @param domains Pointer to array of trusted domain structs to be filled up - * - * @return nt status code of rpc response - **/ - -NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num_domains, int *num_domains, TRUSTDOM ***domains) -{ - TDB_LIST_NODE *keys, *k; - TRUSTDOM *dom = NULL; - char *pattern; - int start_idx; - uint32 idx = 0; - size_t size; - struct trusted_dom_pass *pass; - NTSTATUS status; - - secrets_init(); - - *num_domains = 0; - start_idx = *enum_ctx; - - /* generate searching pattern */ - if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) { - DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n", - max_num_domains, *enum_ctx)); - - *domains = talloc_zero(ctx, sizeof(**domains)*max_num_domains); - - /* fetching trusted domains' data and collecting them in a list */ - keys = tdb_search_keys(tdb, pattern); - - /* - * if there's no keys returned ie. no trusted domain, - * return "no more entries" code - */ - status = NT_STATUS_NO_MORE_ENTRIES; - - /* searching for keys in sectrets db -- way to go ... */ - for (k = keys; k; k = k->next) { - char *secrets_key; - - /* important: ensure null-termination of the key string */ - secrets_key = strndup(k->node_key.dptr, k->node_key.dsize); - if (!secrets_key) { - DEBUG(0, ("strndup failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - pass = secrets_fetch(secrets_key, &size); - - if (size != sizeof(*pass)) { - DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key)); - SAFE_FREE(pass); - continue; - } - - SAFE_FREE(secrets_key); - - if (idx >= start_idx && idx < start_idx + max_num_domains) { - dom = talloc_zero(ctx, sizeof(*dom)); - if (!dom) { - /* free returned tdb record */ - SAFE_FREE(pass); - - return NT_STATUS_NO_MEMORY; - } - - /* copy domain sid */ - SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid)); - memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid)); - - /* copy unicode domain name */ - dom->name = talloc_strdup_w(ctx, pass->uni_name); - - (*domains)[idx - start_idx] = dom; - - *enum_ctx = idx + 1; - (*num_domains)++; - - /* set proper status code to return */ - if (k->next) { - /* there are yet some entries to enumerate */ - status = STATUS_MORE_ENTRIES; - } else { - /* this is the last entry in the whole enumeration */ - status = NT_STATUS_OK; - } - } - - idx++; - - /* free returned tdb record */ - SAFE_FREE(pass); - } + pstrcpy(key, dn); + for (p=key; *p; p++) + if (*p == ',') *p = '/'; - DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains)); - - /* free the results of searching the keys */ - tdb_search_list_free(keys); - - return status; + return secrets_store(key, pw, strlen(pw)); } |