diff options
author | Rob Crittenden <rcritten@redhat.com> | 2010-04-05 16:27:46 -0400 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2010-04-23 04:57:40 -0600 |
commit | 1d635090cbd68b6bec9ce57a2fbfd9ff1b91f908 (patch) | |
tree | 3816a3809f5274741850c89ea830c24859f05e64 /ipa-client/ipa-join.c | |
parent | 7c61663def1b00ceb4daf22be7a8d1c7116b6433 (diff) | |
download | freeipa-1d635090cbd68b6bec9ce57a2fbfd9ff1b91f908.tar.gz freeipa-1d635090cbd68b6bec9ce57a2fbfd9ff1b91f908.tar.xz freeipa-1d635090cbd68b6bec9ce57a2fbfd9ff1b91f908.zip |
Use the certificate subject base in IPA when requesting certs in certmonger.
When using the dogtag CA we can control what the subject of an issued
certificate is regardless of what is in the CSR, we just use the CN value.
The selfsign CA does not have this capability. The subject format must
match the configured format or certificate requests are rejected.
The default format is CN=%s,O=IPA. certmonger by default issues requests
with just CN so all requests would fail if using the selfsign CA.
This subject base is stored in cn=ipaconfig so we can just fetch that
value in the enrollment process and pass it to certmonger to request
the right thing.
Note that this also fixes ipa-join to work with the new argument passing
mechanism.
Diffstat (limited to 'ipa-client/ipa-join.c')
-rw-r--r-- | ipa-client/ipa-join.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/ipa-client/ipa-join.c b/ipa-client/ipa-join.c index 5b1f0a60..094bc948 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 |