summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config/SSSDConfig.py1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ipa.conf1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf1
-rw-r--r--src/db/sysdb.h1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ldap/ldap_opts.h3
-rw-r--r--src/providers/ldap/sdap.h1
-rw-r--r--src/providers/ldap/sdap_async_users.c76
8 files changed, 73 insertions, 12 deletions
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 */