summaryrefslogtreecommitdiffstats
path: root/ldap/admin/src/cfg_sspt.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/admin/src/cfg_sspt.c')
-rw-r--r--ldap/admin/src/cfg_sspt.c1621
1 files changed, 1621 insertions, 0 deletions
diff --git a/ldap/admin/src/cfg_sspt.c b/ldap/admin/src/cfg_sspt.c
new file mode 100644
index 00000000..2ff883d3
--- /dev/null
+++ b/ldap/admin/src/cfg_sspt.c
@@ -0,0 +1,1621 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "ldap.h"
+#include "dsalib.h"
+#include "nspr.h"
+#include "plstr.h"
+#include <string.h>
+
+#define __CFG_SSPT_C
+
+#include "cfg_sspt.h"
+
+/*#define CGI_DEBUG 1*/
+
+#define TEST_CONFIG /* for testing cn=config40 dummy entry instead of real one */
+
+char* const class_top = "top";
+char* const class_organization = "organization";
+char* const class_organizationalUnit = "organizationalunit";
+char* const class_person = "person";
+char* const class_organizationalPerson = "organizationalperson";
+char* const class_inetOrgPerson = "inetorgperson";
+char* const class_groupOfUniqueNames = "groupofuniquenames";
+char* const class_domain = "domain";
+char* const class_extensibleObject = "extensibleObject";
+char* const class_adminDomain = "nsadmindomain";
+char* const class_country = "country";
+char* const class_locality = "locality";
+
+char* const name_objectClass = "objectclass";
+char* const name_cn = "cn";
+char* const name_sn = "sn";
+char* const name_givenname = "givenname";
+char* const name_uid = "uid";
+char* const name_userPassword = "userpassword";
+char* const name_passwordExpirationTime = "passwordExpirationTime";
+char* const name_o = "o";
+char* const name_ou = "ou";
+char* const name_dc = "dc";
+char* const name_member = "member";
+char* const name_uniqueMember = "uniquemember";
+char* const name_aci = "aci";
+char* const name_description = "description";
+char* const name_adminDomain = "nsadmindomainname";
+char* const name_c = "c";
+char* const name_st = "st";
+char* const name_l = "l";
+
+char* const value_configAdminGroupCN = "Configuration Administrators";
+char* const value_configAdminGroupRDN = "cn=Configuration Administrators";
+char* const value_configAdminCN = "Configuration Administrator";
+char* const value_configAdminSN = "Administrator";
+char* const value_configAdminGN = "Configuration";
+char* const value_globalPreferencesOU = "Global Preferences";
+char* const value_hostPreferencesOU = "Host Preferences";
+char* const value_netscapeConfigDesc = "Standard branch for configuration information";
+char* const value_peopleOU = "People";
+char* const value_peopleDesc = "Standard branch for people (uid) entries";
+char* const value_groupsOU = "Groups";
+char* const value_groupsDesc = "Standard Branch for group entries";
+#ifdef TEST_CONFIG
+char* const value_config40 = "config40";
+char* const value_config40DN = "cn=config40";
+#endif /* TEST_CONFIG */
+
+char* dbg_log_file = "ds_sscfg.log";
+
+char* const name_netscaperoot = "NetscapeRoot";
+char* const name_netscaperootDN = "o=NetscapeRoot";
+char* const name_topology = "TopologyManagement";
+char* const name_topologyRDN = "ou=TopologyManagement";
+char* const value_topologyDESC = "Branch for Configuration Administration users and groups";
+char* const name_administratorsOU = "Administrators";
+char* const name_administratorsRDN = "ou=Administrators";
+char* const value_administratorsDESC = "Standard branch for Configuration Administrator (uid) entries";
+char* const name_localDAGroup = "Directory Administrators";
+char* const value_localDAGroupDesc = "Entities with administrative access to this directory server";
+
+static char* const ACI_self_allow = "(targetattr=\""
+ "carLicense ||"
+ "description ||"
+ "displayName ||"
+ "facsimileTelephoneNumber ||"
+ "homePhone ||"
+ "homePostalAddress ||"
+ "initials ||"
+ "jpegPhoto ||"
+ "labeledURL ||"
+ "mail ||"
+ "mobile ||"
+ "pager ||"
+ "photo ||"
+ "postOfficeBox ||"
+ "postalAddress ||"
+ "postalCode ||"
+ "preferredDeliveryMethod ||"
+ "preferredLanguage ||"
+ "registeredAddress ||"
+ "roomNumber ||"
+ "secretary ||"
+ "seeAlso ||"
+ "st ||"
+ "street ||"
+ "telephoneNumber ||"
+ "telexNumber ||"
+ "title ||"
+ "userCertificate ||"
+ "userPassword ||"
+ "userSMIMECertificate ||"
+ "x500UniqueIdentifier\")"
+ "(version 3.0; acl \"Enable self write for common attributes\"; allow (write) "
+ "userdn=\"ldap:///self\";)";
+
+static char* const ACI_anonymous_allow = "(targetattr!=\"userPassword\")"
+ "(version 3.0; "
+ "acl \"Enable anonymous access\"; allow (read, search, compare)"
+ "userdn=\"ldap:///anyone\";)";
+
+static char* const ACI_anonymous_allow_with_filter =
+ "(targetattr=\"*\")(targetfilter=(%s))"
+ "(version 3.0; acl \"Default anonymous access\"; "
+ "allow (read, search) userdn=\"ldap:///anyone\";)";
+
+static char* const ACI_config_admin_group_allow_all = "(targetattr=\"*\")"
+ "(version 3.0; "
+ "acl \"Enable Configuration Administrator Group modification\"; "
+ "allow (all) groupdn=\"ldap:///%s, %s=%s, %s, %s\";)";
+
+static char* const ACI_config_admin_group_allow = "(targetattr=\"*\")"
+ "(version 3.0; "
+ "acl \"Configuration Administrators Group\"; allow (%s) "
+ "groupdn=\"ldap:///%s\";)";
+
+static char* const ACI_local_DA_allow = "(targetattr = \"*\")(version 3.0; "
+ "acl \"Local Directory Administrators Group\"; allow (%s) "
+ "groupdn=\"ldap:///%s\";)";
+
+static char* const ACI_group_expansion = "(targetattr=\"*\")"
+ "(version 3.0; acl \"Enable Group Expansion\"; "
+ "allow (read, search, compare) groupdnattr=\"uniquemember\";)";
+
+static char* const ACI_user_allow_1 = "(targetattr=\"*\")(version 3.0; "
+ "acl \"Configuration Administrator\"; allow (%s) "
+ "userdn=\"ldap:///uid=%s, %s\";)";
+
+static char* const ACI_user_allow_2 = "(targetattr=\"*\")(version 3.0; "
+ "acl \"Configuration Administrator\"; allow (%s) "
+ "userdn=\"ldap:///%s\";)";
+/*
+ This is a list of DSE entries that the Configuration Admin Group has
+ access to and the access rights for that entry
+*/
+static struct _DSEEntriesAndAccess {
+ char *entryDN;
+ char *access;
+} entryAndAccessList[] = {
+ {"cn=config", "all"},
+ {"cn=schema", "all"}
+};
+
+static int entryAndAccessListSize =
+ sizeof(entryAndAccessList)/sizeof(entryAndAccessList[0]);
+
+int
+getEntryAndAccess(int index, const char **entry, const char **access)
+{
+ if (!entry || !access)
+ return 0;
+
+ *entry = 0;
+ *access = 0;
+
+ if (index < 0 || index >= entryAndAccessListSize)
+ return 0;
+
+ *entry = entryAndAccessList[index].entryDN;
+ *access = entryAndAccessList[index].access;
+
+ return 1;
+}
+
+/*
+** ---------------------------------------------------------------------------
+**
+** Utility Routines - Functions for performing string and file operations.
+**
+*/
+
+#ifdef CGI_DEBUG
+#include <stdarg.h>
+
+static void
+debug_log (const char* file, const char* format, ...)
+{
+ va_list args;
+ FILE* fp = fopen(file, "a+");
+ if (fp) {
+ va_start(args, format);
+ vfprintf(fp, format, args);
+ va_end(args);
+ fflush(fp);
+ fclose(fp);
+ }
+}
+
+static void
+debug_log_array (const char* file, char* name, char** vals)
+{
+ FILE* fp = fopen(file, "a+");
+
+ if (fp) {
+ if (vals != NULL) {
+ for (; *vals != NULL; LDAP_UTF8INC(vals)) {
+ fprintf (fp, "%s: %s\n", name, *vals);
+ }
+ fflush(fp);
+ }
+ fclose(fp);
+ }
+}
+
+#endif /* CGI_DEBUG */
+
+static char *
+extract_name_from_dn(const char *dn)
+{
+ char **rdnList = 0;
+ char *ret = 0;
+ if (!dn)
+ return ret;
+
+ rdnList = ldap_explode_dn(dn, 1); /* leave out types */
+ if (!rdnList || !rdnList[0])
+ ret = strdup(dn); /* the given dn is not really a dn */
+ else
+ ret = strdup(rdnList[0]);
+
+ if (rdnList)
+ ldap_value_free(rdnList);
+
+ return ret;
+}
+
+int
+entry_exists(LDAP* ld, const char* entrydn)
+{
+ int exists = 0;
+ int err;
+
+ struct timeval sto = { 10L, 0L };
+ LDAPMessage* pLdapResult;
+
+ err = ldap_search_st(ld, entrydn, LDAP_SCOPE_BASE,
+ "objectClass=*", NULL, 0, &sto, &pLdapResult);
+
+ if (err == LDAP_SUCCESS)
+ {
+ LDAPMessage* pLdapEntry;
+ char* dn;
+
+ for (pLdapEntry = ldap_first_entry(ld, pLdapResult);
+ pLdapEntry != NULL;
+ pLdapEntry = ldap_next_entry(ld, pLdapEntry))
+ {
+ if ((dn = ldap_get_dn(ld, pLdapEntry)) != NULL)
+ {
+ exists = 1;
+ free(dn);
+ /*ldap_memfree(dn);*/
+ break;
+ }
+ }
+
+ ldap_msgfree(pLdapResult);
+ }
+
+ return exists;
+}
+
+int
+add_aci(LDAP* ld, char* DN, char* privilege)
+{
+ int err;
+ int ret = 0;
+ LDAPMod mod;
+ LDAPMod* mods[2];
+ char* aci[2];
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "add_aci('%s', '%s')\n",
+ DN ? DN : "NULL",
+ privilege ? privilege : "NULL");
+#endif
+
+ if (ld == NULL || DN == NULL || privilege == NULL)
+ {
+ return -1;
+ }
+
+ mods[0] = &mod;
+ mods[1] = NULL;
+ mod.mod_op = LDAP_MOD_ADD;
+ mod.mod_type = name_aci;
+ mod.mod_values = aci;
+ aci[0] = privilege;
+ aci[1] = NULL;
+ /* fprintf (stdout, "ldap_modify_s('%s')<br>\n",DN); fflush (stdout); */
+ err = ldap_modify_s (ld, DN, mods);
+ if (err != LDAP_SUCCESS && err != LDAP_TYPE_OR_VALUE_EXISTS) {
+ char* exp = "can't add privilege. ";
+ char* format;
+ char* errmsg;
+ char* explanation;
+ format = "%s (%i) returned from ldap_modify_s(%s, %i). Privilege: %s";
+ errmsg = ldap_err2string (err);
+ explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (DN) + 10 + strlen(aci[0]));
+ sprintf (explanation, format, errmsg, err, DN, LDAP_MOD_ADD, aci[0]);
+ ds_report_warning (DS_INCORRECT_USAGE, exp, explanation);
+ free (explanation);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/*
+ Same as add_aci, except that the 3rd parameter is a format string
+ in printf style format, and the 4th - Nth parameters are a NULL terminated
+ list of strings to substitute in the format; basically just constructs
+ the correct aci string and passes it to add_aci
+*/
+int
+add_aci_v(LDAP* ld, char* DN, char* format, ...)
+{
+ char* acistring = NULL;
+ int ii = 0;
+ int len = 0;
+ int status = 0;
+ int fudge = 10; /* a little extra just to make sure */
+ char *s = 0;
+ va_list ap;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "add_aci_v('%s', '%s')\n",
+ DN ? DN : "NULL",
+ format ? format : "NULL");
+#endif
+
+ if (ld == NULL || DN == NULL || format == NULL)
+ {
+ return -1;
+ }
+
+ /* determine the length of the string to allocate to hold
+ the aci string
+ */
+ len += strlen(format) + fudge;
+ va_start(ap, format);
+ s = va_arg(ap, char*);
+ while (s)
+ {
+ len += strlen(s) + 1;
+ s = va_arg(ap, char*);
+ }
+ va_end(ap);
+
+ va_start(ap, format);
+ acistring = (char *)malloc(len);
+ vsprintf(acistring, format, ap);
+ va_end(ap);
+ status = add_aci(ld, DN, acistring);
+
+ free(acistring);
+
+ return status;
+}
+
+/*
+ Make a dn from lists of dn components. The format argument is in the
+ standard printf format. The varargs list contains the various dn
+ components. The string returned is malloc()'d and must be free()'d by
+ the caller after use. example:
+ make_dn("cn=%s, ou=%s, %s", "Admins", "TopologyManagement", "o=NetscapeRoot", NULL)
+ returns
+ "cn=Admins, ou=TopologyManagement, o=NetscapeRoot"
+*/
+char *
+make_dn(const char* format, ...)
+{
+ char *s;
+ int len = 0;
+ int fudge = 3;
+ va_list ap;
+ char *dnstring;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "make_dn('%s', ...)\n",
+ format ? format : "NULL");
+#endif
+
+ if (format == NULL)
+ {
+ return NULL;
+ }
+
+ /* determine the length of the string to allocate to hold
+ the dn string
+ */
+ len += strlen(format) + fudge;
+ va_start(ap, format);
+ s = va_arg(ap, char*);
+ while (s)
+ {
+ len += strlen(s) + 3;
+ s = va_arg(ap, char*);
+ }
+ va_end(ap);
+
+ va_start(ap, format);
+ dnstring = (char *)malloc(len);
+ vsprintf(dnstring, format, ap);
+ va_end(ap);
+
+ return dnstring;
+}
+
+char *
+admin_user_exists(LDAP* ld, char* base, char *userID)
+{
+ int exists = 0;
+ int err;
+ char search_str[MAX_STRING_LEN];
+
+ struct timeval sto = { 10L, 0L };
+ LDAPMessage* pLdapResult;
+ sprintf (search_str, "uid=%s*", userID ? userID : "admin");
+
+ err = ldap_search_st(ld, base, LDAP_SCOPE_SUBTREE,
+ search_str, NULL, 0, &sto, &pLdapResult);
+
+ if (err == LDAP_SUCCESS)
+ {
+ LDAPMessage* pLdapEntry;
+ char* dn = NULL;
+
+ for (pLdapEntry = ldap_first_entry(ld, pLdapResult);
+ pLdapEntry != NULL;
+ pLdapEntry = ldap_next_entry(ld, pLdapEntry))
+ {
+ if ((dn = ldap_get_dn(ld, pLdapEntry)) != NULL)
+ {
+ exists = 1;
+ /*ldap_memfree(dn);*/
+ break;
+ }
+ }
+
+ ldap_msgfree(pLdapResult);
+ return dn;
+ }
+
+ return NULL;
+}
+
+static void
+getUIDFromDN(const char *userID, char *uid)
+{
+ char **rdnListTypes = 0;
+ char **rdnListNoTypes = 0;
+ int ii = 0;
+ int uidindex = -1;
+ uid[0] = 0;
+
+ rdnListTypes = ldap_explode_dn(userID, 0);
+ if (!rdnListTypes)
+ return; /* userID is not a DN */
+
+ /* find the first rdn in the given userID DN which begins with
+ "uid=" */
+ for (ii = 0; uidindex < 0 && rdnListTypes[ii]; ++ii)
+ {
+ if (!PL_strncasecmp(rdnListTypes[ii], "uid=", 4))
+ uidindex = ii;
+ }
+ ldap_value_free(rdnListTypes);
+
+ if (uidindex < 0) /* did not find an rdn beginning with "uid=" */
+ return;
+
+ rdnListNoTypes = ldap_explode_dn(userID, 1);
+ strcpy(uid, rdnListNoTypes[uidindex]);
+ ldap_value_free(rdnListNoTypes);
+
+ return;
+}
+
+static char *
+create_ssadmin_user(LDAP* ld, char *base, char* userID, char* password)
+{
+ int err;
+ char *ret = 0;
+ char entrydn[1024] = {0};
+ char realuid[1024] = {0};
+ char *admin_dn = NULL;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_ssadmin_user('%s','%s','%s')\n",
+ base ? base : "NULL", userID ? userID : "NULL",
+ password ? password : "NULL");
+#endif
+
+ if (ld == NULL || base == NULL || userID == NULL || *userID == '\0' ||
+ password == NULL || *password == '\0')
+ {
+ return NULL;
+ }
+
+ getUIDFromDN(userID, realuid);
+ if (realuid[0])
+ {
+ sprintf(entrydn, userID);
+ if (entry_exists(ld, entrydn))
+ admin_dn = entrydn;
+ }
+ else
+ {
+ sprintf(entrydn, "%s=%s, %s", name_uid, userID, base);
+ admin_dn = admin_user_exists(ld, base, userID);
+ strcpy(realuid, userID);
+ }
+
+ if (admin_dn)
+ {
+ char error[BIG_LINE];
+ sprintf(error, "A user with uid=%s \"%s\" already exists in the directory"
+ " and will not be overwritten.", realuid[0] ? realuid : "admin", admin_dn);
+ ds_send_error(error, 0);
+ return admin_dn;
+ }
+ else
+ {
+ LDAPMod* attrs[8];
+ LDAPMod attr[7];
+ char* objectClasses[5];
+ char* cn[2];
+ char* sn[2];
+ char* givenname[2];
+ char* uid[2];
+ char* userPassword[2];
+ char* passwordExpirationTime[2];
+
+ attrs[0] = &attr[0];
+ attrs[1] = &attr[1];
+ attrs[2] = &attr[2];
+ attrs[3] = &attr[3];
+ attrs[4] = &attr[4];
+ attrs[5] = &attr[5];
+ attrs[6] = &attr[6];
+ attrs[7] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_person;
+ objectClasses[2] = class_organizationalPerson;
+ objectClasses[3] = class_inetOrgPerson;
+ objectClasses[4] = NULL;
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_cn;
+ attr[1].mod_values = cn;
+ cn[0] = value_configAdminCN;
+ cn[1] = NULL;
+ attr[2].mod_op = LDAP_MOD_ADD;
+ attr[2].mod_type = name_sn;
+ attr[2].mod_values = sn;
+ sn[0] = value_configAdminSN;
+ sn[1] = NULL;
+ attr[3].mod_op = LDAP_MOD_ADD;
+ attr[3].mod_type = name_givenname;
+ attr[3].mod_values = givenname;
+ givenname[0] = value_configAdminGN;
+ givenname[1] = NULL;
+ attr[4].mod_op = LDAP_MOD_ADD;
+ attr[4].mod_type = name_uid;
+ attr[4].mod_values = uid;
+ uid[0] = realuid;
+ uid[1] = NULL;
+ attr[5].mod_op = LDAP_MOD_ADD;
+ attr[5].mod_type = name_userPassword;
+ attr[5].mod_values = userPassword;
+ userPassword[0] = password;
+ userPassword[1] = NULL;
+ attr[6].mod_op = LDAP_MOD_ADD;
+ attr[6].mod_type = name_passwordExpirationTime;
+ attr[6].mod_values = passwordExpirationTime;
+ passwordExpirationTime[0] = "20380119031407Z";
+ passwordExpirationTime[1] = NULL;
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", entrydn); fflush (stdout); */
+
+ err = ldap_add_s (ld, entrydn, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create administrative user."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (entrydn));
+ sprintf (explanation, format, errmsg, err, entrydn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create user", explanation);
+ free (explanation);
+ ret = NULL;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+create_base_entry(
+ LDAP* ld,
+ char* basedn,
+ char *naming_attr_type,
+ char *naming_attr_value,
+ char *objectclassname
+)
+{
+ int err;
+ int ret = 0;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_base_entry('%s','%s')\n",
+ basedn ? basedn : "NULL", naming_attr_value: "NULL");
+#endif
+
+ if (ld == NULL || basedn == NULL || *basedn == '\0')
+ {
+ return -1;
+ }
+
+ if (!entry_exists(ld, basedn))
+ {
+ LDAPMod* attrs[3];
+ LDAPMod attr[2];
+ char* objectClasses[3];
+ char* names[2];
+
+ attrs[0] = &attr[0];
+ attrs[2] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = objectclassname;
+ objectClasses[2] = NULL;
+ attrs[1] = &attr[1];
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = naming_attr_type;
+ attr[1].mod_values = names;
+ names[0] = naming_attr_value;
+ names[1] = NULL;
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", basedn); fflush (stdout); */
+
+ err = ldap_add_s (ld, basedn, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create base entry."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (basedn));
+ sprintf (explanation, format, errmsg, err, basedn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create base entry",
+ explanation);
+ free (explanation);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+static int
+create_organization(LDAP* ld, char* base, char* org)
+{
+ return create_base_entry(ld, base, name_o, org, class_organization);
+}
+
+static int
+create_organizational_unit(LDAP* ld, char* base, char* unit, char *description,
+ char *extra_objectclassName,
+ char *extra_attrName,
+ char *extra_attrValue)
+{
+ int err;
+ int ret = 0;
+ char *entrydn = NULL;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_organizational_unit('%s','%s')\n",
+ base ? base : "NULL", unit ? unit : "NULL");
+#endif
+
+ if (ld == NULL || unit == NULL || *unit == '\0')
+ {
+ return -1;
+ }
+
+ /*
+ if base is null, assume the unit is the full DN of the entry
+ to create; this assumes the caller knows what he/she is doing
+ and has already created the parent entry(ies)
+ */
+ if (!base)
+ entrydn = strdup(unit);
+ else
+ entrydn = make_dn("%s=%s, %s", name_ou, unit, base, 0);
+
+ if (!entry_exists(ld, entrydn))
+ {
+ LDAPMod* attrs[5];
+ LDAPMod attr[4];
+ char* objectClasses[4];
+ char* names[2];
+ char* desc[2];
+ char* extra[2];
+ char *baseName = unit;
+ int attrnum = 0;
+ if (base)
+ {
+ baseName = strdup(unit);
+ }
+ else
+ {
+ /* since the unit is in DN form, we need to extract something to
+ use for the ou: attribute */
+ baseName = extract_name_from_dn(unit);
+ }
+ attrs[0] = &attr[0];
+ attrs[1] = &attr[1];
+ attrs[2] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_organizationalUnit;
+ objectClasses[2] = extra_objectclassName; /* may be null */
+ objectClasses[3] = NULL;
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_ou;
+ attr[1].mod_values = names;
+ names[0] = baseName;
+ names[1] = NULL;
+ attrnum = 2;
+ if (description && *description)
+ {
+ attr[attrnum].mod_op = LDAP_MOD_ADD;
+ attr[attrnum].mod_type = name_description;
+ attr[attrnum].mod_values = desc;
+ desc[0] = description;
+ desc[1] = NULL;
+ attrs[attrnum] = &attr[attrnum];
+ attrs[++attrnum] = NULL;
+ }
+ if (extra_attrName && extra_attrValue &&
+ *extra_attrName && *extra_attrValue)
+ {
+ attr[attrnum].mod_op = LDAP_MOD_ADD;
+ attr[attrnum].mod_type = extra_attrName;
+ attr[attrnum].mod_values = extra;
+ extra[0] = extra_attrValue;
+ extra[1] = NULL;
+ attrs[attrnum] = &attr[attrnum];
+ attrs[++attrnum] = NULL;
+ }
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", DN); fflush (stdout); */
+
+ err = ldap_add_s (ld, entrydn, attrs);
+ if (baseName)
+ free(baseName);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create organizational unit."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (entrydn));
+ sprintf (explanation, format, errmsg, err, entrydn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create organizational unit",
+ explanation);
+ free (explanation);
+ ret = 1;
+ }
+ }
+
+ if (entrydn)
+ free(entrydn);
+
+ return ret;
+}
+
+static int
+create_domain_component(LDAP* ld, char* base, char* domcomp)
+{
+ return create_base_entry(ld, base, name_dc, domcomp, class_domain);
+}
+
+static int
+create_country(LDAP* ld, char* base, char* country)
+{
+ return create_base_entry(ld, base, name_c, country, class_country);
+}
+
+static int
+create_state(LDAP* ld, char* base, char* state)
+{
+ return create_base_entry(ld, base, name_st, state, class_locality);
+}
+
+static int
+create_locality(LDAP* ld, char* base, char* locality)
+{
+ return create_base_entry(ld, base, name_l, locality, class_locality);
+}
+
+static int
+create_base(LDAP* ld, char* base)
+{
+ int ret = 0;
+ char* attr;
+ char **rdnList = 0;
+ char **rdnListNoTypes = 0;
+ enum BASETYPE { unknown, org, orgunit, domcomp, country, state, locality } base_type = unknown;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_base('%s')\n", base ? base : "NULL");
+#endif
+
+ if (ld == NULL || base == NULL || *base == '\0')
+ {
+ return -1;
+ }
+
+ rdnList = ldap_explode_dn(base, 0);
+ if (!rdnList)
+ {
+ char error[BIG_LINE];
+ sprintf(error, "The given base suffix [%s] is not a valid DN", base);
+ ds_send_error(error, 0);
+ return -1;
+ }
+
+ if (PL_strncasecmp(rdnList[0], "o=", 2) == 0)
+ {
+ base_type = org;
+ }
+ else if (PL_strncasecmp(rdnList[0], "ou=", 3) == 0)
+ {
+ base_type = orgunit;
+ }
+ else if (PL_strncasecmp(rdnList[0], "dc=", 3) == 0)
+ {
+ base_type = domcomp;
+ }
+ else if (PL_strncasecmp(rdnList[0], "c=", 2) == 0)
+ {
+ base_type = country;
+ }
+ else if (PL_strncasecmp(rdnList[0], "st=", 3) == 0)
+ {
+ base_type = state;
+ }
+ else if (PL_strncasecmp(rdnList[0], "l=", 2) == 0)
+ {
+ base_type = locality;
+ }
+ else
+ {
+ ds_report_warning (DS_INCORRECT_USAGE, " Unable to create the root suffix.",
+ "In order to create the root suffix in the directory, you must "
+ "specify a distinguished name beginning with o=, ou=, dc=, c=, st=, or l=. "
+ "If you wish to use something else for your root suffix, you "
+ "should first create the directory with one of these suffixes, then you can "
+ "create additional suffixes in any form you choose."
+ );
+ return -1;
+ }
+
+ ldap_value_free(rdnList);
+ /*
+ We need to extract from the base the value to use for the attribute
+ name_attr e.g. ou: foo or o: org.
+ */
+ rdnListNoTypes = ldap_explode_dn(base, 1);
+ attr = rdnListNoTypes[0];
+
+ if (!entry_exists(ld, base))
+ {
+ if (base_type == org)
+ {
+ ret = create_organization(ld, base, attr);
+ }
+ else if (base_type == orgunit)
+ {
+ /* this function is smart enough to extract the name from the DN */
+ ret = create_organizational_unit(ld, 0, base, 0, 0, 0, 0);
+ }
+ else if (base_type == domcomp)
+ {
+ ret = create_domain_component(ld, base, attr);
+ }
+ else if (base_type == country)
+ {
+ ret = create_country(ld, base, attr);
+ }
+ else if (base_type == state)
+ {
+ ret = create_state(ld, base, attr);
+ }
+ else if (base_type == locality)
+ {
+ ret = create_locality(ld, base, attr);
+ }
+ }
+
+ ldap_value_free(rdnListNoTypes);
+
+ /* now add the anon search and self mod acis */
+ if (!ret)
+ {
+ ret = add_aci(ld, base, ACI_anonymous_allow);
+ if (!ret)
+ ret = add_aci(ld, base, ACI_self_allow);
+ }
+
+ return ret;
+}
+
+static int
+create_NetscapeRoot(LDAP* ld, const char *DN)
+{
+/*
+ dn: o=NetscapeRoot
+ o: NetscapeRoot
+ objectclass: top
+ objectclass: organization
+ */
+ int err;
+ int ret = 0;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_NetscapeRoot()\n");
+#endif
+
+ if (ld == NULL)
+ {
+ return -1;
+ }
+
+ if (!entry_exists(ld, DN))
+ {
+ LDAPMod* attrs[4];
+ LDAPMod attr[3];
+ char* objectClasses[4];
+ char* names[2];
+
+ attrs[0] = &attr[0];
+ attrs[3] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_organization;
+ objectClasses[2] = NULL;
+ attrs[1] = &attr[1];
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_o;
+ attr[1].mod_values = names;
+ names[0] = name_netscaperoot;
+ names[1] = NULL;
+ attrs[2] = NULL;
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", DN); fflush (stdout); */
+
+ err = ldap_add_s (ld, DN, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create %s."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (name_netscaperoot));
+ sprintf (explanation, format, name_netscaperoot, errmsg, err,
+ DN);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create NetscapeRoot",
+ explanation);
+ free (explanation);
+ ret = 1;
+ }
+
+ }
+
+ return ret;
+}
+
+static int
+create_configEntry(LDAP* ld)
+{
+/*
+ dn: cn=config40
+ objectclass: top
+ objectclass: extensibleObject
+ cn: config40
+ */
+ char *entrydn = NULL;
+ int err;
+ int ret = 0;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_configEntry()\n");
+#endif
+
+ if (ld == NULL)
+ {
+ return -1;
+ }
+
+ entrydn = make_dn("%s=%s", name_cn, value_config40, 0);
+ if (!entry_exists(ld, entrydn))
+ {
+ LDAPMod* attrs[3];
+ LDAPMod attr[2];
+ char* objectClasses[3];
+ char* names[2];
+
+ attrs[0] = &attr[0];
+ attrs[2] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_extensibleObject;
+ objectClasses[2] = NULL;
+ attrs[1] = &attr[1];
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_cn;
+ attr[1].mod_values = names;
+ names[0] = value_config40;
+ names[1] = NULL;
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", DN); fflush (stdout); */
+
+ err = ldap_add_s (ld, entrydn, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create %s."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (name_netscaperoot));
+ sprintf (explanation, format, value_config40, errmsg, err, entrydn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create config40",
+ explanation);
+ free (explanation);
+ ret = 1;
+ }
+
+ }
+
+ if (entrydn)
+ free(entrydn);
+
+ return ret;
+}
+
+int
+create_group(LDAP* ld, char* base, char* group)
+{
+ int err;
+ int ret = 0;
+ LDAPMod* attrs[3];
+ LDAPMod attr[2];
+ char* objectClasses[3];
+ char* names[2];
+ char *entrydn = 0;
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_group('%s','%s')\n",
+ base ? base : "NULL", group ? group : "NULL");
+#endif
+
+ if (ld == NULL || base == NULL || *base == '\0' ||
+ group == NULL || *group == '\0')
+ {
+ return -1;
+ }
+
+ entrydn = make_dn("%s=%s, %s", name_cn, group, base, 0);
+
+ if (!entry_exists(ld, entrydn))
+ {
+ attrs[0] = &attr[0];
+ attrs[1] = &attr[1];
+ attrs[2] = NULL;
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_groupOfUniqueNames;
+ objectClasses[2] = NULL;
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_cn;
+ attr[1].mod_values = names;
+ names[0] = group;
+ names[1] = NULL;
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", entrydn); fflush (stdout); */
+
+ err = ldap_add_s (ld, entrydn, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create group."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (entrydn));
+ sprintf (explanation, format, errmsg, err, entrydn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create group", explanation);
+ free (explanation);
+ ret = 1;
+ }
+ }
+
+ if (entrydn)
+ free(entrydn);
+
+ return ret;
+}
+
+int
+create_consumer_dn(LDAP* ld, char* dn, char* hashedpw)
+{
+ int err;
+ int ret = 0;
+ LDAPMod* attrs[7];
+ LDAPMod attr[6];
+ char* objectClasses[3];
+ char* names[2];
+ char* snames[2];
+ char* desc[2];
+ char* pwd[2];
+ char* passwordExpirationTime[2];
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "create_consumer_dn('%s','%s')\n",
+ dn ? dn : "NULL", hashedpw ? hashedpw : "NULL");
+#endif
+
+ if (ld == NULL || dn == NULL || hashedpw == NULL)
+ {
+ return -1;
+ }
+
+ if (!entry_exists(ld, dn))
+ {
+ attrs[0] = &attr[0];
+ attrs[1] = &attr[1];
+ attrs[2] = &attr[2];
+ attrs[3] = &attr[3];
+ attrs[4] = &attr[4];
+ attrs[5] = &attr[5];
+ attrs[6] = NULL;
+
+ attr[0].mod_op = LDAP_MOD_ADD;
+ attr[0].mod_type = name_objectClass;
+ attr[0].mod_values = objectClasses;
+ objectClasses[0] = class_top;
+ objectClasses[1] = class_person;
+ objectClasses[2] = NULL;
+
+ attr[1].mod_op = LDAP_MOD_ADD;
+ attr[1].mod_type = name_cn;
+ attr[1].mod_values = names;
+ names[0] = "Replication Consumer";
+ names[1] = NULL;
+
+ attr[2].mod_op = LDAP_MOD_ADD;
+ attr[2].mod_type = name_sn;
+ attr[2].mod_values = snames;
+ snames[0] = "Consumer";
+ snames[1] = NULL;
+
+ attr[3].mod_op = LDAP_MOD_ADD;
+ attr[3].mod_type = name_description;
+ attr[3].mod_values = desc;
+ desc[0] = "Replication Consumer bind entity";
+ desc[1] = NULL;
+
+ attr[4].mod_op = LDAP_MOD_ADD;
+ attr[4].mod_type = name_userPassword;
+ attr[4].mod_values = pwd;
+ pwd[0] = hashedpw;
+ pwd[1] = NULL;
+
+ attr[5].mod_op = LDAP_MOD_ADD;
+ attr[5].mod_type = name_passwordExpirationTime;
+ attr[5].mod_values = passwordExpirationTime;
+ passwordExpirationTime[0] = "20380119031407Z";
+ passwordExpirationTime[1] = NULL;
+
+ /* fprintf (stdout, "ldap_add_s(%s)<br>\n", DN); fflush (stdout); */
+
+ err = ldap_add_s (ld, dn, attrs);
+
+ if (err != LDAP_SUCCESS)
+ {
+ char* format = "Unable to create consumer dn."
+ " (%s (%i) returned from ldap_add_s(%s))";
+ char* errmsg = ldap_err2string (err);
+ char* explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (dn));
+ sprintf (explanation, format, errmsg, err, dn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't create consumer dn", explanation);
+ free (explanation);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+static int
+add_group_member(LDAP* ld, char* DN, char* attr, char* member)
+{
+ int err;
+ int ret = 0;
+ LDAPMod mod;
+ LDAPMod* mods[2];
+ char* members[2];
+
+#ifdef CGI_DEBUG
+ debug_log (dbg_log_file, "add_group_member('%s', '%s', '%s')\n",
+ DN ? DN : "NULL",
+ attr ? attr : "NULL",
+ member ? member : "NULL");
+#endif
+
+ if (ld == NULL || DN == NULL || attr == NULL || member == NULL)
+ {
+ return -1;
+ }
+
+ mods[0] = &mod;
+ mods[1] = NULL;
+ mod.mod_op = LDAP_MOD_ADD;
+ mod.mod_type = attr;
+ mod.mod_values = members;
+ members[0] = member;
+ members[1] = NULL;
+ /* fprintf (stdout, "ldap_modify_s('%s')<br>\n",DN); fflush (stdout); */
+ err = ldap_modify_s (ld, DN, mods);
+ if (err != LDAP_SUCCESS && err != LDAP_TYPE_OR_VALUE_EXISTS) {
+ char* exp = "can't add member. ";
+ char* format;
+ char* errmsg;
+ char* explanation;
+ format = "%s (%i) returned from ldap_modify_s(%s, %i).";
+ errmsg = ldap_err2string (err);
+ explanation = (char*)malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (DN) + 10);
+ sprintf (explanation, format, errmsg, err, DN, LDAP_MOD_ADD);
+ ds_report_warning (DS_INCORRECT_USAGE, exp, explanation);
+ free (explanation);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static LDAP*
+do_bind(SLAPD_CONFIG* slapd, char* rootdn, char* rootpw)
+{
+ LDAP* connection = NULL;
+ int retrymax = 1800; /* wait up to 30 min; init dbcache could be slow. */
+ int err = LDAP_SUCCESS;
+
+ /* added error retry to work around the slow start introduced
+ by blackflag 624053 */
+ while ( retrymax-- )
+ {
+ if (connection == NULL) {
+ connection = ldap_open ("127.0.0.1", slapd->port);
+ }
+
+ if (connection) {
+ err = ldap_simple_bind_s (connection, rootdn, rootpw ? rootpw : "");
+ if (LDAP_SUCCESS == err)
+ break;
+ }
+
+ PR_Sleep(PR_SecondsToInterval(1));
+ }
+
+ if (connection == NULL) {
+ char* format = " Cannot connect to server.";
+ ds_report_warning (DS_NETWORK_ERROR, format, "");
+ } else if (err != LDAP_SUCCESS) {
+ char* errmsg = ldap_err2string (err);
+ char* format = "Unable to bind to server."
+ " (%s (%i) returned from ldap_simple_bind_s(%s))";
+ char* explanation = malloc (strlen (format) + strlen (errmsg) +
+ 9 + strlen (rootdn) + 1);
+ sprintf (explanation, format, errmsg, err, rootdn);
+ ds_report_warning (DS_NETWORK_ERROR, " can't bind to server",
+ explanation);
+ free (explanation);
+ ldap_unbind (connection);
+ connection = NULL;
+ }
+ fflush (stdout);
+ return connection;
+}
+
+static int
+write_ldap_info(SLAPD_CONFIG* slapd, char* base, char* admnm)
+{
+ FILE* fp;
+ int ret = 0;
+
+ char* fmt = "%s/shared/config/ldap.conf";
+ char* infoFileName;
+
+ infoFileName = (char*)malloc(strlen(fmt) + strlen(slapd->slapd_server_root) + 1);
+ sprintf(infoFileName, fmt, slapd->slapd_server_root);
+
+ if ((fp = fopen(infoFileName, "w")) == NULL)
+ {
+ ret = -1;
+ }
+ else
+ {
+ fprintf(fp, "url\tldap://%s:%d/",
+ slapd->host, slapd->port);
+
+ if (base)
+ fprintf(fp, "%s", base);
+
+ fprintf(fp, "\n");
+
+ fprintf(fp, "admnm\t%s\n", admnm);
+
+ fclose(fp);
+ }
+
+ free(infoFileName);
+
+ return ret;
+}
+
+int
+config_configEntry(LDAP* connection, QUERY_VARS* query)
+{
+ /* initial ACIs for o=NetscapeRoot */
+
+ int ret = add_aci_v (connection, value_config40DN, ACI_self_allow, 0);
+ return ret;
+}
+
+int
+config_suitespot(SLAPD_CONFIG* slapd, QUERY_VARS* query)
+{
+ LDAP* connection;
+ const char* DN_formatUID = "uid=%s,%s";
+ char* usageShortMsg = " Required field missing.";
+ char* usageErrorMsg = NULL;
+ int status = 0;
+ char *admin_domainDN = 0;
+ int ii = 0;
+ char *configAdminDN = 0;
+ char *adminGroupDN = 0;
+ char *parentDN = 0;
+ char *localDAGroupDN = 0;
+
+ if (!query->rootDN || *query->rootDN == '\0') {
+ usageErrorMsg = "You must enter the distinguished name of a user with "
+ "unrestricted access to the directory.";
+ } else if (!query->rootPW || *query->rootPW == '\0') {
+ usageErrorMsg = "You must enter the password of the user with "
+ "unrestricted access to the directory.";
+ }
+
+ if (usageErrorMsg) {
+ ds_report_warning (DS_INCORRECT_USAGE, usageShortMsg, usageErrorMsg);
+ return -1;
+ }
+
+ if (!(connection = do_bind (slapd, query->rootDN, query->rootPW)))
+ return 1;
+
+ /* parent dn of admin uid entry */
+ parentDN = make_dn("%s, %s, %s", name_administratorsRDN,
+ name_topologyRDN, query->netscaperoot, 0);
+ if (query->suffix)
+ {
+ status = create_base(connection, query->suffix);
+ if (!status)
+ {
+ add_aci_v(connection, query->suffix, ACI_user_allow_1,
+ "all", query->config_admin_uid, parentDN, 0);
+
+ status = create_group(connection, query->suffix, name_localDAGroup);
+ }
+ }
+
+ if (!status && query->consumerDN && query->consumerPW &&
+ PL_strcasecmp(query->consumerDN, query->rootDN))
+ status = create_consumer_dn(connection,
+ query->consumerDN, query->consumerPW);
+
+ if (!status)
+ {
+ char realuid[1024] = {0};
+ getUIDFromDN(query->config_admin_uid, realuid);
+ if (realuid[0])
+ {
+ /* admid is already a DN */
+ configAdminDN = strdup(query->config_admin_uid);
+ }
+ else
+ {
+ /* create a DN for admid */
+ configAdminDN = make_dn(DN_formatUID, query->config_admin_uid, parentDN, 0);
+ }
+
+ /*
+ Give the Configuration Admin group access to the root DSE entries
+ */
+ adminGroupDN = make_dn("%s, %s=%s, %s, %s", value_configAdminGroupRDN,
+ name_ou, value_groupsOU,
+ name_topologyRDN,
+ query->netscaperoot, 0);
+ if (query->suffix)
+ {
+ localDAGroupDN = make_dn("cn=%s, %s", name_localDAGroup,
+ query->suffix, 0);
+ }
+ else
+ {
+ localDAGroupDN = NULL;
+ }
+ for (ii = 0; ii < entryAndAccessListSize; ++ii)
+ {
+ if (query->cfg_sspt) {
+ add_aci_v(connection, entryAndAccessList[ii].entryDN,
+ ACI_config_admin_group_allow,
+ entryAndAccessList[ii].access,
+ adminGroupDN, 0);
+ }
+ add_aci_v(connection, entryAndAccessList[ii].entryDN,
+ ACI_user_allow_2,
+ entryAndAccessList[ii].access,
+ configAdminDN, 0);
+ if (localDAGroupDN)
+ {
+ add_aci_v(connection, entryAndAccessList[ii].entryDN,
+ ACI_local_DA_allow,
+ entryAndAccessList[ii].access,
+ localDAGroupDN, 0);
+ }
+ }
+ }
+
+ if (query->cfg_sspt)
+ {
+ /* create and set ACIs for o=netscaperoot entry */
+ if (!status)
+ status = create_NetscapeRoot(connection, query->netscaperoot);
+
+ if (!status)
+ status = add_aci_v(connection, query->netscaperoot,
+ ACI_config_admin_group_allow_all,
+ value_configAdminGroupRDN,
+ name_ou, value_groupsOU, name_topologyRDN,
+ query->netscaperoot, 0);
+
+ if (!status)
+ status = add_aci_v(connection, query->netscaperoot,
+ ACI_anonymous_allow_with_filter,
+ query->netscaperoot, 0);
+
+ if (!status)
+ status = add_aci_v(connection, query->netscaperoot, ACI_group_expansion,
+ query->netscaperoot, 0);
+
+ /* create "topologyOU, netscaperoot" entry and set ACIs */
+ if (!status)
+ {
+ char *dn = make_dn("%s, %s", name_topologyRDN,
+ query->netscaperoot, 0);
+ status = create_organizational_unit(connection, NULL, dn,
+ value_topologyDESC,
+ 0, 0, 0);
+
+ if (!status)
+ add_aci(connection, dn, ACI_anonymous_allow);
+
+ free(dn);
+ }
+
+ /* create "ou=Groups, ..." */
+ if (!status)
+ {
+ char *dn = make_dn("%s=%s, %s, %s", name_ou, value_groupsOU,
+ name_topologyRDN, query->netscaperoot, 0);
+ status = create_organizational_unit (connection, NULL, dn,
+ value_groupsDesc, 0, 0, 0);
+ free(dn);
+ }
+
+ /* create "ou=Administrators, ..." */
+ if (!status)
+ {
+ char *dn = make_dn("%s, %s, %s", name_administratorsRDN,
+ name_topologyRDN, query->netscaperoot, 0);
+ status = create_organizational_unit (connection, NULL, dn,
+ value_administratorsDESC,
+ 0, 0, 0);
+ free(dn);
+ }
+
+ /* create "cn=Configuration Administrators, ou=Groups, ..." */
+ if (!status)
+ {
+ char *dn = make_dn("%s=%s, %s, %s", name_ou, value_groupsOU,
+ name_topologyRDN,
+ query->netscaperoot, 0);
+ status = create_group (connection, dn, value_configAdminGroupCN);
+ free(dn);
+ }
+
+ /* create the ss admin user */
+ if (!status)
+ {
+ /* group to add the uid to */
+ char *groupdn = make_dn("%s, %s=%s, %s, %s", value_configAdminGroupRDN,
+ name_ou, value_groupsOU, name_topologyRDN,
+ query->netscaperoot, 0);
+ create_ssadmin_user(connection, parentDN,
+ query->ssAdmID, query->ssAdmPW1);
+
+ status = add_group_member (connection, groupdn,
+ name_uniqueMember, configAdminDN);
+ free (groupdn);
+ }
+
+ admin_domainDN = make_dn("%s=%s, %s", name_ou, query->admin_domain,
+ query->netscaperoot, 0);
+
+ if (!status)
+ status = create_organizational_unit (connection, 0,
+ admin_domainDN,
+ value_netscapeConfigDesc,
+ class_adminDomain,
+ name_adminDomain,
+ query->admin_domain);
+
+ if (!status) {
+ status = create_organizational_unit(connection,
+ admin_domainDN,
+ value_globalPreferencesOU, 0,
+ 0, 0, 0);
+ }
+ if (!status) {
+ status = create_organizational_unit(connection,
+ admin_domainDN,
+ value_hostPreferencesOU, 0,
+ 0, 0, 0);
+ }
+
+ /*
+ ** Write the ldap.info file and the SuiteSpot.ldif file
+ */
+
+ write_ldap_info(slapd, query->suffix, query->ssAdmID);
+ }
+
+ if (!status && query->testconfig)
+ status = create_configEntry(connection);
+
+ if (!status && query->testconfig)
+ status = config_configEntry(connection, query);
+
+ if (connection)
+ ldap_unbind (connection);
+ if (adminGroupDN)
+ free(adminGroupDN);
+ if (configAdminDN)
+ free(configAdminDN);
+ if (parentDN)
+ free(parentDN);
+ if (localDAGroupDN)
+ free(localDAGroupDN);
+
+ return status;
+}