コード例 #1
0
ファイル: kinit.c プロジェクト: brianmay/heimdal
static void
get_default_principal(krb5_context context, krb5_principal *princ)
{
    krb5_error_code ret;

    if ((ret = krb5_get_default_principal(context, princ)) != 0)
	krb5_err(context, 1, ret, "krb5_get_default_principal");
}
コード例 #2
0
ファイル: init_creds_pw.c プロジェクト: AllardJ/Tomato
static krb5_error_code
init_cred (krb5_context context,
	   krb5_creds *cred,
	   krb5_principal client,
	   krb5_deltat start_time,
	   krb5_get_init_creds_opt *options)
{
    krb5_error_code ret;
    int tmp;
    krb5_timestamp now;

    krb5_timeofday (context, &now);

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

    if (client)
	krb5_copy_principal(context, client, &cred->client);
    else {
	ret = krb5_get_default_principal (context,
					  &cred->client);
	if (ret)
	    goto out;
    }

    if (start_time)
	cred->times.starttime  = now + start_time;

    if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE)
	tmp = options->tkt_life;
    else
	tmp = 10 * 60 * 60;
    cred->times.endtime = now + tmp;

    if ((options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) &&
	options->renew_life > 0) {
	cred->times.renew_till = now + options->renew_life;
    }

    return 0;

out:
    krb5_free_cred_contents (context, cred);
    return ret;
}
コード例 #3
0
ファイル: changepw.c プロジェクト: alepharchives/bitrig
krb5_error_code KRB5_LIB_FUNCTION
krb5_set_password(krb5_context context,
		  krb5_creds *creds,
		  char *newpw,
		  krb5_principal targprinc,
		  int *result_code,
		  krb5_data *result_code_string,
		  krb5_data *result_string)
{
    krb5_principal principal = NULL;
    krb5_error_code ret = 0;
    int i;

    *result_code = KRB5_KPASSWD_MALFORMED;
    result_code_string->data = result_string->data = NULL;
    result_code_string->length = result_string->length = 0;

    if (targprinc == NULL) {
	ret = krb5_get_default_principal(context, &principal);
	if (ret)
	    return ret;
    } else
	principal = targprinc;

    for (i = 0; procs[i].name != NULL; i++) {
	*result_code = 0;
	ret = change_password_loop(context, creds, targprinc, newpw, 
				   result_code, result_code_string, 
				   result_string, 
				   &procs[i]);
	if (ret == 0 && *result_code == 0)
	    break;
    }

    if (targprinc == NULL)
	krb5_free_principal(context, principal);
    return ret;
}
コード例 #4
0
ファイル: acquire_cred.c プロジェクト: DavidMulder/heimdal
/*
 * This function produces a cred with a MEMORY ccache containing a TGT
 * acquired with a password.
 */
static OM_uint32
acquire_cred_with_password(OM_uint32 *minor_status,
                           krb5_context context,
                           const char *password,
                           OM_uint32 time_req,
                           gss_const_OID desired_mech,
                           gss_cred_usage_t cred_usage,
                           gsskrb5_cred handle)
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_creds cred;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache = NULL;
    krb5_error_code kret;
    time_t now;
    OM_uint32 left;

    if (cred_usage == GSS_C_ACCEPT) {
        /*
         * TODO: Here we should eventually support user2user (when we get
         *       support for that via an extension to the mechanism
         *       allowing for more than two security context tokens),
         *       and/or new unique MEMORY keytabs (we have MEMORY keytab
         *       support, but we don't have a keytab equivalent of
         *       krb5_cc_new_unique()).  Either way, for now we can't
         *       support this.
         */
        *minor_status = ENOTSUP; /* XXX Better error? */
        return GSS_S_FAILURE;
    }

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

    if (handle->principal == NULL) {
        kret = krb5_get_default_principal(context, &handle->principal);
        if (kret)
            goto end;
    }
    kret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (kret)
        goto end;

    /*
     * Get the current time before the AS exchange so we don't
     * accidentally end up returning a value that puts advertised
     * expiration past the real expiration.
     *
     * We need to do this because krb5_cc_get_lifetime() returns a
     * relative time that we need to add to the current time.  We ought
     * to have a version of krb5_cc_get_lifetime() that returns absolute
     * time...
     */
    krb5_timeofday(context, &now);

    kret = krb5_get_init_creds_password(context, &cred, handle->principal,
                                        password, NULL, NULL, 0, NULL, opt);
    krb5_get_init_creds_opt_free(context, opt);
    if (kret)
        goto end;

    kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
    if (kret)
        goto end;

    kret = krb5_cc_initialize(context, ccache, cred.client);
    if (kret)
        goto end;

    kret = krb5_cc_store_cred(context, ccache, &cred);
    if (kret)
        goto end;

    handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;

    ret = __gsskrb5_ccache_lifetime(minor_status, context, ccache,
                                    handle->principal, &left);
    if (ret != GSS_S_COMPLETE)
        goto end;
    handle->endtime = now + left;
    handle->ccache = ccache;
    ccache = NULL;
    ret = GSS_S_COMPLETE;
    kret = 0;

