andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From eb10a9e242264fe94098743e048bfbba4fc9a422 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@totoro.usersys.redhat.com>
dc8c34
Date: Tue, 13 Nov 2012 11:21:26 -0800
dc8c34
Subject: [PATCH 12/16] Trac Ticket #500 - Newly created users with
dc8c34
 organizationalPerson objectClass fails to sync from
dc8c34
 AD to DS with missing attribute error
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/500
dc8c34
dc8c34
Bug description: Posix Account objectclass requires homeDirectory,
dc8c34
uidNumber, and gidNumber.  When an AD entry has just some of these
dc8c34
attributes or other allow-to-have attributes, i.e., loginShell or
dc8c34
gecos, the entry is incompletely converted to Posix Account entry
dc8c34
and fails to be added due to the missing attribute error.
dc8c34
dc8c34
Fix description: Before transforming the AD entry to the DS posix
dc8c34
account entry, check the required attributes first.  If any of the
dc8c34
above 3 attributes is missing, all of the posix account related
dc8c34
attributes are dropped and added to the DS as a non-posix account
dc8c34
entry.  If the PLUGIN log level is set, this type of message is
dc8c34
logged in the error log.
dc8c34
[] posix-winsync - AD entry CN=<CN>,OU=<OU>,DC=<DC>,DC=<COM> does
dc8c34
not have required attribute uidNumber for posixAccount objectclass.
dc8c34
(cherry picked from commit 19e49e69124ff19530a584f90808aa652a4c686f)
dc8c34
(cherry picked from commit f95bc254e3019727123068af5612058be05fb6be)
dc8c34
---
dc8c34
 ldap/servers/plugins/posix-winsync/posix-winsync.c | 129 ++++++++++++++-------
dc8c34
 ldap/servers/slapd/mapping_tree.c                  |   2 +-
dc8c34
 2 files changed, 91 insertions(+), 40 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c
dc8c34
index aa292c3..92a3a79 100644
dc8c34
--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c
dc8c34
+++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c
dc8c34
@@ -86,14 +86,17 @@ typedef struct _windows_attr_map
dc8c34
 {
dc8c34
     char *windows_attribute_name;
dc8c34
     char *ldap_attribute_name;
dc8c34
+    int isMUST; /* schema: required attribute */
dc8c34
 } windows_attribute_map;
dc8c34
 
dc8c34
-static windows_attribute_map user_attribute_map[] = { { "unixHomeDirectory", "homeDirectory" },
dc8c34
-                                                      { "loginShell", "loginShell" },
dc8c34
-                                                      { "uidNumber", "uidNumber" },
dc8c34
-                                                      { "gidNumber", "gidNumber" },
dc8c34
-                                                      { "gecos", "gecos" },
dc8c34
-                                                      { NULL, NULL } };
dc8c34
+static windows_attribute_map user_attribute_map[] = {
dc8c34
+    { "unixHomeDirectory", "homeDirectory", 1 },
dc8c34
+    { "loginShell", "loginShell", 0 },
dc8c34
+    { "uidNumber", "uidNumber", 1 },
dc8c34
+    { "gidNumber", "gidNumber", 1 },
dc8c34
+    { "gecos", "gecos", 0 },
dc8c34
+    { NULL, NULL, 0 }
dc8c34
+};
dc8c34
 
dc8c34
 static windows_attribute_map user_mssfu_attribute_map[] =
dc8c34
     { { "msSFU30homedirectory", "homeDirectory" },
dc8c34
@@ -751,7 +754,9 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
     int is_present_local = 0;
dc8c34
     int do_modify_local = 0;
dc8c34
     int rc;
dc8c34
+    int i;
dc8c34
     windows_attribute_map *attr_map = user_attribute_map;
dc8c34
+    PRBool posixval = PR_TRUE;
dc8c34
 
dc8c34
     if (posix_winsync_config_get_msSFUSchema())
dc8c34
         attr_map = user_mssfu_attribute_map;
dc8c34
@@ -759,15 +764,33 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
     slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
                     "--> _pre_ds_mod_user_cb -- begin\n");
dc8c34
 
dc8c34
+    /* check all of the required attributes are in the ad_entry:
dc8c34
+     * MUST (cn $ uid $ uidNumber $ gidNumber $ homeDirectory).
dc8c34
+     * If any of the required attributes are missing, drop them before adding
dc8c34
+     * the entry to the DS. */
dc8c34
+    for (i = 0; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
+        Slapi_Attr *pa_attr;
dc8c34
+        if (attr_map[i].isMUST &&
dc8c34
+            slapi_entry_attr_find(ad_entry,
dc8c34
+                                  attr_map[i].windows_attribute_name,
dc8c34
+                                  &pa_attr)) {
dc8c34
+            /* required attribute does not exist */
dc8c34
+            posixval = PR_FALSE;
dc8c34
+            slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
+                            "AD entry %s does not have required attribute %s for posixAccount objectclass.\n",
dc8c34
+                            slapi_entry_get_dn_const(ad_entry),
dc8c34
+                            attr_map[i].ldap_attribute_name);
dc8c34
+        }
dc8c34
+    }
dc8c34
+
dc8c34
     /* add objectclass: posixAccount, uidnumber ,gidnumber ,homeDirectory, loginshell */
