Esempio n. 1
0
/* Process a TGS reply and advance the path traversal to get a foreign TGT. */
static krb5_error_code
step_get_tgt(krb5_context context, krb5_tkt_creds_context ctx)
{
    krb5_error_code code;
    const krb5_data *tgt_realm, *path_realm;

    if (ctx->reply_code != 0) {
        /* The last request failed.  Try the next-closest realm to
         * ctx->cur_realm. */
        ctx->next_realm--;
        if (ctx->next_realm == ctx->cur_realm) {
            /* We've tried all the realms we could and couldn't progress beyond
             * ctx->cur_realm, so it's time to give up. */
            return ctx->reply_code;
        }
        TRACE_TKT_CREDS_CLOSER_REALM(context, ctx->next_realm);
    } else {
        /* Verify that we got a TGT. */
        if (!IS_TGS_PRINC(context, ctx->reply_creds->server))
            return KRB5_KDCREP_MODIFIED;

        /* Use this tgt for the next request regardless of what it is. */
        krb5_free_creds(context, ctx->cur_tgt);
        ctx->cur_tgt = ctx->reply_creds;
        ctx->reply_creds = NULL;

        /* Remember that we saw this realm. */
        tgt_realm = &ctx->cur_tgt->server->data[1];
        code = remember_realm(context, ctx, tgt_realm);
        if (code != 0)
            return code;

        /* See where we wound up on the path (or off it). */
        path_realm = find_realm_in_path(context, ctx, tgt_realm);
        if (path_realm != NULL) {
            /* We got a realm on the expected path, so we can cache it. */
            (void) krb5_cc_store_cred(context, ctx->ccache, ctx->cur_tgt);
            if (path_realm == ctx->last_realm) {
                /* We received a TGT for the target realm. */
                TRACE_TKT_CREDS_TARGET_TGT(context, ctx->cur_tgt->server);
                return end_get_tgt(context, ctx);
            } else if (path_realm != NULL) {
                /* We still have further to go; advance the traversal. */
                TRACE_TKT_CREDS_ADVANCE(context, tgt_realm);
                ctx->cur_realm = path_realm;
                ctx->next_realm = ctx->last_realm;
            }
        } else if (data_eq(*tgt_realm, ctx->client->realm)) {
            /* We were referred back to the local realm, which is bad. */
            return KRB5_KDCREP_MODIFIED;
        } else {
            /* We went off the path; start the off-path chase. */
            TRACE_TKT_CREDS_OFFPATH(context, tgt_realm);
            return begin_get_tgt_offpath(context, ctx);
        }
    }

    /* Generate the next request in the path traversal. */
    return get_tgt_request(context, ctx);
}
Esempio n. 2
0
krb5_error_code KRB5_CALLCONV
krb5_get_credentials(krb5_context context, krb5_flags options,
                     krb5_ccache ccache, krb5_creds *in_creds,
                     krb5_creds **out_creds)
{
    krb5_error_code code;
    krb5_creds *ncreds = NULL;
    krb5_tkt_creds_context ctx = NULL;

    *out_creds = NULL;

    /* Allocate a container. */
    ncreds = k5alloc(sizeof(*ncreds), &code);
    if (ncreds == NULL)
        goto cleanup;

    /* Make and execute a krb5_tkt_creds context to get the credential. */
    code = krb5_tkt_creds_init(context, ccache, in_creds, options, &ctx);
    if (code != 0)
        goto cleanup;
    code = krb5_tkt_creds_get(context, ctx);
    if (code != 0)
        goto cleanup;
    code = krb5_tkt_creds_get_creds(context, ctx, ncreds);
    if (code != 0)
        goto cleanup;

    *out_creds = ncreds;
    ncreds = NULL;

cleanup:
    krb5_free_creds(context, ncreds);
    krb5_tkt_creds_free(context, ctx);
    return code;
}
Esempio n. 3
0
static int
kvno5(krb5_context ctx, const char *host, int socktype, krb5_principal princ,
    krb5_principal sprinc, krb5_ccache ccache)
{
	krb5_error_code	 kerr = 0;
	krb5_creds	 increds;
	krb5_creds	*outcreds = NULL;
	krb5_ticket	*ticket = NULL;

	VERBOSE(1, (stderr, "initiating kvno5/%s ping to %s\n",
	    socktype == SOCK_DGRAM ? "udp" : "tcp", host));

	memset(&increds, 0x0, sizeof(increds));
	increds.client = princ;
	increds.server = sprinc;
	kerr = krb5_get_credentials(ctx, 0, ccache, &increds, &outcreds);
	if (kerr)
		goto bail;

        kerr = krb5_decode_ticket(&outcreds->ticket, &ticket);
        if (kerr)
		goto bail;

	VERBOSE(2, (stderr, "kvno5 says kvno = %d\n", ticket->enc_part.kvno));

bail:
	if (kerr)
		fail_msg("kvno5", socktype, host, error_message(kerr));
	if (ticket)
		krb5_free_ticket(ctx, ticket);
	if (outcreds)
		krb5_free_creds(ctx, outcreds);

	return kerr;
}
Esempio n. 4
0
/* Decode and decrypt a TGS reply, and set the reply_code or reply_creds field
 * of ctx with the result.  Also handle too-big errors. */
