Esempio n. 1
0
/*
 * Request:
 *	NameZ
 *	Creds
 *	
 * Response:
 *	
 */
static krb5_error_code
kcm_op_store(krb5_context context,
	     kcm_client *client,
	     kcm_operation opcode,
	     krb5_storage *request,
	     krb5_storage *response)
{
    krb5_creds creds;
    krb5_error_code ret;
    kcm_ccache ccache;
    char *name;

    ret = krb5_ret_stringz(request, &name);
    if (ret)
	return ret;

    KCM_LOG_REQUEST_NAME(context, client, opcode, name);

    ret = krb5_ret_creds(request, &creds);
    if (ret) {
	free(name);
	return ret;
    }

    ret = kcm_ccache_resolve_client(context, client, opcode,
				    name, &ccache);
    if (ret) {
	free(name);
	krb5_free_cred_contents(context, &creds);
	return ret;
    }

    ret = kcm_ccache_store_cred(context, ccache, &creds, 0);
    if (ret) {
	free(name);
	krb5_free_cred_contents(context, &creds);
	kcm_release_ccache(context, ccache);
	return ret;
    }

    kcm_ccache_enqueue_default(context, ccache, &creds);

    free(name);
    kcm_release_ccache(context, ccache);

    return 0;
}
Esempio n. 2
0
void KRB5_CALLCONV
krb5_free_creds(krb5_context context, krb5_creds *val)
{
    if (val == NULL)
        return;
    krb5_free_cred_contents(context, val);
    free(val);
}
Esempio n. 3
0
/* Convert a JSON value to a ccache handle or to NULL.  Set *new_out to true if
 * the ccache handle is a newly created memory ccache, false otherwise. */
static int
json_to_ccache(krb5_context context, k5_json_value v, krb5_ccache *ccache_out,
               krb5_boolean *new_out)
{
    krb5_error_code ret;
    krb5_ccache ccache = NULL;
    krb5_principal princ;
    krb5_creds creds;
    k5_json_array array;
    size_t i, len;

    *ccache_out = NULL;
    *new_out = FALSE;
    if (k5_json_get_tid(v) == K5_JSON_TID_NULL)
        return 0;
    if (k5_json_get_tid(v) == K5_JSON_TID_STRING) {
        /* We got a reference to an external ccache; just resolve it. */
        return krb5_cc_resolve(context, k5_json_string_utf8(v), ccache_out) ?
            -1 : 0;
    }

    /* We got the contents of a memory ccache. */
    if (k5_json_get_tid(v) != K5_JSON_TID_ARRAY)
        return -1;
    array = v;
    len = k5_json_array_length(array);
    if (len < 1)
        return -1;

    /* Initialize a new memory ccache using the principal in the first array
     * entry.*/
    if (krb5_cc_new_unique(context, "MEMORY", NULL, &ccache))
        return -1;
    if (json_to_principal(context, k5_json_array_get(array, 0), &princ))
        goto invalid;
    ret = krb5_cc_initialize(context, ccache, princ);
    krb5_free_principal(context, princ);
    if (ret)
        goto invalid;

    /* Add remaining array entries to the ccache as credentials. */
    for (i = 1; i < len; i++) {
        if (json_to_creds(context, k5_json_array_get(array, 1), &creds))
            goto invalid;
        ret = krb5_cc_store_cred(context, ccache, &creds);
        krb5_free_cred_contents(context, &creds);
        if (ret)
            goto invalid;
    }

    *ccache_out = ccache;
    *new_out = TRUE;
    return 0;

invalid:
    (void)krb5_cc_destroy(context, ccache);
    return -1;
}
Esempio n. 4
0
uint32_t gpp_store_remote_creds(uint32_t *min, gssx_cred *creds)
{
    krb5_context ctx = NULL;
    krb5_ccache ccache = NULL;
    krb5_creds cred;
    krb5_error_code ret;
    XDR xdrctx;
    bool xdrok;

    *min = 0;

    if (creds == NULL) return GSS_S_CALL_INACCESSIBLE_READ;

    memset(&cred, 0, sizeof(cred));

    ret = krb5_init_context(&ctx);
    if (ret) return ret;

    ret = krb5_cc_default(ctx, &ccache);
    if (ret) goto done;

    ret = krb5_parse_name(ctx,
                          creds->desired_name.display_name.octet_string_val,
                          &cred.client);
    if (ret) goto done;

    ret = krb5_parse_name(ctx, GPKRB_SRV_NAME, &cred.server);
    if (ret) goto done;

    cred.ticket.data = malloc(GPKRB_MAX_CRED_SIZE);
    xdrmem_create(&xdrctx, cred.ticket.data, GPKRB_MAX_CRED_SIZE, XDR_ENCODE);
    xdrok = xdr_gssx_cred(&xdrctx, creds);
    if (!xdrok) {
        ret = ENOSPC;
        goto done;
    }
    cred.ticket.length = xdr_getpos(&xdrctx);

    ret = krb5_cc_store_cred(ctx, ccache, &cred);

    if (ret == KRB5_FCC_NOFILE) {
        /* If a ccache does not exit, try to create one */
        ret = krb5_cc_initialize(ctx, ccache, cred.client);
        if (ret) goto done;

        /* and try again to store the cred */
        ret = krb5_cc_store_cred(ctx, ccache, &cred);
    }

done:
    if (ctx) {
        krb5_free_cred_contents(ctx, &cred);
        if (ccache) krb5_cc_close(ctx, ccache);
        krb5_free_context(ctx);
    }
    *min = ret;
    return ret ? GSS_S_FAILURE : GSS_S_COMPLETE;
}
Esempio n. 5
0
static krb5_error_code
fast_armor_ap_request(krb5_context context,
                      struct krb5int_fast_request_state *state,
                      krb5_ccache ccache, krb5_principal target_principal)
{
    krb5_error_code retval = 0;
    krb5_creds creds, *out_creds = NULL;
    krb5_auth_context authcontext = NULL;
    krb5_data encoded_authenticator;
    krb5_fast_armor *armor = NULL;
    krb5_keyblock *subkey = NULL, *armor_key = NULL;

    encoded_authenticator.data = NULL;
    memset(&creds, 0, sizeof(creds));
    creds.server = target_principal;
    retval = krb5_cc_get_principal(context, ccache, &creds.client);
    if (retval == 0)
        retval = krb5_get_credentials(context, 0, ccache,  &creds, &out_creds);
    if (retval == 0) {
        TRACE_FAST_ARMOR_CCACHE_KEY(context, &out_creds->keyblock);
        retval = krb5_mk_req_extended(context, &authcontext,
                                      AP_OPTS_USE_SUBKEY, NULL /*data*/,
                                      out_creds, &encoded_authenticator);
    }
    if (retval == 0)
        retval = krb5_auth_con_getsendsubkey(context, authcontext, &subkey);
    if (retval == 0)
        retval = krb5_c_fx_cf2_simple(context, subkey, "subkeyarmor",
                                      &out_creds->keyblock, "ticketarmor",
                                      &armor_key);
    if (retval == 0) {
        TRACE_FAST_ARMOR_KEY(context, armor_key);
        armor = calloc(1, sizeof(krb5_fast_armor));
        if (armor == NULL)
            retval = ENOMEM;
    }
    if (retval == 0) {
        armor->armor_type = KRB5_FAST_ARMOR_AP_REQUEST;
        armor->armor_value = encoded_authenticator;
        encoded_authenticator.data = NULL;
        encoded_authenticator.length = 0;
        state->armor = armor;
        armor = NULL;
        state->armor_key = armor_key;
        armor_key = NULL;
    }
    krb5_free_keyblock(context, armor_key);
    krb5_free_keyblock(context, subkey);
    if (out_creds)
        krb5_free_creds(context, out_creds);
    /* target_principal is owned by caller. */
    creds.server = NULL;
    krb5_free_cred_contents(context, &creds);
    if (encoded_authenticator.data)
        krb5_free_data_contents(context, &encoded_authenticator);
    krb5_auth_con_free(context, authcontext);
    return retval;
}
Esempio n. 6
0
/*
 * next_closest_tgt()
 *
 * Using CUR_TGT, attempt to get the cross-realm TGT having its remote
 * realm closest to the target principal's.  Update NXT_TGT, NXT_KDC
 * accordingly.
 */