end:
    if (ccache != NULL)
        krb5_cc_destroy(context, ccache);
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
コード例 #5
0
ファイル: acquire_cred.c プロジェクト: DavidMulder/heimdal
/*
 * Acquires an initiator credential from a ccache or using a keytab.
 */
static OM_uint32
acquire_initiator_cred(OM_uint32 *minor_status,
                       krb5_context context,
                       OM_uint32 time_req,
                       gss_const_OID desired_mech,
                       gss_cred_usage_t cred_usage,
                       gsskrb5_cred handle)
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_creds cred;
    krb5_get_init_creds_opt *opt;
    krb5_principal def_princ = NULL;
    krb5_ccache def_ccache = NULL;
    krb5_ccache ccache = NULL;  /* we may store into this ccache */
    krb5_keytab keytab = NULL;
    krb5_error_code kret = 0;
    OM_uint32 left;
    time_t lifetime = 0;
    time_t now;

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

    /*
     * Get current time early so we can set handle->endtime to a value that
     * cannot accidentally be past the real endtime.  We need a variant of
     * krb5_cc_get_lifetime() that returns absolute endtime.
     */
    krb5_timeofday(context, &now);

    /*
     * First look for a ccache that has the desired_name (which may be
     * the default credential name).
     *
     * If we don't have an unexpired credential, acquire one with a
     * keytab.
     *
     * If we acquire one with a keytab, save it in the ccache we found
     * with the expired credential, if any.
     *
     * If we don't have any such ccache, then use a MEMORY ccache.
     */

    if (handle->principal != NULL) {
        /*
         * Not default credential case.  See if we can find a ccache in
         * the cccol for the desired_name.
         */
	kret = krb5_cc_cache_match(context,
				   handle->principal,
				   &ccache);
	if (kret == 0) {
            kret = krb5_cc_get_lifetime(context, ccache, &lifetime);
            if (kret == 0) {
                if (lifetime > 0)
                    goto found;
                else
                    goto try_keytab;
            }
	}
        /*
         * Fall through.  We shouldn't find this in the default ccache
         * either, but we'll give it a try, then we'll try using a keytab.
         */
    }

    /*
     * Either desired_name was GSS_C_NO_NAME (default cred) or
     * krb5_cc_cache_match() failed (or found expired).
     */
    kret = krb5_cc_default(context, &def_ccache);
    if (kret != 0)
        goto try_keytab;
    kret = krb5_cc_get_lifetime(context, def_ccache, &lifetime);
    if (kret != 0)
        lifetime = 0;
    kret = krb5_cc_get_principal(context, def_ccache, &def_princ);
    if (kret != 0)
        goto try_keytab;
    /*
     * Have a default ccache; see if it matches desired_name.
     */
    if (handle->principal == NULL ||
        krb5_principal_compare(context, handle->principal,
                               def_princ) == TRUE) {
        /*
         * It matches.
         *
         * If we end up trying a keytab then we can write the result to
         * the default ccache.
         */
        if (handle->principal == NULL) {
            kret = krb5_copy_principal(context, def_princ, &handle->principal);
            if (kret)
                goto end;
        }
        if (ccache != NULL)
            krb5_cc_close(context, ccache);
        ccache = def_ccache;
        def_ccache = NULL;
        if (lifetime > 0)
            goto found;
        /* else we fall through and try using a keytab */
    }

try_keytab:
    if (handle->principal == NULL) {
        /* We need to know what client principal to use */
        kret = krb5_get_default_principal(context, &handle->principal);
        if (kret)
            goto end;
    }
    kret = get_keytab(context, &keytab);
    if (kret)
        goto end;

    kret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (kret)
        goto end;
    krb5_timeofday(context, &now);
    kret = krb5_get_init_creds_keytab(context, &cred, handle->principal,
                                      keytab, 0, NULL, opt);
    krb5_get_init_creds_opt_free(context, opt);
    if (kret)
        goto end;

    /*
     * We got a credential with a keytab.  Save it if we can.
     */
    if (ccache == NULL) {
        /*
         * There's no ccache we can overwrite with the credentials we acquired
         * with a keytab.  We'll use a MEMORY ccache then.
         *
         * Note that an application that falls into this repeatedly will do an
         * AS exchange every time it acquires a credential handle.  Hopefully
         * this doesn't happen much.  A workaround is to kinit -k once so that
         * we always re-initialize the matched/default ccache here.  I.e., once
         * there's a FILE/DIR ccache, we'll keep it frash automatically if we
         * have a keytab, but if there's no FILE/DIR ccache, then we'll
         * get a fresh credential *every* time we're asked.
         */
        kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
        if (kret)
            goto end;
        handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
    } /* else we'll re-initialize whichever ccache we matched above */

    kret = krb5_cc_initialize(context, ccache, cred.client);
    if (kret)
        goto end;
    kret = krb5_cc_store_cred(context, ccache, &cred);
    if (kret)
        goto end;

found:
    assert(handle->principal != NULL);
    ret = __gsskrb5_ccache_lifetime(minor_status, context, ccache,
                                    handle->principal, &left);
    if (ret != GSS_S_COMPLETE)
        goto end;
    handle->endtime = now + left;
    handle->ccache = ccache;
    ccache = NULL;
    ret = GSS_S_COMPLETE;
    kret = 0;

