summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/sdap.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-07-31 10:59:43 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-05-02 13:34:50 +0200
commit4dd38025efda88f123eac672f87d3cda12f050c8 (patch)
tree438cb4577369e3fff8e7b5fe5895ad811c422f4b /src/providers/ldap/sdap.c
parentfcb8e3f1f49bb34c409d8dbd75889eb72be05517 (diff)
downloadsssd-4dd38025efda88f123eac672f87d3cda12f050c8.tar.gz
sssd-4dd38025efda88f123eac672f87d3cda12f050c8.tar.xz
sssd-4dd38025efda88f123eac672f87d3cda12f050c8.zip
LDAP: Make it possible to extend an attribute map
https://fedorahosted.org/sssd/ticket/2073 This commit adds a new option ldap_user_extra_attrs that is unset by default. When set, the option contains a list of LDAP attributes the LDAP provider would download and store in addition to the usual set. The list can either contain LDAP attribute names only, or colon-separated tuples of LDAP attribute and SSSD cache attribute name. In case only LDAP attribute name is specified, the attribute is saved to the cache verbatim. Using a custom SSSD attribute name might be required by environments that configure several SSSD domains with different LDAP schemas. Reviewed-by: Simo Sorce <simo@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src/providers/ldap/sdap.c')
-rw-r--r--src/providers/ldap/sdap.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index b303547a4..37a187436 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -71,6 +71,122 @@ int sdap_copy_map(TALLOC_CTX *memctx,
return EOK;
}
+static errno_t split_extra_attr(TALLOC_CTX *mem_ctx,
+ char *conf_attr,
+ char **_sysdb_attr,
+ char **_ldap_attr)
+{
+ char *ldap_attr;
+ char *sysdb_attr;
+ char *sep;
+
+ ldap_attr = conf_attr;
+
+ sep = strchr(conf_attr, ':');
+ if (sep == NULL) {
+ sysdb_attr = talloc_strdup(mem_ctx, conf_attr);
+ ldap_attr = talloc_strdup(mem_ctx, conf_attr);
+ } else {
+ if (sep == conf_attr || *(sep + 1) == '\0') {
+ return ERR_INVALID_EXTRA_ATTR;
+ }
+
+ sysdb_attr = talloc_strndup(mem_ctx, ldap_attr,
+ sep - ldap_attr);
+ ldap_attr = talloc_strdup(mem_ctx, sep+1);
+ }
+
+ if (sysdb_attr == NULL || ldap_attr == NULL) {
+ return ENOMEM;
+ }
+
+ *_sysdb_attr = sysdb_attr;
+ *_ldap_attr = ldap_attr;
+ return EOK;
+}
+
+static bool is_sysdb_duplicate(struct sdap_attr_map *map,
+ int num_entries,
+ const char *sysdb_attr)
+{
+ int i;
+
+ for (i = 0; i < num_entries; i++) {
+ if (strcmp(map[i].sys_name, sysdb_attr) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int sdap_extend_map(TALLOC_CTX *memctx,
+ struct sdap_attr_map *src_map,
+ size_t num_entries,
+ char **extra_attrs,
+ struct sdap_attr_map **_map,
+ size_t *_new_size)
+{
+ struct sdap_attr_map *map;
+ size_t nextra = 0;
+ size_t i;
+ char *ldap_attr;
+ char *sysdb_attr;
+ errno_t ret;
+
+ if (extra_attrs == NULL) {
+ DEBUG(SSSDBG_FUNC_DATA, "No extra attributes\n");
+ *_map = src_map;
+ *_new_size = num_entries;
+ return EOK;
+ }
+
+ for (nextra = 0; extra_attrs[nextra]; nextra++) ;
+ DEBUG(SSSDBG_FUNC_DATA, "%zu extra attributes\n", nextra);
+
+ map = talloc_realloc(memctx, src_map, struct sdap_attr_map,
+ num_entries + nextra + 1);
+ if (map == NULL) {
+ return ENOMEM;
+ }
+
+ for (i = 0; extra_attrs[i]; i++) {
+ ret = split_extra_attr(map, extra_attrs[i], &sysdb_attr, &ldap_attr);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot split %s\n", extra_attrs[i]);
+ continue;
+ }
+
+ if (is_sysdb_duplicate(map, num_entries, sysdb_attr)) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Attribute %s (%s in LDAP) is already used by SSSD, please "
+ "choose a different cache name\n", sysdb_attr, ldap_attr);
+ return ERR_DUP_EXTRA_ATTR;
+ }
+
+ map[num_entries+i].name = ldap_attr;
+ map[num_entries+i].sys_name = sysdb_attr;
+ map[num_entries+i].opt_name = talloc_strdup(map,
+ map[num_entries+i].name);
+ map[num_entries+i].def_name = talloc_strdup(map,
+ map[num_entries+i].name);
+ if (map[num_entries+i].opt_name == NULL ||
+ map[num_entries+i].sys_name == NULL ||
+ map[num_entries+i].name == NULL ||
+ map[num_entries+i].def_name == NULL) {
+ return ENOMEM;
+ }
+ DEBUG(SSSDBG_TRACE_FUNC, "Extending map with %s\n", extra_attrs[i]);
+ }
+
+ /* Sentinel */
+ memset(&map[num_entries+nextra], 0, sizeof(struct sdap_attr_map));
+
+ *_map = map;
+ *_new_size = num_entries + nextra;
+ return EOK;
+}
+
int sdap_get_map(TALLOC_CTX *memctx,
struct confdb_ctx *cdb,
const char *conf_path,