diff options
Diffstat (limited to 'ipa-client')
-rw-r--r-- | ipa-client/ipa-install/ipa-client-install | 17 | ||||
-rw-r--r-- | ipa-client/ipa-join.c | 89 |
2 files changed, 98 insertions, 8 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 |