1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/*
* Kerberos support functions for the wallet client.
*
* Currently, the only function here is one to obtain a ticket cache for a
* given principal and store it in memory for use by the rest of the wallet
* client.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2007, 2008, 2010
* The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/krb5.h>
#include <portable/system.h>
#include <client/internal.h>
#include <util/messages-krb5.h>
#include <util/messages.h>
/*
* Given a Kerberos context and a principal name, authenticate as that user
* and store the TGT in a memory ticket cache for later use by remctl. Dies
* on failure.
*/
void
kinit(krb5_context ctx, const char *principal)
{
krb5_principal princ;
krb5_ccache ccache;
krb5_creds creds;
krb5_get_init_creds_opt *opts;
krb5_error_code status;
char cache_name[] = "/tmp/krb5cc_wallet_XXXXXX";
int fd;
/* Obtain a TGT. */
status = krb5_parse_name(ctx, principal, &princ);
if (status != 0)
die_krb5(ctx, status, "invalid Kerberos principal %s", principal);
status = krb5_get_init_creds_opt_alloc(ctx, &opts);
if (status != 0)
die_krb5(ctx, status, "cannot allocate credential options");
krb5_get_init_creds_opt_set_default_flags(ctx, "wallet", princ->realm,
opts);
memset(&creds, 0, sizeof(creds));
status = krb5_get_init_creds_password(ctx, &creds, princ, NULL,
krb5_prompter_posix, NULL, 0, NULL, opts);
if (status != 0)
die_krb5(ctx, status, "authentication failed");
/* Put the new credentials into a ticket cache. */
fd = mkstemp(cache_name);
if (fd < 0)
sysdie("cannot create temporary ticket cache %s", cache_name);
status = krb5_cc_resolve(ctx, cache_name, &ccache);
if (status != 0)
die_krb5(ctx, status, "cannot create cache %s", cache_name);
status = krb5_cc_initialize(ctx, ccache, princ);
if (status != 0)
die_krb5(ctx, status, "cannot initialize cache %s", cache_name);
krb5_free_principal(ctx, princ);
status = krb5_cc_store_cred(ctx, ccache, &creds);
if (status != 0)
die_krb5(ctx, status, "cannot store credentials");
krb5_cc_close(ctx, ccache);
close(fd);
if (setenv("KRB5CCNAME", cache_name, 1) < 0)
sysdie("cannot set KRB5CCNAME");
}
/*
* Clean up the temporary ticket cache created by kinit().
*/
void
kdestroy(void)
{
const char *cache;
cache = getenv("KRB5CCNAME");
if (cache == NULL)
die("cannot destroy temporary ticket cache: KRB5CCNAME is not set");
if (unlink(cache) < 0)
sysdie("cannot destroy temporary ticket cache");
}
|