예제 #1
0
/*
 * Prompt for a password.
 *
 * This function handles prompting both for a password for regular
 * authentication and for passwords when changing one's password.  The default
 * prompt is simply "Password:"******"Kerberos").
 *
 * If args->config->expose_account is set, we append the principal name (taken
 * from args->config->ctx->princ) before the colon, so the prompts are:
 *
 *     Password for <principal>:
 *     <prefix> <banner> password for <principal>:
 *
 * Normally this is not done because it exposes the realm and possibly any
 * username to principal mappings, plus may confuse some ssh clients if sshd
 * passes the prompt back to the client.
 *
 * The entered password is stored in password.  The memory is allocated by the
 * application and returned as part of the PAM conversation.  It must be freed
 * by the caller.
 *
 * Returns a PAM success or error code.
 */
int
pamk5_get_password(struct pam_args *args, const char *prefix, char **password)
{
    struct context *ctx = args->config->ctx;
    char *prompt = NULL;
    char *principal = NULL;
    krb5_error_code k5_errno;
    int retval;

    if (args->config->expose_account || prefix != NULL)
        if (ctx != NULL && ctx->context != NULL && ctx->princ != NULL) {
            k5_errno = krb5_unparse_name(ctx->context, ctx->princ, &principal);
            if (k5_errno != 0)
                putil_debug_krb5(args, k5_errno, "krb5_unparse_name failed");
        }
    if (prefix == NULL) {
        if (args->config->expose_account && principal != NULL) {
            if (asprintf(&prompt, "Password for %s: ", principal) < 0)
                goto fail;
        } else {
            prompt = strdup("Password: "******"" : args->config->banner;
        bspace = (args->config->banner == NULL) ? "" : " ";
        if (args->config->expose_account && principal != NULL) {
            retval = asprintf(&prompt, "%s%s%s password for %s: ", prefix,
                              bspace, banner, principal);
            if (retval < 0)
                goto fail;
        } else {
            retval = asprintf(&prompt, "%s%s%s password: ", prefix, bspace,
                              banner);
            if (retval < 0)
                goto fail;
        }
    }
    if (principal != NULL)
        krb5_free_unparsed_name(ctx->context, principal);
    retval = pamk5_conv(args, prompt, PAM_PROMPT_ECHO_OFF, password);
    free(prompt);
    return retval;

fail:
    if (principal != NULL)
        krb5_free_unparsed_name(ctx->context, principal);
    return PAM_BUF_ERR;
}
예제 #2
0
static PyObject *
k5_cc_get_principal(PyObject *self, PyObject *args)
{
    krb5_context ctx;
    char *ccname, *name;
    krb5_error_code code;
    krb5_ccache ccache;
    krb5_principal principal;
    PyObject *ret;

    if (!PyArg_ParseTuple( args, "s", &ccname))
	return NULL;

    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_cc_resolve(ctx, ccname, &ccache);
    RETURN_ON_ERROR("krb5_cc_resolve()", code);
    code = krb5_cc_get_principal(ctx, ccache, &principal);
    RETURN_ON_ERROR("krb5_cc_get_principal()", code);
    code = krb5_unparse_name(ctx, principal, &name);
    RETURN_ON_ERROR("krb5_unparse_name()", code);

    ret = PyString_FromString(name);
    if (ret == NULL)
	return ret;

    code = krb5_cc_close(ctx, ccache);
    RETURN_ON_ERROR("krb5_cc_close()", code);
    krb5_free_unparsed_name(ctx, name);
    krb5_free_principal(ctx, principal);
    krb5_free_context(ctx);

    return ret;
}
예제 #3
0
static void DEFAULT_CC
k5_end(struct k5_data *k5)
{
    if (k5->name)
    {
        krb5_free_unparsed_name(k5->ctx, k5->name);
    }

    if (k5->me)
    {
        krb5_free_principal(k5->ctx, k5->me);
    }

    if (k5->cc)
    {
        krb5_cc_close(k5->ctx, k5->cc);
    }

    if (k5->ctx)
    {
        krb5_free_context(k5->ctx);
    }

    g_memset(k5, 0, sizeof(struct k5_data));
}
예제 #4
0
파일: s2p.c 프로젝트: Akasurde/krb5
int
main(int argc, char **argv)
{
    krb5_principal princ;
    krb5_int32 type;
    const char *service, *hostname;
    char *name;

    /* Parse arguments. */
    assert(argc == 4);
    hostname = argv[1];
    service = argv[2];
    if (strcmp(argv[3], "unknown") == 0)
        type = KRB5_NT_UNKNOWN;
    else if (strcmp(argv[3], "srv-hst") == 0)
        type = KRB5_NT_SRV_HST;
    else
        abort();

    check(krb5_init_context(&ctx));
    check(krb5_sname_to_principal(ctx, hostname, service, type, &princ));
    check(krb5_unparse_name(ctx, princ, &name));
    printf("%s\n", name);

    krb5_free_unparsed_name(ctx, name);
    krb5_free_principal(ctx, princ);
    krb5_free_context(ctx);
    return 0;
}
예제 #5
0
파일: klist.c 프로젝트: INNOAUS/krb5
static int
list_ccache(krb5_ccache cache)
{
    krb5_error_code ret;
    krb5_principal princ = NULL;
    char *princname = NULL, *ccname = NULL;
    int expired, status = 1;

    ret = krb5_cc_get_principal(context, cache, &princ);
    if (ret)                    /* Uninitialized cache file, probably. */
        goto cleanup;
    ret = krb5_unparse_name(context, princ, &princname);
    if (ret)
        goto cleanup;
    ret = krb5_cc_get_full_name(context, cache, &ccname);
    if (ret)
        goto cleanup;

    expired = check_ccache(cache);

    printf("%-30.30s %s", princname, ccname);
    if (expired)
        printf(" %s", _("(Expired)"));
    printf("\n");

    status = 0;

cleanup:
    krb5_free_principal(context, princ);
    krb5_free_unparsed_name(context, princname);
    krb5_free_string(context, ccname);
    return status;
}
예제 #6
0
/*
 * Set up cred to be an S4U2Proxy credential by copying in the impersonator's
 * creds, setting a cache config variable with the impersonator principal name,
 * and saving the impersonator principal name in the cred structure.
 */
static krb5_error_code
make_proxy_cred(krb5_context context, krb5_gss_cred_id_t cred,
                krb5_gss_cred_id_t impersonator_cred)
{
    krb5_error_code code;
    krb5_data data;
    char *str;

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

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

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

    return krb5_copy_principal(context, impersonator_cred->name->princ,
                               &cred->impersonator);
}
예제 #7
0
파일: ccfns.c 프로젝트: Akasurde/krb5
krb5_error_code
k5_build_conf_principals(krb5_context context, krb5_ccache id,
                         krb5_const_principal principal,
                         const char *name, krb5_creds *cred)
{
    krb5_principal client;
    krb5_error_code ret;
    char *pname = NULL;

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

    ret = krb5_cc_get_principal(context, id, &client);
    if (ret)
        return ret;

    if (principal) {
        ret = krb5_unparse_name(context, principal, &pname);
        if (ret)
            return ret;
    }

    ret = krb5_build_principal(context, &cred->server,
                               sizeof(conf_realm) - 1, conf_realm,
                               conf_name, name, pname, (char *)NULL);
    krb5_free_unparsed_name(context, pname);
    if (ret) {
        krb5_free_principal(context, client);
        return ret;
    }
    ret = krb5_copy_principal(context, client, &cred->client);
    krb5_free_principal(context, client);
    return ret;
}
예제 #8
0
파일: pac_sign.c 프로젝트: NiChrome/krb5
static krb5_error_code
k5_insert_client_info(krb5_context context,
                      krb5_pac pac,
                      krb5_timestamp authtime,
                      krb5_const_principal principal)
{
    krb5_error_code ret;
    krb5_data client_info;
    char *princ_name_utf8 = NULL;
    unsigned char *princ_name_ucs2 = NULL, *p;
    size_t princ_name_ucs2_len = 0;
    krb5_ui_8 nt_authtime;

    /* If we already have a CLIENT_INFO buffer, then just validate it */
    if (k5_pac_locate_buffer(context, pac, KRB5_PAC_CLIENT_INFO,
                             &client_info) == 0) {
        return k5_pac_validate_client(context, pac, authtime, principal);
    }

    ret = krb5_unparse_name_flags(context, principal,
                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
                                  &princ_name_utf8);
    if (ret != 0)
        goto cleanup;

    ret = krb5int_utf8s_to_ucs2les(princ_name_utf8,
                                   &princ_name_ucs2,
                                   &princ_name_ucs2_len);
    if (ret != 0)
        goto cleanup;

    client_info.length = PAC_CLIENT_INFO_LENGTH + princ_name_ucs2_len;
    client_info.data = NULL;

    ret = k5_pac_add_buffer(context, pac, KRB5_PAC_CLIENT_INFO,
                            &client_info, TRUE, &client_info);
    if (ret != 0)
        goto cleanup;

    p = (unsigned char *)client_info.data;

    /* copy in authtime converted to a 64-bit NT time */
    k5_seconds_since_1970_to_time(authtime, &nt_authtime);
    store_64_le(nt_authtime, p);
    p += 8;

    /* copy in number of UCS-2 characters in principal name */
    store_16_le(princ_name_ucs2_len, p);
    p += 2;

    /* copy in principal name */
    memcpy(p, princ_name_ucs2, princ_name_ucs2_len);

cleanup:
    if (princ_name_ucs2 != NULL)
        free(princ_name_ucs2);
    krb5_free_unparsed_name(context, princ_name_utf8);

    return ret;
}
예제 #9
0
static krb5_error_code sss_an2ln(krb5_context context,
                                 krb5_localauth_moddata data,
                                 const char *type, const char *residual,
                                 krb5_const_principal aname, char **lname_out)
{
    krb5_error_code kerr;
    char *princ_str;
    struct passwd pwd = { 0 };
    char *buffer = NULL;
    size_t buflen;
    enum nss_status nss_status;
    int nss_errno;
    int ret;
    char *str;

    kerr = krb5_unparse_name(context, aname, &princ_str);
    if (kerr != 0) {
        return kerr;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = malloc(buflen);
    if (buffer == NULL) {
        ret = ENOMEM;
        goto done;
    }

    nss_status = _nss_sss_getpwnam_r(princ_str, &pwd, buffer, buflen,
                                     &nss_errno);
    if (nss_status != NSS_STATUS_SUCCESS) {
        if (nss_status == NSS_STATUS_NOTFOUND) {
            ret = KRB5_PLUGIN_NO_HANDLE;
        } else {
            ret = EIO;
        }
        goto done;
    }

    if (pwd.pw_name == NULL) {
        ret = EINVAL;
        goto done;
    }

    str = strdup(pwd.pw_name);
    if (str == NULL) {
        ret = ENOMEM;
        goto done;
    }

    *lname_out = str;

    ret = 0;

done:
    krb5_free_unparsed_name(context, princ_str);
    free(buffer);

    return ret;
}
예제 #10
0
파일: fe-auth.c 프로젝트: cbbrowne/postgres
static void
pg_krb5_destroy(struct krb5_info * info)
{
	krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client);
	krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
	krb5_free_unparsed_name(info->pg_krb5_context, info->pg_krb5_name);
	krb5_free_context(info->pg_krb5_context);
}
예제 #11
0
DWORD
ADUKrb5GetPrincipalName(
    PCSTR pszCachePath,
    PSTR* ppszPrincipalName
    )
{
    DWORD dwError = 0;
    krb5_error_code ret = 0;
    krb5_context    ctx = NULL;
    krb5_ccache     cc = NULL;
    krb5_principal  pKrb5Principal = NULL;
    PSTR  pszKrb5PrincipalName = NULL;
    PSTR  pszPrincipalName = NULL;

    ret = krb5_init_context(&ctx);
    BAIL_ON_KRB_ERROR(ctx, ret);

    ret = krb5_cc_resolve(ctx, pszCachePath, &cc);
    BAIL_ON_KRB_ERROR(ctx, ret);

    ret = krb5_cc_get_principal(ctx, cc, &pKrb5Principal);
    BAIL_ON_KRB_ERROR(ctx, ret);

    ret = krb5_unparse_name(ctx, pKrb5Principal, &pszKrb5PrincipalName);
    BAIL_ON_KRB_ERROR(ctx, ret);

    dwError = LwAllocateString(pszKrb5PrincipalName, &pszPrincipalName);
    BAIL_ON_MAC_ERROR(dwError);

    *ppszPrincipalName = pszPrincipalName;

cleanup:

    if (ctx)
    {
        if (pszKrb5PrincipalName)
        {
            krb5_free_unparsed_name(ctx, pszKrb5PrincipalName);
        }
        if (pKrb5Principal)
        {
            krb5_free_principal(ctx, pKrb5Principal);
        }
        if (cc)
        {
            krb5_cc_close(ctx, cc);
        }
        krb5_free_context(ctx);
    }

    return dwError;

error:

    *ppszPrincipalName = NULL;

    goto cleanup;
}
예제 #12
0
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
			      krb5_address *const *addrs, krb5_enctype *ktypes,
			      krb5_preauthtype *pre_auth_types,
			      krb5_keytab arg_keytab, krb5_ccache ccache,
			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
    krb5_error_code retval;
    krb5_gic_opt_ext *opte;
    char * server = NULL;
    krb5_keytab keytab;
    krb5_principal client_princ, server_princ;
    int use_master = 0;
    
    retval = krb5int_populate_gic_opt(context, &opte,
				      options, addrs, ktypes,
				      pre_auth_types, creds);
    if (retval)
	return retval;

    if (arg_keytab == NULL) {
	retval = krb5_kt_default(context, &keytab);
	if (retval)
	    return retval;
    }
    else keytab = arg_keytab;
    
    retval = krb5_unparse_name( context, creds->server, &server);
    if (retval)
	goto cleanup;
    server_princ = creds->server;
    client_princ = creds->client;
    retval = krb5_get_init_creds (context,
				  creds, creds->client,  
				  krb5_prompter_posix,  NULL,
				  0, server, opte,
				  krb5_get_as_key_keytab, (void *)keytab,
				  &use_master, ret_as_reply);
    krb5_free_unparsed_name( context, server);
    krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
    if (retval) {
	goto cleanup;
    }
	if (creds->server)
	    krb5_free_principal( context, creds->server);
	if (creds->client)
	    krb5_free_principal( context, creds->client);
	creds->client = client_princ;
	creds->server = server_princ;
	
    /* store it in the ccache! */
    if (ccache)
	if ((retval = krb5_cc_store_cred(context, ccache, creds)))
	    goto cleanup;
 cleanup:    if (arg_keytab == NULL)
     krb5_kt_close(context, keytab);
    return retval;
}
예제 #13
0
파일: ad.c 프로젝트: jonrober/krb5-sync
/*
 * Push a password change to Active Directory.  Takes the module
 * configuration, a Kerberos context, the principal whose password is being
 * changed (we will have to change the realm), and the new password and its
 * length.  Returns a Kerberos error code.
 */
krb5_error_code
sync_ad_chpass(kadm5_hook_modinfo *config, krb5_context ctx,
               krb5_principal principal, const char *password)
{
    krb5_error_code code;
    char *target = NULL;
    krb5_ccache ccache;
    krb5_principal ad_principal = NULL;
    int result_code;
    krb5_data result_code_string, result_string;

    /* Ensure the configuration is sane. */
    CHECK_CONFIG(ad_realm);

    /* Get the credentials we'll use to make the change in AD. */
    code = get_creds(config, ctx, &ccache);
    if (code != 0)
        return code;

    /* Get the corresponding AD principal. */
    code = get_ad_principal(config, ctx, principal, &ad_principal);
    if (code != 0)
        goto done;

    /* This is just for logging purposes. */
    code = krb5_unparse_name(ctx, ad_principal, &target);
    if (code != 0)
        goto done;

    /* Do the actual password change and record any error. */
    code = krb5_set_password_using_ccache(ctx, ccache, (char *) password,
                                          ad_principal, &result_code,
                                          &result_code_string, &result_string);
    if (code != 0)
        goto done;
    if (result_code != 0) {
        code = sync_error_generic(ctx, "password change failed for %s: (%d)"
                                  " %.*s%s%.*s", target, result_code,
                                  (int) result_code_string.length,
                                  (char *) result_code_string.data,
                                  result_string.length ? ": " : "",
                                  (int) result_string.length,
                                  (char *) result_string.data);
        goto done;
    }
    free(result_string.data);
    free(result_code_string.data);
    sync_syslog_info(config, "krb5-sync: %s password changed", target);

done:
    krb5_cc_destroy(ctx, ccache);
    if (target != NULL)
        krb5_free_unparsed_name(ctx, target);
    if (ad_principal != NULL)
        krb5_free_principal(ctx, ad_principal);
    return code;
}
예제 #14
0
파일: gic_pwd.c 프로젝트: Baalmart/krb5
/*
  Rewrites get_in_tkt in terms of newer get_init_creds API.
  Attempts to get an initial ticket for creds->client to use server
  creds->server, (realm is taken from creds->client), with options
  options, and using creds->times.starttime, creds->times.endtime,
  creds->times.renew_till as from, till, and rtime.
  creds->times.renew_till is ignored unless the RENEWABLE option is requested.

  If addrs is non-NULL, it is used for the addresses requested.  If it is
  null, the system standard addresses are used.

  If password is non-NULL, it is converted using the cryptosystem entry
  point for a string conversion routine, seeded with the client's name.
  If password is passed as NULL, the password is read from the terminal,
  and then converted into a key.

  A succesful call will place the ticket in the credentials cache ccache.

  returns system errors, encryption errors
*/
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options,
                              krb5_address *const *addrs, krb5_enctype *ktypes,
                              krb5_preauthtype *pre_auth_types,
                              const char *password, krb5_ccache ccache,
                              krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
    krb5_error_code retval;
    krb5_data pw0;
    char pw0array[1024];
    char * server;
    krb5_principal server_princ, client_princ;
    int use_master = 0;
    krb5_get_init_creds_opt *opts = NULL;

    pw0.data = pw0array;
    if (password && password[0]) {
        if (strlcpy(pw0.data, password, sizeof(pw0array)) >= sizeof(pw0array))
            return EINVAL;
        pw0.length = strlen(password);
    } else {
        pw0.data[0] = '\0';
        pw0.length = sizeof(pw0array);
    }
    retval = krb5int_populate_gic_opt(context, &opts,
                                      options, addrs, ktypes,
                                      pre_auth_types, creds);
    if (retval)
        return (retval);
    retval = krb5_unparse_name( context, creds->server, &server);
    if (retval) {
        krb5_get_init_creds_opt_free(context, opts);
        return (retval);
    }
    server_princ = creds->server;
    client_princ = creds->client;
    retval = krb5int_get_init_creds(context, creds, creds->client,
                                    krb5_prompter_posix, NULL,
                                    0, server, opts,
                                    krb5_get_as_key_password, &pw0,
                                    &use_master, ret_as_reply);
    krb5_free_unparsed_name( context, server);
    krb5_get_init_creds_opt_free(context, opts);
    if (retval) {
        return (retval);
    }
    krb5_free_principal( context, creds->server);
    krb5_free_principal( context, creds->client);
    creds->client = client_princ;
    creds->server = server_princ;
    /* store it in the ccache! */
    if (ccache)
        if ((retval = krb5_cc_store_cred(context, ccache, creds)))
            return (retval);
    return retval;
}
예제 #15
0
파일: rd_req_dec.c 프로젝트: gladiac/krb5
/* Return a helpful code and error when we cannot iterate over the keytab and
 * the specified server does not match the ticket server. */
