示例#1
0
/*
 * Set up cred to be an S4U2Proxy credential by copying in the impersonator's
 * creds, setting a cache config variable with the impersonator principal name,
 * and saving the impersonator principal name in the cred structure.
 */
static krb5_error_code
make_proxy_cred(krb5_context context, krb5_gss_cred_id_t cred,
                krb5_gss_cred_id_t impersonator_cred)
{
    krb5_error_code code;
    krb5_data data;
    char *str;

    code = krb5_cc_copy_creds(context, impersonator_cred->ccache,
                              cred->ccache);
    if (code)
        return code;

    code = krb5_unparse_name(context, impersonator_cred->name->princ, &str);
    if (code)
        return code;

    data = string2data(str);
    code = krb5_cc_set_config(context, cred->ccache, NULL,
                              KRB5_CONF_PROXY_IMPERSONATOR, &data);
    krb5_free_unparsed_name(context, str);
    if (code)
        return code;

    return krb5_copy_principal(context, impersonator_cred->name->princ,
                               &cred->impersonator);
}
示例#2
0
static int mod_authn_gssapi_store_krb5_creds(server *srv, connection *con, plugin_data *p,
                                             krb5_context kcontext, krb5_ccache delegated_cred)
{
    krb5_error_code problem;
    krb5_principal princ = NULL;
    krb5_ccache ccache   = NULL;

    problem = krb5_cc_get_principal(kcontext, delegated_cred, &princ);
    if (problem) {
        mod_authn_gssapi_log_krb5_error(srv, __FILE__, __LINE__, "krb5_cc_get_principal", NULL, kcontext, problem);
        goto end;
    }

    if (mod_authn_gssapi_create_krb5_ccache(srv, con, p, kcontext, princ, &ccache)) {
        goto end;
    }

    problem = krb5_cc_copy_creds(kcontext, delegated_cred, ccache);
    if (problem) {
        mod_authn_gssapi_log_krb5_error(srv, __FILE__, __LINE__, "krb5_cc_copy_creds", NULL, kcontext, problem);
        goto end;
    }

    krb5_free_principal(kcontext, princ);
    krb5_cc_close(kcontext, ccache);
    return 0;

    end:
        if (princ)
            krb5_free_principal(kcontext, princ);
        if (ccache)
            krb5_cc_destroy(kcontext, ccache);
        return -1;
}
示例#3
0
文件: t_cc_config.c 项目: WeiY/krb5
/*
 * The default unset code path depends on the underlying ccache implementation
 * knowing how to remove a credential, which most types don't actually support,
 * so we have to jump through some hoops to ensure that when we set a value for
 * a key, it'll be the only value for that key that'll be found later.  The
 * ccache portions of libkrb5 will currently duplicate some of the actual
 * tickets.
 */