static krb5_error_code
next_closest_tgt(struct tr_state *ts, krb5_principal client)
{
    krb5_error_code retval;
    krb5_creds tgtq;

    retval = 0;
    memset(&tgtq, 0, sizeof(tgtq));

    for (ts->nxt_kdc = ts->lst_kdc;
	 ts->nxt_kdc > ts->cur_kdc;
	 ts->nxt_kdc--) {

	krb5_free_cred_contents(ts->ctx, &tgtq);
	retval = kdc_mcred(ts, client, &tgtq);
	if (retval)
	    goto cleanup;
	/* Don't waste time retrying ccache for direct path. */
	if (ts->cur_kdc != ts->kdc_list || ts->nxt_kdc != ts->lst_kdc) {
	    retval = try_ccache(ts, &tgtq);
	    if (!retval)
		break;
	    if (HARD_CC_ERR(retval))
		goto cleanup;
	}
	/* Not in the ccache, so talk to a KDC. */
	retval = try_kdc(ts, &tgtq);
	if (!retval) {
	    break;
	}
	/*
	 * Because try_kdc() validates referral TGTs, it can return an
	 * error indicating a bogus referral.  The loop continues when
	 * it gets a bogus referral, which is arguably the right
	 * thing.  (Previous implementation unconditionally failed.)
	 */
    }
    /*
     * If we have a non-zero retval, we either have a hard error or we
     * failed to find a closer TGT.
     */
cleanup:
    krb5_free_cred_contents(ts->ctx, &tgtq);
    return retval;
}
Esempio n. 7
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_creds_tag(krb5_storage *sp,
		   krb5_creds *creds)
{
    krb5_error_code ret;
    int8_t dummy8;
    int32_t dummy32, header;

    memset(creds, 0, sizeof(*creds));

    ret = krb5_ret_int32 (sp, &header);
    if (ret) goto cleanup;

    if (header & SC_CLIENT_PRINCIPAL) {
	ret = krb5_ret_principal (sp,  &creds->client);
	if(ret) goto cleanup;
    }
    if (header & SC_SERVER_PRINCIPAL) {
	ret = krb5_ret_principal (sp,  &creds->server);
	if(ret) goto cleanup;
    }
    if (header & SC_SESSION_KEY) {
	ret = krb5_ret_keyblock (sp,  &creds->session);
	if(ret) goto cleanup;
    }
    ret = krb5_ret_times (sp,  &creds->times);
    if(ret) goto cleanup;
    ret = krb5_ret_int8 (sp,  &dummy8);
    if(ret) goto cleanup;
    ret = krb5_ret_int32 (sp,  &dummy32);
    if(ret) goto cleanup;
    creds->flags.b = int2TicketFlags(bitswap32(dummy32));
    if (header & SC_ADDRESSES) {
	ret = krb5_ret_addrs (sp,  &creds->addresses);
	if(ret) goto cleanup;
    }
    if (header & SC_AUTHDATA) {
	ret = krb5_ret_authdata (sp,  &creds->authdata);
	if(ret) goto cleanup;
    }
    if (header & SC_TICKET) {
	ret = krb5_ret_data (sp,  &creds->ticket);
	if(ret) goto cleanup;
    }
    if (header & SC_SECOND_TICKET) {
	ret = krb5_ret_data (sp,  &creds->second_ticket);
	if(ret) goto cleanup;
    }

cleanup:
    if(ret) {
#if 0
	krb5_free_cred_contents(context, creds); /* XXX */
#endif
    }
    return ret;
}
Esempio n. 8
0
/*
 * remove
 *
 * - remove the specified credentials from the NC
 */