dc8c34
     /* in the ad to ds case we have no changelog, so we have to compare the entries */
dc8c34
     for (rc = slapi_entry_first_attr(ad_entry, &attr); rc == 0;
dc8c34
          rc = slapi_entry_next_attr(ad_entry, attr, &attr)) {
dc8c34
         char *type = NULL;
dc8c34
-        size_t i = 0;
dc8c34
 
dc8c34
         slapi_attr_get_type(attr, &type);
dc8c34
-        for (; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
+        for (i = 0; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
             if (0 == slapi_attr_type_cmp(type, attr_map[i].windows_attribute_name,
dc8c34
                                          SLAPI_TYPE_CMP_SUBTYPE)) {
dc8c34
                 Slapi_Attr *local_attr = NULL;
dc8c34
@@ -779,7 +802,10 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
                 slapi_entry_attr_find(ds_entry, local_type, &local_attr);
dc8c34
                 is_present_local = (NULL == local_attr) ? 0 : 1;
dc8c34
                 if (is_present_local) {
dc8c34
+                    /* DS entry has the posix attrs.
dc8c34
+                     * I.e., it is a posix account*/
dc8c34
                     int values_equal = 0;
dc8c34
+                    posixval = PR_TRUE;
dc8c34
                     values_equal = attr_compare_equal(attr, local_attr);
dc8c34
                     if (!values_equal) {
dc8c34
                         slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
@@ -791,8 +817,8 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
                                                   valueset_get_valuearray(vs));
dc8c34
                         *do_modify = 1;
dc8c34
                     }
dc8c34
-                } else {
dc8c34
-
dc8c34
+                } else if (posixval) {
dc8c34
+                    /* only if AD provides the all necessary attributes */
dc8c34
                     slapi_mods_add_mod_values(smods, LDAP_MOD_ADD, local_type,
dc8c34
                                               valueset_get_valuearray(vs));
dc8c34
                     *do_modify = do_modify_local = 1;
dc8c34
@@ -804,10 +830,11 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
         }
dc8c34
     }
dc8c34
     slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
-                    "<-- _pre_ds_mod_user_cb present %d modify %d\n", is_present_local,
dc8c34
-                    do_modify_local);
dc8c34
+                    "<-- _pre_ds_mod_user_cb present %d modify %d isPosixaccount %s\n",
dc8c34
+                    is_present_local, do_modify_local,
dc8c34
+                    posixval?"yes":"no");
dc8c34
 