static void
unset_config(krb5_context context, krb5_ccache ccache,
             krb5_principal server, const char *key)
{
    krb5_ccache tmp1, tmp2;
    krb5_cc_cursor cursor;
    krb5_creds mcreds, creds;

    memset(&mcreds, 0, sizeof(mcreds));
    memset(&creds, 0, sizeof(creds));
    bail_on_err(context, "Error while deriving configuration principal names",
                k5_build_conf_principals(context, ccache, server, key,
                                         &mcreds));
    bail_on_err(context, "Error resolving first in-memory ccache",
                krb5_cc_resolve(context, "MEMORY:tmp1", &tmp1));
    bail_on_err(context, "Error initializing first in-memory ccache",
                krb5_cc_initialize(context, tmp1, mcreds.client));
    bail_on_err(context, "Error resolving second in-memory ccache",
                krb5_cc_resolve(context, "MEMORY:tmp2", &tmp2));
    bail_on_err(context, "Error initializing second in-memory ccache",
                krb5_cc_initialize(context, tmp2, mcreds.client));
    bail_on_err(context, "Error copying credentials to first in-memory ccache",
                krb5_cc_copy_creds(context, ccache, tmp1));
    bail_on_err(context, "Error starting traversal of first in-memory ccache",
                krb5_cc_start_seq_get(context, tmp1, &cursor));
    while (krb5_cc_next_cred(context, tmp1, &cursor, &creds) == 0) {
        if (!krb5_is_config_principal(context, creds.server) ||
            !krb5_principal_compare(context, mcreds.server, creds.server) ||
            !krb5_principal_compare(context, mcreds.client, creds.client)) {
            bail_on_err(context,
                        "Error storing non-config item to in-memory ccache",
                        krb5_cc_store_cred(context, tmp2, &creds));
        }
    }
    bail_on_err(context, "Error ending traversal of first in-memory ccache",
                krb5_cc_end_seq_get(context, tmp1, &cursor));
    bail_on_err(context, "Error clearing ccache",
                krb5_cc_initialize(context, ccache, mcreds.client));
    bail_on_err(context, "Error storing creds to the ccache",
                krb5_cc_copy_creds(context, tmp2, ccache));
    bail_on_err(context, "Error cleaning up first in-memory ccache",
                krb5_cc_destroy(context, tmp1));
    bail_on_err(context, "Error cleaning up second in-memory ccache",
                krb5_cc_destroy(context, tmp2));
}
std::unique_ptr<Krb5CCache> Krb5CredentialsCacheManager::readInCache() {
  auto mem = folly::make_unique<Krb5CCache>(
    Krb5CCache::makeNewUnique(ctx_.get(), "MEMORY"));
  // Get the default local cache
  Krb5CCache file_cache = Krb5CCache::makeDefault(ctx_.get());
  Krb5Principal client = file_cache.getClientPrincipal();

  // Copy the cache into memory
  krb5_error_code code = krb5_cc_initialize(
    ctx_.get(), mem->get(), client.get());
  raiseIf(code, "initializing memory ccache");
  code = krb5_cc_copy_creds(ctx_.get(), file_cache.get(), mem->get());
  raiseIf(code, "copying to memory cache");

  auto service_list = mem->getServicePrincipalList();
  for (auto& service : service_list)  {
    incUsedService(folly::to<string>(service));
  }

  return mem;
}
示例#5
0
static PyObject *
k5_cc_copy_creds(PyObject *self, PyObject *args)
{
    krb5_context ctx;
    char *namein, *nameout;
    krb5_error_code code;
    krb5_ccache ccin, ccout;
    krb5_principal principal;

    if (!PyArg_ParseTuple( args, "ss", &namein, &nameout))
	return NULL;

    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_cc_resolve(ctx, namein, &ccin);
    RETURN_ON_ERROR("krb5_cc_resolve()", code);
    code = krb5_cc_get_principal(ctx, ccin, &principal);
    RETURN_ON_ERROR("krb5_cc_get_principal()", code);

    code = krb5_cc_resolve(ctx, nameout, &ccout);
    RETURN_ON_ERROR("krb5_cc_resolve()", code);
    code = krb5_cc_initialize(ctx, ccout, principal);
    RETURN_ON_ERROR("krb5_cc_get_initialize()", code);
    code = krb5_cc_copy_creds(ctx, ccin, ccout);
    RETURN_ON_ERROR("krb5_cc_copy_creds()", code);

    code = krb5_cc_close(ctx, ccin);
    RETURN_ON_ERROR("krb5_cc_close()", code);
    code = krb5_cc_close(ctx, ccout);
    RETURN_ON_ERROR("krb5_cc_close()", code);
    krb5_free_principal(ctx, principal);
    krb5_free_context(ctx);

    Py_INCREF(Py_None);
    return Py_None;
}
示例#6
0
static OM_uint32
copy_initiator_creds(OM_uint32 *minor_status,
                     gss_cred_id_t input_cred_handle,
                     const gss_OID desired_mech,
                     OM_uint32 overwrite_cred,
                     OM_uint32 default_cred)
{
    OM_uint32 major_status;
    krb5_error_code code;
    krb5_gss_cred_id_t kcred = NULL;
    krb5_context context = NULL;
    krb5_ccache ccache = NULL;

    if (!default_cred) {
        *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    major_status = krb5_gss_validate_cred_1(minor_status,
                                            input_cred_handle,
                                            context);
    if (GSS_ERROR(major_status))
        goto cleanup;

    kcred = (krb5_gss_cred_id_t)input_cred_handle;

    if (kcred->ccache == NULL || kcred->proxy_cred) {
        *minor_status = KG_CCACHE_NOMATCH;
        major_status = GSS_S_DEFECTIVE_CREDENTIAL;
        goto cleanup;
    }

    if (!overwrite_cred &&
        has_unexpired_creds(kcred, desired_mech, default_cred)) {
        major_status = GSS_S_DUPLICATE_ELEMENT;
        goto cleanup;
    }

    code = krb5int_cc_default(context, &ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_cc_copy_creds(context, kcred->ccache, ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    *minor_status = 0;
    major_status = GSS_S_COMPLETE;

cleanup:
    if (kcred != NULL)
        k5_mutex_unlock(&kcred->lock);
    if (ccache != NULL)
        krb5_cc_close(context, ccache);
    krb5_free_context(context);

    return major_status;
}
示例#7
0
文件: ms2mit.c 项目: irakhlin/krb5
int
main(int argc, char *argv[])
{
    krb5_context kcontext = NULL;
    krb5_error_code code;
    krb5_ccache ccache=NULL;
    krb5_ccache mslsa_ccache=NULL;
    krb5_cc_cursor cursor;
    krb5_creds creds;
    krb5_principal princ = NULL;
    int found_tgt = 0;
    int has_tickets;
    int option;
    char * ccachestr = 0;

    prog = strrchr(argv[0], '/');
    prog = prog ? (prog + 1) : argv[0];

    while ((option = getopt(argc, argv, "c:h")) != -1) {
        switch (option) {
        case 'c':
            ccachestr = optarg;
            break;
        case 'h':
        default:
            xusage();
            break;
        }
    }

    if (code = krb5_init_context(&kcontext)) {
        com_err(argv[0], code, "while initializing kerberos library");
        goto cleanup;
    }

    if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) {
        com_err(argv[0], code, "while opening MS LSA ccache");
        goto cleanup;
    }

    /* Enumerate tickets from cache looking for a TGT */
    if ((code = krb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) {
        com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache");
        goto cleanup;
    }

    while (!found_tgt) {
        code = krb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds);
        if (code)
            break;

        /* Check if the ticket is a TGT */
        if (is_local_tgt(creds.server))
            found_tgt = 1;

        krb5_free_cred_contents(kcontext, &creds);
    }
    krb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor);

    if (!found_tgt) {
        fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MS LSA\n",
                argv[0]);
        /* Only set the LSA cache as the default if it actually has tickets. */
        code = cc_has_tickets(kcontext, mslsa_ccache, &has_tickets);
        if (code)
            goto cleanup;

        if (has_tickets)
            code = krb5int_cc_user_set_default_name(kcontext, "MSLSA:");

        goto cleanup;
    }

    if (code = krb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) {
        com_err(argv[0], code, "while obtaining MS LSA principal");
        goto cleanup;
    }

    if (ccachestr)
        code = krb5_cc_resolve(kcontext, ccachestr, &ccache);
    else
        code = krb5_cc_resolve(kcontext, "API:", &ccache);
    if (code) {
        com_err(argv[0], code, "while getting default ccache");
        goto cleanup;
    }
    if (code = krb5_cc_initialize(kcontext, ccache, princ)) {
        com_err (argv[0], code, "when initializing ccache");
        goto cleanup;
    }

    if (code = krb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) {
        com_err (argv[0], code, "while copying MS LSA ccache to default ccache");
        goto cleanup;
    }

    /* Don't try and set the default cache if the cache name was specified. */
    if (ccachestr == NULL) {
        /* On success set the default cache to API. */
        code = krb5int_cc_user_set_default_name(kcontext, "API:");
        if (code) {
            com_err(argv[0], code, "when setting default to API");
            goto cleanup;
        }
    }

cleanup:
    krb5_free_principal(kcontext, princ);
    if (ccache != NULL)
        krb5_cc_close(kcontext, ccache);
    if (mslsa_ccache != NULL)
        krb5_cc_close(kcontext, mslsa_ccache);
    krb5_free_context(kcontext);
    return code ? 1 : 0;
}
示例#8
0
static OM_uint32
copy_initiator_creds(OM_uint32 *minor_status,
                     gss_cred_id_t input_cred_handle,
                     const gss_OID desired_mech,
                     OM_uint32 overwrite_cred,
                     OM_uint32 default_cred,
                     gss_const_key_value_set_t cred_store)
{
    OM_uint32 major_status;
    krb5_error_code code;
    krb5_gss_cred_id_t kcred = NULL;
    krb5_context context = NULL;
    krb5_ccache ccache = NULL;
    const char *ccache_name;

    *minor_status = 0;

    if (!default_cred && cred_store == GSS_C_NO_CRED_STORE) {
        *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    code = krb5_gss_init_context(&context);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    major_status = krb5_gss_validate_cred_1(minor_status,
                                            input_cred_handle,
                                            context);
    if (GSS_ERROR(major_status))
        goto cleanup;

    kcred = (krb5_gss_cred_id_t)input_cred_handle;

    if (kcred->ccache == NULL) {
        *minor_status = KG_CCACHE_NOMATCH;
        major_status = GSS_S_DEFECTIVE_CREDENTIAL;
        goto cleanup;
    }

    if (!overwrite_cred &&
        has_unexpired_creds(kcred, desired_mech, default_cred, cred_store)) {
        major_status = GSS_S_DUPLICATE_ELEMENT;
        goto cleanup;
    }

    major_status = kg_value_from_cred_store(cred_store,
                                            KRB5_CS_CCACHE_URN, &ccache_name);
    if (GSS_ERROR(major_status))
        goto cleanup;

    if (ccache_name != NULL) {
        code = krb5_cc_resolve(context, ccache_name, &ccache);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_CRED_UNAVAIL;
            goto cleanup;
        }
        code = krb5_cc_initialize(context, ccache,
                                  kcred->name->princ);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_CRED_UNAVAIL;
            goto cleanup;
        }
    }

    if (ccache == NULL) {
        if (!default_cred) {
            *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
            major_status = GSS_S_FAILURE;
            goto cleanup;
        }
        code = krb5int_cc_default(context, &ccache);
        if (code != 0) {
            *minor_status = code;
            major_status = GSS_S_FAILURE;
            goto cleanup;
        }
    }

    code = krb5_cc_copy_creds(context, kcred->ccache, ccache);
    if (code != 0) {
        *minor_status = code;
        major_status = GSS_S_FAILURE;
        goto cleanup;
    }

    *minor_status = 0;
    major_status = GSS_S_COMPLETE;