static krb5_error_code
get_creds_from_tgs_reply(krb5_context context, krb5_tkt_creds_context ctx,
                         krb5_data *reply)
{
    krb5_error_code code;

    krb5_free_creds(context, ctx->reply_creds);
    ctx->reply_creds = NULL;
    code = krb5int_process_tgs_reply(context, reply, ctx->cur_tgt, ctx->kdcopt,
                                     ctx->cur_tgt->addresses, NULL,
                                     ctx->tgs_in_creds, ctx->timestamp,
                                     ctx->nonce, ctx->subkey, NULL, NULL,
                                     &ctx->reply_creds);
    if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG) {
        /* Instruct the caller to re-send the request with TCP. */
        code = set_caller_request(context, ctx);
        if (code != 0)
            return code;
        return KRB5KRB_ERR_RESPONSE_TOO_BIG;
    }

    /* Depending on our state, we may or may not be able to handle an error.
     * For now, store it in the context and return success. */
    TRACE_TKT_CREDS_RESPONSE_CODE(context, code);
    ctx->reply_code = code;
    return 0;
}
Esempio n. 5
0
static int
get_cred(struct kafs_data *data, const char *name, const char *inst,
	 const char *realm, uid_t uid, struct kafs_token *kt)
{
    krb5_error_code ret;
    krb5_creds in_creds, *out_creds;
    struct krb5_kafs_data *d = data->data;

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

    ret = krb5_make_principal(d->context, &in_creds.server,
			      realm, name, inst, NULL);
    if(ret)
	return ret;
    ret = krb5_cc_get_principal(d->context, d->id, &in_creds.client);
    if(ret){
	krb5_free_principal(d->context, in_creds.server);
	return ret;
    }
    in_creds.session.keytype = ETYPE_DES_CBC_CRC;
    ret = krb5_get_credentials(d->context, 0, d->id, &in_creds, &out_creds);
    krb5_free_principal(d->context, in_creds.server);
    krb5_free_principal(d->context, in_creds.client);
    if(ret)
	return ret;

    ret = v5_convert(d->context, d->id, out_creds, uid,
		     (inst != NULL && inst[0] != '\0') ? inst : realm, kt);
    krb5_free_creds(d->context, out_creds);

    return ret;
}
Esempio n. 6
0
/*
 * Generate the next request in the path traversal.  If a cached TGT for the
 * target realm appeared in the ccache since we started the TGT acquisition
 * process, this function may invoke end_get_tgt().
 */