static krb5_error_code
nomatch_error(krb5_context context, krb5_const_principal server,
              krb5_const_principal tkt_server)
{
    krb5_error_code ret;
    char *sname = NULL, *tsname = NULL;

    assert(server != NULL);
    ret = unparse_princs(context, server, tkt_server, &sname, &tsname);
    if (ret)
        return ret;

    krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US,
                           _("Server principal %s does not match request "
                             "ticket server %s"), sname, tsname);
    krb5_free_unparsed_name(context, sname);
    krb5_free_unparsed_name(context, tsname);
    return KRB5KRB_AP_ERR_NOT_US;
}
예제 #16
0
파일: rd_req_dec.c 프로젝트: gladiac/krb5
/* Return a helpful code and error when we cannot look up the keytab entry for
 * an explicit server principal using the ticket's kvno and enctype. */
static krb5_error_code
keytab_fetch_error(krb5_context context, krb5_error_code code,
                   krb5_const_principal princ,
                   krb5_const_principal tkt_server, krb5_kvno tkt_kvno,
                   krb5_boolean explicit_server)
{
    krb5_error_code ret;
    char *sname = NULL, *tsname = NULL;

    if (code == ENOENT || code == EPERM || code == EACCES) {
        k5_change_error_message_code(context, code, KRB5KRB_AP_ERR_NOKEY);
        return KRB5KRB_AP_ERR_NOKEY;
    }

    if (code == KRB5_KT_NOTFOUND) {
        ret = explicit_server ? KRB5KRB_AP_ERR_NOKEY : KRB5KRB_AP_ERR_NOT_US;
        k5_change_error_message_code(context, code, ret);
        return ret;
    }

    if (code != KRB5_KT_KVNONOTFOUND)
        return code;

    assert(princ != NULL);
    ret = unparse_princs(context, princ, tkt_server, &sname, &tsname);
    if (ret)
        return ret;
    if (krb5_principal_compare(context, princ, tkt_server)) {
        ret = KRB5KRB_AP_ERR_BADKEYVER;
        krb5_set_error_message(context, ret,
                               _("Cannot find key for %s kvno %d in keytab"),
                               sname, (int)tkt_kvno);
    } else {
        ret = KRB5KRB_AP_ERR_NOT_US;
        krb5_set_error_message(context, ret,
                               _("Cannot find key for %s kvno %d in keytab "
                                 "(request ticket server %s)"),
                               sname, (int)tkt_kvno, tsname);
    }
    krb5_free_unparsed_name(context, sname);
    krb5_free_unparsed_name(context, tsname);
    return ret;
}
예제 #17
0
 krb5_error_code smb_krb5_unparse_name(krb5_context context,
					krb5_const_principal principal,
					char **unix_name)
{
	krb5_error_code ret;
	char *utf8_name;

	ret = krb5_unparse_name(context, principal, &utf8_name);
	if (ret) {
		return ret;
	}

	if (pull_utf8_allocate(unix_name, utf8_name)==-1) {
		krb5_free_unparsed_name(context, utf8_name);
		return ENOMEM;
	}
	krb5_free_unparsed_name(context, utf8_name);
	return 0;
}
예제 #18
0
static void
tr_dbg_rtree(struct tr_state *ts, const char *prog, krb5_principal princ)
{
    char *str;

    if (krb5_unparse_name(ts->ctx, princ, &str))
	return;
    fprintf(stderr, "%s: %s\n", prog, str);
    krb5_free_unparsed_name(ts->ctx, str);
}
예제 #19
0
/*
 * initialize
 *
 * initialize the cache, check to see if one already exists for this
 * principal if not set our principal to this principal. This
 * searching enables ticket sharing
 */
