summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-11-07 14:41:08 +0000
committerGerald Carter <jerry@samba.org>2003-11-07 14:41:08 +0000
commite9bd28d0a7b0fd667e52683013404dc4b1e03673 (patch)
tree9c1599d3f70a7246bc4657e21c7827fa8840a403
parent178a4635245c2c433b9a510282ad5c49a2ffe804 (diff)
downloadsamba-e9bd28d0a7b0fd667e52683013404dc4b1e03673.tar.gz
samba-e9bd28d0a7b0fd667e52683013404dc4b1e03673.tar.bz2
samba-e9bd28d0a7b0fd667e52683013404dc4b1e03673.zip
fix for bug 680 (heads up). This gist is to map the
UNIX entity foo to DOMAIN\foo instead of SERVER\foo on members of a Samba domain when all UNIX accounts are shared via NIS, et. al. * allow winbindd to match local accounts to domain SID when 'winbind trusted domains only = yes' * remove code in idmap_ldap that searches the user suffix and group suffix. It's not needed and provides inconsistent functionality from the tdb backend. This has been tested. I'm still waiting on some more feedback but This needs to be in 3.0.1pre2 for widespread use. (This used to be commit cac4723e206bd001882011c9e12327064d032268)
-rw-r--r--source3/nsswitch/winbindd_sid.c240
-rw-r--r--source3/passdb/lookup_sid.c22
-rw-r--r--source3/sam/idmap_ldap.c484
3 files changed, 361 insertions, 385 deletions
diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c
index ac1ee11555..0faeec5636 100644
--- a/source3/nsswitch/winbindd_sid.c
+++ b/source3/nsswitch/winbindd_sid.c
@@ -130,16 +130,75 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
state->request.data.sid));
- /* Split sid into domain sid and user rid */
if (!string_to_sid(&sid, state->request.data.sid)) {
DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
return WINBINDD_ERROR;
}
+ /* This gets a little tricky. If we assume that usernames are syncd between
+ /etc/passwd and the windows domain (such as a member of a Samba domain),
+ the we need to get the uid from the OS and not alocate one ourselves */
+
+ if ( lp_winbind_trusted_domains_only() ) {
+ struct winbindd_domain *domain = NULL;
+ DOM_SID sid2;
+ uint32 rid;
+
+ domain = find_domain_from_name( lp_workgroup() );
+ if ( !domain ) {
+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sid_copy( &sid2, &sid );
+ sid_split_rid( &sid2, &rid );
+
+ if ( sid_equal( &sid2, &domain->sid ) ) {
+
+ fstring domain_name;
+ fstring user;
+ enum SID_NAME_USE type;
+ struct passwd *pw = NULL;
+ unid_t id;
+
+ /* ok...here's we know that we are dealing with our
+ own domain (the one to which we are joined). And
+ we know that there must be a UNIX account for this user.
+ So we lookup the sid and the call getpwnam().*/
+
+
+ /* But first check and see if we don't already have a mapping */
+
+ flags = ID_QUERY_ONLY;
+ if ( NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) )
+ return WINBINDD_OK;
+
+ /* now fall back to the hard way */
+
+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, user, &type) )
+ return WINBINDD_ERROR;
+
+ if ( !(pw = getpwnam(user)) ) {
+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
+ "set but this user [%s] doesn't exist!\n", user));
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.uid = pw->pw_uid;
+
+ id.uid = pw->pw_uid;
+ idmap_set_mapping( &sid, id, ID_USERID );
+
+ return WINBINDD_OK;
+ }
+
+ }
+
if ( state->request.flags & WBFLAG_QUERY_ONLY )
flags = ID_QUERY_ONLY;
/* Find uid for this sid and return it */
+
if ( !NT_STATUS_IS_OK(idmap_sid_to_uid(&sid, &(state->response.data.uid), flags)) ) {
DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid));
return WINBINDD_ERROR;
@@ -167,6 +226,64 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ /* This gets a little tricky. If we assume that usernames are syncd between
+ /etc/passwd and the windows domain (such as a member of a Samba domain),
+ the we need to get the uid from the OS and not alocate one ourselves */
+
+ if ( lp_winbind_trusted_domains_only() ) {
+ struct winbindd_domain *domain = NULL;
+ DOM_SID sid2;
+ uint32 rid;
+ unid_t id;
+
+ domain = find_domain_from_name( lp_workgroup() );
+ if ( !domain ) {
+ DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sid_copy( &sid2, &sid );
+ sid_split_rid( &sid2, &rid );
+
+ if ( sid_equal( &sid2, &domain->sid ) ) {
+
+ fstring domain_name;
+ fstring group;
+ enum SID_NAME_USE type;
+ struct group *grp = NULL;
+
+ /* ok...here's we know that we are dealing with our
+ own domain (the one to which we are joined). And
+ we know that there must be a UNIX account for this group.
+ So we lookup the sid and the call getpwnam().*/
+
+ /* But first check and see if we don't already have a mapping */
+
+ flags = ID_QUERY_ONLY;
+ if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) )
+ return WINBINDD_OK;
+
+ /* now fall back to the hard way */
+
+ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) )
+ return WINBINDD_ERROR;
+
+ if ( !(grp = getgrnam(group)) ) {
+ DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is "
+ "set but this group [%s] doesn't exist!\n", group));
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.gid = grp->gr_gid;
+
+ id.gid = grp->gr_gid;
+ idmap_set_mapping( &sid, id, ID_GROUPID );
+
+ return WINBINDD_OK;
+ }
+
+ }
+
if ( state->request.flags & WBFLAG_QUERY_ONLY )
flags = ID_QUERY_ONLY;
@@ -185,28 +302,65 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
-#if 0 /* JERRY */
- /* we cannot do this check this anymore since a domain member of
- a Samba domain may share unix accounts via NIS or LDAP. In this
- case the uid/gid will be out of winbindd's range but still might
- be resolved to a SID via an ldap idmap backend */
-
- if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high)) {
- return WINBINDD_ERROR;
- }
-#endif
-
DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.uid));
+ if ( (state->request.data.uid < server_state.uid_low )
+ || (state->request.data.uid > server_state.uid_high) )
+ {
+ struct passwd *pw = NULL;
+ enum SID_NAME_USE type;
+ unid_t id;
+ struct winbindd_domain *domain;
+
+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
+
+ /* if we don't trust /etc/password then when can't know
+ anything about this uid */
+
+ if ( !lp_winbind_trusted_domains_only() )
+ return WINBINDD_ERROR;
+
+
+ /* look for an idmap entry first */
+
+ if ( NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid)) )
+ goto done;
+
+ /* if users exist in /etc/passwd, we should try to
+ use that uid. Get the username and the lookup the SID */
+
+ if ( !(pw = getpwuid(state->request.data.uid)) )
+ return WINBINDD_ERROR;
+
+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ if ( !winbindd_lookup_sid_by_name(domain, pw->pw_name, &sid, &type) )
+ return WINBINDD_ERROR;
+
+ if ( type != SID_NAME_USER )
+ return WINBINDD_ERROR;
+
+ /* don't fail if we can't store it */
+
+ id.uid = pw->pw_uid;
+ idmap_set_mapping( &sid, id, ID_USERID );
+
+ goto done;
+ }
+
/* Lookup rid for this uid */
+
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) {
DEBUG(1, ("Could not convert uid %lu to rid\n",
(unsigned long)state->request.data.uid));
return WINBINDD_ERROR;
}
+done:
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_USER;
@@ -219,28 +373,64 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
-#if 0 /* JERRY */
- /* we cannot do this check this anymore since a domain member of
- a Samba domain may share unix accounts via NIS or LDAP. In this
- case the uid/gid will be out of winbindd's range but still might
- be resolved to a SID via an ldap idmap backend */
-
- if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high)) {
- return WINBINDD_ERROR;
- }
-#endif
-
DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.gid));
+
+ if ( (state->request.data.gid < server_state.gid_low)
+ || (state->request.data.gid > server_state.gid_high) )
+ {
+ struct group *grp = NULL;
+ enum SID_NAME_USE type;
+ unid_t id;
+ struct winbindd_domain *domain;
+
+ /* SPECIAL CASE FOR MEMBERS OF SAMBA DOMAINS */
+
+ /* if we don't trust /etc/group then when can't know
+ anything about this gid */
+
+ if ( !lp_winbind_trusted_domains_only() )
+ return WINBINDD_ERROR;
+
+ /* look for an idmap entry first */
+
+ if ( NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid)) )
+ goto done;
+
+ /* if users exist in /etc/group, we should try to
+ use that gid. Get the username and the lookup the SID */
+
+ if ( !(grp = getgrgid(state->request.data.gid)) )
+ return WINBINDD_ERROR;
+
+ if ( !(domain = find_domain_from_name(lp_workgroup())) ) {
+ DEBUG(0,("winbindd_uid_to_sid: can't find my own domain!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ if ( !winbindd_lookup_sid_by_name(domain, grp->gr_name, &sid, &type) )
+ return WINBINDD_ERROR;
+
+ if ( type!=SID_NAME_DOM_GRP && type!=SID_NAME_ALIAS )
+ return WINBINDD_ERROR;
+
+ /* don't fail if we can't store it */
+
+ id.gid = grp->gr_gid;
+ idmap_set_mapping( &sid, id, ID_GROUPID );
+
+ goto done;
+ }
/* Lookup sid for this uid */
+
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) {
DEBUG(1, ("Could not convert gid %lu to sid\n",
(unsigned long)state->request.data.gid));
return WINBINDD_ERROR;
}
+done:
/* Construct sid and return it */
sid_to_string(state->response.data.sid.sid, &sid);
state->response.data.sid.type = SID_NAME_DOM_GRP;
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index f84ff28db9..425c9b87f1 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -299,15 +299,20 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
{
- uid_t low, high;
fstring sid;
+ uid_t low, high;
ZERO_STRUCTP(psid);
if (fetch_sid_from_uid_cache(psid, uid))
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) {
+ /* DC's never use winbindd to resolve users outside the
+ defined idmap range */
+
+ if ( lp_server_role()==ROLE_DOMAIN_MEMBER
+ || (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) )
+ {
if (winbind_uid_to_sid(psid, uid)) {
DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
@@ -336,15 +341,20 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
{
- gid_t low, high;
fstring sid;
+ gid_t low, high;
ZERO_STRUCTP(psid);
if (fetch_sid_from_gid_cache(psid, gid))
return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) {
+ /* DC's never use winbindd to resolve groups outside the
+ defined idmap range */
+
+ if ( lp_server_role()==ROLE_DOMAIN_MEMBER
+ || (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) )
+ {
if (winbind_gid_to_sid(psid, gid)) {
DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
@@ -458,7 +468,9 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
/* winbindd knows it; Ensure this is a group sid */
- if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
+ if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS)
+ && (name_type != SID_NAME_WKN_GRP))
+ {
DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
(unsigned int)name_type ));
diff --git a/source3/sam/idmap_ldap.c b/source3/sam/idmap_ldap.c
index 72fcb47b03..2a94de755a 100644
--- a/source3/sam/idmap_ldap.c
+++ b/source3/sam/idmap_ldap.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
idmap LDAP backend
@@ -7,17 +7,17 @@
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
Copyright (C) Gerald Carter 2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -34,25 +34,84 @@
#include "smbldap.h"
-#define IDMAP_GROUP_SUFFIX "ou=idmap group"
-#define IDMAP_USER_SUFFIX "ou=idmap people"
-
-
struct ldap_idmap_state {
struct smbldap_state *smbldap_state;
TALLOC_CTX *mem_ctx;
};
-#define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating
- new id */
-
static struct ldap_idmap_state ldap_state;
-static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type);
-static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id, int id_type,
- const char *ldap_dn, LDAPMessage *entry);
-static NTSTATUS ldap_idmap_close(void);
+/* number tries while allocating new id */
+#define LDAP_MAX_ALLOC_ID 128
+
+
+/***********************************************************************
+ This function cannot be called to modify a mapping, only set a new one
+***********************************************************************/
+static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
+{
+ pstring dn;
+ pstring id_str;
+ fstring type;
+ LDAPMod **mods = NULL;
+ int rc = -1;
+ int ldap_op;
+ fstring sid_string;
+ LDAPMessage *entry = NULL;
+
+ sid_to_string( sid_string, sid );
+
+ ldap_op = LDAP_MOD_ADD;
+ pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
+ sid_string, lp_ldap_idmap_suffix());
+
+ if ( id_type & ID_USERID )
+ fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) );
+ else
+ fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) );
+
+ pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid));
+
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
+
+ smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
+ entry, &mods, type, id_str );
+
+ smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
+ entry, &mods,
+ get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
+ sid_string );
+
+ /* There may well be nothing at all to do */
+
+ if (mods) {
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY );
+ rc = smbldap_add(ldap_state.smbldap_state, dn, mods);
+ ldap_mods_free( mods, True );
+ } else {
+ rc = LDAP_SUCCESS;
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ &ld_error);
+ DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
+ (ldap_op == LDAP_MOD_ADD) ? "add" : "replace",
+ sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type));
+ DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
+ ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
+ sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid), type));
+
+ return NT_STATUS_OK;
+}
/**********************************************************************
Even if the sambaDomain attribute in LDAP tells us that this RID is
@@ -77,7 +136,7 @@ static BOOL sid_in_use(struct ldap_idmap_state *state,
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
+ DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
sid_string, ld_error));
SAFE_FREE(ld_error);
@@ -142,7 +201,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
}
/* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and
- algorithmic_rid_base. The other two are to avoid stomping on the
+ algorithmic_rid_base. The other two are to avoid stomping on the
different sets of algorithmic RIDs */
if (smbldap_get_single_attribute(state->smbldap_state->ldap_struct, entry,
@@ -337,7 +396,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
attr_list = get_attr_list( idpool_attr_list );
-
+
rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(),
LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &result);
@@ -421,86 +480,45 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
LDAPMessage *result = NULL;
LDAPMessage *entry = NULL;
- fstring id_str;
pstring sid_str;
pstring filter;
pstring suffix;
const char *type;
- const char *obj_class;
int rc;
int count;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
char **attr_list;
- /* first we try for a samba user or group mapping */
-
- if ( id_type & ID_USERID ) {
+ if ( id_type & ID_USERID )
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
- obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.uid );
- pstrcpy( suffix, lp_ldap_suffix());
- }
- else {
+ else
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
- obj_class = LDAP_OBJ_GROUPMAP;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
- pstrcpy( suffix, lp_ldap_group_suffix() );
- }
+
+ pstrcpy( suffix, lp_ldap_idmap_suffix() );
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+ LDAP_OBJ_IDMAP_ENTRY, type,
+ ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid));
+
DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter ));
attr_list = get_attr_list( sidmap_attr_list );
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str);
-
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
+ filter, attr_list, 0, &result);
+
if (rc != LDAP_SUCCESS) {
DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
ldap_err2string(rc) ));
goto out;
}
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if (count > 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n",
- count));
- goto out;
- }
-
- /* fall back to looking up an idmap entry if we didn't find and
- actual user or group */
-
- if (count == 0) {
- ldap_msgfree(result);
- result = NULL;
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
- LDAP_OBJ_IDMAP_ENTRY, type,
- ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid));
-
- pstrcpy( suffix, lp_ldap_idmap_suffix() );
-
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
- ldap_err2string(rc) ));
- goto out;
- }
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
- type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid)));
- goto out;
- }
+ if (count != 1) {
+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
+ type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid)));
+ goto out;
}
entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
@@ -508,7 +526,7 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
if ( !smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, sid_str) )
goto out;
- if (!string_to_sid(sid, sid_str))
+ if (!string_to_sid(sid, sid_str))
goto out;
ret = NT_STATUS_OK;
@@ -545,29 +563,14 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str,
(*id_type & ID_GROUPID ? "group" : "user") ));
- /* ahhh.... ok. We have to check users and groups in places other
- than idmap (hint: we're a domain member of a Samba domain) */
-
- if ( *id_type & ID_GROUPID ) {
-
+ suffix = lp_ldap_idmap_suffix();
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
+
+ if ( *id_type & ID_GROUPID )
type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER );
- suffix = lp_ldap_group_suffix();
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str);
-
- }
- else {
-
+ else
type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER );
- suffix = lp_ldap_suffix();
- pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
- LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str);
-
- }
DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter));
@@ -575,84 +578,55 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
attr_list = get_attr_list( sidmap_attr_list );
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if ( rc != LDAP_SUCCESS ) {
- DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n",
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
ldap_err2string(rc) ));
goto out;
}
+
+ /* check for the number of entries returned */
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
+
if ( count > 1 ) {
- DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n",
+ DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
filter, count));
goto out;
}
+
+ /* try to allocate a new id if we still haven't found one */
- /* see if we need to do a search here */
-
- if ( count == 0 ) {
-
- if ( result ) {
- ldap_msgfree(result);
- result = NULL;
- }
-
- /* look in idmap suffix */
-
- suffix = lp_ldap_idmap_suffix();
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
+ if ( !count ) {
+ int i;
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
- ldap_err2string(rc) ));
+ if (*id_type & ID_QUERY_ONLY) {
+ DEBUG(5,("ldap_get_id_from_sid: No matching entry found and QUERY_ONLY flag set\n"));
goto out;
}
-
- /* check for the number of entries returned */
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- if ( count > 1 ) {
- DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
- filter, count));
- goto out;
- }
-
-
- /* try to allocate a new id if we still haven't found one */
-
- if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) {
- int i;
-
- DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
+ DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
- ret = ldap_allocate_id(id, *id_type);
- if ( NT_STATUS_IS_OK(ret) )
- break;
- }
+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
+ ret = ldap_allocate_id(id, *id_type);
+ if ( NT_STATUS_IS_OK(ret) )
+ break;
+ }
- if ( !NT_STATUS_IS_OK(ret) ) {
- DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
- goto out;
- }
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ goto out;
+ }
- DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
- (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
+ DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
+ (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
- ret = ldap_set_mapping(sid, *id, *id_type);
+ ret = ldap_set_mapping(sid, *id, *id_type);
- /* all done */
+ /* all done */
- goto out;
- }
+ goto out;
}
DEBUG(10,("ldap_get_id_from_sid: success\n"));
@@ -684,206 +658,6 @@ out:
return ret;
}
-/***********************************************************************
- This function cannot be called to modify a mapping, only set a new one
-
- This takes a possible pointer to the existing entry for the UID or SID
- involved.
-***********************************************************************/
-
-static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id,
- int id_type, const char *ldap_dn,
- LDAPMessage *entry)
-{
- pstring dn;
- pstring id_str;
- fstring type;
- LDAPMod **mods = NULL;
- int rc = -1;
- int ldap_op;
- fstring sid_string;
- char **values = NULL;
- int i;
-
- sid_to_string( sid_string, sid );
-
- if (ldap_dn) {
- DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn));
- ldap_op = LDAP_MOD_REPLACE;
- pstrcpy( dn, ldap_dn );
- } else {
- ldap_op = LDAP_MOD_ADD;
- pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
- sid_string, lp_ldap_idmap_suffix());
- }
-
- if ( id_type & ID_USERID )
- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) );
- else
- fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) );
-
- pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid));
-
- if (entry)
- values = ldap_get_values(ldap_state.smbldap_state->ldap_struct, entry, "objectClass");
-
- if (values) {
- BOOL found_idmap = False;
- for (i=0; values[i]; i++) {
- if (StrCaseCmp(values[i], LDAP_OBJ_IDMAP_ENTRY) == 0) {
- found_idmap = True;
- break;
- }
- }
- if (!found_idmap)
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_IDMAP_ENTRY );
- } else {
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_IDMAP_ENTRY );
- }
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods, type, id_str );
-
- smbldap_make_mod( ldap_state.smbldap_state->ldap_struct,
- entry, &mods,
- get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
- sid_string );
-
- /* There may well be nothing at all to do */
- if (mods) {
- switch(ldap_op)
- {
- case LDAP_MOD_ADD:
- smbldap_set_mod( &mods, LDAP_MOD_ADD,
- "objectClass", LDAP_OBJ_SID_ENTRY );
- rc = smbldap_add(ldap_state.smbldap_state, dn, mods);
- break;
- case LDAP_MOD_REPLACE:
- rc = smbldap_modify(ldap_state.smbldap_state, dn, mods);
- break;
- }
-
- ldap_mods_free( mods, True );
- } else {
- rc = LDAP_SUCCESS;
- }
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
- (ldap_op == LDAP_MOD_ADD) ? "add" : "replace",
- sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type));
- DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
- sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid :
- (unsigned long)id.gid), type));
-
- return NT_STATUS_OK;
-}
-
-/***********************************************************************
- This function cannot be called to modify a mapping, only set a new one
-***********************************************************************/
-
-static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- char *dn = NULL;
- LDAPMessage *result = NULL;
- LDAPMessage *entry = NULL;
- const char *type;
- const char *obj_class;
- const char *posix_obj_class;
- const char *suffix;
- fstring sid_str;
- fstring id_str;
- pstring filter;
- char **attr_list;
- int rc;
- int count;
-
- /* try for a samba user or group mapping (looking for an entry with a SID) */
- if ( id_type & ID_USERID ) {
- obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- suffix = lp_ldap_suffix();
- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
- posix_obj_class = LDAP_OBJ_POSIXACCOUNT;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.uid );
- }
- else {
- obj_class = LDAP_OBJ_GROUPMAP;
- suffix = lp_ldap_group_suffix();
- type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
- posix_obj_class = LDAP_OBJ_POSIXGROUP;
- fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
- }
-
- sid_to_string(sid_str, sid);
- pstr_sprintf(filter,
- "(|"
- "(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))"
- "(&(objectClass=%s)(%s=%s))"
- ")",
- /* objectClasses that might contain a SID */
- LDAP_OBJ_SID_ENTRY, LDAP_OBJ_IDMAP_ENTRY, obj_class,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str,
-
- /* objectClasses that might contain a Unix UID/GID */
- posix_obj_class,
- /* Unix UID/GID specifier*/
- type,
- /* actual ID */
- id_str);
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS)
- goto out;
-
- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- /* fall back to looking up an idmap entry if we didn't find anything under the idmap
- user or group suffix */
-
- if (count == 1) {
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
- if (!dn)
- goto out;
- DEBUG(10, ("Found partial mapping entry at dn=%s, looking for %s\n", dn, type));
-
- ret = ldap_set_mapping_internals(sid, id, id_type, dn, entry);
-
- goto out;
- } else if (count > 1) {
- DEBUG(0, ("Too many entries trying to find DN to attach ldap \n"));
- goto out;
- }
-
- ret = ldap_set_mapping_internals(sid, id, id_type, NULL, NULL);
-
-out:
- if (result)
- ldap_msgfree(result);
- SAFE_FREE(dn);
-
- return ret;
-}
-
-
/**********************************************************************
Verify the sambaUnixIdPool entry in the directiry.
**********************************************************************/