static krb5_error_code
get_tgt_request(krb5_context context, krb5_tkt_creds_context ctx)
{
    krb5_error_code code;
    krb5_creds *cached_tgt;

    while (1) {
        /* Check if we have a cached TGT for the target realm. */
        code = get_cached_tgt(context, ctx, ctx->next_realm, &cached_tgt);
        if (code != 0)
            return code;
        if (cached_tgt != NULL) {
            /* Advance the current realm and keep going. */
            TRACE_TKT_CREDS_CACHED_INTERMEDIATE_TGT(context, cached_tgt);
            krb5_free_creds(context, ctx->cur_tgt);
            ctx->cur_tgt = cached_tgt;
            if (ctx->next_realm == ctx->last_realm)
                return end_get_tgt(context, ctx);
            ctx->cur_realm = ctx->next_realm;
            ctx->next_realm = ctx->last_realm;
            continue;
        }

        return make_request_for_tgt(context, ctx, ctx->next_realm);
    }
}
Esempio n. 7
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_kdc_cred(krb5_context context,
		  krb5_ccache id,
		  krb5_kdc_flags flags,
		  krb5_addresses *addresses,
		  Ticket  *second_ticket,
		  krb5_creds *in_creds,
		  krb5_creds **out_creds
		  )
{
    krb5_error_code ret;
    krb5_creds *krbtgt;

    *out_creds = calloc(1, sizeof(**out_creds));
    if(*out_creds == NULL)
	return krb5_enomem(context);
    ret = _krb5_get_krbtgt (context,
			    id,
			    in_creds->server->realm,
			    &krbtgt);
    if(ret) {
	free(*out_creds);
	*out_creds = NULL;
	return ret;
    }
    ret = get_cred_kdc(context, id, flags, addresses,
		       in_creds, krbtgt, NULL, NULL, *out_creds);
    krb5_free_creds (context, krbtgt);
    if(ret) {
	free(*out_creds);
	*out_creds = NULL;
    }
    return ret;
}
Esempio n. 8
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_get_kdc_cred(krb5_context context,
		  krb5_ccache id,
		  krb5_kdc_flags flags,
		  krb5_addresses *addresses,
		  Ticket  *second_ticket,
		  krb5_creds *in_creds,
		  krb5_creds **out_creds
		  )
{
    krb5_error_code ret;
    krb5_creds *krbtgt;

    *out_creds = calloc(1, sizeof(**out_creds));
    if(*out_creds == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    ret = _krb5_get_krbtgt (context,
			    id,
			    in_creds->server->realm,
			    &krbtgt);
    if(ret) {
	free(*out_creds);
	return ret;
    }
    ret = get_cred_kdc(context, id, flags, addresses, 
		       in_creds, krbtgt, *out_creds);
    krb5_free_creds (context, krbtgt);
    if(ret)
	free(*out_creds);
    return ret;
}
Esempio n. 9
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. 10
0
void KRB5_CALLCONV
krb5_tkt_creds_free(krb5_context context, krb5_tkt_creds_context ctx)
{
    if (ctx == NULL)
        return;
    krb5_free_creds(context, ctx->in_creds);
    krb5_cc_close(context, ctx->ccache);
    krb5_free_principal(context, ctx->req_server);
    krb5_free_authdata(context, ctx->authdata);
    krb5_free_creds(context, ctx->cur_tgt);
    krb5int_free_data_list(context, ctx->realms_seen);
    krb5_free_principal(context, ctx->tgt_princ);
    krb5_free_keyblock(context, ctx->subkey);
    krb5_free_data_contents(context, &ctx->previous_request);
    krb5int_free_data_list(context, ctx->realm_path);
    krb5_free_creds(context, ctx->reply_creds);
    free(ctx);
}
Esempio n. 11
0
/*
 * Determine the starting IAKERB state for a context. If we already
 * have a ticket, we may not need to do IAKERB at all.
 */
static krb5_error_code
iakerb_get_initial_state(iakerb_ctx_id_t ctx,
                         krb5_gss_cred_id_t cred,
                         krb5_gss_name_t target,
                         OM_uint32 time_req,
                         enum iakerb_state *state)
{
    krb5_creds in_creds, *out_creds = NULL;
    krb5_error_code code;

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

    in_creds.client = cred->name->princ;
    in_creds.server = target->princ;

    if (cred->name->ad_context != NULL) {
        code = krb5_authdata_export_authdata(ctx->k5c,
                                             cred->name->ad_context,
                                             AD_USAGE_TGS_REQ,
                                             &in_creds.authdata);
        if (code != 0)
            goto cleanup;
    }

    if (time_req != 0 && time_req != GSS_C_INDEFINITE) {
        krb5_timestamp now;

        code = krb5_timeofday(ctx->k5c, &now);
        if (code != 0)
            goto cleanup;

        in_creds.times.endtime = now + time_req;
    }

    /* Make an AS request if we have no creds or it's time to refresh them. */
    if (cred->expire == 0 || kg_cred_time_to_refresh(ctx->k5c, cred)) {
        *state = IAKERB_AS_REQ;
        code = 0;
        goto cleanup;
    }

    code = krb5_get_credentials(ctx->k5c, KRB5_GC_CACHED, cred->ccache,
                                &in_creds, &out_creds);
    if (code == KRB5_CC_NOTFOUND || code == KRB5_CC_NOT_KTYPE) {
        *state = cred->have_tgt ? IAKERB_TGS_REQ : IAKERB_AS_REQ;
        code = 0;
    } else if (code == 0) {
        *state = IAKERB_AP_REQ;
        krb5_free_creds(ctx->k5c, out_creds);
    }

cleanup:
    krb5_free_authdata(ctx->k5c, in_creds.authdata);

    return code;
}
Esempio n. 12
0
void KRB5_CALLCONV
krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts)
{
    register krb5_creds **tgtpp;
    if (tgts == NULL)
        return;
    for (tgtpp = tgts; *tgtpp; tgtpp++)
        krb5_free_creds(context, *tgtpp);
    free(tgts);
}
Esempio n. 13
0
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[])
{
  char svrnam[MAILTMPLEN],cltnam[MAILTMPLEN];
  krb5_context ctx;
  krb5_timestamp now;
  krb5_principal service;
  krb5_ccache ccache;
  krb5_error_code code;
  krb5_creds *crd = (krb5_creds *) memset (fs_get (sizeof (krb5_creds)),0,
						   sizeof (krb5_creds));
  struct passwd *ret = NIL;
  if (*pass) {			/* only if password non-empty */
				/* make service name */
    sprintf (svrnam,"%.80s@%.512s",
	     (char *) mail_parameters (NIL,GET_SERVICENAME,NIL),
	     tcp_serverhost ());
				/* make client name with principal */
    sprintf (cltnam,"%.80s/%.80s",pw->pw_name,
	     (char *) mail_parameters (NIL,GET_SERVICENAME,NIL));
				/* get a context */
    if (!krb5_init_context (&ctx)) {
				/* get time, client and server principals */
      if (!krb5_timeofday (ctx,&now) &&
	/* Normally, kerb_cp_svr_name (defined/set in env_unix.c) is NIL, so
	 * only the user name is used as a client principal.  A few sites want
	 * to have separate client principals for different services, but many
	 * other sites vehemently object...
	 */
	  !krb5_parse_name (ctx,kerb_cp_svr_name ? cltnam : pw->pw_name,
			    &crd->client) &&
	  !krb5_parse_name (ctx,svrnam,&service) &&
	  !krb5_build_principal_ext(ctx,&crd->server,
				    krb5_princ_realm (ctx,crd->client)->length,
				    krb5_princ_realm (ctx,crd->client)->data,
				    KRB5_TGS_NAME_SIZE,KRB5_TGS_NAME,
				    krb5_princ_realm (ctx,crd->client)->length,
				    krb5_princ_realm (ctx,crd->client)->data,
				    0)) {
				/* expire in 3 minutes */
	crd->times.endtime = now + (3 * 60);
	if (krb5_cc_resolve (ctx,"MEMORY:pwk",&ccache) ||
	    krb5_cc_initialize (ctx,ccache,crd->client)) ccache = 0;
	if (!krb5_get_in_tkt_with_password (ctx,NIL,NIL,NIL,NIL,pass,ccache,
					    crd,0) &&
	    !krb5_verify_init_creds (ctx,crd,service,0,ccache ? &ccache : 0,0))
	  ret = pw;
	krb5_free_creds (ctx,crd);/* flush creds and service principal */
	krb5_free_principal (ctx,service);
      }
      krb5_free_context (ctx);	/* don't need context any more */
    }
  }
  return ret;
}
Esempio n. 14
0
/*
 * try_kdc()
 *
 * Using CUR_TGT, attempt to get desired NXT_TGT.  Update NXT_KDC if
 * successful.
 */