end:
    if (ccache != NULL) {
        if ((handle->cred_flags & GSS_CF_DESTROY_CRED_ON_RELEASE) != 0)
            krb5_cc_destroy(context, ccache);
        else
            krb5_cc_close(context, ccache);
    }
    if (def_ccache != NULL)
        krb5_cc_close(context, def_ccache);
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(context, def_princ);
    if (keytab != NULL)
	krb5_kt_close(context, keytab);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
コード例 #6
0
ファイル: kverify.c プロジェクト: 2asoft/freebsd
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_error_code ret;
    krb5_creds cred;
    krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
    krb5_get_init_creds_opt *get_options;
    krb5_verify_init_creds_opt verify_options;
    krb5_principal principal = NULL;
    int optidx = 0;

    setprogname (argv[0]);

    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

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

    krb5_get_init_creds_opt_set_preauth_list (get_options,
					      pre_auth_types,
					      1);

    krb5_verify_init_creds_opt_init (&verify_options);

    if (argc) {
	ret = krb5_parse_name(context, argv[0], &principal);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_parse_name: %s", argv[0]);
    } else {
	ret = krb5_get_default_principal(context, &principal);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_get_default_principal");

    }

    ret = krb5_get_init_creds_password (context,
					&cred,
					principal,
					NULL,
					krb5_prompter_posix,
					NULL,
					0,
					NULL,
					get_options);
    if (ret)
	krb5_err(context, 1, ret,  "krb5_get_init_creds");

    ret = krb5_verify_init_creds (context,
				  &cred,
				  NULL,
				  NULL,
				  NULL,
				  &verify_options);
    if (ret)
	krb5_err(context, 1, ret, "krb5_verify_init_creds");
    krb5_free_cred_contents (context, &cred);
    krb5_free_context (context);
    return 0;
}
コード例 #7
0
ファイル: acquire_cred.c プロジェクト: abokth/heimdal
static OM_uint32 acquire_initiator_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   gss_const_OID credential_type,
		   const void *credential_data,
		   gss_const_name_t desired_name,
		   OM_uint32 time_req,
		   gss_const_OID desired_mech,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle
		  )
{
    OM_uint32 ret;
    krb5_creds cred;
    krb5_principal def_princ;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache;
    krb5_keytab keytab;
    krb5_error_code kret;

    keytab = NULL;
    ccache = NULL;
    def_princ = NULL;
    ret = GSS_S_FAILURE;
    memset(&cred, 0, sizeof(cred));

    /*
     * If we have a preferred principal, lets try to find it in all
     * caches, otherwise, fall back to default cache, ignore all
     * errors while searching.
     */

    if (credential_type != GSS_C_NO_OID &&
	!gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
	kret = KRB5_NOCREDS_SUPPLIED; /* XXX */
	goto end;
    }

    if (handle->principal) {
	kret = krb5_cc_cache_match (context,
				    handle->principal,
				    &ccache);
	if (kret == 0) {
	    ret = GSS_S_COMPLETE;
	    goto found;
	}
    }

    if (ccache == NULL) {
	kret = krb5_cc_default(context, &ccache);
	if (kret)
	    goto end;
    }
    kret = krb5_cc_get_principal(context, ccache, &def_princ);
    if (kret != 0) {
	/* we'll try to use a keytab below */
	krb5_cc_close(context, ccache);
	def_princ = NULL;
	kret = 0;
    } else if (handle->principal == NULL)  {
	kret = krb5_copy_principal(context, def_princ, &handle->principal);
	if (kret)
	    goto end;
    } else if (handle->principal != NULL &&
	       krb5_principal_compare(context, handle->principal,
				      def_princ) == FALSE) {
	krb5_free_principal(context, def_princ);
	def_princ = NULL;
	krb5_cc_close(context, ccache);
	ccache = NULL;
    }
    if (def_princ == NULL) {
	/* We have no existing credentials cache,
	 * so attempt to get a TGT using a keytab.
	 */
	if (handle->principal == NULL) {
	    kret = krb5_get_default_principal(context, &handle->principal);
	    if (kret)
		goto end;
	}
	kret = krb5_get_init_creds_opt_alloc(context, &opt);
	if (kret)
	    goto end;
	if (credential_type != GSS_C_NO_OID &&
	    gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
	    gss_buffer_t password = (gss_buffer_t)credential_data;

	    /* XXX are we requiring password to be NUL terminated? */

	    kret = krb5_get_init_creds_password(context, &cred,
						handle->principal,
						password->value,
						NULL, NULL, 0, NULL, opt);
	} else {
	    kret = get_keytab(context, &keytab);
	    if (kret) {
		krb5_get_init_creds_opt_free(context, opt);
		goto end;
	    }
	    kret = krb5_get_init_creds_keytab(context, &cred,
					      handle->principal, keytab,
					      0, NULL, opt);
	}
	krb5_get_init_creds_opt_free(context, opt);
	if (kret)
	    goto end;
	kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
				  NULL, &ccache);
	if (kret)
	    goto end;
	kret = krb5_cc_initialize(context, ccache, cred.client);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	kret = krb5_cc_store_cred(context, ccache, &cred);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	handle->lifetime = cred.times.endtime;
	handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
    } else {

	ret = __gsskrb5_ccache_lifetime(minor_status,
					context,
					ccache,
					handle->principal,
					&handle->lifetime);
	if (ret != GSS_S_COMPLETE) {
	    krb5_cc_close(context, ccache);
	    goto end;
	}
	kret = 0;
    }
 found:
    handle->ccache = ccache;
    ret = GSS_S_COMPLETE;

