mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-09-03 20:52:56 -05:00
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:
+4
-88
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user