static krb5_error_code
try_kdc(struct tr_state *ts, krb5_creds *tgtq)
{
    krb5_error_code retval;
    krb5_creds ltgtq;
    krb5_creds *tmp_out_cred;

    TR_DBG(ts, "try_kdc");
    /* This check should probably be in gc_via_tkt. */
    if (!krb5_c_valid_enctype(ts->cur_tgt->keyblock.enctype))
	return KRB5_PROG_ETYPE_NOSUPP;

    ltgtq = *tgtq;
    ltgtq.is_skey = FALSE;
    ltgtq.ticket_flags = ts->cur_tgt->ticket_flags;
    /*
     * Solaris Kerberos:
     * Store credential in a temporary ticket as we may not
     * want to add it to ts->kdc_tgts if it is already in
     * the cache.
     */
    retval = krb5_get_cred_via_tkt(ts->ctx, ts->cur_tgt,
				   FLAGS2OPTS(ltgtq.ticket_flags),
				   ts->cur_tgt->addresses,
				   &ltgtq, &tmp_out_cred);
    if (retval) {
	ts->ntgts--;
	ts->nxt_tgt = ts->cur_tgt;
	TR_DBG_RET(ts, "try_kdc", retval);
	return retval;
    }

    /*
     * Solaris Kerberos:
     * See if the returned creds are different to the requested creds.
     * This can happen when the server returns a TGT "closer" to the
     * desired realm.
     */ 
    if (!(krb5_principal_compare(ts->ctx, tgtq->server, tmp_out_cred->server))) {
	    /* Not equal, ticket may already be in the cache */
	    retval = try_ccache(ts, tmp_out_cred);
	    if (!retval) {
	        krb5_free_creds(ts->ctx, tmp_out_cred);
	        retval = find_nxt_kdc(ts);
	        return retval;
	    }
	}

    ts->kdc_tgts[ts->ntgts++] = tmp_out_cred;
    ts->nxt_tgt = ts->kdc_tgts[ts->ntgts-1];
    retval = find_nxt_kdc(ts);
    TR_DBG_RET(ts, "try_kdc", retval);
    return retval;
}
Esempio n. 15
0
/*
 * Begin the process of getting a foreign TGT, either for the explicitly
 * specified server realm or for the fallback realm.  Expects that
 * ctx->server->realm is the realm of the desired TGT, and that
 * ctx->getting_tgt_for is the state we should advance to after we have the
 * desired TGT.
 */
