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 <rcritten@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
This commit is contained in:
Rob Crittenden
2018-08-29 09:03:18 +02:00
committed by Tibor Dudlák
parent ad85cc8eae
commit 8af6accfa5
2 changed files with 18 additions and 95 deletions
+4 -88
View File
@@ -371,62 +371,6 @@ done:
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 @@ done:
* 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 @@ done:
}
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)
+14 -7
View File
@@ -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,20 @@ 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:
logger.debug("config_show failed %s", e, exc_info=True)
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()