cleanup:
    if (kcred != NULL)
        k5_mutex_unlock(&kcred->lock);
    if (ccache != NULL)
        krb5_cc_close(context, ccache);
    krb5_free_context(context);

    return major_status;
}
示例#9
0
文件: t_cc.c 项目: Baalmart/krb5
static void
cc_test(krb5_context context, const char *name, krb5_flags flags)
{
    krb5_ccache id, id2;
    krb5_creds creds;
    krb5_error_code kret;
    krb5_cc_cursor cursor;
    krb5_principal tmp;

    const char *c_name;
    char newcache[300];
    char *save_type;

    kret = init_test_cred(context);
    CHECK(kret, "init_creds");

    kret = krb5_cc_resolve(context, name, &id);
    CHECK(kret, "resolve");
    kret = krb5_cc_initialize(context, id, test_creds.client);
    CHECK(kret, "initialize");

    c_name = krb5_cc_get_name(context, id);
    CHECK_STR(c_name, "get_name");

    c_name = krb5_cc_get_type(context, id);
    CHECK_STR(c_name, "get_type");
    save_type=strdup(c_name);
    CHECK_STR(save_type, "copying type");

    kret = krb5_cc_store_cred(context, id, &test_creds);
    CHECK(kret, "store");

    kret = krb5_cc_get_principal(context, id, &tmp);
    CHECK(kret, "get_principal");

    CHECK_BOOL(krb5_realm_compare(context, tmp, test_creds.client) != TRUE,
               "realms do not match", "realm_compare");


    CHECK_BOOL(krb5_principal_compare(context, tmp, test_creds.client) != TRUE,
               "principals do not match", "principal_compare");

    krb5_free_principal(context, tmp);

    kret = krb5_cc_set_flags (context, id, flags);
    CHECK(kret, "set_flags");

    kret = krb5_cc_start_seq_get(context, id, &cursor);
    CHECK(kret, "start_seq_get");
    kret = 0;
    while (kret != KRB5_CC_END) {
        if(debug) printf("Calling next_cred\n");
        kret = krb5_cc_next_cred(context, id, &cursor, &creds);
        if(kret == KRB5_CC_END) {
            if(debug) printf("next_cred: ok at end\n");
        }
        else {
            CHECK(kret, "next_cred");
            krb5_free_cred_contents(context, &creds);
        }

    }
    kret = krb5_cc_end_seq_get(context, id, &cursor);
    CHECK(kret, "end_seq_get");

    kret = krb5_cc_close(context, id);
    CHECK(kret, "close");


    /* ------------------------------------------------- */
    kret = krb5_cc_resolve(context, name, &id);
    CHECK(kret, "resolve2");

    {
        /* Copy the cache test*/
        snprintf(newcache, sizeof(newcache), "%s.new", name);
        kret = krb5_cc_resolve(context, newcache, &id2);
        CHECK(kret, "resolve of new cache");

        /* This should fail as the new creds are not initialized */
        kret = krb5_cc_copy_creds(context, id, id2);
        CHECK_FAIL(KRB5_FCC_NOFILE, kret, "copy_creds");

        kret = krb5_cc_initialize(context, id2, test_creds.client);
        CHECK(kret, "initialize of id2");

        kret = krb5_cc_copy_creds(context, id, id2);
        CHECK(kret, "copy_creds");

        kret = krb5_cc_destroy(context, id2);
        CHECK(kret, "destroy new cache");
    }

    /* Destroy the first cache */
    kret = krb5_cc_destroy(context, id);
    CHECK(kret, "destroy");

    /* ----------------------------------------------------- */
    /* Tests the generate new code */
    kret = krb5_cc_new_unique(context, save_type,
                              NULL, &id2);
    CHECK(kret, "new_unique");

    kret = krb5_cc_initialize(context, id2, test_creds.client);
    CHECK(kret, "initialize");

    kret = krb5_cc_store_cred(context, id2, &test_creds);
    CHECK(kret, "store");

    kret = krb5_cc_destroy(context, id2);
    CHECK(kret, "destroy id2");

    free(save_type);
    free_test_cred(context);

}
示例#10
0
void
main(
    int argc,
    char *argv[]
    )
{
    krb5_context kcontext;
    krb5_error_code code;
    krb5_ccache ccache=NULL;
    krb5_ccache mslsa_ccache=NULL;
    krb5_cc_cursor cursor;
    krb5_creds creds;
    krb5_principal princ;
    int initial_ticket = 0;
    int option;
    char * ccachestr = 0;

    prog = strrchr(argv[0], '/');
    prog = prog ? (prog + 1) : argv[0];

    while ((option = getopt(argc, argv, "c:h")) != -1) {
        switch (option) {
        case 'c':
            ccachestr = optarg;
            break;
        case 'h':
        default:
            xusage();
            break;
        }
    }
        
    if (code = krb5_init_context(&kcontext)) {
        com_err(argv[0], code, "while initializing kerberos library");
        exit(1);
    }
  
    if (code = krb5_cc_resolve(kcontext, "MSLSA:", &mslsa_ccache)) {
        com_err(argv[0], code, "while opening MS LSA ccache");
        krb5_free_context(kcontext);
        exit(1);
    }

    if (code = krb5_cc_set_flags(kcontext, mslsa_ccache, KRB5_TC_NOTICKET)) {
        com_err(argv[0], code, "while setting KRB5_TC_NOTICKET flag");
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    /* Enumerate tickets from cache looking for an initial ticket */
    if ((code = krb5_cc_start_seq_get(kcontext, mslsa_ccache, &cursor))) {
        com_err(argv[0], code, "while initiating the cred sequence of MS LSA ccache");
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    while (!(code = krb5_cc_next_cred(kcontext, mslsa_ccache, &cursor, &creds))) 
    {
        if ( creds.ticket_flags & TKT_FLG_INITIAL ) {
            krb5_free_cred_contents(kcontext, &creds);
            initial_ticket = 1;
            break;
        }
        krb5_free_cred_contents(kcontext, &creds);
    }
    krb5_cc_end_seq_get(kcontext, mslsa_ccache, &cursor);

    if (code = krb5_cc_set_flags(kcontext, mslsa_ccache, 0)) {
        com_err(argv[0], code, "while clearing flags");
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    if ( !initial_ticket ) {
        fprintf(stderr, "%s: Initial Ticket Getting Tickets are not available from the MS LSA\n",
                argv[0]);
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    if (code = krb5_cc_get_principal(kcontext, mslsa_ccache, &princ)) {
        com_err(argv[0], code, "while obtaining MS LSA principal");
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    if (ccachestr)
        code = krb5_cc_resolve(kcontext, ccachestr, &ccache);
    else
        code = krb5_cc_default(kcontext, &ccache);
    if (code) {
        com_err(argv[0], code, "while getting default ccache");
        krb5_free_principal(kcontext, princ);
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }
    if (code = krb5_cc_initialize(kcontext, ccache, princ)) {
        com_err (argv[0], code, "when initializing ccache");
        krb5_free_principal(kcontext, princ);
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_cc_close(kcontext, ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    if (code = krb5_cc_copy_creds(kcontext, mslsa_ccache, ccache)) {
        com_err (argv[0], code, "while copying MS LSA ccache to default ccache");
        krb5_free_principal(kcontext, princ);
        krb5_cc_close(kcontext, ccache);
        krb5_cc_close(kcontext, mslsa_ccache);
        krb5_free_context(kcontext);
        exit(1);
    }

    krb5_free_principal(kcontext, princ);
    krb5_cc_close(kcontext, ccache);
    krb5_cc_close(kcontext, mslsa_ccache);
    krb5_free_context(kcontext);
    return(0);
}