static krb5_error_code
begin_get_tgt(krb5_context context, krb5_tkt_creds_context ctx)
{
    krb5_error_code code;
    krb5_creds *cached_tgt;

    ctx->state = STATE_GET_TGT;

    /* See if we have a cached TGT for the server realm. */
    code = get_cached_tgt(context, ctx, &ctx->server->realm, &cached_tgt);
    if (code != 0)
        return code;
    if (cached_tgt != NULL) {
        TRACE_TKT_CREDS_CACHED_SERVICE_TGT(context, cached_tgt);
        krb5_free_creds(context, ctx->cur_tgt);
        ctx->cur_tgt = cached_tgt;
        return end_get_tgt(context, ctx);
    }

    /* Start with the local tgt. */
    krb5_free_creds(context, ctx->cur_tgt);
    ctx->cur_tgt = NULL;
    code = get_cached_tgt(context, ctx, &ctx->client->realm, &ctx->cur_tgt);
    if (code != 0)
        return code;
    if (ctx->cur_tgt == NULL)
        return ctx->cache_code;
    TRACE_TKT_CREDS_LOCAL_TGT(context, ctx->cur_tgt);

    /* Initialize the realm path. */
    code = init_realm_path(context, ctx);
    if (code != 0)
        return code;

    /* Empty out the realms-seen list for loop checking. */
    krb5int_free_data_list(context, ctx->realms_seen);
    ctx->realms_seen = NULL;

    /* Generate the first request. */
    return get_tgt_request(context, ctx);
}
Esempio n. 16
0
static void
store_tgts(krb5_context context, krb5_ccache ccache, krb5_creds **tgts)
{
    size_t n;

    for (n = 0; tgts && tgts[n]; n++) {
	krb5_const_principal server = tgts[n]->server; 

	if (krb5_principal_is_krbtgt(context, server) && strcmp(server->name.name_string.val[1], server->realm) != 0)
	    krb5_cc_store_cred(context, ccache, tgts[n]);
    }
    for (n = 0; tgts && tgts[n]; n++)
	krb5_free_creds(context, tgts[n]);
}
Krb5Credentials Krb5CCache::getCredentials(
  const krb5_creds& in_creds, krb5_flags options) {

  krb5_creds* out_creds;
  krb5_context ctx = context_.get();
  // The krb5 impl doesn't modify in_creds.
  krb5_error_code code = krb5_get_credentials(
    ctx, options, ccache_, const_cast<krb5_creds*>(&in_creds),
    &out_creds);
  raiseIf(ctx, code, "get credentials");
  SCOPE_EXIT { krb5_free_creds(ctx, out_creds); };

  return Krb5Credentials(std::move(*out_creds));
}
Esempio n. 18
0
static void
eval_kgetcred(heim_dict_t o)
{
    heim_string_t server, ccache;
    krb5_get_creds_opt opt;
    heim_bool_t nostore;
    krb5_error_code ret;
    krb5_ccache cc = NULL;
    krb5_principal s;
    krb5_creds *out = NULL;

    if (ptop)
	ptop->tgs_req++;

    server = heim_dict_get_value(o, HSTR("server"));
    if (server == NULL)
	krb5_errx(kdc_context, 1, "no server");

    ccache = heim_dict_get_value(o, HSTR("ccache"));
    if (ccache == NULL)
	krb5_errx(kdc_context, 1, "no ccache");

    nostore = heim_dict_get_value(o, HSTR("nostore"));
    if (nostore == NULL)
	nostore = heim_bool_create(1);

    ret = krb5_cc_resolve(kdc_context, heim_string_get_utf8(ccache), &cc);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");

    ret = krb5_parse_name(kdc_context, heim_string_get_utf8(server), &s);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_parse_name");

    ret = krb5_get_creds_opt_alloc(kdc_context, &opt);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_get_creds_opt_alloc");

    if (heim_bool_val(nostore))
	krb5_get_creds_opt_add_options(kdc_context, opt, KRB5_GC_NO_STORE);

    ret = krb5_get_creds(kdc_context, opt, cc, s, &out);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_get_creds");
    
    krb5_free_creds(kdc_context, out);
    krb5_free_principal(kdc_context, s);
    krb5_get_creds_opt_free(kdc_context, opt);
    krb5_cc_close(kdc_context, cc);
}
Esempio n. 19
0
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
			    gss_ctx_id_t * context_handle,
			    gss_buffer_t output_token)
{
    krb5_context context;
    gsskrb5_ctx ctx;

    GSSAPI_KRB5_INIT (&context);

    *minor_status = 0;

    if (output_token) {
	output_token->length = 0;
	output_token->value  = NULL;
    }

    if (*context_handle == GSS_C_NO_CONTEXT)
	return GSS_S_COMPLETE;

    ctx = (gsskrb5_ctx) *context_handle;
    *context_handle = GSS_C_NO_CONTEXT;

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    krb5_auth_con_free (context, ctx->auth_context);
    krb5_auth_con_free (context, ctx->deleg_auth_context);
    if (ctx->kcred)
	krb5_free_creds(context, ctx->kcred);
    if(ctx->source)
	krb5_free_principal (context, ctx->source);
    if(ctx->target)
	krb5_free_principal (context, ctx->target);
    if (ctx->ticket)
	krb5_free_ticket (context, ctx->ticket);
    if(ctx->order)
	_gssapi_msg_order_destroy(&ctx->order);
    if (ctx->service_keyblock)
	krb5_free_keyblock (context, ctx->service_keyblock);
    krb5_data_free(&ctx->fwd_data);
    if (ctx->crypto)
    	krb5_crypto_destroy(context, ctx->crypto);

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
    memset(ctx, 0, sizeof(*ctx));
    free (ctx);
    return GSS_S_COMPLETE;
}
Esempio n. 20
0
/* Remove creds from d, invalidate any existing cursors, and unset the client
 * principal.  The caller is responsible for locking. */