end:
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(context, def_princ);
    if (keytab != NULL)
	krb5_kt_close(context, keytab);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
コード例 #8
0
static OM_uint32 acquire_initiator_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   const gss_name_t desired_name,
		   OM_uint32 time_req,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle
		  )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_creds cred;
    krb5_principal def_princ = NULL;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache = NULL;
    krb5_error_code kret;

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

    /*
     * If we have a preferred principal, lets try to find it in all
     * caches, otherwise, fall back to default cache, ignore all
     * errors while searching.
     */

    if (handle->principal) {
	kret = krb5_cc_cache_match (context,
				    handle->principal,
				    &ccache);
	if (kret == 0) {
	    goto found;
	}
    }

    if (ccache == NULL) {
	kret = krb5_cc_default(context, &ccache);
	if (kret)
	    goto end;
    }
    kret = krb5_cc_get_principal(context, ccache, &def_princ);
    if (kret != 0) {
	/* we'll try to use a keytab below */
	krb5_cc_close(context, ccache);
	def_princ = NULL;
	kret = 0;
    } else if (handle->principal == NULL)  {
	kret = krb5_copy_principal(context, def_princ, &handle->principal);
	if (kret)
	    goto end;
    } else if (handle->principal != NULL &&
	       krb5_principal_compare(context, handle->principal,
				      def_princ) == FALSE) {
	krb5_free_principal(context, def_princ);
	def_princ = NULL;
	krb5_cc_close(context, ccache);
	ccache = NULL;
    }
    if (def_princ == NULL) {
	/* We have no existing credentials cache,
	 * so attempt to get a TGT using a keytab.
	 */
	if (handle->principal == NULL) {
	    kret = krb5_get_default_principal(context, &handle->principal);
	    if (kret)
		goto end;
	}
	/*
	 * Require user is in the keytab before trying to talk to
	 * the KDC.
	 */
	kret = get_keytab(context, handle, 0);
	if (kret)
	    goto end;
	/* since the name might have changed, let double check the credential cache */
	kret = krb5_cc_cache_match(context, handle->principal, &ccache);
	if (kret == 0)
	    goto found;
	kret = krb5_get_init_creds_opt_alloc(context, &opt);
	if (kret)
	    goto end;
	kret = krb5_get_init_creds_keytab(context, &cred,
					  handle->principal, handle->keytab,
					  0, NULL, opt);
	krb5_get_init_creds_opt_free(context, opt);
	if (kret)
	    goto end;
	kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
	if (kret)
	    goto end;
	kret = krb5_cc_initialize(context, ccache, cred.client);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	kret = krb5_cc_store_cred(context, ccache, &cred);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	handle->endtime = cred.times.endtime;
	handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;

    } else {
    found:
	ret = __gsskrb5_ccache_lifetime(minor_status,
					context,
					ccache,
					handle->principal,
					&handle->endtime);
	if (ret != GSS_S_COMPLETE) {
	    krb5_cc_close(context, ccache);
	    goto end;
	}
	kret = 0;
    }

    handle->ccache = ccache;
    ret = GSS_S_COMPLETE;

end:
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(context, def_princ);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
コード例 #9
0
ファイル: kinit.c プロジェクト: martinssonj/heimdal
int
main (int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache  ccache;
    krb5_principal principal;
    int optidx = 0;
    krb5_deltat ticket_life = 0;
    int parseflags = 0;

    setprogname (argv[0]);

    setlocale (LC_ALL, "");
    bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
    textdomain("heimdal_kuser");

    ret = krb5_init_context (&context);
    if (ret == KRB5_CONFIG_BADFORMAT)
	errx (1, "krb5_init_context failed to parse configuration file");
    else if (ret)
	errx(1, "krb5_init_context failed: %d", ret);

    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    if (canonicalize_flag || enterprise_flag)
	parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;

    if (pk_enterprise_flag) {
	ret = krb5_pk_enterprise_cert(context, pk_user_id,
				      argv[0], &principal,
				      &ent_user_id);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");

	pk_user_id = NULL;

    } else if (anonymous_flag) {

	ret = krb5_make_principal(context, &principal, argv[0],
				  KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME,
				  NULL);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_make_principal");
	krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);

    } else {
	if (argv[0]) {
	    ret = krb5_parse_name_flags (context, argv[0], parseflags,
					 &principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_parse_name");
	} else {
	    ret = krb5_get_default_principal (context, &principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_get_default_principal");
	}
    }

    if(fcache_version)
	krb5_set_fcache_version(context, fcache_version);

    if(renewable_flag == -1)
	/* this seems somewhat pointless, but whatever */
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"renewable", FALSE, &renewable_flag);
    if(do_afslog == -1)
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"afslog", TRUE, &do_afslog);

    if(cred_cache)
	ret = krb5_cc_resolve(context, cred_cache, &ccache);
    else {
	if(argc > 1) {
	    char s[1024];
	    ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
	    if(ret)
		krb5_err(context, 1, ret, "creating cred cache");
	    snprintf(s, sizeof(s), "%s:%s",
		     krb5_cc_get_type(context, ccache),
		     krb5_cc_get_name(context, ccache));
	    setenv("KRB5CCNAME", s, 1);
	} else {
	    ret = krb5_cc_cache_match(context, principal, &ccache);
	    if (ret) {
		const char *type;
		ret = krb5_cc_default (context, &ccache);
		if (ret)
		    krb5_err (context, 1, ret, N_("resolving credentials cache", ""));

		/*
		 * Check if the type support switching, and we do,
		 * then do that instead over overwriting the current
		 * default credential
		 */
		type = krb5_cc_get_type(context, ccache);
		if (krb5_cc_support_switch(context, type)) {
		    krb5_cc_close(context, ccache);
		    ret = krb5_cc_new_unique(context, type, NULL, &ccache);
		}
	    }
	}
    }
    if (ret)
	krb5_err (context, 1, ret, N_("resolving credentials cache", ""));

