From e889b82599ddd939ed2a65b0011d5807c587cf05 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Mon, 30 Jan 2012 16:29:32 -0500 Subject: Add support defaultNamingContext and add --basedn to migrate-ds There are two sides to this, the server and client side. On the server side we attempt to add a defaultNamingContext on already installed servers. This will fail on older 389-ds instances but the failure is not fatal. New installations on versions of 389-ds that support this attribute will have it already defined. On the client side we need to look for both defaultNamingContext and namingContexts. We still need to check that the defaultNamingContext is an IPA server (info=IPAV2). The migration change also takes advantage of this and adds a new option which allows one to provide a basedn to use instead of trying to detect it. https://fedorahosted.org/freeipa/ticket/1919 https://fedorahosted.org/freeipa/ticket/2314 --- ipa-client/ipa-join.c | 80 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 25 deletions(-) (limited to 'ipa-client/ipa-join.c') diff --git a/ipa-client/ipa-join.c b/ipa-client/ipa-join.c index 57c7bcb28..bc46e9387 100644 --- a/ipa-client/ipa-join.c +++ b/ipa-client/ipa-join.c @@ -276,16 +276,52 @@ fail: return NULL; } +/* + * Given a list of naming contexts check each one to see if it has + * an IPA v2 server in it. The first one we find wins. + */ +static int +check_ipa_server(LDAP *ld, char **ldap_base, struct berval **vals) +{ + struct berval **infovals; + LDAPMessage *entry, *res = NULL; + char *info_attrs[] = {"info", NULL}; + int i, ret = 0; + + for (i = 0; !*ldap_base && vals[i]; i++) { + ret = ldap_search_ext_s(ld, vals[i]->bv_val, + LDAP_SCOPE_BASE, "(info=IPA*)", info_attrs, + 0, NULL, NULL, NULL, 0, &res); + + if (ret != LDAP_SUCCESS) { + break; + } + + entry = ldap_first_entry(ld, res); + infovals = ldap_get_values_len(ld, entry, info_attrs[0]); + if (!strcmp(infovals[0]->bv_val, "IPA V2.0")) + *ldap_base = strdup(vals[i]->bv_val); + ldap_msgfree(res); + res = NULL; + } + + return ret; +} + +/* + * Determine the baseDN of the remote server. Look first for a + * defaultNamingContext, otherwise fall back to reviewing each + * namingContext. + */ static int get_root_dn(const char *ipaserver, char **ldap_base) { LDAP *ld = NULL; - char *root_attrs[] = {"namingContexts", NULL}; - char *info_attrs[] = {"info", NULL}; + char *root_attrs[] = {"namingContexts", "defaultNamingContext", NULL}; LDAPMessage *entry, *res = NULL; struct berval **ncvals; - struct berval **infovals; - int i, ret, rval = 0; + struct berval **defvals; + int ret, rval = 0; ld = connect_ldap(ipaserver, NULL, NULL); if (!ld) { @@ -306,33 +342,27 @@ get_root_dn(const char *ipaserver, char **ldap_base) *ldap_base = NULL; - /* loop through to find the IPA context */ entry = ldap_first_entry(ld, res); - ncvals = ldap_get_values_len(ld, entry, root_attrs[0]); - if (!ncvals) { - fprintf(stderr, _("No values for %s"), root_attrs[0]); - rval = 14; - goto done; + + defvals = ldap_get_values_len(ld, entry, root_attrs[1]); + if (defvals) { + ret = check_ipa_server(ld, ldap_base, defvals); } - for (i = 0; !*ldap_base && ncvals[i]; i++) { - ret = ldap_search_ext_s(ld, ncvals[i]->bv_val, - LDAP_SCOPE_BASE, "(info=IPA*)", info_attrs, - 0, NULL, NULL, NULL, 0, &res); + ldap_value_free_len(defvals); - if (ret != LDAP_SUCCESS) { - break; + /* loop through to find the IPA context */ + if (ret == LDAP_SUCCESS && !*ldap_base) { + ncvals = ldap_get_values_len(ld, entry, root_attrs[0]); + if (!ncvals) { + fprintf(stderr, _("No values for %s"), root_attrs[0]); + rval = 14; + ldap_value_free_len(ncvals); + goto done; } - - entry = ldap_first_entry(ld, res); - infovals = ldap_get_values_len(ld, entry, info_attrs[0]); - if (!strcmp(infovals[0]->bv_val, "IPA V2.0")) - *ldap_base = strdup(ncvals[i]->bv_val); - ldap_msgfree(res); - res = NULL; + ret = check_ipa_server(ld, ldap_base, ncvals); + ldap_value_free_len(ncvals); } - ldap_value_free_len(ncvals); - if (ret != LDAP_SUCCESS) { fprintf(stderr, _("Search for IPA namingContext failed with error %d\n"), ret); rval = 14; -- cgit