dc8c34
-    if (!is_present_local && do_modify_local) {
dc8c34
+    if (!is_present_local && do_modify_local && posixval) {
dc8c34
         Slapi_Attr *oc_attr = NULL;
dc8c34
         Slapi_Value *voc = slapi_value_new();
dc8c34
 
dc8c34
@@ -988,8 +1015,9 @@ posix_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
 {
dc8c34
     Slapi_Attr *attr = NULL;
dc8c34
     char *type = NULL;
dc8c34
-    PRBool posixval = PR_FALSE;
dc8c34
+    PRBool posixval = PR_TRUE;
dc8c34
     windows_attribute_map *attr_map = user_attribute_map;
dc8c34
+    int i = 0;
dc8c34
 
dc8c34
     if (posix_winsync_config_get_msSFUSchema())
dc8c34
         attr_map = user_mssfu_attribute_map;
dc8c34
@@ -998,42 +1026,65 @@ posix_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry *rawentry, Slap
dc8c34
     slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
                     "--> _pre_ds_add_user_cb -- begin\n");
dc8c34
 
dc8c34
-    for (slapi_entry_first_attr(ad_entry, &attr); attr; slapi_entry_next_attr(ad_entry, attr, &attr)) {
dc8c34
-        size_t i = 0;
dc8c34
-
dc8c34
-        slapi_attr_get_type(attr, &type);
dc8c34
-        if (!type) {
dc8c34
-            continue;
dc8c34
+    /* check all of the required attributes are in the ad_entry:
dc8c34
+     * MUST (cn $ uid $ uidNumber $ gidNumber $ homeDirectory).
dc8c34
+     * If any of the required attributes are missing, drop them before adding
dc8c34
+     * the entry to the DS. */
dc8c34
+    for (i = 0; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
+        Slapi_Attr *pa_attr;
dc8c34
+        if (attr_map[i].isMUST &&
dc8c34
+            slapi_entry_attr_find(ad_entry,
dc8c34
+                                  attr_map[i].windows_attribute_name,
dc8c34
+                                  &pa_attr)) {
dc8c34
+            /* required attribute does not exist */
dc8c34
+            posixval = PR_FALSE;
dc8c34
+            slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
+                            "AD entry %s does not have required attribute %s for posixAccount objectclass.\n",
dc8c34
+                            slapi_entry_get_dn_const(ad_entry),
dc8c34
+                            attr_map[i].ldap_attribute_name);
dc8c34
         }
dc8c34
+    }
dc8c34
 
dc8c34
-        slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, "--> _pre_ds_add_user_cb -- "
dc8c34
-            "look for [%s] to new entry [%s]\n", type, slapi_entry_get_dn_const(ds_entry));
dc8c34
-        for (; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
-            if (slapi_attr_type_cmp(attr_map[i].windows_attribute_name, type,
dc8c34
-                                    SLAPI_TYPE_CMP_SUBTYPE) == 0) {
dc8c34
-                Slapi_ValueSet *svs = NULL;
dc8c34
-                slapi_attr_get_valueset(attr, &svs);
dc8c34
-                slapi_entry_add_valueset(ds_entry, attr_map[i].ldap_attribute_name, svs);
dc8c34
-                slapi_valueset_free(svs);
dc8c34
+    /* converts the AD attributes to DS posix attribute if all the posix
dc8c34
+     * required attributes are available */
dc8c34
+    if (posixval) {
dc8c34
+        int rc;
dc8c34
+        for (slapi_entry_first_attr(ad_entry, &attr); attr;
dc8c34
+             slapi_entry_next_attr(ad_entry, attr, &attr)) {
dc8c34
 
dc8c34
-                slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
-                                "--> _pre_ds_add_user_cb -- "
dc8c34
-                                    "adding val for [%s] to new entry [%s]\n", type,
dc8c34
-                                slapi_entry_get_dn_const(ds_entry));
dc8c34
-                posixval = PR_TRUE;
dc8c34
+            slapi_attr_get_type(attr, &type);
dc8c34
+            if (!type) {
dc8c34
+                continue;
dc8c34
+            }
dc8c34
+
dc8c34
+            slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
+                            "--> _pre_ds_add_user_cb -- "
dc8c34
+                            "look for [%s] to new entry [%s]\n",
dc8c34
+                            type, slapi_entry_get_dn_const(ds_entry));
dc8c34
+            for (i = 0; attr_map[i].windows_attribute_name != NULL; i++) {
dc8c34
+                if (slapi_attr_type_cmp(attr_map[i].windows_attribute_name,
dc8c34
+                                        type, SLAPI_TYPE_CMP_SUBTYPE) == 0) {
dc8c34
+                    Slapi_ValueSet *svs = NULL;
dc8c34
+                    slapi_attr_get_valueset(attr, &svs);
dc8c34
+                    slapi_entry_add_valueset(ds_entry,
dc8c34
+                                          attr_map[i].ldap_attribute_name, svs);
dc8c34
+                    slapi_valueset_free(svs);
dc8c34
+
dc8c34
+                    slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
+                                    "--> _pre_ds_add_user_cb -- "
dc8c34
+                                    "adding val for [%s] to new entry [%s]\n",
dc8c34
+                                    type, slapi_entry_get_dn_const(ds_entry));
dc8c34
+                }
dc8c34
             }
dc8c34
         }
dc8c34
-    }
dc8c34
-    if (posixval) {
dc8c34
-        int rc;
dc8c34
         rc = slapi_entry_add_string(ds_entry, "objectClass", "posixAccount");
dc8c34
         rc |= slapi_entry_add_string(ds_entry, "objectClass", "shadowAccount");
dc8c34
         rc |= slapi_entry_add_string(ds_entry, "objectClass", "inetUser");
dc8c34
-        if (rc != 0)
dc8c34
+        if (rc != 0) {
dc8c34
             slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
dc8c34
                             "<-- _pre_ds_add_user_cb -- adding objectclass for new entry failed %d\n",
dc8c34
                             rc);
dc8c34
-        else {
dc8c34
+        } else {
dc8c34
             if (posix_winsync_config_get_mapNestedGrouping()) {
dc8c34
                 memberUidLock();
dc8c34
                 addUserToGroupMembership(ds_entry);
dc8c34
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
dc8c34
index e8e414f..da8e4f3 100644
dc8c34
--- a/ldap/servers/slapd/mapping_tree.c
dc8c34
+++ b/ldap/servers/slapd/mapping_tree.c
dc8c34
@@ -2451,7 +2451,7 @@ int slapi_mapping_tree_select_and_check(Slapi_PBlock *pb,char *newdn, Slapi_Back
dc8c34
             {
dc8c34
                 ret = LDAP_AFFECTS_MULTIPLE_DSAS;
dc8c34
                 PR_snprintf(errorbuf, BUFSIZ,
dc8c34
-                                "Cannot move entries accross backends\n");
dc8c34
+                                "Cannot move entries across backends\n");
dc8c34
                 goto unlock_and_return;
dc8c34
             }
dc8c34
         }
dc8c34
-- 
dc8c34
1.7.11.7
dc8c34