From 532eb49e129bedf57cdbd0a66f39ad228b8f2482 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Sun, 22 Apr 2012 20:52:58 -0400 Subject: LDAP: Map the user's primaryGroupID --- src/providers/ldap/ldap_opts.h | 3 ++ src/providers/ldap/sdap.h | 1 + src/providers/ldap/sdap_async_users.c | 76 +++++++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 12 deletions(-) (limited to 'src/providers/ldap') diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h index 646c54ec..62b03713 100644 --- a/src/providers/ldap/ldap_opts.h +++ b/src/providers/ldap/ldap_opts.h @@ -137,6 +137,7 @@ struct sdap_attr_map rfc2307_user_map[] = { { "ldap_user_member_of", NULL, SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", NULL, SYSDB_UUID, NULL }, { "ldap_user_objectsid", NULL, SYSDB_SID, NULL }, + { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, @@ -189,6 +190,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = { /* FIXME: this is 389ds specific */ { "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL }, { "ldap_user_objectsid", NULL, SYSDB_SID, NULL }, + { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, @@ -241,6 +243,7 @@ struct sdap_attr_map ad2008r2_user_map[] = { { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", "objectGUID", SYSDB_UUID, NULL }, { "ldap_user_objectsid", "objectSID", SYSDB_SID, NULL }, + { "ldap_user_primary_group", "primaryGroupID", SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", NULL, SYSDB_SHADOWPW_LASTCHANGE, NULL }, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 2de4a5cb..ba19cbab 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -244,6 +244,7 @@ enum sdap_user_attrs { SDAP_AT_USER_MEMBEROF, SDAP_AT_USER_UUID, SDAP_AT_USER_OBJECTSID, + SDAP_AT_USER_PRIMARY_GROUP, SDAP_AT_USER_MODSTAMP, SDAP_AT_USER_USN, SDAP_AT_SP_LSTCHG, diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c index 9aa09da9..c6534993 100644 --- a/src/providers/ldap/sdap_async_users.c +++ b/src/providers/ldap/sdap_async_users.c @@ -47,7 +47,7 @@ int sdap_save_user(TALLOC_CTX *memctx, const char *homedir; const char *shell; uid_t uid; - gid_t gid; + gid_t gid, primary_gid; struct sysdb_attrs *user_attrs; char *upn = NULL; size_t i; @@ -58,7 +58,8 @@ int sdap_save_user(TALLOC_CTX *memctx, bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING); struct dom_sid *dom_sid; char *sid_str; - char *dom_sid_str; + char *dom_sid_str = NULL; + char *group_sid_str; enum idmap_error_code err; DEBUG(9, ("Save user\n")); @@ -126,9 +127,9 @@ int sdap_save_user(TALLOC_CTX *memctx, &el); if (ret != EOK || el->num_values != 1) { DEBUG(SSSDBG_MINOR_FAILURE, - ("No [%s] attribute for user [%s] while id-mapping\n", + ("No [%s] attribute for user [%s] while id-mapping. [%d][%s]\n", opts->user_map[SDAP_AT_USER_OBJECTSID].name, - name)); + name, el->num_values, strerror(ret))); goto fail; } @@ -213,14 +214,65 @@ int sdap_save_user(TALLOC_CTX *memctx, goto fail; } - ret = sysdb_attrs_get_uint32_t(attrs, - opts->user_map[SDAP_AT_USER_GID].sys_name, - &gid); - if (ret != EOK) { - DEBUG(1, ("no gid provided for [%s] in domain [%s].\n", - name, dom->name)); - ret = EINVAL; - goto fail; + if (use_id_mapping) { + ret = sysdb_attrs_get_uint32_t( + attrs, + opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, + &primary_gid); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("no primary group ID provided for [%s] in domain [%s].\n", + name, dom->name)); + ret = EINVAL; + goto fail; + } + + /* The primary group ID is just the RID part of the objectSID + * of the group. Generate the GID by adding this to the domain + * SID value. + */ + + /* First, get the domain SID if we didn't do so above */ + if (!dom_sid_str) { + ret = sdap_idmap_get_dom_sid_from_object(tmpctx, sid_str, + &dom_sid_str); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not parse domain SID from [%s]\n", sid_str)); + goto fail; + } + } + + /* Add the RID to the end */ + group_sid_str = talloc_asprintf(tmpctx, "%s-%lu", + dom_sid_str, + (unsigned long)primary_gid); + if (!group_sid_str) { + ret = ENOMEM; + goto fail; + } + + /* Convert the SID into a UNIX group ID */ + err = sss_idmap_sid_to_unix(opts->idmap_ctx->map, + group_sid_str, + (uint32_t *)&gid); + if (err != IDMAP_SUCCESS) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not convert objectSID [%s] to a UNIX ID\n", + group_sid_str)); + ret = EIO; + goto fail; + } + } else { + ret = sysdb_attrs_get_uint32_t(attrs, + opts->user_map[SDAP_AT_USER_GID].sys_name, + &gid); + if (ret != EOK) { + DEBUG(1, ("no gid provided for [%s] in domain [%s].\n", + name, dom->name)); + ret = EINVAL; + goto fail; + } } /* check that the gid is valid for this domain */ -- cgit