From fdc2851233f532eb78363784712c597c63e1c4c1 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Thu, 20 Aug 2020 16:57:38 -0400 Subject: [PATCH 08/11] Switch IPA calls to use the JSON-RPC endpoint instead of XMLRPC IPA has provided a JSON-RPC interface for many years now and has long term plans to drop support for XMLRPC. --- src/ipa.c | 546 ++++++++++++++++++++++++++++++++++++++-------- src/store-files.c | 2 + 2 files changed, 463 insertions(+), 85 deletions(-) diff --git a/src/ipa.c b/src/ipa.c index e4295826..8c089e68 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -33,8 +33,7 @@ #include -#include -#include +#include #include #include @@ -46,7 +45,7 @@ #include "store.h" #include "submit-e.h" #include "submit-u.h" -#include "submit-x.h" +#include "submit-h.h" #include "util.h" #ifdef ENABLE_NLS @@ -56,6 +55,229 @@ #define _(_text) (_text) #endif +static char * +get_error_message(krb5_context ctx, krb5_error_code kcode) +{ + const char *ret; +#ifdef HAVE_KRB5_GET_ERROR_MESSAGE + ret = ctx ? krb5_get_error_message(ctx, kcode) : NULL; + if (ret == NULL) { + ret = error_message(kcode); + } +#else + ret = error_message(kcode); +#endif + return strdup(ret); +} + +char * +cm_submit_ccache_realm(char **msg) +{ + krb5_context ctx; + krb5_ccache ccache; + krb5_principal princ; + krb5_error_code kret; + krb5_data *data; + char *ret; + + if (msg != NULL) { + *msg = NULL; + } + + kret = krb5_init_context(&ctx); + if (kret != 0) { + fprintf(stderr, "Error initializing Kerberos: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return NULL; + } + kret = krb5_cc_default(ctx, &ccache); + if (kret != 0) { + fprintf(stderr, "Error resolving default ccache: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return NULL; + } + kret = krb5_cc_get_principal(ctx, ccache, &princ); + if (kret != 0) { + fprintf(stderr, "Error reading default principal: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return NULL; + } + data = krb5_princ_realm(ctx, princ); + if (data == NULL) { + fprintf(stderr, "Error retrieving principal realm.\n"); + if (msg != NULL) { + *msg = "Error retrieving principal realm.\n"; + } + return NULL; + } + ret = malloc(data->length + 1); + if (ret == NULL) { + fprintf(stderr, "Out of memory for principal realm.\n"); + if (msg != NULL) { + *msg = "Out of memory for principal realm.\n"; + } + return NULL; + } + memcpy(ret, data->data, data->length); + ret[data->length] = '\0'; + return ret; +} + +krb5_error_code +cm_submit_make_ccache(const char *ktname, const char *principal, char **msg) +{ + krb5_context ctx; + krb5_keytab keytab; + krb5_ccache ccache; + krb5_creds creds; + krb5_principal princ; + krb5_error_code kret; + krb5_get_init_creds_opt gicopts, *gicoptsp; + char *ret; + + if (msg != NULL) { + *msg = NULL; + } + + kret = krb5_init_context(&ctx); + if (kret != 0) { + ret = get_error_message(ctx, kret); + fprintf(stderr, "Error initializing Kerberos: %s.\n", ret); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + if (ktname != NULL) { + kret = krb5_kt_resolve(ctx, ktname, &keytab); + } else { + kret = krb5_kt_default(ctx, &keytab); + } + if (kret != 0) { + fprintf(stderr, "Error resolving keytab: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + princ = NULL; + if (principal != NULL) { + kret = krb5_parse_name(ctx, principal, &princ); + if (kret != 0) { + fprintf(stderr, "Error parsing \"%s\": %s.\n", + principal, ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + } else { + kret = krb5_sname_to_principal(ctx, NULL, NULL, + KRB5_NT_SRV_HST, &princ); + if (kret != 0) { + fprintf(stderr, "Error building client name: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + } + memset(&creds, 0, sizeof(creds)); +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + memset(&gicopts, 0, sizeof(gicopts)); + gicoptsp = NULL; + kret = krb5_get_init_creds_opt_alloc(ctx, &gicoptsp); + if (kret != 0) { + fprintf(stderr, "Internal error: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } +#else + krb5_get_init_creds_opt_init(&gicopts); + gicoptsp = &gicopts; +#endif + krb5_get_init_creds_opt_set_forwardable(gicoptsp, 1); + kret = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, + 0, NULL, gicoptsp); +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + krb5_get_init_creds_opt_free(ctx, gicoptsp); +#endif + if (kret != 0) { + fprintf(stderr, "Error obtaining initial credentials: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + ccache = NULL; + kret = krb5_cc_resolve(ctx, "MEMORY:" PACKAGE_NAME "_submit", + &ccache); + if (kret == 0) { + kret = krb5_cc_initialize(ctx, ccache, creds.client); + } + if (kret != 0) { + fprintf(stderr, "Error initializing credential cache: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + kret = krb5_cc_store_cred(ctx, ccache, &creds); + if (kret != 0) { + fprintf(stderr, + "Error storing creds in credential cache: %s.\n", + ret = get_error_message(ctx, kret)); + if (msg != NULL) { + *msg = ret; + } else { + free(ret); + } + return kret; + } + krb5_cc_close(ctx, ccache); + krb5_kt_close(ctx, keytab); + krb5_free_principal(ctx, princ); + krb5_free_context(ctx); + putenv("KRB5CCNAME=MEMORY:" PACKAGE_NAME "_submit"); + return 0; +} + static int interact(LDAP *ld, unsigned flags, void *defaults, void *sasl_interact) { @@ -200,7 +422,7 @@ cm_find_default_naming_context(LDAP *ld, char **basedn) } static int -cm_locate_xmlrpc_service(const char *server, +cm_locate_jsonrpc_service(const char *server, int ldap_uri_cmd, const char *ldap_uri, const char *host, const char *domain, @@ -213,10 +435,13 @@ cm_locate_xmlrpc_service(const char *server, LDAPDN rdn; struct berval *lbv; char *lattrs[2] = {"cn", NULL}; - const char *relativedn = "cn=masters,cn=ipa,cn=etc", *dn; + const char *relativedn = "cn=masters,cn=ipa,cn=etc"; + char *dn; char ldn[LINE_MAX], lfilter[LINE_MAX], uri[LINE_MAX] = "", **list; int i, j, rc, n; unsigned int flags; + int rval = 0; + int alloc_basedn = 0; *uris = NULL; @@ -231,14 +456,16 @@ cm_locate_xmlrpc_service(const char *server, if (basedn == NULL) { i = cm_find_default_naming_context(ld, &basedn); if (i != 0) { - free(basedn); - return i; + rval = i; + goto done; } + alloc_basedn = 1; } if (basedn == NULL) { printf(_("Unable to determine base DN of " "domain information on IPA server.\n")); - return CM_SUBMIT_STATUS_UNCONFIGURED; + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto done; } /* Now look up the names of the master CAs. */ snprintf(lfilter, sizeof(lfilter), @@ -248,26 +475,31 @@ cm_locate_xmlrpc_service(const char *server, "(ipaConfigString=enabledService)" ")", service); snprintf(ldn, sizeof(ldn), "%s,%s", relativedn, basedn); - free(basedn); + if (alloc_basedn) { + free(basedn); + } rc = ldap_search_ext_s(ld, ldn, LDAP_SCOPE_SUBTREE, lfilter, lattrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &lresult); if (rc != LDAP_SUCCESS) { fprintf(stderr, "Error searching '%s': %s.\n", ldn, ldap_err2string(rc)); - return CM_SUBMIT_STATUS_UNCONFIGURED; + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto done; } /* Read their parents' for "cn" values. */ n = ldap_count_entries(ld, lresult); if (n == 0) { fprintf(stderr, "No CA masters found.\n"); ldap_msgfree(lresult); - return CM_SUBMIT_STATUS_UNCONFIGURED; + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto done; } list = talloc_array_ptrtype(NULL, list, n + 2); if (list == NULL) { fprintf(stderr, "Out of memory.\n"); - return CM_SUBMIT_STATUS_UNCONFIGURED; + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto done; } i = 0; for (lmsg = ldap_first_entry(ld, lresult); @@ -314,7 +546,7 @@ cm_locate_xmlrpc_service(const char *server, switch (flags & 0x0f) { case LDAP_AVA_STRING: list[i] = talloc_asprintf(list, - "https://%.*s/ipa/xml", + "https://%.*s/ipa/json", (int) lbv->bv_len, lbv->bv_val); if (list[i] != NULL) { @@ -328,15 +560,67 @@ cm_locate_xmlrpc_service(const char *server, ldap_dnfree(rdn); } } + ldap_memfree(dn); } ldap_msgfree(lresult); if (i == 0) { free(list); - return CM_SUBMIT_STATUS_UNCONFIGURED; + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto done; } list[i] = NULL; *uris = list; - return CM_SUBMIT_STATUS_ISSUED; + rval = CM_SUBMIT_STATUS_ISSUED; + +done: + if (ld) { + ldap_unbind_ext(ld, NULL, NULL); + } + + return rval; +} + +/* + * Parse the JSON response from the IPA server. + * + * It will return one of three types of values: + * + * < 0 is failure to parse JSON output + * 0 is success, no errors were found + * > 0 is the IPA API error code + */ +static int +parse_json_result(const char *result, char **error_message) { + json_error_t j_error; + + json_t *j_root = NULL; + json_t *j_error_obj = NULL; + + int error_code = 0; + + j_root = json_loads(result, 0, &j_error); + if (!j_root) { + cm_log(0, "Parsing JSON-RPC response failed: %s\n", j_error.text); + return -1; + } + + j_error_obj = json_object_get(j_root, "error"); + if (!j_error_obj || json_is_null(j_error_obj)) { + json_decref(j_root); + return 0; // no errors + } + + if (json_unpack_ex(j_error_obj, &j_error, 0, "{s:i, s:s}", + "code", &error_code, + "message", error_message) != 0) { + cm_log(0, "Failed extracting error from JSON-RPC response: %s\n", j_error.text); + json_decref(j_root); + return -1; + } + + cm_log(0, "JSON-RPC error: %d: %s\n", error_code, *error_message); + json_decref(j_root); + return error_code; } /* Make an XML-RPC request to the "cert_request" method. */ @@ -344,63 +628,98 @@ static int submit_or_poll_uri(const char *uri, const char *cainfo, const char *capath, const char *uid, const char *pwd, const char *csr, const char *reqprinc, const char *profile, - const char *issuer) + const char *issuer, int verbose) { - struct cm_submit_x_context *ctx; - const char *args[2]; + void *ctx; + struct cm_submit_h_context *hctx; char *s, *p; int i; + json_t *json_req = NULL; + json_error_t j_error; + const char *results = NULL; + char *json_str = NULL; + char *error_message = NULL; + char *referer = NULL; + int rval = 0; + json_t *j_root = NULL; + json_t *j_result_outer = NULL; + json_t *j_result = NULL; + json_t *j_cert = NULL; + const char *certificate = NULL; if ((uri == NULL) || (strlen(uri) == 0)) { return CM_SUBMIT_STATUS_UNCONFIGURED; } - /* Prepare to make an XML-RPC request. */ + ctx = talloc_new(NULL); + + referer = talloc_asprintf(ctx, "%s", uri); + + /* Prepare to make a JSON-RPC request. */ submit: - if ((uid != NULL) && (pwd != NULL) && - (strlen(uid) > 0) && (strlen(pwd) > 0)) { - ctx = cm_submit_x_init(NULL, uri, "cert_request", - cainfo, capath, uid, pwd, - cm_submit_x_negotiate_off, - cm_submit_x_delegate_off);; - } else { - ctx = cm_submit_x_init(NULL, uri, "cert_request", - cainfo, capath, NULL, NULL, - cm_submit_x_negotiate_on, - cm_submit_x_delegate_on); + json_req = json_pack_ex(&j_error, 0, + "{s:s, s:[[s], {s:s, s:s*, s:s*, s:b}]}", + "method", "cert_request", + "params", + csr, + "principal", reqprinc, + "profile_id", profile, + "cacn", issuer, + "add", 1); + if (!json_req) { + cm_log(0, "json_pack_ex() failed: %s\n", j_error.text); + return CM_SUBMIT_STATUS_UNCONFIGURED; } - if (ctx == NULL) { - fprintf(stderr, "Error setting up for XMLRPC to %s on " - "the client.\n", uri); - printf(_("Error setting up for XMLRPC on the client.\n")); + json_str = json_dumps(json_req, 0); + json_decref(json_req); + if (!json_str) { + cm_log(0, "json_dumps() failed\n"); return CM_SUBMIT_STATUS_UNCONFIGURED; } - /* Add the CSR contents as the sole unnamed argument. */ - args[0] = csr; - args[1] = NULL; - cm_submit_x_add_arg_as(ctx, args); - /* Add the principal name named argument. */ - cm_submit_x_add_named_arg_s(ctx, "principal", reqprinc); - /* Add the requested profile name named argument. */ - if (profile != NULL) { - cm_submit_x_add_named_arg_s(ctx, "profile_id", profile); - } - /* Add the requested CA issuer named argument. */ - if (issuer != NULL) { - cm_submit_x_add_named_arg_s(ctx, "cacn", issuer); + hctx = cm_submit_h_init(ctx, "POST", uri, json_str, + "application/json", "application/json", + referer, cainfo, capath, + NULL, NULL, NULL, + cm_submit_h_negotiate_on, + cm_submit_h_delegate_off, + cm_submit_h_clientauth_off, + cm_submit_h_env_modify_off, + verbose > 1 ? + cm_submit_h_curl_verbose_on : + cm_submit_h_curl_verbose_off); + free(json_str); + + if (hctx == NULL) { + fprintf(stderr, "Error setting up JSON-RPC to %s on " + "the client.\n", uri); + printf(_("Error setting up for JSON-RPC on the client.\n")); + rval = CM_SUBMIT_STATUS_UNCONFIGURED; + goto cleanup; } - /* Tell the server to add entries for a principal if one - * doesn't exist yet. */ - cm_submit_x_add_named_arg_b(ctx, "add", 1); /* Submit the request. */ fprintf(stderr, "Submitting request to \"%s\".\n", uri); - cm_submit_x_run(ctx); + cm_submit_h_run(hctx); /* Check the results. */ - if (cm_submit_x_faulted(ctx) == 0) { - i = cm_submit_x_fault_code(ctx); + + results = cm_submit_h_results(hctx, NULL); + cm_log(1, "%s\n", results); + if (cm_submit_h_response_code(hctx) != 200) { + cm_log(0, "JSON-RPC call failed with HTTP status code: %d\n", + cm_submit_h_response_code(hctx)); + cm_log(0, "code = %d, code_text = \"%s\"\n", + cm_submit_h_result_code(hctx), cm_submit_h_result_code_text(hctx)); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + i = parse_json_result(results, &error_message); + if (i < 0) { + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + if (i > 0) { /* Interpret the error. See errors.py to get the * classifications. */ switch (i / 1000) { @@ -424,8 +743,9 @@ submit: } printf("Server at %s denied our request, " "giving up: %d (%s).\n", uri, i, - cm_submit_x_fault_text(ctx)); - return CM_SUBMIT_STATUS_REJECTED; + error_message); + rval = CM_SUBMIT_STATUS_REJECTED; + goto cleanup; break; case 1: /* authentication error - transient? */ case 4: /* execution error - transient? */ @@ -433,22 +753,51 @@ submit: default: printf("Server at %s failed request, " "will retry: %d (%s).\n", uri, i, - cm_submit_x_fault_text(ctx)); - return CM_SUBMIT_STATUS_UNREACHABLE; + error_message); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; break; } - } else - if (cm_submit_x_has_results(ctx) == 0) { - if (cm_submit_x_get_named_s(ctx, "certificate", - &s) == 0) { + } else { + j_root = json_loads(results, 0, &j_error); + if (!j_root) { + cm_log(0, "Parsing JSON-RPC response failed: %s\n", j_error.text); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + + j_result_outer = json_object_get(j_root, "result"); + if (!j_result_outer) { + cm_log(0, "Parsing JSON-RPC response failed, no outer result\n"); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + + j_result = json_object_get(j_result_outer, "result"); + if (!j_result) { + cm_log(0, "Parsing JSON-RPC response failed, no inner result\n"); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + + j_cert = json_object_get(j_result, "certificate"); + if (!j_cert) { + cm_log(0, "Parsing JSON-RPC response failed, no certificate\n"); + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; + } + certificate = json_string_value(j_cert); + + if (certificate) { /* If we got a certificate, we're probably * okay. */ - fprintf(stderr, "Certificate: \"%s\"\n", s); - s = cm_submit_u_base64_from_text(s); + fprintf(stderr, "Certificate: \"%s\"\n", certificate); + s = cm_submit_u_base64_from_text(certificate); if (s == NULL) { printf("Out of memory parsing server " "response, will retry.\n"); - return CM_SUBMIT_STATUS_UNREACHABLE; + rval = CM_SUBMIT_STATUS_UNREACHABLE; + goto cleanup; } p = cm_submit_u_pem_from_base64("CERTIFICATE", FALSE, s); @@ -457,15 +806,19 @@ submit: } free(s); free(p); - return CM_SUBMIT_STATUS_ISSUED; + rval = CM_SUBMIT_STATUS_ISSUED; + goto cleanup; } else { - return CM_SUBMIT_STATUS_REJECTED; + rval = CM_SUBMIT_STATUS_REJECTED; } - } else { - /* No useful response, no fault. Try again, from - * scratch, later. */ - return CM_SUBMIT_STATUS_UNREACHABLE; } + +cleanup: + json_decref(j_root); + cm_submit_h_cleanup(hctx); + talloc_free(ctx); + + return rval; } static int @@ -473,16 +826,17 @@ submit_or_poll(const char *uri, const char *cainfo, const char *capath, const char *server, int ldap_uri_cmd, const char *ldap_uri, const char *host, const char *domain, char *basedn, const char *uid, const char *pwd, const char *csr, - const char *reqprinc, const char *profile, const char *issuer) + const char *reqprinc, const char *profile, const char *issuer, + int verbose) { int i, u; char **uris; i = submit_or_poll_uri(uri, cainfo, capath, uid, pwd, csr, reqprinc, - profile, issuer); + profile, issuer, verbose); if ((i == CM_SUBMIT_STATUS_UNREACHABLE) || (i == CM_SUBMIT_STATUS_UNCONFIGURED)) { - u = cm_locate_xmlrpc_service(server, ldap_uri_cmd, ldap_uri, + u = cm_locate_jsonrpc_service(server, ldap_uri_cmd, ldap_uri, host, domain, basedn, "CA", &uris); if ((u == 0) && (uris != NULL)) { for (u = 0; uris[u] != NULL; u++) { @@ -491,7 +845,7 @@ submit_or_poll(const char *uri, const char *cainfo, const char *capath, } i = submit_or_poll_uri(uris[u], cainfo, capath, uid, pwd, csr, reqprinc, - profile, issuer); + profile, issuer, verbose); if ((i != CM_SUBMIT_STATUS_UNREACHABLE) && (i != CM_SUBMIT_STATUS_UNCONFIGURED)) { talloc_free(uris); @@ -562,7 +916,7 @@ fetch_roots(const char *server, int ldap_uri_cmd, const char *ldap_uri, return CM_SUBMIT_STATUS_ISSUED; } /* Read our realm name from our ccache. */ - realm = cm_submit_x_ccache_realm(&kerr); + realm = cm_submit_ccache_realm(&kerr); /* Read all of the certificates. */ for (lmsg = ldap_first_entry(ld, lresult); lmsg != NULL; @@ -588,6 +942,9 @@ fetch_roots(const char *server, int ldap_uri_cmd, const char *ldap_uri, ldap_msgfree(lresult); free(realm); free(kerr); + if (ld) { + ldap_unbind_ext(ld, NULL, NULL); + } return CM_SUBMIT_STATUS_ISSUED; } @@ -600,7 +957,8 @@ main(int argc, const char **argv) char *csr, *p, uri[LINE_MAX], *reqprinc = NULL, *ipaconfig, *kerr; char *uid = NULL, *pwd = NULL, *pwdfile = NULL; const char *xmlrpc_uri = NULL, *ldap_uri = NULL, *server = NULL, *csrfile; - int xmlrpc_uri_cmd = 0, ldap_uri_cmd = 0, verbose = 0; + const char *jsonrpc_uri = NULL; + int jsonrpc_uri_cmd = 0, ldap_uri_cmd = 0, verbose = 0; const char *mode = CM_OP_SUBMIT; char ldn[LINE_MAX], *basedn = NULL, *profile = NULL, *issuer = NULL; krb5_error_code kret; @@ -609,6 +967,7 @@ main(int argc, const char **argv) {"host", 'h', POPT_ARG_STRING, &host, 0, "IPA server hostname", "HOSTNAME"}, {"domain", 'd', POPT_ARG_STRING, &domain, 0, "IPA domain name", "NAME"}, {"xmlrpc-url", 'H', POPT_ARG_STRING, NULL, 'H', "IPA XMLRPC service location", "URL"}, + {"jsonrpc-url", 'J', POPT_ARG_STRING, NULL, 'J', "IPA JSON-RPC service location", "URL"}, {"ldap-url", 'L', POPT_ARG_STRING, NULL, 'L', "IPA LDAP service location", "URL"}, {"capath", 'C', POPT_ARG_STRING, &capath, 0, NULL, "DIRECTORY"}, {"cafile", 'c', POPT_ARG_STRING, &cainfo, 0, NULL, "FILENAME"}, @@ -659,9 +1018,10 @@ main(int argc, const char **argv) poptSetOtherOptionHelp(pctx, "[options] [csrfile]"); while ((c = poptGetNextOpt(pctx)) > 0) { switch (c) { - case 'H': - xmlrpc_uri = poptGetOptArg(pctx); - xmlrpc_uri_cmd++; + case 'H': /* XMLRPC URI kept for backwards compatibility */ + case 'J': + jsonrpc_uri = poptGetOptArg(pctx); + jsonrpc_uri_cmd++; break; case 'L': ldap_uri = poptGetOptArg(pctx); @@ -724,6 +1084,11 @@ main(int argc, const char **argv) "global", "xmlrpc_uri"); } + if (jsonrpc_uri == NULL) { + jsonrpc_uri = get_config_entry(ipaconfig, + "global", + "jsonrpc_uri"); + } if (ldap_uri == NULL) { /* Preferred, but likely to only be set on a * server. */ @@ -756,6 +1121,7 @@ main(int argc, const char **argv) } } } + free(ipaconfig); csr = NULL; memset(uri, '\0', sizeof(uri)); memset(ldn, '\0', sizeof(ldn)); @@ -787,16 +1153,25 @@ main(int argc, const char **argv) (getenv(CM_SUBMIT_ISSUER_ENV) != NULL)) { issuer = strdup(getenv(CM_SUBMIT_ISSUER_ENV)); } - if ((server != NULL) && !xmlrpc_uri_cmd) { + if ((server != NULL) && !jsonrpc_uri_cmd) { snprintf(uri, sizeof(uri), - "https://%s/ipa/xml", server); + "https://%s/ipa/json", server); + } else + if (jsonrpc_uri != NULL) { + snprintf(uri, sizeof(uri), "%s", jsonrpc_uri); } else if (xmlrpc_uri != NULL) { - snprintf(uri, sizeof(uri), "%s", xmlrpc_uri); + /* strip off the trailing xml and replace with json */ + if ((strlen(xmlrpc_uri) + 1) > sizeof(uri)) { + printf(_("xmlrpc_uri is longer than %ld.\n"), sizeof(uri) - 2); + return CM_SUBMIT_STATUS_UNCONFIGURED; + } + snprintf(uri, strlen(xmlrpc_uri) - 2, "%s", xmlrpc_uri); + strcat(uri, "json"); } else if (host != NULL) { snprintf(uri, sizeof(uri), - "https://%s/ipa/xml", host); + "https://%s/ipa/json", host); } /* Read the CSR from the environment, or from the file named on @@ -891,7 +1266,7 @@ main(int argc, const char **argv) /* Setup a ccache unless we're told to use the default one. */ kerr = NULL; if (make_keytab_ccache && - ((kret = cm_submit_x_make_ccache(ktname, kpname, &kerr)) != 0)) { + ((kret = cm_submit_make_ccache(ktname, kpname, &kerr)) != 0)) { fprintf(stderr, "Error setting up ccache at the client: %s.\n", kerr); if (ktname == NULL) { @@ -939,11 +1314,12 @@ main(int argc, const char **argv) ret = submit_or_poll(uri, cainfo, capath, server, ldap_uri_cmd, ldap_uri, host, domain, basedn, uid, pwd, csr, reqprinc, profile, - issuer); + issuer, verbose); free(csr); free(profile); free(issuer); free(reqprinc); + free(basedn); return ret; } else if (strcasecmp(mode, CM_OP_FETCH_ROOTS) == 0) { diff --git a/src/store-files.c b/src/store-files.c index 4c3b2232..85ac692e 100644 --- a/src/store-files.c +++ b/src/store-files.c @@ -2650,6 +2650,7 @@ cm_store_get_all_cas(void *parent) j++; } #endif +#ifdef WITH_XMLRPC #ifdef WITH_CERTMASTER /* Make sure we get at least one certmaster entry. */ for (k = 0; k < j; k++) { @@ -2670,6 +2671,7 @@ cm_store_get_all_cas(void *parent) j++; } #endif +#endif #ifdef WITH_IPA /* Make sure we get at least 1 dogtag-ipa-renew-agent entry. */ for (k = 0; k < j; k++) { -- 2.25.4