krb5_error_code KRB5_CALLCONV 
krb5_stdccv3_remove (krb5_context context, 
                     krb5_ccache id,
                     krb5_flags flags, 
                     krb5_creds *in_creds)
{
    krb5_error_code err = 0;
    stdccCacheDataPtr ccapi_data = id->data;
    cc_credentials_iterator_t iterator = NULL;
    int found = 0;
    
    if (!err) {
        err = stdccv3_setup(context, ccapi_data);
    }
    
    
    if (!err) {
        err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache,
                                                 &iterator);
    }

    /* Note: CCAPI v3 ccaches can contain both v4 and v5 creds */
    while (!err && !found) {
        cc_credentials_t credentials = NULL;
        
        err = cc_credentials_iterator_next (iterator, &credentials);
        
        if (!err && (credentials->data->version == cc_credentials_v5)) {
            krb5_creds creds;
            
            err = copy_cc_cred_union_to_krb5_creds(context, 
                                                   credentials->data, &creds);

            if (!err) {
                found = krb5_creds_compare (context, in_creds, &creds);
                krb5_free_cred_contents (context, &creds);
            }
            
            if (!err && found) {
                err = cc_ccache_remove_credentials (ccapi_data->NamedCache, credentials);
            }
        }
        
        if (credentials) { cc_credentials_release (credentials); }
    }
    if (err == ccIteratorEnd) { err = ccErrCredentialsNotFound; }    

    if (iterator) {
        err = cc_credentials_iterator_release(iterator);
    }

    if (!err) {
        cache_changed ();
    }
    
    return cc_err_xlate (err);
}
Esempio n. 9
0
static isc_result_t
check_credentials(krb5_context context, krb5_ccache ccache, krb5_principal service)
{
    char *realm = NULL;
    krb5_creds creds;
    krb5_creds mcreds;
    krb5_error_code krberr;
    krb5_timestamp now;
    isc_result_t result = ISC_R_FAILURE;

    memset(&mcreds, 0, sizeof(mcreds));
    memset(&creds, 0, sizeof(creds));

    krberr = krb5_get_default_realm(context, &realm);
    CHECK_KRB5(context, krberr, "Failed to retrieve default realm");

    krberr = krb5_build_principal(context, &mcreds.server,
                    strlen(realm), realm,
                    "krbtgt", realm, NULL);
    CHECK_KRB5(context, krberr, "Failed to build 'krbtgt/REALM' principal");

    mcreds.client = service;

    krberr = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &creds);

    if (krberr) {
        const char * errmsg = krb5_get_error_message(context, krberr);
        log_error("Credentials are not present in cache (%s)\n", errmsg);
        krb5_free_error_message(context, errmsg);
        result = ISC_R_FAILURE;
        goto cleanup;
    }
    CHECK_KRB5(context, krberr, "Credentials are not present in cache ");
   
    krberr = krb5_timeofday(context, &now);
    CHECK_KRB5(context, krberr, "Failed to get time of day");


    if (now > (creds.times.endtime + KRB_MIN_TIME)) {
        log_error("Credentials cache expired");
        result = ISC_R_FAILURE;
        goto cleanup;
    } else { 
        char buf[255];
        char fill = ' ';
        krb5_timestamp_to_sfstring(creds.times.endtime, buf, 16, &fill);
        log_info("Credentials valid til %s\n", buf);
    }

    result = ISC_R_SUCCESS;

cleanup:
    krb5_free_cred_contents(context, &creds);
    if (mcreds.server) krb5_free_principal(context, mcreds.server);
    if (realm) krb5_free_default_realm(context, realm);
    return result;
}
Esempio n. 10
0
static void
get_creds(krb5_context context, const char *keytab_str,
	  krb5_ccache *cache, const char *serverhost)
{
    krb5_keytab keytab;
    krb5_principal client;
    krb5_error_code ret;
    krb5_get_init_creds_opt *init_opts;
    krb5_creds creds;
    char *server;
    char keytab_buf[256];
    int aret;

    if (keytab_str == NULL) {
	ret = krb5_kt_default_name (context, keytab_buf, sizeof(keytab_buf));
	if (ret)
	    krb5_err (context, 1, ret, "krb5_kt_default_name");
	keytab_str = keytab_buf;
    }

    ret = krb5_kt_resolve(context, keytab_str, &keytab);
    if(ret)
	krb5_err(context, 1, ret, "%s", keytab_str);


    ret = krb5_sname_to_principal (context, slave_str, IPROP_NAME,
				   KRB5_NT_SRV_HST, &client);
    if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal");

    ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
    if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");

    aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
    if (aret == -1 || server == NULL)
	krb5_errx (context, 1, "malloc: no memory");

    ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
				     0, server, init_opts);
    free (server);
    krb5_get_init_creds_opt_free(context, init_opts);
    if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");

    ret = krb5_kt_close(context, keytab);
    if(ret) krb5_err(context, 1, ret, "krb5_kt_close");

    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, cache);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_cc_initialize(context, *cache, client);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_store_cred(context, *cache, &creds);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, client);
}
Esempio n. 11
0
/*
 * Obtain renewed credentials for the given service using the existing
 * credentials in the provided ticket cache.
 */