#ifndef NO_AFS
    if(argc > 1 && k_hasafs ())
	k_setpag();
#endif

    if (lifetime) {
	int tmp = parse_time (lifetime, "s");
	if (tmp < 0)
	    errx (1, N_("unparsable time: %s", ""), lifetime);

	ticket_life = tmp;
    }

    if(addrs_flag == 0 && extra_addresses.num_strings > 0)
	krb5_errx(context, 1,
		  N_("specifying both extra addresses and "
		     "no addresses makes no sense", ""));
    {
	int i;
	krb5_addresses addresses;
	memset(&addresses, 0, sizeof(addresses));
	for(i = 0; i < extra_addresses.num_strings; i++) {
	    ret = krb5_parse_address(context, extra_addresses.strings[i],
				     &addresses);
	    if (ret == 0) {
		krb5_add_extra_addresses(context, &addresses);
		krb5_free_addresses(context, &addresses);
	    }
	}
	free_getarg_strings(&extra_addresses);
    }

    if(renew_flag || validate_flag) {
	ret = renew_validate(context, renew_flag, validate_flag,
			     ccache, server_str, ticket_life);
	exit(ret != 0);
    }

    get_new_tickets(context, principal, ccache, ticket_life, 1);

#ifndef NO_AFS
    if(do_afslog && k_hasafs())
	krb5_afslog(context, ccache, NULL, NULL);
#endif
    if(argc > 1) {
	struct renew_ctx ctx;
	time_t timeout;

	timeout = ticket_lifetime(context, ccache, principal,
				  server_str, NULL) / 2;

	ctx.context = context;
	ctx.ccache = ccache;
	ctx.principal = principal;
	ctx.ticket_life = ticket_life;

	ret = simple_execvp_timed(argv[1], argv+1,
				  renew_func, &ctx, timeout);
#define EX_NOEXEC	126
#define EX_NOTFOUND	127
	if(ret == EX_NOEXEC)
	    krb5_warnx(context, N_("permission denied: %s", ""), argv[1]);
	else if(ret == EX_NOTFOUND)
	    krb5_warnx(context, N_("command not found: %s", ""), argv[1]);

	krb5_cc_destroy(context, ccache);
#ifndef NO_AFS
	if(k_hasafs())
	    k_unlog();
#endif
    } else {
	krb5_cc_close (context, ccache);
	ret = 0;
    }
    krb5_free_principal(context, principal);
    krb5_free_context (context);
    return ret;
}
コード例 #10
0
ファイル: acquire_cred.c プロジェクト: alepharchives/bitrig
static OM_uint32 acquire_initiator_cred
		  (OM_uint32 * minor_status,
		   const gss_name_t desired_name,
		   OM_uint32 time_req,
		   const gss_OID_set desired_mechs,
		   gss_cred_usage_t cred_usage,
		   gss_cred_id_t handle,
		   gss_OID_set * actual_mechs,
		   OM_uint32 * time_rec
		  )
{
    OM_uint32 ret;
    krb5_creds cred;
    krb5_principal def_princ;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache;
    krb5_keytab keytab;
    krb5_error_code kret;

    keytab = NULL;
    ccache = NULL;
    def_princ = NULL;
    ret = GSS_S_FAILURE;
    memset(&cred, 0, sizeof(cred));

    kret = krb5_cc_default(gssapi_krb5_context, &ccache);
    if (kret)
	goto end;
    kret = krb5_cc_get_principal(gssapi_krb5_context, ccache,
	&def_princ);
    if (kret != 0) {
	/* we'll try to use a keytab below */
	krb5_cc_destroy(gssapi_krb5_context, ccache);
	ccache = NULL;
	kret = 0;
    } else if (handle->principal == NULL)  {
	kret = krb5_copy_principal(gssapi_krb5_context, def_princ,
	    &handle->principal);
	if (kret)
	    goto end;
    } else if (handle->principal != NULL &&
	krb5_principal_compare(gssapi_krb5_context, handle->principal,
	def_princ) == FALSE) {
	/* Before failing, lets check the keytab */
	krb5_free_principal(gssapi_krb5_context, def_princ);
	def_princ = NULL;
    }
    if (def_princ == NULL) {
	/* We have no existing credentials cache,
	 * so attempt to get a TGT using a keytab.
	 */
	if (handle->principal == NULL) {
	    kret = krb5_get_default_principal(gssapi_krb5_context,
		&handle->principal);
	    if (kret)
		goto end;
	}
	kret = get_keytab(&keytab);
	if (kret)
	    goto end;
	kret = krb5_get_init_creds_opt_alloc(gssapi_krb5_context, &opt);
	if (kret)
	    goto end;
	kret = krb5_get_init_creds_keytab(gssapi_krb5_context, &cred,
	    handle->principal, keytab, 0, NULL, opt);
	krb5_get_init_creds_opt_free(opt);
	if (kret)
	    goto end;
	kret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_mcc_ops,
		&ccache);
	if (kret)
	    goto end;
	kret = krb5_cc_initialize(gssapi_krb5_context, ccache, cred.client);
	if (kret)
	    goto end;
	kret = krb5_cc_store_cred(gssapi_krb5_context, ccache, &cred);
	if (kret)
	    goto end;
	handle->lifetime = cred.times.endtime;
    } else {
	krb5_creds in_cred, *out_cred;
	krb5_const_realm realm;

	memset(&in_cred, 0, sizeof(in_cred));
	in_cred.client = handle->principal;
	
	realm = krb5_principal_get_realm(gssapi_krb5_context, 
					 handle->principal);
	if (realm == NULL) {
	    kret = KRB5_PRINC_NOMATCH; /* XXX */
	    goto end;
	}

	kret = krb5_make_principal(gssapi_krb5_context, &in_cred.server, 
				   realm, KRB5_TGS_NAME, realm, NULL);
	if (kret)
	    goto end;

	kret = krb5_get_credentials(gssapi_krb5_context, 0, 
				    ccache, &in_cred, &out_cred);
	krb5_free_principal(gssapi_krb5_context, in_cred.server);
	if (kret)
	    goto end;

	handle->lifetime = out_cred->times.endtime;
	krb5_free_creds(gssapi_krb5_context, out_cred);
    }

    handle->ccache = ccache;
    ret = GSS_S_COMPLETE;