static void
empty_mcc_cache(krb5_context context, krb5_mcc_data *d)
{
    krb5_mcc_link *curr, *next;

    for (curr = d->link; curr != NULL; curr = next) {
        next = curr->next;
        krb5_free_creds(context, curr->creds);
        free(curr);
    }
    d->link = NULL;
    d->generation++;
    krb5_free_principal(context, d->prin);
    d->prin = NULL;
}
Esempio n. 21
0
static int
get_cred(struct kafs_data *data, const char *name, const char *inst,
	 const char *realm, uid_t uid, struct kafs_token *kt)
{
    krb5_error_code ret;
    krb5_creds in_creds, *out_creds;
    struct krb5_kafs_data *d = data->data;
    int invalid;

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

    ret = krb5_make_principal(d->context, &in_creds.server,
			      realm, name, inst, NULL);
    if(ret)
	return ret;
    ret = krb5_cc_get_principal(d->context, d->id, &in_creds.client);
    if(ret){
	krb5_free_principal(d->context, in_creds.server);
	return ret;
    }

    in_creds.session.keytype = ETYPE_DES_CBC_CRC;

    /* check if des is disable, and in that case enable it for afs */
    invalid = krb5_enctype_valid(d->context, in_creds.session.keytype);
    if (invalid)
	krb5_enctype_enable(d->context, in_creds.session.keytype);

    ret = krb5_get_credentials(d->context, 0, d->id, &in_creds, &out_creds);
    if (ret) {
	in_creds.session.keytype = ETYPE_DES_CBC_MD5;
	ret = krb5_get_credentials(d->context, 0, d->id, &in_creds, &out_creds);
    }

    if (invalid)
	krb5_enctype_disable(d->context, in_creds.session.keytype);

    krb5_free_principal(d->context, in_creds.server);
    krb5_free_principal(d->context, in_creds.client);
    if(ret)
	return ret;

    ret = v5_convert(d->context, d->id, out_creds, uid,
		     (inst != NULL && inst[0] != '\0') ? inst : realm, kt);
    krb5_free_creds(d->context, out_creds);

    return ret;
}
Esempio n. 22
0
static void
krb5_mcc_free(krb5_context context, krb5_ccache id)
{
    krb5_mcc_cursor curr,next;
    krb5_mcc_data *d;

    d = (krb5_mcc_data *) id->data;
    for (curr = d->link; curr;) {
        krb5_free_creds(context, curr->creds);
        next = curr->next;
        free(curr);
        curr = next;
    }
    d->link = NULL;
    krb5_free_principal(context, d->prin);
}
Esempio n. 23
0
static time_t
ticket_lifetime(krb5_context context, krb5_ccache cache, krb5_principal client,
		const char *server, time_t *renew)
{
    krb5_creds in_cred, *cred;
    krb5_error_code ret;
    time_t timeout;
    time_t curtime;

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

    ret = krb5_cc_get_principal(context, cache, &in_cred.client);
    if (ret) {
	krb5_warn(context, ret, "krb5_cc_get_principal");
	return 0;
    }
    ret = get_server(context, in_cred.client, server, &in_cred.server);
    if (ret) {
	krb5_free_principal(context, in_cred.client);
	krb5_warn(context, ret, "get_server");
	return 0;
    }

    ret = krb5_get_credentials(context, KRB5_GC_CACHED,
			       cache, &in_cred, &cred);
    krb5_free_principal(context, in_cred.client);
    krb5_free_principal(context, in_cred.server);
    if (ret) {
	krb5_warn(context, ret, "krb5_get_credentials");
	return 0;
    }
    curtime = time(NULL);
    timeout = cred->times.endtime - curtime;
    if (timeout < 0)
	timeout = 0;
    if (renew) {
	*renew = cred->times.renew_till - curtime;
	if (*renew < 0)
	    *renew = 0;
    }
    krb5_free_creds(context, cred);
    return timeout;
}
Esempio n. 24
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. 25
0
File: kinit.c Progetto: gojdic/samba
static krb5_error_code
do_524init(krb5_context context, krb5_ccache ccache,
	   krb5_creds *creds, const char *server)
{
    krb5_error_code ret;

    struct credentials c;
    krb5_creds in_creds, *real_creds;

    if(creds != NULL)
	real_creds = creds;
    else {
	krb5_principal client;
	krb5_cc_get_principal(context, ccache, &client);
	memset(&in_creds, 0, sizeof(in_creds));
	ret = get_server(context, client, server, &in_creds.server);
	if(ret) {
	    krb5_free_principal(context, client);
	    return ret;
	}
	in_creds.client = client;
	ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds);
	krb5_free_principal(context, client);
	krb5_free_principal(context, in_creds.server);
	if(ret)
	    return ret;
    }
    ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c);
    if(ret)
	krb5_warn(context, ret, "converting creds");
    else {
	krb5_error_code tret = _krb5_krb_tf_setup(context, &c, NULL, 0);
	if(tret)
	    krb5_warn(context, tret, "saving v4 creds");
    }

    if(creds == NULL)
	krb5_free_creds(context, real_creds);
    memset(&c, 0, sizeof(c));

    return ret;
}
Esempio n. 26
0
/*
 * Modifies:
 * the memory cache
 *
 * Effects:
 * Remove the given creds from the ccache.
 */
