summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-client/ipa-install/ipa-client-install17
-rw-r--r--ipa-client/ipa-join.c89
-rw-r--r--ipaserver/plugins/join.py3
-rw-r--r--ipaserver/rpcserver.py3
4 files changed, 103 insertions, 9 deletions
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 9e66e786b..7a5e09310 100644
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -301,7 +301,7 @@ def configure_krb5_conf(fstore, cli_basedn, cli_realm, cli_domain, cli_server, d
return 0
-def configure_certmonger(fstore, options):
+def configure_certmonger(fstore, subject_base, cli_realm, options):
started = True
try:
@@ -319,8 +319,10 @@ def configure_certmonger(fstore, options):
# Request our host cert
if started:
+ subject = 'CN=%s,%s' % (socket.getfqdn(), subject_base)
+ principal = 'host/%s@%s' % (socket.getfqdn(), cli_realm)
try:
- run(["ipa-getcert", "request", "-d", "/etc/pki/nssdb", "-n", "Server-Cert"])
+ run(["ipa-getcert", "request", "-d", "/etc/pki/nssdb", "-n", "Server-Cert", "-N", subject, "-K", principal])
except:
print "certmonger request for host certificate failed"
@@ -370,6 +372,8 @@ def main():
cli_realm = None
cli_basedn = None
+ subject_base = "O=IPA"
+
if options.unattended and (options.password is None and options.principal is None and options.prompt_password is False) and not options.on_master:
print "One of password and principal are required."
return 1
@@ -489,6 +493,13 @@ def main():
if not options.force:
return 1
print " Use ipa-getkeytab to obtain a host principal for this server."
+
+ start = stderr.find('Certificate subject base is: ')
+ if start >= 0:
+ start = start + 29
+ subject_base = stderr[start:]
+ subject_base = subject_base.strip()
+
finally:
if options.principal is not None:
(stderr, stdout, returncode) = run(["/usr/kerberos/bin/kdestroy"], raiseonerr=False)
@@ -511,7 +522,7 @@ def main():
print "Configured /etc/ldap.conf"
if not options.on_master:
- configure_certmonger(fstore, options)
+ configure_certmonger(fstore, subject_base, cli_realm, options)
# If on master assume kerberos is already configured properly.
if not options.on_master:
diff --git a/ipa-client/ipa-join.c b/ipa-client/ipa-join.c
index 5b1f0a606..094bc948e 100644
--- a/ipa-client/ipa-join.c
+++ b/ipa-client/ipa-join.c
@@ -261,6 +261,57 @@ done:
return rval;
}
+static int
+get_subject(const char *ipaserver, char *ldap_base, char **subject)
+{
+ LDAP *ld = NULL;
+ char *attrs[] = {"ipaCertificateSubjectBase", NULL};
+ char base[LINE_MAX];
+ LDAPMessage *entry, *res = NULL;
+ struct berval **ncvals;
+ int ret, rval = 0;
+
+ ld = connect_ldap(ipaserver, NULL, NULL);
+ if (!ld) {
+ rval = 14;
+ goto done;
+ }
+
+ strcpy(base, "cn=ipaconfig,cn=etc,");
+ strcat(base, ldap_base);
+
+ 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",
+ attrs[0], 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:
+ if (res) ldap_msgfree(res);
+ if (ld != NULL) {
+ ldap_unbind_ext(ld, NULL, NULL);
+ }
+
+ return rval;
+}
+
/* Join a host to the current IPA realm.
*
* There are several scenarios for this:
@@ -280,7 +331,7 @@ done:
* the state of the entry.
*/
static int
-join_ldap(const char *ipaserver, const char *hostname, const char ** binddn, const char *bindpw, const char ** princ, int quiet)
+join_ldap(const char *ipaserver, const char *hostname, const char ** binddn, const char *bindpw, const char **princ, const char **subject, int quiet)
{
LDAP *ld;
char *filter = NULL;
@@ -304,6 +355,11 @@ join_ldap(const char *ipaserver, const char *hostname, const char ** binddn, con
goto done;
}
+ if (get_subject(ipaserver, ldap_base, &subject) != 0) {
+ fprintf(stderr, "Unable to determine certificate subject of %s\n", ipaserver);
+ /* Not a critical failure */
+ }
+
ld = connect_ldap(ipaserver, NULL, NULL);
if (!ld) {
fprintf(stderr, "Unable to make an LDAP connection to %s\n", ipaserver);
@@ -382,6 +438,7 @@ ldap_done:
free(filter);
free(search_base);
free(ldap_base);
+ free(subject);
if (ld != NULL) {
ldap_unbind_ext(ld, NULL, NULL);
}
@@ -392,8 +449,9 @@ done:
}
static int
-join_krb5(const char *ipaserver, const char *hostname, const char **hostdn, const char **princ, int quiet) {
+join_krb5(const char *ipaserver, const char *hostname, const char **hostdn, const char **princ, const char **subject, int quiet) {
xmlrpc_env env;
+ xmlrpc_value * argArrayP = NULL;
xmlrpc_value * paramArrayP = NULL;
xmlrpc_value * paramP = NULL;
xmlrpc_value * optionsP = NULL;
@@ -403,6 +461,7 @@ join_krb5(const char *ipaserver, const char *hostname, const char **hostdn, cons
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;
@@ -424,17 +483,19 @@ join_krb5(const char *ipaserver, const char *hostname, const char **hostdn, cons
#endif
serverInfoP = xmlrpc_server_info_new(&env, url);
+ argArrayP = xmlrpc_array_new(&env);
paramArrayP = xmlrpc_array_new(&env);
if (hostname == NULL)
paramP = xmlrpc_string_new(&env, uinfo.nodename);
else
paramP = xmlrpc_string_new(&env, hostname);
+ xmlrpc_array_append_item(&env, argArrayP, paramP);
#ifdef REALM
if (!quiet)
printf("Joining %s to IPA realm %s\n", uinfo.nodename, iparealm);
#endif
- xmlrpc_array_append_item(&env, paramArrayP, paramP);
+ xmlrpc_array_append_item(&env, paramArrayP, argArrayP);
xmlrpc_DECREF(paramP);
optionsP = xmlrpc_build_value(&env, "{s:s,s:s}",
@@ -488,7 +549,20 @@ join_krb5(const char *ipaserver, const char *hostname, const char **hostdn, cons
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);
if (resultP) xmlrpc_DECREF(resultP);
@@ -513,6 +587,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *k
char *iparealm = NULL;
char * conf_data = NULL;
const char * princ = NULL;
+ const char * subject = NULL;
const char * hostdn = NULL;
struct utsname uinfo;
@@ -548,7 +623,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *k
}
if (bindpw)
- rval = join_ldap(ipaserver, hostname, &hostdn, bindpw, &princ, quiet);
+ rval = join_ldap(ipaserver, hostname, &hostdn, bindpw, &princ, &subject, quiet);
else {
krberr = krb5_init_context(&krbctx);
if (krberr) {
@@ -569,7 +644,7 @@ join(const char *server, const char *hostname, const char *bindpw, const char *k
rval = 6;
goto cleanup;
}
- rval = join_krb5(ipaserver, hostname, &hostdn, &princ, quiet);
+ rval = join_krb5(ipaserver, hostname, &hostdn, &princ, &subject, quiet);
}
if (rval) goto cleanup;
@@ -629,7 +704,11 @@ join(const char *server, const char *hostname, const char *bindpw, const char *k
}
cleanup:
+ if (NULL != subject)
+ fprintf(stderr, "Certificate subject base is: %s\n", subject);
+
free((char *)princ);
+ free((char *)subject);
if (bindpw)
ldap_memfree((void *)hostdn);
else
diff --git a/ipaserver/plugins/join.py b/ipaserver/plugins/join.py
index e2f72bfaf..74fa806ff 100644
--- a/ipaserver/plugins/join.py
+++ b/ipaserver/plugins/join.py
@@ -113,6 +113,9 @@ class join(Command):
attrs_list = api.Command['host_add'](hostname)['result']
dn = attrs_list['dn']
+ config = api.Command['config_show']()['result']
+ attrs_list['ipacertificatesubjectbase'] = config['ipacertificatesubjectbase']
+
return (dn, attrs_list)
api.register(join)
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index 795a240d9..71d55445b 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -295,7 +295,8 @@ class xmlserver(WSGIExecutioner):
self.info('response: %s: %s', error.__class__.__name__, str(error))
response = Fault(error.errno, error.strerror)
else:
- self.info('response: entries returned %d', result.get('count', 1))
+ if isinstance(result, dict):
+ self.info('response: entries returned %d', result.get('count', 1))
response = (result,)
return xml_dumps(response, methodresponse=True)