end:
    if (cred.client != NULL)
	krb5_free_cred_contents(gssapi_krb5_context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(gssapi_krb5_context, def_princ);
    if (keytab != NULL)
	krb5_kt_close(gssapi_krb5_context, keytab);
    if (ret != GSS_S_COMPLETE) {
	if (ccache != NULL)
	    krb5_cc_close(gssapi_krb5_context, ccache);
	if (kret != 0) {
	    *minor_status = kret;
	    gssapi_krb5_set_error_string ();
	}
    }
    return (ret);
}
コード例 #11
0
ファイル: kpasswd.c プロジェクト: DavidMulder/heimdal
int
main (int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_principal principal;
    krb5_get_init_creds_opt *opt;
    krb5_ccache id = NULL;
    int exit_value;
    int optidx = 0;

    setprogname(argv[0]);

    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1, args, sizeof(args) / sizeof(args[0]));
    if (help_flag)
	usage(0, args, sizeof(args) / sizeof(args[0]));
    if (version_flag) {
	print_version(NULL);
	return 0;
    }
    argc -= optidx;
    argv += optidx;

    ret = krb5_init_context (&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

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

    krb5_get_init_creds_opt_set_tkt_life (opt, 300);
    krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
    krb5_get_init_creds_opt_set_proxiable (opt, FALSE);

    if (cred_cache_str) {
	ret = krb5_cc_resolve(context, cred_cache_str, &id);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");
    } else {
	ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_new_unique");
    }

    if (cred_cache_str == NULL) {
	krb5_principal admin_principal = NULL;
	krb5_creds cred;

	if (admin_principal_str) {
	    ret = krb5_parse_name (context, admin_principal_str,
				   &admin_principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_parse_name");
	} else if (argc == 1) {
	    ret = krb5_parse_name (context, argv[0], &admin_principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_parse_name");
	} else {
	    ret = krb5_get_default_principal (context, &admin_principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_get_default_principal");
	}

	ret = krb5_get_init_creds_password (context,
					    &cred,
					    admin_principal,
					    NULL,
					    krb5_prompter_posix,
					    NULL,
					    0,
					    "kadmin/changepw",
					    opt);
	switch (ret) {
	case 0:
	    break;
	case KRB5_LIBOS_PWDINTR :
	    return 1;
	case KRB5KRB_AP_ERR_BAD_INTEGRITY :
	case KRB5KRB_AP_ERR_MODIFIED :
	    krb5_errx(context, 1, "Password incorrect");
	    break;
	default:
	    krb5_err(context, 1, ret, "krb5_get_init_creds");
	}

	krb5_get_init_creds_opt_free(context, opt);

	ret = krb5_cc_initialize(context, id, admin_principal);
	krb5_free_principal(context, admin_principal);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_cc_initialize");

	ret = krb5_cc_store_cred(context, id, &cred);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_cc_store_cred");

	krb5_free_cred_contents (context, &cred);
    }

    if (argc == 0) {
	exit_value = change_password(context, NULL, id);
    } else {
	exit_value = 0;

	while (argc-- > 0) {

	    ret = krb5_parse_name (context, argv[0], &principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_parse_name");

	    ret = change_password(context, principal, id);
	    if (ret)
		exit_value = 1;
	    krb5_free_principal(context, principal);
	    argv++;
	}
    }

    if (cred_cache_str == NULL) {
	ret = krb5_cc_destroy(context, id);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_destroy");
    } else {
	ret = krb5_cc_close(context, id);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_close");
    }

    krb5_free_context (context);
    return exit_value;
}
コード例 #12
0
ファイル: inquire_cred.c プロジェクト: Henauxg/minix
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
(OM_uint32 * minor_status,
 const gss_cred_id_t cred_handle,
 gss_name_t * output_name,
 OM_uint32 * lifetime,
 gss_cred_usage_t * cred_usage,
 gss_OID_set * mechanisms
    )
{
    krb5_context context;
    gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL;
    gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL;
    gsskrb5_cred acred = NULL, icred = NULL;
    OM_uint32 ret;

    *minor_status = 0;

    if (output_name)
	*output_name = NULL;
    if (mechanisms)
	*mechanisms = GSS_C_NO_OID_SET;

    GSSAPI_KRB5_INIT (&context);

    if (cred_handle == GSS_C_NO_CREDENTIAL) {
	ret = _gsskrb5_acquire_cred(minor_status,
				    GSS_C_NO_NAME,
				    GSS_C_INDEFINITE,
				    GSS_C_NO_OID_SET,
				    GSS_C_ACCEPT,
				    &aqcred_accept,
				    NULL,
				    NULL);
	if (ret == GSS_S_COMPLETE)
	    acred = (gsskrb5_cred)aqcred_accept;

	ret = _gsskrb5_acquire_cred(minor_status,
				    GSS_C_NO_NAME,
				    GSS_C_INDEFINITE,
				    GSS_C_NO_OID_SET,
				    GSS_C_INITIATE,
				    &aqcred_init,
				    NULL,
				    NULL);
	if (ret == GSS_S_COMPLETE)
	    icred = (gsskrb5_cred)aqcred_init;

	if (icred == NULL && acred == NULL) {
	    *minor_status = 0;
	    return GSS_S_NO_CRED;
	}
    } else
	acred = (gsskrb5_cred)cred_handle;

    if (acred)
	HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
    if (icred)
	HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);

    if (output_name != NULL) {
	if (icred && icred->principal != NULL) {
	    gss_name_t name;

	    if (acred && acred->principal)
		name = (gss_name_t)acred->principal;
	    else
		name = (gss_name_t)icred->principal;

            ret = _gsskrb5_duplicate_name(minor_status, name, output_name);
            if (ret)
		goto out;
	} else if (acred && acred->usage == GSS_C_ACCEPT) {
	    krb5_principal princ;
	    *minor_status = krb5_sname_to_principal(context, NULL,
						    NULL, KRB5_NT_SRV_HST,
						    &princ);
	    if (*minor_status) {
		ret = GSS_S_FAILURE;
		goto out;
	    }
	    *output_name = (gss_name_t)princ;
	} else {
	    krb5_principal princ;
	    *minor_status = krb5_get_default_principal(context,
						       &princ);
	    if (*minor_status) {
		ret = GSS_S_FAILURE;
		goto out;
	    }
	    *output_name = (gss_name_t)princ;
	}
    }
    if (lifetime != NULL) {
	OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE;

	if (acred) alife = acred->lifetime;
	if (icred) ilife = icred->lifetime;

	ret = _gsskrb5_lifetime_left(minor_status,
				     context,
				     min(alife,ilife),
				     lifetime);
	if (ret)
	    goto out;
    }
    if (cred_usage != NULL) {
	if (acred && icred)
	    *cred_usage = GSS_C_BOTH;
	else if (acred)
	    *cred_usage = GSS_C_ACCEPT;
	else if (icred)
	    *cred_usage = GSS_C_INITIATE;
	else
	    abort();
    }

    if (mechanisms != NULL) {
        ret = gss_create_empty_oid_set(minor_status, mechanisms);
        if (ret)
	    goto out;
	if (acred)
	    ret = gss_add_oid_set_member(minor_status,
					 &acred->mechanisms->elements[0],
					 mechanisms);
	if (ret == GSS_S_COMPLETE && icred)
	    ret = gss_add_oid_set_member(minor_status,
					 &icred->mechanisms->elements[0],
					 mechanisms);
        if (ret)
	    goto out;
    }
    ret = GSS_S_COMPLETE;
out:
    if (acred)
	HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex);
    if (icred)
	HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex);

    if (aqcred_init != GSS_C_NO_CREDENTIAL)
	ret = _gsskrb5_release_cred(minor_status, &aqcred_init);
    if (aqcred_accept != GSS_C_NO_CREDENTIAL)
	ret = _gsskrb5_release_cred(minor_status, &aqcred_accept);

    return ret;
}
コード例 #13
0
ファイル: kinit.c プロジェクト: gojdic/samba
int
main (int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache  ccache;
    krb5_principal principal;
    int optidx = 0;
    krb5_deltat ticket_life = 0;
    int parseflags = 0;

    setprogname (argv[0]);

    setlocale (LC_ALL, "");
#if defined(HEIMDAL_LOCALEDIR)
    bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
    textdomain("heimdal_kuser");
#endif

    ret = krb5_init_context (&context);
    if (ret == KRB5_CONFIG_BADFORMAT)
	errx (1, "krb5_init_context failed to parse configuration file");
    else if (ret)
	errx(1, "krb5_init_context failed: %d", ret);

    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    if (canonicalize_flag)
	parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;

    if (argv[0]) {
	ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_parse_name");
    } else {
	ret = krb5_get_default_principal (context, &principal);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_get_default_principal");
    }

    if(fcache_version)
	krb5_set_fcache_version(context, fcache_version);

    if(renewable_flag == -1)
	/* this seems somewhat pointless, but whatever */
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"renewable", FALSE, &renewable_flag);
#ifndef HEIMDAL_SMALLER
    if(get_v4_tgt == -1)
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"krb4_get_tickets", FALSE, &get_v4_tgt);
#endif
    if(do_afslog == -1)
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"afslog", TRUE, &do_afslog);

    if(cred_cache)
	ret = krb5_cc_resolve(context, cred_cache, &ccache);
    else {
	if(argc > 1) {
	    char s[1024];
	    ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache);
	    if(ret)
		krb5_err(context, 1, ret, "creating cred cache");
	    snprintf(s, sizeof(s), "%s:%s",
		     krb5_cc_get_type(context, ccache),
		     krb5_cc_get_name(context, ccache));
	    setenv("KRB5CCNAME", s, 1);
#ifndef HEIMDAL_SMALLER
	    if (get_v4_tgt) {
		int fd;
		if (asprintf(&krb4_cc_name, "%s_XXXXXX", TKT_ROOT) < 0)
		    krb5_errx(context, 1, "out of memory");
		if((fd = mkstemp(krb4_cc_name)) >= 0) {
		    close(fd);
		    setenv("KRBTKFILE", krb4_cc_name, 1);
		} else {
		    free(krb4_cc_name);
		    krb4_cc_name = NULL;
		}
	    }
#endif
	} else {
	    ret = krb5_cc_cache_match(context, principal, &ccache);
	    if (ret)
		ret = krb5_cc_default (context, &ccache);
	}
    }
    if (ret)
	krb5_err (context, 1, ret, N_("resolving credentials cache", ""));

    if(argc > 1 && k_hasafs ())
	k_setpag();

    if (lifetime) {
	int tmp = parse_time (lifetime, "s");
	if (tmp < 0)
	    errx (1, N_("unparsable time: %s", ""), lifetime);

	ticket_life = tmp;
    }

    if(addrs_flag == 0 && extra_addresses.num_strings > 0)
	krb5_errx(context, 1,
		  N_("specifying both extra addresses and "
		     "no addresses makes no sense", ""));
    {
	int i;
	krb5_addresses addresses;
	memset(&addresses, 0, sizeof(addresses));
	for(i = 0; i < extra_addresses.num_strings; i++) {
	    ret = krb5_parse_address(context, extra_addresses.strings[i],
				     &addresses);
	    if (ret == 0) {
		krb5_add_extra_addresses(context, &addresses);
		krb5_free_addresses(context, &addresses);
	    }
	}
	free_getarg_strings(&extra_addresses);
    }

    if(renew_flag || validate_flag) {
	ret = renew_validate(context, renew_flag, validate_flag,
			     ccache, server_str, ticket_life);
	exit(ret != 0);
    }

