URL: https://github.com/freeipa/freeipa/pull/2299 Author: rcritten Title: #2299: Retrieve certificate subject base directly instead of ipa-join Action: opened
PR body: """ The subject base is used as a fallback to find the available CA certificates during client enrollment if the LDAP connection fails (e.g. due to new client connecting to very old server) and for constructing the subject if a certificate is requested. raw=True is passed to config-show in order to avoid parsing the server roles which will fail because the services aren't marked as enabled until after the client installation is successful on a master. ipa-join providing the subject base via stderr was fragile and would cause client enrollment to fail if any other output was included in stderr. https://pagure.io/freeipa/issue/7674 Testing is handled by existing integration tests, both in plain installations and --request-cert to ensure there is a subject base. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/2299/head:pr2299 git checkout pr2299
From e3d199cd4ecb57fec0dc048a17b6399d89f8318e Mon Sep 17 00:00:00 2001 From: Rob Crittenden <rcrit...@redhat.com> Date: Mon, 20 Aug 2018 15:10:34 -0400 Subject: [PATCH] Retrieve certificate subject base directly instead of ipa-join The subject base is used as a fallback to find the available CA certificates during client enrollment if the LDAP connection fails (e.g. due to new client connecting to very old server) and for constructing the subject if a certificate is requested. raw=True is passed to config-show in order to avoid parsing the server roles which will fail because the services aren't marked as enabled until after the client installation is successful on a master. ipa-join providing the subject base via stderr was fragile and would cause client enrollment to fail if any other output was included in stderr. https://pagure.io/freeipa/issue/7674 Signed-off-by: Rob Crittenden <rcrit...@redhat.com> --- client/ipa-join.c | 92 ++----------------------------------- ipaclient/install/client.py | 20 +++++--- 2 files changed, 17 insertions(+), 95 deletions(-) diff --git a/client/ipa-join.c b/client/ipa-join.c index 7f406b440a..7f454f723d 100644 --- a/client/ipa-join.c +++ b/client/ipa-join.c @@ -371,62 +371,6 @@ get_root_dn(const char *ipaserver, char **ldap_base) return rval; } -/* - * Get the certificate subject base from the IPA configuration. - * - * Not considered a show-stopper if this fails for some reason. - * - * The caller is responsible for binding/unbinding to LDAP. - */ -static int -get_subject(LDAP *ld, char *ldap_base, const char **subject, int quiet) -{ - char *attrs[] = {"ipaCertificateSubjectBase", NULL}; - char *base = NULL; - LDAPMessage *entry, *res = NULL; - struct berval **ncvals; - int ret, rval = 0; - - ret = asprintf(&base, "cn=ipaconfig,cn=etc,%s", ldap_base); - if (ret == -1) - { - if (!quiet) - fprintf(stderr, _("Out of memory!\n")); - rval = 3; - goto done; - } - - ret = ldap_search_ext_s(ld, base, LDAP_SCOPE_BASE, - "objectclass=*", attrs, 0, - NULL, NULL, NULL, 0, &res); - - if (ret != LDAP_SUCCESS) { - fprintf(stderr, - _("Search for ipaCertificateSubjectBase failed with error %d"), - ret); - rval = 14; - goto done; - } - - entry = ldap_first_entry(ld, res); - ncvals = ldap_get_values_len(ld, entry, attrs[0]); - if (!ncvals) { - fprintf(stderr, _("No values for %s"), attrs[0]); - rval = 14; - goto done; - } - - *subject = strdup(ncvals[0]->bv_val); - - ldap_value_free_len(ncvals); - -done: - free(base); - if (res) ldap_msgfree(res); - - return rval; -} - /* Join a host to the current IPA realm. * * There are several scenarios for this: @@ -446,7 +390,7 @@ get_subject(LDAP *ld, char *ldap_base, const char **subject, int quiet) * the state of the entry. */ static int -join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bindpw, const char *basedn, const char **princ, const char **subject, int quiet) +join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bindpw, const char *basedn, const char **princ, int quiet) { LDAP *ld; int rval = 0; @@ -458,7 +402,6 @@ join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bin *binddn = NULL; *princ = NULL; - *subject = NULL; if (NULL != basedn) { ldap_base = strdup(basedn); @@ -494,14 +437,6 @@ join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bin goto done; } - if (get_subject(ld, ldap_base, subject, quiet) != 0) { - if (!quiet) - fprintf(stderr, - _("Unable to determine certificate subject of %s\n"), - ipaserver); - /* Not a critical failure */ - } - valrequest.bv_val = (char *)hostname; valrequest.bv_len = strlen(hostname); @@ -538,7 +473,7 @@ join_ldap(const char *ipaserver, char *hostname, char ** binddn, const char *bin } static int -join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **princ, const char **subject, int force, int quiet) { +join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **princ, int force, int quiet) { xmlrpc_env env; xmlrpc_value * argArrayP = NULL; xmlrpc_value * paramArrayP = NULL; @@ -550,7 +485,6 @@ join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **pri struct utsname uinfo; xmlrpc_value *princP = NULL; xmlrpc_value *krblastpwdchangeP = NULL; - xmlrpc_value *subjectP = NULL; xmlrpc_value *hostdnP = NULL; const char *krblastpwdchange = NULL; char * url = NULL; @@ -559,7 +493,6 @@ join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **pri int ret; *hostdn = NULL; - *subject = NULL; *princ = NULL; /* Start up our XML-RPC client library. */ @@ -658,18 +591,6 @@ join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **pri goto cleanup; } - xmlrpc_struct_find_value(&env, structP, "ipacertificatesubjectbase", &subjectP); - if (subjectP) { - xmlrpc_value * singleprincP = NULL; - - /* FIXME: all values are returned as lists currently. Once this is - * fixed we can read the string directly. - */ - xmlrpc_array_read_item(&env, subjectP, 0, &singleprincP); - xmlrpc_read_string(&env, singleprincP, *&subject); - xmlrpc_DECREF(subjectP); - } - cleanup: if (argArrayP) xmlrpc_DECREF(argArrayP); if (paramArrayP) xmlrpc_DECREF(paramArrayP); @@ -922,7 +843,6 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b char *iparealm = NULL; char * host = NULL; const char * princ = NULL; - const char * subject = NULL; char * hostdn = NULL; struct utsname uinfo; @@ -963,7 +883,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b } if (bindpw) - rval = join_ldap(ipaserver, host, &hostdn, bindpw, basedn, &princ, &subject, quiet); + rval = join_ldap(ipaserver, host, &hostdn, bindpw, basedn, &princ, quiet); else { krberr = krb5_init_context(&krbctx); if (krberr) { @@ -987,7 +907,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b rval = 6; goto cleanup; } - rval = join_krb5(ipaserver, host, &hostdn, &princ, &subject, force, + rval = join_krb5(ipaserver, host, &hostdn, &princ, force, quiet); } @@ -1049,11 +969,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *b } cleanup: - if (NULL != subject && !quiet && rval == 0) - fprintf(stderr, _("Certificate subject base is: %s\n"), subject); - free((char *)princ); - free((char *)subject); free(host); if (bindpw) diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py index 800a467340..045b4ba482 100644 --- a/ipaclient/install/client.py +++ b/ipaclient/install/client.py @@ -2684,13 +2684,6 @@ def _install(options): else: logger.info("Enrolled in IPA realm %s", cli_realm) - start = stderr.find('Certificate subject base is: ') - if start >= 0: - start = start + 29 - subject_base = stderr[start:] - subject_base = subject_base.strip() - subject_base = DN(subject_base) - if options.principal is not None: run([paths.KDESTROY], raiseonerr=False, env=env) @@ -2856,6 +2849,19 @@ def _install(options): if not ca_enabled: disable_ra() + try: + result = api.Backend.rpcclient.forward( + 'config_show', + raw=True, # so that servroles are not queried + version=u'2.0' + ) + except Exception as e: + raise ScriptError( + "Failed to retrieve CA certificate subject base: {}".format(e), + rval=CLIENT_INSTALL_ERROR) + else: + subject_base = DN(result['result']['ipacertificatesubjectbase'][0]) + # Create IPA NSS database try: create_ipa_nssdb()
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org