summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/back-sch.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/back-sch.c b/src/back-sch.c
index 98542c5..d1998d7 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -419,6 +419,67 @@ backend_set_operational_attributes(Slapi_Entry *e,
}
}
+#ifdef USE_NSSWITCH
+#define IPA_ATTR_EXTERNAL_MEMBER "ipaExternalMember"
+static void
+backend_set_process_external_members(Slapi_PBlock *pb,
+ Slapi_Entry *e,
+ struct plugin_state *state,
+ struct backend_set_data *data)
+{
+ Slapi_Attr *attr = NULL;
+ Slapi_ValueSet *valueset;
+ bool_t is_attr_exists, is_group_exists;
+ struct backend_staged_search staged = {0, };
+ struct backend_search_cbdata cbdata = {0, };
+
+ is_attr_exists = slapi_entry_attr_find(e, IPA_ATTR_EXTERNAL_MEMBER, &attr) == 0;
+
+ if (!is_attr_exists || attr == NULL) {
+ return;
+ }
+
+ /* There are external members in this entry, do group lookup via SSSD
+ * and update entry's memberUid attribute */
+
+ staged.name = slapi_entry_attr_get_charptr(e, "cn");
+ staged.type = SCH_NSSWITCH_GROUP;
+ staged.search_members = FALSE;
+ staged.is_id = FALSE;
+ staged.is_sid = FALSE;
+ staged.container_sdn = slapi_sdn_get_dn(data->container_sdn);
+ staged.entries = NULL;
+ staged.count = 0;
+ cbdata.nsswitch_buffer_len = MAX(16384, MAX(sysconf(_SC_GETPW_R_SIZE_MAX), sysconf(_SC_GETGR_R_SIZE_MAX)));
+ cbdata.nsswitch_buffer = malloc(cbdata.nsswitch_buffer_len);
+ cbdata.state = state;
+ cbdata.staged = &staged;
+
+ is_group_exists = backend_retrieve_from_nsswitch(&staged, &cbdata);
+ if (is_group_exists && staged.entries != NULL && staged.entries[0] != NULL) {
+ attr = NULL;
+ if (slapi_entry_attr_find(staged.entries[0], "memberUid", &attr) == 0) {
+ (void)slapi_attr_get_valueset(attr, &valueset);
+ if (slapi_entry_attr_find(e, "memberUid", &attr) == 0) {
+ slapi_attr_set_valueset(attr, valueset);
+ } else {
+ slapi_entry_add_valueset(e, "memberUid", valueset);
+ slapi_valueset_free(valueset);
+ }
+ }
+ slapi_entry_free(staged.entries[0]);
+ }
+
+ if (staged.entries != NULL) {
+ free(staged.entries);
+ }
+
+ (void)slapi_entry_attr_delete(e, IPA_ATTR_EXTERNAL_MEMBER);
+ free(cbdata.nsswitch_buffer);
+ slapi_ch_free_string(&staged.name);
+}
+#endif
+
/* Given a map-entry directory entry, determine a key, a value, and extra data
* to be stored in the map cache, and add them to the map cache. */
static void
@@ -613,6 +674,9 @@ backend_set_entry_from(Slapi_PBlock *pb, enum backend_entry_source source,
slapi_entry_add_string(entry,
"objectClass", "extensibleObject");
}
+#ifdef USE_NSSWITCH
+ backend_set_process_external_members(pb, entry, data->common.state, data);
+#endif
/* Clean up the entry by doing a round trip through the LDIF parser. */
ldif = slapi_entry2str(entry, &len);
slapi_entry_free(entry);