krb5_error_code
krb5_get_renewed_creds(krb5_context ctx, krb5_creds *creds,
                       krb5_const_principal client, krb5_ccache ccache,
                       const char *in_tkt_service)
{
    krb5_kdc_flags flags;
    krb5_creds in, *old = NULL, *out = NULL;
    krb5_error_code code;

    flags.i = 0;
    flags.b.renewable = 1;
    flags.b.renew = 1;
    memset(&in, 0, sizeof(in));
    code = krb5_copy_principal(ctx, client, &in.client);
    if (code != 0)
        goto done;
    if (in_tkt_service == NULL) {
        const char *realm;

        realm = krb5_principal_get_realm(ctx, client);
        if (realm == NULL) {
            code = KRB5_CONFIG_NODEFREALM;
            goto done;
        }
        code = krb5_build_principal(ctx, &in.server, strlen(realm), realm,
                                    "krbtgt", realm, (const char *) NULL);
        if (code != 0)
            goto done;
    } else {
        code = krb5_parse_name(ctx, in_tkt_service, &in.server);
        if (code != 0)
            goto done;
    }
    code = krb5_get_credentials(ctx, 0, ccache, &in, &old);
    if (code != 0)
        goto done;
    flags.b.forwardable = old->flags.b.forwardable;
    flags.b.proxiable = old->flags.b.proxiable;
    code = krb5_get_kdc_cred(ctx, ccache, flags, NULL, NULL, old, &out);
    if (code != 0)
        goto done;
#ifdef HAVE_KRB5_COPY_CREDS_CONTENTS
    code = krb5_copy_creds_contents(ctx, out, creds);
    krb5_free_creds(ctx, out);
#else
    /* No good alternative -- hope this works. */
    *creds = *out;
    free(out);
#endif

done:
    krb5_free_cred_contents(ctx, &in);
    if (old != NULL)
        krb5_free_creds(ctx, old);
    return code;
}
Esempio n. 12
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_mk_req_exact(krb5_context context,
		  krb5_auth_context *auth_context,
		  const krb5_flags ap_req_options,
		  const krb5_principal server,
		  krb5_data *in_data,
		  krb5_ccache ccache,
		  krb5_data *outbuf)
{
    krb5_error_code ret;
    krb5_creds this_cred, *cred;

    memset(&this_cred, 0, sizeof(this_cred));

    ret = krb5_cc_get_principal(context, ccache, &this_cred.client);

    if(ret)
	return ret;

    ret = krb5_copy_principal (context, server, &this_cred.server);
    if (ret) {
	krb5_free_cred_contents (context, &this_cred);
	return ret;
    }

    this_cred.times.endtime = 0;
    if (auth_context && *auth_context && (*auth_context)->keytype)
	this_cred.session.keytype = (*auth_context)->keytype;

    ret = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
    krb5_free_cred_contents(context, &this_cred);
    if (ret)
	return ret;

    ret = krb5_mk_req_extended (context,
				auth_context,
				ap_req_options,
				in_data,
				cred,
				outbuf);
    krb5_free_creds(context, cred);
    return ret;
}
Esempio n. 13
0
/*
 * next_closest_tgt()
 *
 * Using CUR_TGT, attempt to get the cross-realm TGT having its remote
 * realm closest to the target principal's.  Update NXT_TGT, NXT_KDC
 * accordingly.
 */
