aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2008-01-19 01:20:38 +0000
committerRuss Allbery <rra@stanford.edu>2008-01-19 01:20:38 +0000
commitcf71c7dac06561b14c8be3383fdb2ca4f3a318d9 (patch)
treed6b05a005c67710a6d2831abba193923f2070f93
parentb4f2b5bf10e32777b1fcfa8417aa190755247815 (diff)
The wallet client now supports a -u option, saying to obtain Kerberos
credentials for the given user and use those for authentication rather than using an existing ticket cache.
-rw-r--r--Makefile.am4
-rw-r--r--NEWS4
-rw-r--r--TODO8
-rw-r--r--client/internal.h5
-rw-r--r--client/krb5.c64
-rw-r--r--client/wallet.c11
-rw-r--r--client/wallet.pod13
7 files changed, 101 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 8cf0e21..cbc9dff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,8 +34,8 @@ util_libutil_a_SOURCES = util/concat.c util/messages.c util/util.h \
bin_PROGRAMS = client/wallet
dist_sbin_SCRIPTS = server/keytab-backend server/wallet-backend
client_wallet_SOURCES = client/error.c client/file.c client/internal.h \
- client/keytab.c client/remctl.c client/srvtab.c client/wallet.c \
- system.h
+ client/keytab.c client/krb5.c client/remctl.c client/srvtab.c \
+ client/wallet.c system.h
client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS)
client_wallet_LDFLAGS = $(REMCTL_LDFLAGS)
client_wallet_LDADD = util/libutil.a portable/libportable.a $(REMCTL_LIBS) \
diff --git a/NEWS b/NEWS
index 24326f3..0a3550a 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,10 @@ wallet 0.6 (unreleased)
keytab keys into that file rather than moving aside the old keytab and
creating a new keytab with only the new keys.
+ The wallet client now supports a -u option, saying to obtain Kerberos
+ credentials for the given user and use those for authentication rather
+ than using an existing ticket cache.
+
Support enforcing a naming policy for wallet objects via a Perl
function in the wallet server configuration file.
diff --git a/TODO b/TODO
index 2a09965..3315681 100644
--- a/TODO
+++ b/TODO
@@ -35,9 +35,7 @@ Release 1.0:
* Log failures in the wallet-backend properly, which also requires
catching all exceptions.
-* Add support to the wallet client for getting Kerberos tickets, using the
- -u option similar to leland_srvtab. Needs good error messages on
- Kerberos failures.
+* Improve the error message for Kerberos authentication failures.
* Error messages from ACL operations should refer to the ACLs by name
instead of by ID.
@@ -165,3 +163,7 @@ May or may not be good ideas:
* Remove the hard-coded ADMIN ACL in the server with something more
configurable, perhaps a global ACL table or something.
+
+* When obtaining tickets in the wallet client with -u, should we get a TGT
+ as we do now or just directly obtain the service ticket we're going to
+ use for remctl?
diff --git a/client/internal.h b/client/internal.h
index 8595412..88b0e24 100644
--- a/client/internal.h
+++ b/client/internal.h
@@ -29,6 +29,11 @@ struct remctl;
BEGIN_DECLS
+/* Given a Kerberos context and a principal name, obtain Kerberos credentials
+ for that principal and store them in a memory cache for use by later
+ operations. */
+void kinit(krb5_context, const char *principal);
+
/* Given a remctl object, run a remctl command. If data is non-NULL, saves
the standard output from the command into data with the length in length.
Otherwise, prints it to standard output. Either way, prints standard error
diff --git a/client/krb5.c b/client/krb5.c
new file mode 100644
index 0000000..606cbb9
--- /dev/null
+++ b/client/krb5.c
@@ -0,0 +1,64 @@
+/* $Id$
+**
+** 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 <rra@stanford.edu>
+** Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+*/
+
+#include <config.h>
+#include <system.h>
+
+#include <krb5.h>
+
+#include <client/internal.h>
+#include <util/util.h>
+
+/* The memory cache used for wallet authentication. */
+#define CACHE_NAME "MEMORY:wallet"
+
+
+/*
+** 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;
+
+ /* Obtain a TGT. */
+ status = krb5_parse_name(ctx, principal, &princ);
+ if (status != 0)
+ die_krb5(ctx, status, "invalid Kerberos principal %s", principal);
+ krb5_get_init_creds_opt_init(&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 memory cache. */
+ 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);
+ if (putenv((char *) "KRB5CCNAME=" CACHE_NAME) != 0)
+ sysdie("cannot set KRB5CCNAME");
+}
diff --git a/client/wallet.c b/client/wallet.c
index 9dc97c2..8ce7ae0 100644
--- a/client/wallet.c
+++ b/client/wallet.c
@@ -26,6 +26,7 @@ struct options {
char *type;
char *server;
char *principal;
+ char *user;
int port;
};
@@ -114,6 +115,7 @@ set_defaults(krb5_context ctx, struct options *options)
default_string(ctx, "wallet_server", WALLET_SERVER, &options->server);
default_string(ctx, "wallet_principal", NULL, &options->principal);
default_number(ctx, "wallet_port", WALLET_PORT, &options->port);
+ options->user = NULL;
}
@@ -144,7 +146,7 @@ main(int argc, char *argv[])
die_krb5(ctx, retval, "cannot initialize Kerberos");
set_defaults(ctx, &options);
- while ((option = getopt(argc, argv, "c:f:k:hp:S:s:v")) != EOF) {
+ while ((option = getopt(argc, argv, "c:f:k:hp:S:s:u:v")) != EOF) {
switch (option) {
case 'c':
options.type = optarg;
@@ -171,6 +173,9 @@ main(int argc, char *argv[])
case 's':
options.server = optarg;
break;
+ case 'u':
+ options.user = optarg;
+ break;
case 'v':
printf("%s\n", PACKAGE_STRING);
exit(0);
@@ -200,6 +205,10 @@ main(int argc, char *argv[])
if (options.server == NULL)
die("no server specified in krb5.conf or with -s");
+ /* If a user was specified, obtain Kerberos tickets. */
+ if (options.user != NULL)
+ kinit(ctx, options.user);
+
/* Open a remctl connection. */
r = remctl_new();
if (r == NULL)
diff --git a/client/wallet.pod b/client/wallet.pod
index 0a6f395..de20586 100644
--- a/client/wallet.pod
+++ b/client/wallet.pod
@@ -6,7 +6,7 @@ wallet - Client for retrieving secure data from a central server
B<wallet> [B<-hv>] [B<-c> I<command>] [B<-f> I<output>]
[B<-k> I<principal>] [B<-p> I<port>] [S<B<-s> I<server>>] [B<-S> I<srvtab>]
-I<command> [I<arg> ...]
+[B<-u> I<principal>] I<command> [I<arg> ...]
=head1 DESCRIPTION
@@ -118,6 +118,15 @@ The wallet server to connect to. The default may be set when compiling
the wallet client. If it isn't, either B<-s> must be given or the server
must be set in F<krb5.conf>. See L<CONFIGURATION> below.
+=item B<-u> I<principal>
+
+Rather than using the user's existing ticket cache for authentication,
+authenticate as I<principal> first and use those credentials for
+authentication to the wallet server. B<wallet> will prompt for the
+password for I<principal>. Non-password authentication methods such as
+PKINIT aren't supported; to use those, run B<kinit> first and use an
+existing ticket cache.
+
=item B<-v>
Display the version of the B<wallet> client and exit. All other valid
@@ -418,7 +427,7 @@ overrides this setting.
=head1 SEE ALSO
-krb5.conf(5), remctl(1), remctld(8)
+kadmin(8), kinit(1), krb5.conf(5), remctl(1), remctld(8)
This program is part of the wallet system. The current version is available
from L<http://www.eyrie.org/~eagle/software/wallet/>.