Beispiel #1
0
// XXX Could probably create a bunch of send jobs in a single get of the lock.
void RPCSub::sendThread ()
{
    Json::Value jvEvent;
    bool    bSend;

    do
    {
        {
            // Obtain the lock to manipulate the queue and change sending.
            boost::mutex::scoped_lock sl (mLockInfo);

            if (mDeque.empty ())
            {
                mSending    = false;
                bSend       = false;
            }
            else
            {
                std::pair<int, Json::Value> pEvent  = mDeque.front ();

                mDeque.pop_front ();

                jvEvent     = pEvent.second;
                jvEvent["seq"]  = pEvent.first;

                bSend       = true;
            }
        }

        // Send outside of the lock.
        if (bSend)
        {
            // XXX Might not need this in a try.
            try
            {
                WriteLog (lsINFO, RPCSub) << boost::str (boost::format ("callRPC calling: %s") % mIp);

                callRPC (
                    theApp->getIOService (),
                    mIp, mPort,
                    mUsername, mPassword,
                    mPath, "event",
                    jvEvent,
                    mSSL);
            }
            catch (const std::exception& e)
            {
                WriteLog (lsINFO, RPCSub) << boost::str (boost::format ("callRPC exception: %s") % e.what ());
            }
        }
    }
    while (bSend);
}
Beispiel #2
0
static int
unenroll_host(const char *server, const char *hostname, const char *ktname, int quiet)
{
    int rval = 0;
    int ret;
    char *ipaserver = NULL;
    char *host = NULL;
    struct utsname uinfo;
    char *principal = NULL;
    char *realm = NULL;

    krb5_context krbctx = NULL;
    krb5_keytab keytab = NULL;
    krb5_ccache ccache = NULL;
    krb5_principal princ = NULL;
    krb5_error_code krberr;
    krb5_creds creds;
    krb5_get_init_creds_opt gicopts;
    char tgs[LINE_MAX];

    xmlrpc_env env;
    xmlrpc_value * argArrayP = NULL;
    xmlrpc_value * paramArrayP = NULL;
    xmlrpc_value * paramP = NULL;
    xmlrpc_value * resultP = NULL;
    xmlrpc_server_info * serverInfoP = NULL;
    xmlrpc_value *princP = NULL;
    char * url = NULL;
    char * user_agent = NULL;

    if (server) {
        ipaserver = strdup(server);
    } else {
        char * conf_data = read_config_file(IPA_CONFIG);
        if ((ipaserver = getIPAserver(conf_data)) == NULL) {
            if (!quiet)
                fprintf(stderr, _("Unable to determine IPA server from %s\n"),
                        IPA_CONFIG);
            exit(1);
        }
        free(conf_data);
    }

    if (NULL == hostname) {
        uname(&uinfo);
        host = strdup(uinfo.nodename);
    } else {
        host = strdup(hostname);
    }

    if (NULL == strstr(host, ".")) {
        if (!quiet)
            fprintf(stderr, _("The hostname must be fully-qualified: %s\n"),
                    host);
        rval = 16;
        goto cleanup;
    }

    krberr = krb5_init_context(&krbctx);
    if (krberr) {
        if (!quiet)
            fprintf(stderr, _("Unable to join host: "
                              "Kerberos context initialization failed\n"));
        rval = 1;
        goto cleanup;
    }
    krberr = krb5_kt_resolve(krbctx, ktname, &keytab);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error resolving keytab: %s.\n"),
                error_message(krberr));
        rval = 7;
        goto cleanup;
    }

    krberr = krb5_get_default_realm(krbctx, &realm);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error getting default Kerberos realm: %s.\n"),
                error_message(krberr));
        rval = 21;
        goto cleanup;
    }

    ret = asprintf(&principal, "host/%s@%s", host,  realm);
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto cleanup;
    }

    krberr = krb5_parse_name(krbctx, principal, &princ);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error parsing \"%1$s\": %2$s.\n"),
                            principal, error_message(krberr));
        return krberr;
    }
    strcpy(tgs, KRB5_TGS_NAME);
    snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "/%.*s",
             (krb5_princ_realm(krbctx, princ))->length,
             (krb5_princ_realm(krbctx, princ))->data);
    snprintf(tgs + strlen(tgs), sizeof(tgs) - strlen(tgs), "@%.*s",
             (krb5_princ_realm(krbctx, princ))->length,
             (krb5_princ_realm(krbctx, princ))->data);
    memset(&creds, 0, sizeof(creds));
    krb5_get_init_creds_opt_init(&gicopts);
    krb5_get_init_creds_opt_set_forwardable(&gicopts, 1);
    krberr = krb5_get_init_creds_keytab(krbctx, &creds, princ, keytab,
                                      0, tgs, &gicopts);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr, _("Error obtaining initial credentials: %s.\n"),
                    error_message(krberr));
        return krberr;
    }

    krberr = krb5_cc_resolve(krbctx, "MEMORY:ipa-join", &ccache);
    if (krberr == 0) {
        krberr = krb5_cc_initialize(krbctx, ccache, creds.client);
    } else {
        if (!quiet)
            fprintf(stderr,
                    _("Unable to generate Kerberos Credential Cache\n"));
        rval = 19;
        goto cleanup;
    }
    krberr = krb5_cc_store_cred(krbctx, ccache, &creds);
    if (krberr != 0) {
        if (!quiet)
            fprintf(stderr,
                    _("Error storing creds in credential cache: %s.\n"),
                    error_message(krberr));
        return krberr;
    }
    krb5_cc_close(krbctx, ccache);
    ccache = NULL;
    putenv("KRB5CCNAME=MEMORY:ipa-join");

    /* Start up our XML-RPC client library. */
    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);

    xmlrpc_env_init(&env);

    xmlrpc_client_setup_global_const(&env);