static krb5_error_code
next_closest_tgt(struct tr_state *ts, krb5_principal client)
{
    krb5_error_code retval;
    krb5_creds tgtq;

    retval = 0;
    memset(&tgtq, 0, sizeof(tgtq));

    for (ts->nxt_kdc = ts->lst_kdc;
	 ts->nxt_kdc > ts->cur_kdc;
	 ts->nxt_kdc--) {

	krb5_free_cred_contents(ts->ctx, &tgtq);
	retval = kdc_mcred(ts, client, &tgtq);
	if (retval)
	    goto cleanup;
	/* Don't waste time retrying ccache for direct path. */
	if (ts->cur_kdc != ts->kdc_list || ts->nxt_kdc != ts->lst_kdc) {
	    retval = try_ccache(ts, &tgtq);
	    if (!retval)
		break;
	    if (HARD_CC_ERR(retval))
		goto cleanup;
	}
	/* Not in the ccache, so talk to a KDC. */
	retval = try_kdc(ts, &tgtq);
	if (!retval) {
	    break;
	}
	/*
	 * In case of errors in try_kdc() or find_nxt_kdc(), continue
	 * looping through the KDC list.
	 */
    }
    /*
     * If we have a non-zero retval, we either have a hard error or we
     * failed to find a closer TGT.
     */
cleanup:
    krb5_free_cred_contents(ts->ctx, &tgtq);
    return retval;
}
Esempio n. 14
0
File: klist.c Progetto: INNOAUS/krb5
/* Display the contents of cache. */
static int
show_ccache(krb5_ccache cache)
{
    krb5_cc_cursor cur;
    krb5_creds creds;
    krb5_principal princ;
    krb5_error_code ret;

    ret = krb5_cc_get_principal(context, cache, &princ);
    if (ret) {
        com_err(progname, ret, "");
        return 1;
    }
    ret = krb5_unparse_name(context, princ, &defname);
    if (ret) {
        com_err(progname, ret, _("while unparsing principal name"));
        return 1;
    }

    printf(_("Ticket cache: %s:%s\nDefault principal: %s\n\n"),
           krb5_cc_get_type(context, cache), krb5_cc_get_name(context, cache),
           defname);
    /* XXX Translating would disturb table alignment; skip for now. */
    fputs("Valid starting", stdout);
    fillit(stdout, timestamp_width - sizeof("Valid starting") + 3, (int) ' ');
    fputs("Expires", stdout);
    fillit(stdout, timestamp_width - sizeof("Expires") + 3, (int) ' ');
    fputs("Service principal\n", stdout);

    ret = krb5_cc_start_seq_get(context, cache, &cur);
    if (ret) {
        com_err(progname, ret, _("while starting to retrieve tickets"));
        return 1;
    }
    while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) {
        if (show_config || !krb5_is_config_principal(context, creds.server))
            show_credential(&creds);
        krb5_free_cred_contents(context, &creds);
    }
    krb5_free_principal(context, princ);
    krb5_free_unparsed_name(context, defname);
    defname = NULL;
    if (ret == KRB5_CC_END) {
        ret = krb5_cc_end_seq_get(context, cache, &cur);
        if (ret) {
            com_err(progname, ret, _("while finishing ticket retrieval"));
            return 1;
        }
        return 0;
    } else {
        com_err(progname, ret, _("while retrieving a ticket"));
        return 1;
    }
}
Esempio n. 15
0
/*
  simulate a kinit, putting the tgt in the given credentials cache.
  Orignally by [email protected]
*/
int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
                               krb5_principal principal, const char *password,
                               time_t *expire_time, time_t *kdc_time)
{
    krb5_error_code code = 0;
    krb5_creds my_creds;
    krb5_get_init_creds_opt options;

    krb5_get_init_creds_opt_init(&options);

    krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);

    if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
                NULL,
                NULL, 0, NULL, &options))) {
        return code;
    }

    if ((code = krb5_cc_initialize(ctx, cc, principal))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if (expire_time) {
        *expire_time = (time_t) my_creds.times.endtime;
    }

    if (kdc_time) {
        *kdc_time = (time_t) my_creds.times.starttime;
    }

    krb5_free_cred_contents(ctx, &my_creds);

    return 0;
}
Esempio n. 16
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
{
    krb5_error_code ret;
    int8_t dummy8;
    int32_t dummy32;

    memset(creds, 0, sizeof(*creds));
    ret = krb5_ret_principal (sp,  &creds->client);
    if(ret) goto cleanup;
    ret = krb5_ret_principal (sp,  &creds->server);
    if(ret) goto cleanup;
    ret = krb5_ret_keyblock (sp,  &creds->session);
    if(ret) goto cleanup;
    ret = krb5_ret_times (sp,  &creds->times);
    if(ret) goto cleanup;
    ret = krb5_ret_int8 (sp,  &dummy8);
    if(ret) goto cleanup;
    ret = krb5_ret_int32 (sp,  &dummy32);
    if(ret) goto cleanup;
    /*
     * Runtime detect the what is the higher bits of the bitfield. If
     * any of the higher bits are set in the input data, it's either a
     * new ticket flag (and this code need to be removed), or it's a
     * MIT cache (or new Heimdal cache), lets change it to our current
     * format.
     */
    {
	uint32_t mask = 0xffff0000;
	creds->flags.i = 0;
	creds->flags.b.anonymous = 1;
	if (creds->flags.i & mask)
	    mask = ~mask;
	if (dummy32 & mask)
	    dummy32 = bitswap32(dummy32);
    }
    creds->flags.i = dummy32;
    ret = krb5_ret_addrs (sp,  &creds->addresses);
    if(ret) goto cleanup;
    ret = krb5_ret_authdata (sp,  &creds->authdata);
    if(ret) goto cleanup;
    ret = krb5_ret_data (sp,  &creds->ticket);
    if(ret) goto cleanup;
    ret = krb5_ret_data (sp,  &creds->second_ticket);
cleanup:
    if(ret) {
#if 0
	krb5_free_cred_contents(context, creds); /* XXX */
#endif
    }
    return ret;
}
 bool next_any() {
   krb5_context ctx = context_.get();
   krb5_free_cred_contents(ctx, &creds_);
   memset(&creds_, 0, sizeof(creds_));
   krb5_error_code code =
     krb5_cc_next_cred(ctx, cc_->get(), &cursor_, &creds_);
   if (code == KRB5_CC_END) {
     return false;
   } else {
     raiseIf(ctx, code, "reading next credential");
   }
   return true;
 }