krb5_error_code KRB5_CALLCONV  krb5_stdcc_initialize 
       (krb5_context context, krb5_ccache id,  krb5_principal princ) 
{
	stdccCacheDataPtr	ccapi_data = NULL;
  	int 			err;
  	char 			*cName = NULL;
	krb5_error_code		retval;
  	
	if ((retval = stdcc_setup(context, NULL)))
		return retval;
	
  	/* test id for null */
  	if (id == NULL) return KRB5_CC_NOMEM;
  	
	if ((retval = krb5_unparse_name(context, princ, &cName)))
		return retval;

	ccapi_data = id->data;


	if (ccapi_data->NamedCache)
		cc_close(gCntrlBlock, &ccapi_data->NamedCache);

	err = cc_create(gCntrlBlock, ccapi_data->cache_name, cName,
			CC_CRED_V5, 0L, &ccapi_data->NamedCache);
	if (err != CC_NOERROR) {
		krb5_free_unparsed_name(context, cName);
		return cc_err_xlate(err);
	}

#if 0
	/*
	 * Some implementations don't set the principal name
	 * correctly, so we force set it to the correct value.
	 */
	err = cc_set_principal(gCntrlBlock, ccapi_data->NamedCache,
			       CC_CRED_V5, cName);
#endif
	krb5_free_unparsed_name(context, cName);
	cache_changed();
	
	return cc_err_xlate(err);
}
예제 #20
0
static rlm_rcode_t krb5_parse_user(rlm_krb5_t *inst, REQUEST *request,
			   	   krb5_principal *client)
{
	krb5_error_code ret;
	char *princ_name;
	
	/*
	 * 	We can only authenticate user requests which HAVE
	 * 	a User-Name attribute.
	 */
	if (!request->username) {
		RDEBUG("Attribute \"User-Name\" is required for "
		       "authentication");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 * 	We can only authenticate user requests which HAVE
	 * 	a User-Password attribute.
	 */
	if (!request->password) {
		RDEBUG("Attribute \"User-Password\" is required for "
		       "authentication");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 * 	Ensure that we're being passed a plain-text password,
	 * 	and not anything else.
	 */
	if (request->password->da->attr != PW_USER_PASSWORD) {
		RDEBUG("Attribute \"User-Password\" is required for "
		       "authentication.  Cannot use \"%s\".",
		       request->password->da->name);
		
		return RLM_MODULE_INVALID;
	}
	
	ret = krb5_parse_name(*(inst->context), request->username->vp_strvalue,
			      client);
	if (ret) {
		RDEBUG("Failed parsing username as principal: %s",
		       error_message(ret));
		       
		return RLM_MODULE_FAIL;
	}

	krb5_unparse_name(*(inst->context), *client, &princ_name);
	RDEBUG("Using client principal \"%s\"", princ_name);
	krb5_free_unparsed_name(*(inst->context), princ_name);

	return RLM_MODULE_OK;
}
예제 #21
0
파일: sss_krb5.c 프로젝트: 3van/sssd
void KRB5_CALLCONV sss_krb5_free_unparsed_name(krb5_context context, char *name)
{
#ifdef HAVE_KRB5_FREE_UNPARSED_NAME
    krb5_free_unparsed_name(context, name);
#else
    if (name != NULL) {
        memset(name, 0, strlen(name));
        free(name);
    }
#endif
}
예제 #22
0
파일: klist.c 프로젝트: 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;
    }
}
예제 #23
0
jobject BuildClientPrincipal(JNIEnv *env, krb5_context kcontext, krb5_principal principalName) {
    // Get the full principal string.
    char *principalString = NULL;
    jobject principal = NULL;
    int err = krb5_unparse_name (kcontext, principalName, &principalString);

    if (!err) {
        // Make a PrincipalName from the full string and the type.  Let the PrincipalName class parse it out.
        jstring principalStringObj = (*env)->NewStringUTF(env, principalString);
        if (principalStringObj == NULL) {
            if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); }
            return (jobject) NULL;
        }
        principal = (*env)->NewObject(env, principalNameClass, principalNameConstructor, principalStringObj, principalName->type);
        if (principalString != NULL) { krb5_free_unparsed_name (kcontext, principalString); }
        (*env)->DeleteLocalRef(env, principalStringObj);
    }

    return principal;
}
예제 #24
0
파일: rd_req_dec.c 프로젝트: gladiac/krb5
/* Return a helpful code and error when ticket decryption fails using the key
 * for an explicit server principal. */