#if 1
    ret = asprintf(&url, "https://%s:443/ipa/xml", ipaserver);
#else
    ret = asprintf(&url, "http://%s:8888/", ipaserver);
#endif
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto cleanup;
    }
    serverInfoP = xmlrpc_server_info_new(&env, url);

    argArrayP = xmlrpc_array_new(&env);
    paramArrayP = xmlrpc_array_new(&env);

    paramP = xmlrpc_string_new(&env, host);
    xmlrpc_array_append_item(&env, argArrayP, paramP);
    xmlrpc_array_append_item(&env, paramArrayP, argArrayP);
    xmlrpc_DECREF(paramP);

    if ((user_agent = set_user_agent(ipaserver)) == NULL) {
        rval = 3;
        goto cleanup;
    }
    callRPC(user_agent, &env, serverInfoP, "host_disable", paramArrayP, &resultP);
    if (handle_fault(&env)) {
        rval = 17;
        goto cleanup;
    }

    xmlrpc_struct_find_value(&env, resultP, "result", &princP);
    if (princP) {
        xmlrpc_bool result;

        xmlrpc_read_bool(&env, princP, &result);
        if (result == 1) {
            if (!quiet)
                fprintf(stderr, _("Unenrollment successful.\n"));
        } else {
            if (!quiet)
                fprintf(stderr, _("Unenrollment failed.\n"));
        }

        xmlrpc_DECREF(princP);
    } else {
        fprintf(stderr, _("result not found in XML-RPC response\n"));
        rval = 20;
        goto cleanup;
    }

cleanup:

    free(user_agent);
    if (keytab) krb5_kt_close(krbctx, keytab);
    free((char *)principal);
    free((char *)ipaserver);
    if (princ) krb5_free_principal(krbctx, princ);
    if (ccache) krb5_cc_close(krbctx, ccache);
    if (krbctx) krb5_free_context(krbctx);

    free(url);
    xmlrpc_env_clean(&env);
    xmlrpc_client_cleanup();

    return rval;
}
Beispiel #3
0
static int
join_krb5(const char *ipaserver, char *hostname, char **hostdn, const char **princ, const char **subject, int force, int quiet) {
    xmlrpc_env env;
    xmlrpc_value * argArrayP = NULL;
    xmlrpc_value * paramArrayP = NULL;
    xmlrpc_value * paramP = NULL;
    xmlrpc_value * optionsP = NULL;
    xmlrpc_value * resultP = NULL;
    xmlrpc_value * structP = NULL;
    xmlrpc_server_info * serverInfoP = NULL;
    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;
    char * user_agent = NULL;
    int rval = 0;
    int ret;

    *hostdn = NULL;
    *subject = NULL;
    *princ = NULL;

    /* Start up our XML-RPC client library. */
    xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);

    uname(&uinfo);

    xmlrpc_env_init(&env);

    xmlrpc_client_setup_global_const(&env);

#if 1
    ret = asprintf(&url, "https://%s:443/ipa/xml", ipaserver);
#else
    ret = asprintf(&url, "http://%s:8888/", ipaserver);
#endif
    if (ret == -1)
    {
        if (!quiet)
            fprintf(stderr, _("Out of memory!\n"));
        rval = 3;
        goto cleanup;
    }

    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, argArrayP);
    xmlrpc_DECREF(paramP);

    optionsP = xmlrpc_build_value(&env, "{s:s,s:s}",
                                  "nsosversion", uinfo.release,
                                  "nshardwareplatform", uinfo.machine);
    xmlrpc_array_append_item(&env, paramArrayP, optionsP);
    xmlrpc_DECREF(optionsP);

    if ((user_agent = set_user_agent(ipaserver)) == NULL) {
        rval = 3;
        goto cleanup;
    }
    callRPC(user_agent, &env, serverInfoP, "join", paramArrayP, &resultP);
    if (handle_fault(&env)) {
        rval = 17;
        goto cleanup_xmlrpc;
    }

    /* Return value is the form of an array. The first value is the
     * DN, the second a struct of attribute values
     */
    xmlrpc_array_read_item(&env, resultP, 0, &hostdnP);
    xmlrpc_read_string(&env, hostdnP, (const char **)hostdn);
    xmlrpc_DECREF(hostdnP);
    xmlrpc_array_read_item(&env, resultP, 1, &structP);

    xmlrpc_struct_find_value(&env, structP, "krbprincipalname", &princP);
    if (princP) {
        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, princP, 0, &singleprincP);
        xmlrpc_read_string(&env, singleprincP, &*princ);
        xmlrpc_DECREF(princP);
        xmlrpc_DECREF(singleprincP);
    } else {
        if (!quiet)
            fprintf(stderr, _("principal not found in XML-RPC response\n"));
        rval = 12;
        goto cleanup;
    }
    xmlrpc_struct_find_value(&env, structP, "krblastpwdchange", &krblastpwdchangeP);
    if (krblastpwdchangeP && !force) {
        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, krblastpwdchangeP, 0, &singleprincP);
        xmlrpc_read_string(&env, singleprincP, &krblastpwdchange);
        xmlrpc_DECREF(krblastpwdchangeP);
        if (!quiet)
            fprintf(stderr, _("Host is already joined.\n"));
        rval = 13;
        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);

cleanup_xmlrpc:
    free(user_agent);
    free(url);
    free((char *)krblastpwdchange);
    xmlrpc_env_clean(&env);
    xmlrpc_client_cleanup();

    return rval;
}