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/config/SSSDConfig.py | 1 + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + src/db/sysdb.h | 1 + src/providers/ipa/ipa_opts.h | 1 + src/providers/ldap/ldap_opts.h | 3 ++ src/providers/ldap/sdap.h | 1 + src/providers/ldap/sdap_async_users.c | 76 +++++++++++++++++++++++++++----- 8 files changed, 73 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index b9c484fe5..aa35f9c6c 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -207,6 +207,7 @@ option_strings = { 'ldap_user_shell' : _('Shell attribute'), 'ldap_user_uuid' : _('UUID attribute'), 'ldap_user_objectsid' : _("objectSID attribute"), + 'ldap_user_primary_group' : _('Active Directory primary group attribute for ID-mapping'), 'ldap_user_principal' : _('User principal attribute (for Kerberos)'), 'ldap_user_fullname' : _('Full Name'), 'ldap_user_member_of' : _('memberOf attribute'), diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index ac375075b..20eb71f4c 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -62,6 +62,7 @@ ldap_user_home_directory = str, None, false ldap_user_shell = str, None, false ldap_user_uuid = str, None, false ldap_user_objectsid = str, None, false +ldap_user_primary_group = str, None, false ldap_user_principal = str, None, false ldap_user_fullname = str, None, false ldap_user_member_of = str, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index 2768366b3..a0694c708 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -54,6 +54,7 @@ ldap_user_home_directory = str, None, false ldap_user_shell = str, None, false ldap_user_uuid = str, None, false ldap_user_objectsid = str, None, false +ldap_user_primary_group = str, None, false ldap_user_principal = str, None, false ldap_user_fullname = str, None, false ldap_user_member_of = str, None, false diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 98255bede..a0d176ec7 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -108,6 +108,7 @@ #define SYSDB_UUID "uniqueID" #define SYSDB_SID "objectSID" +#define SYSDB_PRIMARY_GROUP "ADPrimaryGroupID" #define SYSDB_SID_STR "objectSIDString" #define SYSDB_UPN "userPrincipalName" #define SYSDB_CCACHE_FILE "ccacheFile" diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index 1fe78183e..f688f765c 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -143,6 +143,7 @@ struct sdap_attr_map ipa_user_map[] = { { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "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 }, diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h index 646c54ecb..62b037133 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 2de4a5cb9..ba19cbabe 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 9aa09da98..c6534993a 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