static krb5_error_code KRB5_CALLCONV
krb5_mcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
                     krb5_creds *creds)
{
    krb5_mcc_data *data = (krb5_mcc_data *)cache->data;
    krb5_mcc_link *l;

    k5_cc_mutex_lock(context, &data->lock);

    for (l = data->link; l != NULL; l = l->next) {
        if (l->creds != NULL &&
            krb5int_cc_creds_match_request(context, flags, creds, l->creds)) {
            krb5_free_creds(context, l->creds);
            l->creds = NULL;
        }
    }

    k5_cc_mutex_unlock(context, &data->lock);
    return 0;
}
Esempio n. 27
0
static krb5_error_code
get_kadm_ticket(krb5_context context,
		krb5_ccache id,
		krb5_principal client,
		const char *server_name)
{
    krb5_error_code ret;
    krb5_creds in, *out;

    memset(&in, 0, sizeof(in));
    in.client = client;
    ret = krb5_parse_name(context, server_name, &in.server);
    if(ret)
	return ret;
    ret = krb5_get_credentials(context, 0, id, &in, &out);
    if(ret == 0)
	krb5_free_creds(context, out);
    krb5_free_principal(context, in.server);
    return ret;
}
Esempio n. 28
0
krb5_error_code KRB5_CALLCONV
krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
	    krb5_flags ap_req_options, char *service, char *hostname,
	    krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf)
{
    krb5_error_code 	  retval;
    krb5_principal	  server;
    krb5_creds 		* credsp;
    krb5_creds 		  creds;

    retval = krb5_sname_to_principal(context, hostname, service,
				     KRB5_NT_SRV_HST, &server);
    if (retval)
      return retval;

    /* obtain ticket & session key */
    memset((char *)&creds, 0, sizeof(creds));
    if ((retval = krb5_copy_principal(context, server, &creds.server)))
	goto cleanup_princ;

    if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)) != 0)
	goto cleanup_creds;

    if ((retval = krb5_get_credentials(context, 0,
				       ccache, &creds, &credsp)) != 0)
	goto cleanup_creds;

    retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
				  in_data, credsp, outbuf);

    krb5_free_creds(context, credsp);