Esempio n. 18
0
static int
print_tickets (krb5_context context,
	       krb5_ccache ccache,
	       krb5_principal principal)
{
    krb5_error_code ret;
    krb5_cc_cursor cursor;
    krb5_creds cred;
    char *str;

    ret = krb5_unparse_name (context, principal, &str);
    if (ret) {
	lreply(500, "krb5_unparse_name: %d", ret);
	return 500;
    }

    lreply(200, "%17s: %s:%s",
	   "Credentials cache",
	   krb5_cc_get_type(context, ccache),
	   krb5_cc_get_name(context, ccache));
    lreply(200, "%17s: %s", "Principal", str);
    free (str);

    ret = krb5_cc_start_seq_get (context, ccache, &cursor);
    if (ret) {
	lreply(500, "krb5_cc_start_seq_get: %d", ret);
	return 500;
    }

    lreply(200, "  Issued               Expires              Principal");

    while ((ret = krb5_cc_next_cred (context,
				     ccache,
				     &cursor,
				     &cred)) == 0) {
	if (print_cred(context, &cred))
	    return 500;
	krb5_free_cred_contents (context, &cred);
    }
    if (ret != KRB5_CC_END) {
	lreply(500, "krb5_cc_get_next: %d", ret);
	return 500;
    }
    ret = krb5_cc_end_seq_get (context, ccache, &cursor);
    if (ret) {
	lreply(500, "krb5_cc_end_seq_get: %d", ret);
	return 500;
    }

    return 200;
}
Esempio n. 19
0
/*
 * Indicate the we failed to log in to this service/host with these
 * credentials.  The caller passes an unsigned int which they
 * initialise to the number of times they would like to retry.
 *
 * This method is used to support re-trying with freshly fetched
 * credentials in case a server is rebuilt while clients have
 * non-expired tickets. When the client code gets a logon failure they
 * throw away the existing credentials for the server and retry.
 */
_PUBLIC_ bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred,
						    const char *principal,
						    unsigned int *count)
{
	struct ccache_container *ccc;
	krb5_creds creds, creds2;
	int ret;

	if (principal == NULL) {
		/* no way to delete if we don't know the principal */
		return false;
	}

	ccc = cred->ccache;
	if (ccc == NULL) {
		/* not a kerberos connection */
		return false;
	}

	if (*count > 0) {
		/* We have already tried discarding the credentials */
		return false;
	}
	(*count)++;

	ZERO_STRUCT(creds);
	ret = krb5_parse_name(ccc->smb_krb5_context->krb5_context, principal, &creds.server);
	if (ret != 0) {
		return false;
	}

	ret = krb5_cc_retrieve_cred(ccc->smb_krb5_context->krb5_context, ccc->ccache, KRB5_TC_MATCH_SRV_NAMEONLY, &creds, &creds2);
	if (ret != 0) {
		/* don't retry - we didn't find these credentials to remove */
		return false;
	}

	ret = krb5_cc_remove_cred(ccc->smb_krb5_context->krb5_context, ccc->ccache, KRB5_TC_MATCH_SRV_NAMEONLY, &creds);
	krb5_free_cred_contents(ccc->smb_krb5_context->krb5_context, &creds2);
	if (ret != 0) {
		/* don't retry - we didn't find these credentials to
		 * remove. Note that with the current backend this
		 * never happens, as it always returns 0 even if the
		 * creds don't exist, which is why we do a separate
		 * krb5_cc_retrieve_cred() above.
		 */
		return false;
	}
	return true;
}
Esempio n. 20
0
/*
 * clean_cc_tgts()
 *
 * Free CC_TGTS which were dirty, then mark them clean.
 */