#ifndef HEIMDAL_SMALLER
    if(!convert_524)
#endif
	get_new_tickets(context, principal, ccache, ticket_life, 1);

#ifndef HEIMDAL_SMALLER
    if(get_v4_tgt || convert_524)
	do_524init(context, ccache, NULL, server_str);
#endif
    if(do_afslog && k_hasafs())
	krb5_afslog(context, ccache, NULL, NULL);
    if(argc > 1) {
	struct renew_ctx ctx;
	time_t timeout;

	timeout = ticket_lifetime(context, ccache, principal, server_str) / 2;

	ctx.context = context;
	ctx.ccache = ccache;
	ctx.principal = principal;
	ctx.ticket_life = ticket_life;

	ret = simple_execvp_timed(argv[1], argv+1,
				  renew_func, &ctx, timeout);
#define EX_NOEXEC	126
#define EX_NOTFOUND	127
	if(ret == EX_NOEXEC)
	    krb5_warnx(context, N_("permission denied: %s", ""), argv[1]);
	else if(ret == EX_NOTFOUND)
	    krb5_warnx(context, N_("command not found: %s", ""), argv[1]);
	
	krb5_cc_destroy(context, ccache);
#ifndef HEIMDAL_SMALLER
	_krb5_krb_dest_tkt(context, krb4_cc_name);
#endif
	if(k_hasafs())
	    k_unlog();
    } else {
	krb5_cc_close (context, ccache);
	ret = 0;
    }
    krb5_free_principal(context, principal);
    krb5_free_context (context);
    return ret;
}