cleanup_creds:
    krb5_free_cred_contents(context, &creds);

cleanup_princ:
    krb5_free_principal(context, server);

    return retval;
}
Esempio n. 29
0
File: changepw.c Progetto: WeiY/krb5
krb5_error_code KRB5_CALLCONV
krb5_set_password_using_ccache(krb5_context context,
                               krb5_ccache ccache,
                               char *newpw,
                               krb5_principal change_password_for,
                               int *result_code,
                               krb5_data *result_code_string,
                               krb5_data *result_string
)
{
    krb5_creds          creds;
    krb5_creds          *credsp;
    krb5_error_code     code;

    /*
    ** get the proper creds for use with krb5_set_password -
    */
    memset (&creds, 0, sizeof(creds));
    /*
    ** first get the principal for the password service -
    */
    code = krb5_cc_get_principal (context, ccache, &creds.client);
    if (!code) {
        code = krb5_build_principal(context, &creds.server,
                                    change_password_for->realm.length,
                                    change_password_for->realm.data,
                                    "kadmin", "changepw", NULL);
        if (!code) {
            code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
            if (!code) {
                code = krb5_set_password(context, credsp, newpw, change_password_for,
                                         result_code, result_code_string,
                                         result_string);
                krb5_free_creds(context, credsp);
            }
        }
        krb5_free_cred_contents(context, &creds);
    }
    return code;
}
Esempio n. 30
0
Code_t
ZMakeZcodeRealmAuthentication(register ZNotice_t *notice,
			      char *buffer,
			      int buffer_len,
			      int *phdr_len,
			      char *realm)
{
#ifdef HAVE_KRB5
    Code_t result;
    krb5_creds *creds = NULL;

    result = ZGetCredsRealm(&creds, realm);
    if (!result)
	result = Z_MakeZcodeAuthentication(notice, buffer, buffer_len, phdr_len,
					   creds);
    if (creds != NULL)
	krb5_free_creds(Z_krb5_ctx, creds);
    return result;
#else /* HAVE_KRB5 */
    return ZERR_INTERNAL;
#endif
}