summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2008-08-19 18:00:49 -0600
committerRob Crittenden <rcritten@redhat.com>2008-10-13 14:15:17 -0400
commit6ed9cae100605a545d51f944663db69a8f2f9c58 (patch)
tree041019113408e22e6528a306194a9b178022274f
parent430225f42f852d17f996da07b4b2f62ad9d2a44e (diff)
downloadfreeipa-6ed9cae100605a545d51f944663db69a8f2f9c58.tar.gz
freeipa-6ed9cae100605a545d51f944663db69a8f2f9c58.tar.xz
freeipa-6ed9cae100605a545d51f944663db69a8f2f9c58.zip
Added support for posixAccount -lookup attribute containing the homeDirectory prefix and use that to construct the homeDirectory attribute -lookup attribute containing the default gidNumber and use that to add the gidNumber to new users -construct the gecos field from the cn attribute
-rw-r--r--ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif5
-rw-r--r--ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c182
2 files changed, 184 insertions, 3 deletions
diff --git a/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif b/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif
index ecbdbab43..c12d2a98e 100644
--- a/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif
+++ b/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync-conf.ldif
@@ -9,3 +9,8 @@ nsslapd-plugintype: preoperation
nsslapd-pluginenabled: on
nsslapd-plugin-depends-on-type: database
nsslapd-plugin-depends-on-named: Multimaster Replication Plugin
+ipaWinSyncRealmFilter: (objectclass=krbRealmContainer)
+ipaWinSyncRealmAttr: cn
+ipaWinSyncNewEntryFilter: (cn=ipaConfig)
+ipaWinSyncNewUserOCAttr: ipauserobjectclasses
+ipaWinSyncUserFlatten: true
diff --git a/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c b/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c
index 2c29567a3..bb9a77cd6 100644
--- a/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c
+++ b/ipa-server/ipa-slapi-plugins/ipa-winsync/ipa-winsync.c
@@ -50,9 +50,13 @@
* objectclasses and attributes, and changing the DN.
*/
+#include <slapi-plugin.h>
+#include "winsync-plugin.h"
+/*
#include <dirsrv/slapi-plugin.h>
#include <dirsrv/winsync-plugin.h>
-#include <ipa-winsync.h>
+*/
+#include "ipa-winsync.h"
static char *ipa_winsync_plugin_name = IPA_WINSYNC_PLUGIN_NAME;
@@ -134,7 +138,7 @@ ipa_winsync_pre_ds_search_all_cb(void *cbdata, const char *agmt_dn,
/* We only want to grab users from the ds side - no groups */
slapi_ch_free_string(filter);
/* maybe use ntUniqueId=* - only get users that have already been
- synced with AD already - ntUniqueId and ntUserDomainId are
+ synced with AD - ntUniqueId and ntUserDomainId are
indexed for equality only - need to add presence? */
*filter = slapi_ch_strdup("(&(objectclass=ntuser)(ntUserDomainId=*))");
@@ -204,10 +208,172 @@ static void
ipa_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry *rawentry,
Slapi_Entry *ad_entry, Slapi_Entry *ds_entry)
{
+ IPA_WinSync_Domain_Config *ipaconfig = (IPA_WinSync_Domain_Config *)cbdata;
+ Slapi_Attr *attr = NULL;
+ Slapi_Attr *e_attr = NULL;
+ char *type = NULL;
+ PRBool flatten = PR_TRUE;
+ IPA_WinSync_Config *global_ipaconfig = ipa_winsync_get_config();
+
slapi_log_error(SLAPI_LOG_PLUGIN, ipa_winsync_plugin_name,
"--> ipa_winsync_pre_ds_add_user_cb -- begin\n");
- /* add the objectclasses to the entry */
+ if (!ipaconfig || !ipaconfig->domain_e || !ipaconfig->realm_name ||
+ !ipaconfig->homedir_prefix) {
+ slapi_log_error(SLAPI_LOG_FATAL, ipa_winsync_plugin_name,
+ "Error: configuration failure: cannot map Windows "
+ "entry dn [%s], DS entry dn [%s]\n",
+ slapi_entry_get_dn_const(ad_entry),
+ slapi_entry_get_dn_const(ds_entry));
+ return;
+ }
+
+
+ slapi_lock_mutex(global_ipaconfig->lock);
+ flatten = global_ipaconfig->flatten;
+ slapi_unlock_mutex(global_ipaconfig->lock);
+
+ if (flatten) {
+ char **rdns = NULL;
+ int ii;
+ /* grab the ous from the DN and store them in the entry */
+ type = "ou";
+ rdns = ldap_explode_dn(slapi_entry_get_dn_const(ad_entry), 0);
+ for (ii = 0; rdns && rdns[ii]; ++ii) {
+ /* go through the DN looking for ou= rdns */
+ if (!PL_strncasecmp(rdns[ii], "ou=", 3)) {
+ char *val = PL_strchr(rdns[ii], '=');
+ Slapi_Value *sv = NULL;
+ val++;
+ sv = slapi_value_new_string(val);
+ /* entry could already have this value */
+ if (!slapi_entry_attr_has_syntax_value(ds_entry, type, sv)) {
+ /* attr-value sv not found in ds_entry; add it */
+ slapi_log_error(SLAPI_LOG_PLUGIN, ipa_winsync_plugin_name,
+ "--> ipa_winsync_pre_ds_add_user_cb -- "
+ "adding val for [%s] to new entry [%s]\n",
+ type, slapi_entry_get_dn_const(ds_entry));
+
+ slapi_entry_add_value(ds_entry, type, sv);
+ }
+ slapi_value_free(&sv);
+ }
+ }
+ ldap_value_free(rdns);
+ }
+
+ /* add the objectclasses and attributes to the entry */
+ for (slapi_entry_first_attr(ipaconfig->domain_e, &attr); attr;
+ slapi_entry_next_attr(ipaconfig->domain_e, attr, &attr))
+ {
+ slapi_attr_get_type(attr, &type);
+ if (!type) {
+ continue; /* should never happen */
+ }
+
+ if (!slapi_entry_attr_find(ds_entry, type, &e_attr) && e_attr) {
+ /* already has attribute - add missing values */
+ Slapi_Value *sv = NULL;
+ int ii = 0;
+ for (ii = slapi_attr_first_value(attr, &sv); ii != -1;
+ ii = slapi_attr_next_value(attr, ii, &sv))
+ {
+ if (!slapi_entry_attr_has_syntax_value(ds_entry, type, sv)) {
+ /* attr-value sv not found in ds_entry; add it */
+ slapi_log_error(SLAPI_LOG_PLUGIN, ipa_winsync_plugin_name,
+ "--> ipa_winsync_pre_ds_add_user_cb -- "
+ "adding val for [%s] to new entry [%s]\n",
+ type, slapi_entry_get_dn_const(ds_entry));
+
+ slapi_entry_add_value(ds_entry, type, sv);
+ }
+ }
+ } else { /* attr not found */
+ Slapi_ValueSet *svs = NULL;
+ slapi_attr_get_valueset(attr, &svs); /* makes a copy */
+ slapi_entry_add_valueset(ds_entry, type, svs);
+ slapi_valueset_free(svs); /* free the copy */
+ }
+ }
+
+ /* add other attributes */
+ type = "krbPrincipalName";
+ if (slapi_entry_attr_find(ds_entry, type, &e_attr) || !e_attr) {
+ char *upn = NULL;
+ char *uid = NULL;
+ char *samAccountName = NULL;
+ /* if the ds_entry already has a uid, use that */
+ if ((uid = slapi_entry_attr_get_charptr(ds_entry, "uid"))) {
+ upn = slapi_ch_smprintf("%s@%s", uid, ipaconfig->realm_name);
+ slapi_ch_free_string(&uid);
+ /* otherwise, use the samAccountName from the ad_entry */
+ } else if ((samAccountName =
+ slapi_entry_attr_get_charptr(ad_entry, "samAccountName"))) {
+ upn = slapi_ch_smprintf("%s@%s", samAccountName, ipaconfig->realm_name);
+ slapi_ch_free_string(&samAccountName);
+ } else { /* fatal error - nothing to use for krbPrincipalName */
+ slapi_log_error(SLAPI_LOG_FATAL, ipa_winsync_plugin_name,
+ "Error creating %s for realm [%s] for Windows "
+ "entry dn [%s], DS entry dn [%s] - Windows entry "
+ "has no samAccountName, and DS entry has no uid.\n",
+ type, ipaconfig->realm_name,
+ slapi_entry_get_dn_const(ad_entry),
+ slapi_entry_get_dn_const(ds_entry));
+ }
+
+ if (upn) {
+ slapi_entry_attr_set_charptr(ds_entry, type, upn);
+ slapi_ch_free_string(&upn);
+ }
+ }
+
+ type = "homeDirectory";
+ if (slapi_entry_attr_find(ds_entry, type, &e_attr) || !e_attr) {
+ char *homeDir = NULL;
+ char *uid = NULL;
+ char *samAccountName = NULL;
+ /* if the ds_entry already has a uid, use that */
+ if ((uid = slapi_entry_attr_get_charptr(ds_entry, "uid"))) {
+ homeDir = slapi_ch_smprintf("%s/%s", ipaconfig->homedir_prefix, uid);
+ slapi_ch_free_string(&uid);
+ /* otherwise, use the samAccountName from the ad_entry */
+ } else if ((samAccountName =
+ slapi_entry_attr_get_charptr(ad_entry, "samAccountName"))) {
+ homeDir = slapi_ch_smprintf("%s/%s", ipaconfig->homedir_prefix,
+ samAccountName);
+ slapi_ch_free_string(&samAccountName);
+ } else { /* fatal error - nothing to use for homeDirectory */
+ slapi_log_error(SLAPI_LOG_FATAL, ipa_winsync_plugin_name,
+ "Error creating %s for realm [%s] for Windows "
+ "entry dn [%s], DS entry dn [%s] - Windows entry "
+ "has no samAccountName, and DS entry has no uid.\n",
+ type, ipaconfig->realm_name,
+ slapi_entry_get_dn_const(ad_entry),
+ slapi_entry_get_dn_const(ds_entry));
+ }
+
+ if (homeDir) {
+ slapi_entry_attr_set_charptr(ds_entry, type, homeDir);
+ slapi_ch_free_string(&homeDir);
+ }
+ }
+
+ /* gecos is not required, but nice to have */
+ type = "gecos";
+ if (slapi_entry_attr_find(ds_entry, type, &e_attr) || !e_attr) {
+ char *cn = NULL;
+ char *displayName = NULL;
+ /* if the ds_entry already has a cn, use that */
+ if ((cn = slapi_entry_attr_get_charptr(ds_entry, "cn"))) {
+ slapi_entry_attr_set_charptr(ds_entry, type, cn);
+ slapi_ch_free_string(&cn);
+ /* otherwise, use the displayName from the ad_entry */
+ } else if ((displayName =
+ slapi_entry_attr_get_charptr(ad_entry, "displayName"))) {
+ slapi_entry_attr_set_charptr(ds_entry, type, displayName);
+ slapi_ch_free_string(&displayName);
+ }
+ }
slapi_log_error(SLAPI_LOG_PLUGIN, ipa_winsync_plugin_name,
"<-- ipa_winsync_pre_ds_add_user_cb -- end\n");
@@ -234,11 +400,21 @@ ipa_winsync_get_new_ds_user_dn_cb(void *cbdata, const Slapi_Entry *rawentry,
const Slapi_DN *ds_suffix, const Slapi_DN *ad_suffix)
{
char **rdns = NULL;
+ PRBool flatten = PR_TRUE;
+ IPA_WinSync_Config *ipaconfig = ipa_winsync_get_config();
slapi_log_error(SLAPI_LOG_PLUGIN, ipa_winsync_plugin_name,
"--> ipa_winsync_get_new_ds_user_dn_cb -- old dn [%s] -- begin\n",
*new_dn_string);
+ slapi_lock_mutex(ipaconfig->lock);
+ flatten = ipaconfig->flatten;
+ slapi_unlock_mutex(ipaconfig->lock);
+
+ if (!flatten) {
+ return;
+ }
+
rdns = ldap_explode_dn(*new_dn_string, 0);
if (!rdns || !rdns[0]) {
ldap_value_free(rdns);