diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2011-09-21 10:39:06 +0200 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2011-10-06 11:08:25 -0400 |
commit | bcec4a854de207a4f399d14f936a21edc5575683 (patch) | |
tree | b35506c7abd26d7b5e8306e44ed50960713318fc /src/db | |
parent | d7c7edcf4c7014dff3f84b5b56dbd4453cf608aa (diff) | |
download | sssd_unused-bcec4a854de207a4f399d14f936a21edc5575683.tar.gz sssd_unused-bcec4a854de207a4f399d14f936a21edc5575683.tar.xz sssd_unused-bcec4a854de207a4f399d14f936a21edc5575683.zip |
Better handling for aliases
Add sysdb interface to get name aliases
Add a sysdb_get_direct_parents function
Store name aliases for users, groups
Return users and groups based on alias
https://fedorahosted.org/sssd/ticket/926
Fix typo in sysdb_get_direct_parents
Diffstat (limited to 'src/db')
-rw-r--r-- | src/db/sysdb.c | 60 | ||||
-rw-r--r-- | src/db/sysdb.h | 18 | ||||
-rw-r--r-- | src/db/sysdb_search.c | 108 |
3 files changed, 179 insertions, 7 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c index 42a4240f..a1c16318 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -2131,7 +2131,7 @@ errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, if (strcasecmp(rdn_attr, ldap_attr) != 0) { /* Multiple entries, and the RDN attribute doesn't match. * We have no way of resolving this deterministically, - * so we'll punt. + * so we'll use the first value as a fallback. */ DEBUG(3, ("The entry has multiple names and the RDN attribute does " "not match. Will use the first value as fallback.\n")); @@ -2171,6 +2171,64 @@ done: return ret; } +/* + * An entity with multiple names would have multiple SYSDB_NAME attributes + * after being translated into sysdb names using a map. + * Given a primary name returned by sysdb_attrs_primary_name(), this function + * returns the other SYSDB_NAME attribute values so they can be saved as + * SYSDB_NAME_ALIAS into cache. + */ +errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx, + struct sysdb_attrs *attrs, + const char *primary, + const char ***_aliases) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_message_element *sysdb_name_el; + size_t i, ai; + errno_t ret; + const char **aliases = NULL; + const char *name; + + if (_aliases == NULL) return EINVAL; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + ret = sysdb_attrs_get_el(attrs, + SYSDB_NAME, + &sysdb_name_el); + if (sysdb_name_el->num_values == 0) { + ret = EINVAL; + goto done; + } + + aliases = talloc_array(tmp_ctx, const char *, + sysdb_name_el->num_values); + if (!aliases) { + ret = ENOMEM; + goto done; + } + + ai = 0; + for (i=0; i < sysdb_name_el->num_values; i++) { + name = (const char *)sysdb_name_el->values[i].data; + if (strcmp(primary, name) != 0) { + aliases[ai] = name; + ai++; + } + } + + aliases[ai] = NULL; + ret = EOK; +done: + *_aliases = talloc_steal(mem_ctx, aliases); + talloc_free(tmp_ctx); + return ret; +} + errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, struct sysdb_attrs **attr_list, diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 68d3021e..7f2e41f9 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -46,6 +46,7 @@ #define SYSDB_NETGROUP_CLASS "netgroup" #define SYSDB_NAME "name" +#define SYSDB_NAME_ALIAS "nameAlias" #define SYSDB_OBJECTCLASS "objectClass" #define SYSDB_NEXTID "nextID" @@ -106,15 +107,15 @@ #define SYSDB_NC "objectclass="SYSDB_NETGROUP_CLASS #define SYSDB_MPGC "|("SYSDB_UC")("SYSDB_GC")" -#define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")("SYSDB_NAME"=%s))" +#define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_PWUID_FILTER "(&("SYSDB_UC")("SYSDB_UIDNUM"=%lu))" #define SYSDB_PWENT_FILTER "("SYSDB_UC")" -#define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")("SYSDB_NAME"=%s))" +#define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRNA2_FILTER "(&("SYSDB_UC")("SYSDB_MEMBEROF"=%s))" #define SYSDB_GRGID_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRENT_FILTER "("SYSDB_GC")" -#define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_NAME"=%s))" +#define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRGID_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRENT_MPG_FILTER "("SYSDB_MPGC")" @@ -222,6 +223,10 @@ errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, struct sysdb_attrs *attrs, const char *ldap_attr, const char **_primary); +errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx, + struct sysdb_attrs *attrs, + const char *primary, + const char ***_aliases); errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, struct sysdb_attrs **attr_list, @@ -735,4 +740,11 @@ errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb, enum sysdb_member_type type, char **remove_attrs); +errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *dom, + enum sysdb_member_type mtype, + const char *name, + char ***_direct_parents); + #endif /* __SYS_DB_H__ */ diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c index dfae4ddf..9c386cae 100644 --- a/src/db/sysdb_search.c +++ b/src/db/sysdb_search.c @@ -63,7 +63,7 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER, - sanitized_name); + sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; @@ -248,7 +248,7 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx, ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, fmt_filter, - sanitized_name); + sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; @@ -512,7 +512,8 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn, LDB_SCOPE_SUBTREE, attributes, - SYSDB_PWNAM_FILTER, sanitized_name); + SYSDB_PWNAM_FILTER, sanitized_name, + sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; @@ -888,3 +889,104 @@ done: talloc_zfree(tmpctx); return ret; } + +errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *dom, + enum sysdb_member_type mtype, + const char *name, + char ***_direct_parents) +{ + errno_t ret; + const char *dn; + struct ldb_dn *basedn; + static const char *group_attrs[] = { SYSDB_NAME, NULL }; + const char *member_filter; + size_t direct_sysdb_count = 0; + struct ldb_message **direct_sysdb_groups = NULL; + char **direct_parents = NULL; + TALLOC_CTX *tmp_ctx = NULL; + int i, pi; + const char *tmp_str; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) return ENOMEM; + + if (mtype == SYSDB_MEMBER_USER) { + dn = sysdb_user_strdn(tmp_ctx, dom->name, name); + } else if (mtype == SYSDB_MEMBER_GROUP) { + dn = sysdb_group_strdn(tmp_ctx, dom->name, name); + } else { + DEBUG(1, ("Unknown member type\n")); + ret = EINVAL; + goto done; + } + + if (!dn) { + ret = ENOMEM; + goto done; + } + + member_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", + SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS, + SYSDB_MEMBER, dn); + if (!member_filter) { + ret = ENOMEM; + goto done; + } + + basedn = ldb_dn_new_fmt(tmp_ctx, sysdb_ctx_get_ldb(sysdb), + SYSDB_TMPL_GROUP_BASE, dom->name); + if (!basedn) { + ret = ENOMEM; + goto done; + } + + DEBUG(8, ("searching sysdb with filter [%s]\n", member_filter)); + + ret = sysdb_search_entry(tmp_ctx, sysdb, basedn, + LDB_SCOPE_SUBTREE, member_filter, group_attrs, + &direct_sysdb_count, &direct_sysdb_groups); + if (ret == ENOENT) { + direct_sysdb_count = 0; + } else if (ret != EOK && ret != ENOENT) { + DEBUG(2, ("sysdb_search_entry failed: [%d]: %s\n", + ret, strerror(ret))); + goto done; + } + + /* EOK */ + /* Get the list of sysdb groups by name */ + direct_parents = talloc_array(tmp_ctx, char *, direct_sysdb_count+1); + if (!direct_parents) { + ret = ENOMEM; + goto done; + } + + pi = 0; + for(i = 0; i < direct_sysdb_count; i++) { + tmp_str = ldb_msg_find_attr_as_string(direct_sysdb_groups[i], + SYSDB_NAME, NULL); + if (!tmp_str) { + /* This should never happen, but if it does, just continue */ + continue; + } + + direct_parents[pi] = talloc_strdup(direct_parents, tmp_str); + if (!direct_parents[pi]) { + DEBUG(1, ("A group with no name?\n")); + ret = EIO; + goto done; + } + pi++; + } + direct_parents[pi] = NULL; + + DEBUG(7, ("%s is a member of %d sysdb groups\n", + name, direct_sysdb_count)); + *_direct_parents = talloc_steal(mem_ctx, direct_parents); + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} |