static krb5_error_code
integrity_error(krb5_context context, krb5_const_principal server,
                krb5_const_principal tkt_server)
{
    krb5_error_code ret;
    char *sname = NULL, *tsname = NULL;

    assert(server != NULL);
    ret = unparse_princs(context, server, tkt_server, &sname, &tsname);
    if (ret)
        return ret;

    ret = krb5_principal_compare(context, server, tkt_server) ?
        KRB5KRB_AP_ERR_BAD_INTEGRITY : KRB5KRB_AP_ERR_NOT_US;
    krb5_set_error_message(context, ret,
                           _("Cannot decrypt ticket for %s using keytab "
                             "key for %s"), tsname, sname);
    krb5_free_unparsed_name(context, sname);
    krb5_free_unparsed_name(context, tsname);
    return ret;
}
예제 #25
0
파일: in_tkt_sky.c 프로젝트: Akasurde/krb5
/*
  Similar to krb5_get_in_tkt_with_password.

  Attempts to get an initial ticket for creds->client to use server
  creds->server, (realm is taken from creds->client), with options
  options, and using creds->times.starttime, creds->times.endtime,
  creds->times.renew_till as from, till, and rtime.
  creds->times.renew_till is ignored unless the RENEWABLE option is requested.

  If addrs is non-NULL, it is used for the addresses requested.  If it is
  null, the system standard addresses are used.

  If keyblock is NULL, an appropriate key for creds->client is retrieved
  from the system key store (e.g. /etc/srvtab).  If keyblock is non-NULL,
  it is used as the decryption key.

  A succesful call will place the ticket in the credentials cache ccache.

  returns system errors, encryption errors

*/
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_skey(krb5_context context, krb5_flags options,
                          krb5_address *const *addrs, krb5_enctype *ktypes,
                          krb5_preauthtype *pre_auth_types,
                          const krb5_keyblock *key, krb5_ccache ccache,
                          krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
    krb5_error_code retval;
    char *server;
    krb5_principal server_princ, client_princ;
    int use_master = 0;
    krb5_get_init_creds_opt *opts = NULL;

    retval = k5_populate_gic_opt(context, &opts, options, addrs, ktypes,
                                 pre_auth_types, creds);
    if (retval)
        return retval;

    retval = krb5_get_init_creds_opt_set_out_ccache(context, opts, ccache);
    if (retval)
        goto cleanup;

#ifndef LEAN_CLIENT
    if (key == NULL) {
        retval = krb5_get_init_creds_keytab(context, creds, creds->client,
                                            NULL /* keytab */,
                                            creds->times.starttime,
                                            NULL /* in_tkt_service */,
                                            opts);
        goto cleanup;
    }
#endif /* LEAN_CLIENT */

    retval = krb5_unparse_name(context, creds->server, &server);
    if (retval)
        goto cleanup;
    server_princ = creds->server;
    client_princ = creds->client;
    retval = k5_get_init_creds(context, creds, creds->client,
                               krb5_prompter_posix, NULL, 0, server, opts,
                               get_as_key_skey, (void *)key, &use_master,
                               ret_as_reply);
    krb5_free_unparsed_name(context, server);
    if (retval)
        goto cleanup;
    krb5_free_principal( context, creds->server);
    krb5_free_principal( context, creds->client);
    creds->client = client_princ;
    creds->server = server_princ;
cleanup:
    krb5_get_init_creds_opt_free(context, opts);
    return retval;
}
예제 #26
0
파일: kinit.c 프로젝트: brianmay/heimdal
static krb5_error_code
get_switched_ccache(krb5_context context,
		    const char * type,
		    krb5_principal principal,
		    krb5_ccache *ccache)
{
    krb5_error_code ret;

#ifdef _WIN32
    if (strcmp(type, "API") == 0) {
	/*
	 * Windows stores the default ccache name in the
	 * registry which is shared across multiple logon
	 * sessions for the same user.  The API credential
	 * cache provides a unique name space per logon
	 * session.  Therefore there is no need to generate
	 * a unique ccache name.  Instead use the principal
	 * name.  This provides a friendlier user experience.
	 */
	char * unparsed_name;
	char * cred_cache;

	ret = krb5_unparse_name(context, principal,
				&unparsed_name);
	if (ret)
	    krb5_err(context, 1, ret,
		     N_("unparsing principal name", ""));

	ret = asprintf(&cred_cache, "API:%s", unparsed_name);
	krb5_free_unparsed_name(context, unparsed_name);
	if (ret == -1 || cred_cache == NULL)
	    krb5_err(context, 1, ret,
		      N_("building credential cache name", ""));

	ret = krb5_cc_resolve(context, cred_cache, ccache);
	free(cred_cache);
    } else if (strcmp(type, "MSLSA") == 0) {
	/*
	 * The Windows MSLSA cache when it is writeable
	 * stores tickets for multiple client principals
	 * in a single credential cache.
	 */
	ret = krb5_cc_resolve(context, "MSLSA:", ccache);
    } else {
	ret = krb5_cc_new_unique(context, type, NULL, ccache);
    }
#else /* !_WIN32 */
    ret = krb5_cc_new_unique(context, type, NULL, ccache);
#endif /* _WIN32 */

    return ret;
}
예제 #27
0
파일: kprop.c 프로젝트: INNOAUS/krb5
static void
get_tickets(krb5_context context)
{
    char *server;
    krb5_error_code retval;
    krb5_keytab keytab = NULL;
    krb5_principal server_princ = NULL;

    /* Figure out what tickets we'll be using to send. */
    retval = sn2princ_realm(context, NULL, KPROP_SERVICE_NAME, realm,
                            &my_principal);
    if (retval) {
        com_err(progname, errno, _("while setting client principal name"));
        exit(1);
    }

    /* Construct the principal name for the slave host. */
    memset(&creds, 0, sizeof(creds));
    retval = sn2princ_realm(context, slave_host, KPROP_SERVICE_NAME, realm,
                            &server_princ);
    if (retval) {
        com_err(progname, errno, _("while setting server principal name"));
        exit(1);
    }
    retval = krb5_unparse_name_flags(context, server_princ,
                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server);
    if (retval) {
        com_err(progname, retval, _("while unparsing server name"));
        exit(1);
    }

    if (srvtab != NULL) {
        retval = krb5_kt_resolve(context, srvtab, &keytab);
        if (retval) {
            com_err(progname, retval, _("while resolving keytab"));
            exit(1);
        }
    }

    retval = krb5_get_init_creds_keytab(context, &creds, my_principal, keytab,
                                        0, server, NULL);
    if (retval) {
        com_err(progname, retval, _("while getting initial credentials\n"));
        exit(1);
    }

    if (keytab != NULL)
        krb5_kt_close(context, keytab);
    krb5_free_unparsed_name(context, server);
    krb5_free_principal(context, server_princ);
}
예제 #28
0
static void
tr_dbg(struct tr_state *ts, const char *prog)
{
    krb5_error_code retval;
    char *cur_tgt_str, *cur_kdc_str, *nxt_kdc_str;

    cur_tgt_str = cur_kdc_str = nxt_kdc_str = NULL;
    retval = krb5_unparse_name(ts->ctx, ts->cur_tgt->server, &cur_tgt_str);
    if (retval) goto cleanup;
    retval = krb5_unparse_name(ts->ctx, *ts->cur_kdc, &cur_kdc_str);
    if (retval) goto cleanup;
    retval = krb5_unparse_name(ts->ctx, *ts->nxt_kdc, &nxt_kdc_str);
    if (retval) goto cleanup;
    fprintf(stderr, "%s: cur_tgt %s\n", prog, cur_tgt_str);
    fprintf(stderr, "%s: cur_kdc %s\n", prog, cur_kdc_str);
    fprintf(stderr, "%s: nxt_kdc %s\n", prog, nxt_kdc_str);
cleanup:
    if (cur_tgt_str)
	krb5_free_unparsed_name(ts->ctx, cur_tgt_str);
    if (cur_kdc_str)
	krb5_free_unparsed_name(ts->ctx, cur_kdc_str);
    if (nxt_kdc_str)
	krb5_free_unparsed_name(ts->ctx, nxt_kdc_str);
}
예제 #29
0
파일: fast_util.c 프로젝트: Akasurde/krb5
/*
 * Construct the secure cookie encryption key for the given local-realm TGT
 * entry, kvno, and client principal.  The cookie key is derived from the first
 * TGT key for the given kvno, using the concatenation of "COOKIE" and the
 * unparsed client principal name as input.  If kvno is 0, the highest current
 * kvno of the TGT is used.  If kvno_out is not null, *kvno_out is set to the
 * kvno used.
 */
