diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2011-03-16 12:29:37 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2011-03-23 04:58:37 -0400 |
commit | d86c2d2995933d61fc3c63f74ec260b5c8c75bf9 (patch) | |
tree | b480ea82383bedf7408bed830fd1c658486cb02f | |
parent | 42d8e67c26df2b7660507d26b9a50911bdd3cf18 (diff) | |
download | sssd-d86c2d2995933d61fc3c63f74ec260b5c8c75bf9.tar.gz sssd-d86c2d2995933d61fc3c63f74ec260b5c8c75bf9.tar.xz sssd-d86c2d2995933d61fc3c63f74ec260b5c8c75bf9.zip |
Add sysdb_attrs_primary_name()
This function will check a sysdb_attrs struct for the primary name
of the entity it represents. If there are multiple entries, it
will pick the one that matches the RDN. If none match, it will
throw an error.
-rw-r--r-- | src/db/sysdb.c | 102 | ||||
-rw-r--r-- | src/db/sysdb.h | 4 |
2 files changed, 106 insertions, 0 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c index 34c65dfab..ef9d0a237 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -2154,3 +2154,105 @@ done: talloc_free(tmp_ctx); return ret; } + +errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, + struct sysdb_attrs *attrs, + const char *ldap_attr, + const char **_primary) +{ + errno_t ret; + char *rdn_attr = NULL; + char *rdn_val = NULL; + struct ldb_message_element *sysdb_name_el; + struct ldb_message_element *orig_dn_el; + size_t i; + TALLOC_CTX *tmpctx = NULL; + + tmpctx = talloc_new(NULL); + if (!tmpctx) { + return ENOMEM; + } + + ret = sysdb_attrs_get_el(attrs, + SYSDB_NAME, + &sysdb_name_el); + if (sysdb_name_el->num_values == 0) { + ret = EINVAL; + goto done; + } + + if (sysdb_name_el->num_values == 1) { + /* Entry contains only one name. Just return that */ + *_primary = (const char *)sysdb_name_el->values[0].data; + ret = EOK; + goto done; + } + + /* Multiple values for name. Check whether one matches the RDN */ + + ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &orig_dn_el); + if (ret) { + goto done; + } + if (orig_dn_el->num_values == 0) { + DEBUG(7, ("Original DN is not available.\n")); + } else if (orig_dn_el->num_values == 1) { + ret = sysdb_get_rdn(sysdb, tmpctx, + (const char *) orig_dn_el->values[0].data, + &rdn_attr, + &rdn_val); + if (ret != EOK) { + DEBUG(1, ("Could not get rdn from [%s]\n", + (const char *) orig_dn_el->values[0].data)); + goto done; + } + } else { + DEBUG(1, ("Should not have more than one origDN\n")); + ret = EINVAL; + goto done; + } + + /* First check whether the attribute name matches */ + DEBUG(8, ("Comparing attribute names [%s] and [%s]\n", + rdn_attr, ldap_attr)); + 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. + */ + DEBUG(1, ("Cannot save entry. It has multiple names and the RDN " + "attribute does not match\n")); + ret = EINVAL; + goto done; + } + + for (i = 0; i < sysdb_name_el->num_values; i++) { + if (strcasecmp(rdn_val, + (const char *)sysdb_name_el->values[i].data) == 0) { + /* This name matches the RDN. Use it */ + break; + } + } + if (i < sysdb_name_el->num_values) { + /* Match was found */ + *_primary = (const char *)sysdb_name_el->values[i].data; + } else { + /* If we can't match the name to the RDN, we just have to + * throw up our hands. There's no deterministic way to + * decide which name is correct. + */ + DEBUG(1, ("Cannot save entry. Unable to determine groupname\n")); + ret = EINVAL; + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + DEBUG(1, ("Could not determine primary name: [%d][%s]\n", + ret, strerror(ret))); + } + talloc_free(tmpctx); + return ret; +} diff --git a/src/db/sysdb.h b/src/db/sysdb.h index caef6163e..e98426551 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -215,6 +215,10 @@ int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs, const char *domain, struct ldb_val *values, int num_values); +errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, + struct sysdb_attrs *attrs, + const char *ldap_attr, + const char **_primary); /* convert an ldb error into an errno error */ int sysdb_error_to_errno(int ldberr); |