static void
clean_cc_tgts(struct tr_state *ts)
{
    unsigned int i;
    struct cc_tgts *rb;

    rb = &ts->cc_tgts;
    for (i = 0; i < NCC_TGTS; i++) {
	if (rb->dirty[i]) {
	    krb5_free_cred_contents(ts->ctx, &rb->cred[i]);
	    rb->dirty[i] = 0;
	}
    }
}
Esempio n. 21
0
int
ZGetCredsRealm(krb5_creds **creds_out,
	       char *realm)
{
  krb5_creds creds_in;
  krb5_creds creds_tmp;
  krb5_ccache ccache; /* XXX make this a global or static?*/
  int result;

  result = krb5_cc_default(Z_krb5_ctx, &ccache);
  if (result)
    return result;

  memset((char *)&creds_in, 0, sizeof(creds_in));
  result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
				strlen(realm),
				realm,
				SERVER_SERVICE, SERVER_INSTANCE,
				NULL);
  if (result) {
    krb5_cc_close(Z_krb5_ctx, ccache);
    return result;
  }

  result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
  if (!result) {
      result = krb5_cc_retrieve_cred(Z_krb5_ctx, ccache,
#ifdef KRB5_TC_SUPPORTED_KTYPES
				     KRB5_TC_SUPPORTED_KTYPES, /* MIT */
#else
                                     0, /* Heimdal or other Space KRB5 */
#endif
                                     &creds_in, &creds_tmp);
      if (!result) {
	  *creds_out = malloc(sizeof(creds_tmp));
	  if (*creds_out == NULL)
	      result = errno;
	  else
	      memcpy(*creds_out, &creds_tmp, sizeof(creds_tmp));
      }
  }
  if (result == KRB5_CC_NOTFOUND || result == KRB5_CC_END)
      result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out);

  krb5_cc_close(Z_krb5_ctx, ccache);
  krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */

  return result;
}
Esempio n. 22
0
static void
check_ticket_count(gss_cred_id_t cred, int expected)
{
    krb5_error_code ret;
    krb5_context context = NULL;
    krb5_creds kcred;
    krb5_cc_cursor cur;
    krb5_ccache ccache;
    int count = 0;
    gss_key_value_set_desc store;
    gss_key_value_element_desc elem;
    OM_uint32 major, minor;
    const char *ccname = "MEMORY:count";

    store.count = 1;
    store.elements = &elem;
    elem.key = "ccache";
    elem.value = ccname;
    major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, &mech_krb5, 1, 0,
                                &store, NULL, NULL);
    check_gsserr("gss_store_cred_into", major, minor);

    ret = krb5_init_context(&context);
    check_k5err(context, "krb5_init_context", ret);

    ret = krb5_cc_resolve(context, ccname, &ccache);
    check_k5err(context, "krb5_cc_resolve", ret);

    ret = krb5_cc_start_seq_get(context, ccache, &cur);
    check_k5err(context, "krb5_cc_start_seq_get", ret);

    while (!krb5_cc_next_cred(context, ccache, &cur, &kcred)) {
        if (!krb5_is_config_principal(context, kcred.server))
            count++;
        krb5_free_cred_contents(context, &kcred);
    }

    ret = krb5_cc_end_seq_get(context, ccache, &cur);
    check_k5err(context, "krb5_cc_end_seq_get", ret);

    if (expected != count) {
        printf("Expected %d tickets but got %d\n", expected, count);
        exit(1);
    }

    krb5_cc_destroy(context, ccache);
    krb5_free_context(context);
}
Esempio n. 23
0
static krb5_error_code
copy_creds_except(krb5_context context, krb5_ccache incc,
                  krb5_ccache outcc, krb5_principal princ)
{
    krb5_error_code code;
    krb5_flags flags;
    krb5_cc_cursor cur;
    krb5_creds creds;

    flags = 0;                           /* turns off OPENCLOSE mode */
    if ((code = krb5_cc_set_flags(context, incc, flags)))
        return(code);
    if ((code = krb5_cc_set_flags(context, outcc, flags)))
        return(code);

    if ((code = krb5_cc_start_seq_get(context, incc, &cur)))
        goto cleanup;

    while (!(code = krb5_cc_next_cred(context, incc, &cur, &creds))) {
        if (krb5_principal_compare(context, princ, creds.server))
            continue;

        code = krb5_cc_store_cred(context, outcc, &creds);
        krb5_free_cred_contents(context, &creds);
        if (code)
            goto cleanup;
    }

    if (code != KRB5_CC_END)
        goto cleanup;

    code = 0;

cleanup:
    flags = KRB5_TC_OPENCLOSE;

    if (code)
        krb5_cc_set_flags(context, incc, flags);
    else
        code = krb5_cc_set_flags(context, incc, flags);

    if (code)
        krb5_cc_set_flags(context, outcc, flags);
    else
        code = krb5_cc_set_flags(context, outcc, flags);

    return(code);
}
Esempio n. 24
0
static krb5_error_code
verify_common (krb5_context context,
	       krb5_principal principal,
	       krb5_ccache ccache,
	       krb5_keytab keytab,
	       krb5_boolean secure,
	       const char *service,
	       krb5_creds cred)
{
    krb5_error_code ret;
    krb5_principal server;
    krb5_verify_init_creds_opt vopt;
    krb5_ccache id;

    ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
				   &server);
    if(ret)
	return ret;

    krb5_verify_init_creds_opt_init(&vopt);
    krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);

    ret = krb5_verify_init_creds(context,
				 &cred,
				 server,
				 keytab,
				 NULL,
				 &vopt);
    krb5_free_principal(context, server);
    if(ret)
	return ret;
    if(ccache == NULL)
	ret = krb5_cc_default (context, &id);
    else
	id = ccache;
    if(ret == 0){
	ret = krb5_cc_initialize(context, id, principal);
	if(ret == 0){
	    ret = krb5_cc_store_cred(context, id, &cred);
	}
	if(ccache == NULL)
	    krb5_cc_close(context, id);
    }
    krb5_free_cred_contents(context, &cred);
    return ret;
}
Esempio n. 25
0
int
v5::credentialCheck(krb5_context kcontext, krb5_principal kprincipal,
                    int promptInterval, krb5_timestamp *tgtEndtime)
{
	krb5_creds my_creds;
	krb5_timestamp now;
	Ktw::reqAction retval = Ktw::none;

	if (!getTgtFromCcache(kcontext, &my_creds))
	{
		tgtEndtime = 0;
		return retval;
	}

	if (krb5_principal_compare (kcontext, my_creds.client, kprincipal))
	{
		krb5_free_principal(kcontext, kprincipal);
		krb5_copy_principal(kcontext, my_creds.client, &kprincipal);
	}
	
	if ((krb5_timeofday(kcontext, &now) == 0) &&
	    (now + (promptInterval * 60) >= my_creds.times.endtime))
	{
		qDebug("now:                   %d", now);
		qDebug("starttime:             %d", my_creds.times.starttime);
		qDebug("endtime:               %d", my_creds.times.endtime);
		qDebug("next Prompt:           %d", (now + (promptInterval * 60)));
		qDebug("renew possible untill: %d", my_creds.times.renew_till);
		if(now + (promptInterval * 60) >= my_creds.times.renew_till)
		{
			retval = Ktw::reinit;
		}
		else
		{		
			retval = Ktw::renew;
		}
	}
	
	*tgtEndtime = my_creds.times.endtime;

	krb5_free_cred_contents(kcontext, &my_creds);

	qDebug("credentials_expiring_real returns: %d", retval);
	
	return retval;
}
Esempio n. 26
0
krb5_error_code KRB5_CALLCONV krb5_stdcc_retrieve 
       		(krb5_context context, 
		   krb5_ccache id, 
		   krb5_flags whichfields, 
		   krb5_creds *mcreds, 
		   krb5_creds *creds )
{
	krb5_error_code	retval;
	krb5_cc_cursor curs = NULL;
	krb5_creds *fetchcreds;
		
	if ((retval = stdcc_setup(context, NULL)))
		return retval;
	
	fetchcreds = (krb5_creds *)malloc(sizeof(krb5_creds));
  	if (fetchcreds == NULL) return KRB5_CC_NOMEM;
	
	/* we're going to use the iterators */
	krb5_stdcc_start_seq_get(context, id, &curs);
	
	while (!krb5_stdcc_next_cred(context, id, &curs, fetchcreds)) {
		/*
		 * look at each credential for a match
		 * use this match routine since it takes the
		 * whichfields and the API doesn't
		 */
		if (stdccCredsMatch(context, fetchcreds,
				    mcreds, whichfields)) {
			/* we found it, copy and exit */
			*creds = *fetchcreds;
			krb5_stdcc_end_seq_get(context, id, &curs);
			return 0;
		}
		/* free copy allocated by next_cred */
		krb5_free_cred_contents(context, fetchcreds);
	}
		
	/* no luck, end get and exit */
	krb5_stdcc_end_seq_get(context, id, &curs);
	
	/* we're not using this anymore so we should get rid of it! */
	free(fetchcreds);
	
	return KRB5_CC_NOTFOUND;
}
Esempio n. 27
0
static gboolean
credentials_expiring_real (KaApplet *applet)
{
    krb5_creds my_creds;
    krb5_timestamp now;
    gboolean retval = FALSE;

    if (!kcontext_valid)
        return retval;

    memset (&my_creds, 0, sizeof (my_creds));
    ka_applet_set_tgt_renewable (applet, FALSE);
    if (!ka_get_tgt_from_ccache (kcontext, &my_creds)) {
        creds_expiry = 0;
        retval = TRUE;
        goto out;
    }

    /* copy principal from cache if any */
    if (kprincipal == NULL ||
        krb5_principal_compare (kcontext, my_creds.client, kprincipal)) {
        if (kprincipal)
            krb5_free_principal (kcontext, kprincipal);
        krb5_copy_principal (kcontext, my_creds.client, &kprincipal);
    }
    creds_expiry = my_creds.times.endtime;
    if ((krb5_timeofday (kcontext, &now) == 0) &&
        (now + ka_applet_get_pw_prompt_secs (applet) >
         my_creds.times.endtime))
        retval = TRUE;

    /* If our creds are expiring, determine whether they are renewable.
     * If the expiry is already at the renew_till time, don't consider
     * credentials renewable */
    if (retval && get_cred_renewable (&my_creds)
        && my_creds.times.renew_till > now
        && my_creds.times.renew_till > creds_expiry) {
        ka_applet_set_tgt_renewable (applet, TRUE);
    }

  out:
    krb5_free_cred_contents (kcontext, &my_creds);
    ka_applet_update_status (applet, creds_expiry);
    return retval;
}
Esempio n. 28
0
static void
get_creds(krb5_context context, krb5_ccache *cache)
{
    krb5_keytab keytab;
    krb5_principal client;
    krb5_error_code ret;
    krb5_get_init_creds_opt *init_opts;
    krb5_preauthtype preauth = KRB5_PADATA_ENC_TIMESTAMP;
    krb5_creds creds;

    ret = krb5_kt_register(context, &hdb_kt_ops);
    if(ret) krb5_err(context, 1, ret, "krb5_kt_register");

    ret = krb5_kt_resolve(context, ktname, &keytab);
    if(ret) krb5_err(context, 1, ret, "krb5_kt_resolve");

    ret = krb5_make_principal(context, &client, NULL,
			      "kadmin", HPROP_NAME, NULL);
    if(ret) krb5_err(context, 1, ret, "krb5_make_principal");

    ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
    if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
    krb5_get_init_creds_opt_set_preauth_list(init_opts, &preauth, 1);

    ret = krb5_get_init_creds_keytab(context, &creds, client, keytab, 0, NULL, init_opts);
    if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");

    krb5_get_init_creds_opt_free(context, init_opts);

    ret = krb5_kt_close(context, keytab);
    if(ret) krb5_err(context, 1, ret, "krb5_kt_close");

    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, cache);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_cc_initialize(context, *cache, client);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");

    krb5_free_principal(context, client);

    ret = krb5_cc_store_cred(context, *cache, &creds);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents(context, &creds);
}
Esempio n. 29
0
static krb5_error_code
mcc_remove_cred(krb5_context context,
		 krb5_ccache id,
		 krb5_flags which,
		 krb5_creds *mcreds)
{
    krb5_mcache *m = MCACHE(id);
    struct link **q, *p;
    for(q = &m->creds, p = *q; p; p = *q) {
	if(krb5_compare_creds(context, which, mcreds, &p->cred)) {
	    *q = p->next;
	    krb5_free_cred_contents(context, &p->cred);
	    free(p);
	} else
	    q = &p->next;
    }
    return 0;
}
Esempio n. 30
0
// Free function for the Kerberos::Krb5 class.
static void rkrb5_free(RUBY_KRB5* ptr){
  if(!ptr)
    return;

  if(ptr->keytab)
    krb5_kt_close(ptr->ctx, ptr->keytab);

  if(ptr->ctx)
    krb5_free_cred_contents(ptr->ctx, &ptr->creds);

  if(ptr->princ)
    krb5_free_principal(ptr->ctx, ptr->princ);

  if(ptr->ctx)
    krb5_free_context(ptr->ctx);

  free(ptr);
}