static krb5_error_code
get_cookie_key(krb5_context context, krb5_db_entry *tgt, krb5_kvno kvno,
               krb5_const_principal client_princ, krb5_keyblock **key_out,
               krb5_kvno *kvno_out)
{
    krb5_error_code ret;
    krb5_key_data *kd;
    krb5_keyblock kb;
    krb5_data d;
    krb5_int32 start = 0;
    char *princstr = NULL, *derive_input = NULL;

    *key_out = NULL;
    memset(&kb, 0, sizeof(kb));

    /* Find the first krbtgt key with the specified kvno. */
    ret = krb5_dbe_search_enctype(context, tgt, &start, -1, -1, kvno, &kd);
    if (ret)
        goto cleanup;

    /* Decrypt the key. */
    ret = krb5_dbe_decrypt_key_data(context, NULL, kd, &kb, NULL);
    if (ret)
        goto cleanup;

    /* Construct the input string and derive the cookie key. */
    ret = krb5_unparse_name(context, client_princ, &princstr);
    if (ret)
        goto cleanup;
    if (asprintf(&derive_input, "COOKIE%s", princstr) < 0) {
        ret = ENOMEM;
        goto cleanup;
    }
    d = string2data(derive_input);
    ret = krb5_c_derive_prfplus(context, &kb, &d, ENCTYPE_NULL, key_out);

    if (kvno_out != NULL)
        *kvno_out = kd->key_data_kvno;

cleanup:
    krb5_free_keyblock_contents(context, &kb);
    krb5_free_unparsed_name(context, princstr);
    free(derive_input);
    return ret;
}
예제 #30
0
파일: tabdump.c 프로젝트: PADL/krb5
/* Iterator function for krb5_db_iterate() */
static krb5_error_code
tditer(void *ptr, krb5_db_entry *entry)
{
    krb5_error_code ret;
    struct rec_args *args = ptr;
    char *name;

    ret = krb5_unparse_name(util_context, entry->princ, &name);
    if (ret) {
        com_err(progname, ret, _("while unparsing principal name"));
        return ret;
    }
    ret = args->tdtype->princ_fn(args, name, entry);
    krb5_free_unparsed_name(util_context, name);
    if (ret)
        return ret;
    return 0;
}