('krb_users/user_commands/kinit', 'kinit', u'obtain and cache Kerberos ticket-granting ticket', [u'MIT'], 1),
('krb_users/user_commands/klist', 'klist', u'list cached Kerberos tickets', [u'MIT'], 1),
('krb_users/user_commands/kdestroy', 'kdestroy', u'destroy Kerberos tickets', [u'MIT'], 1),
+ ('krb_users/user_commands/kswitch', 'kswitch', u'switch primary ticket cache', [u'MIT'], 1),
('krb_users/user_commands/kpasswd', 'kpasswd', u'change a user\'s Kerberos password', [u'MIT'], 1),
('krb_users/user_commands/kvno', 'kvno', u'print key version numbers of Kerberos principals', [u'MIT'], 1),
('krb_users/user_commands/ksu', 'ksu', u'Kerberized super-user', [u'MIT'], 1),
kinit.rst
klist.rst
kdestroy.rst
+ kswitch.rst
kpasswd.rst
kvno.rst
ksu.rst
~~~~~~~~~~~~~
*kdestroy*
+ [**-A**]
[**-q**]
[**-c** *cache_name*]
OPTIONS
~~~~~~~~~~~~~
+ **-A**
+ Destroys all caches in the collection, if a cache collection is
+ available.
+
**-q**
Run quietly. Normally *kdestroy* beeps if it fails to destroy the user's tickets. The *-q* flag suppresses this behavior.
*kdestroy* uses the following environment variables:
- **KRB5CCNAME** - Location of the Kerberos 5 credentials (ticket) cache.
+ **KRB5CCNAME**
+ Location of the default Kerberos 5 credentials (ticket)
+ cache, in the form *type*:*residual*. If no type prefix is
+ present, the **FILE** type is assumed. The type of the
+ default cache may determine the availability of a cache
+ collection; for instance, a default cache of type **DIR**
+ causes caches within the directory to be present in the
+ collection.
FILES
use *cache_name* as the Kerberos 5 credentials (ticket) cache name and location;
if this option is not used, the default cache name and location are used.
- The default credentials cache may vary between systems. If the **KRB5CCNAME** environment variable is set, its
- value is used to name the default ticket cache. Any existing contents of the cache are destroyed by kinit.
+ The default credentials cache may vary between systems. If
+ the **KRB5CCNAME** environment variable is set, its value is
+ used to name the default ticket cache. If a principal name
+ is specified and the type of the default credentials cache
+ supports a collection (such as the DIR type), an existing
+ cache containing credentials for the principal is selected
+ or a new one is created and becomes the new primary cache.
+ Otherwise, any existing contents of the default cache are
+ destroyed by kinit.
**-S** *service_name*
specify an alternate service name to use when getting initial tickets.
*kinit* uses the following environment variables:
- **KRB5CCNAME** Location of the Kerberos 5 credentials (ticket) cache.
+ **KRB5CCNAME**
+ Location of the default Kerberos 5 credentials (ticket)
+ cache, in the form *type*:*residual*. If no type prefix is
+ present, the **FILE** type is assumed. The type of the
+ default cache may determine the availability of a cache
+ collection; for instance, a default cache of type **DIR**
+ causes caches within the directory to be present in the
+ collection.
FILES
**klist**
[**-e**]
- [[**-c**] [**-f**] [**-s**] [**-a** [**-n**]]]
+ [[**-c**] [**-l**] [**-A**] [**-f**] [**-s**] [**-a** [**-n**]]]
[**-k** [**-t**] [**-K**]]
[**-V**]
[*cache_name* | *keytab_name*]
Displays the encryption types of the session key and the ticket for each credential in the credential cache,
or each key in the keytab file.
+ **-l**
+ If a cache collection is available, displays a table
+ summarizing the caches present in the collection.
+
+ **-A**
+ If a cache collection is available, displays the contents of
+ all of the caches in the collection.
+
**-c**
List tickets held in a credentials cache. This is the default if neither *-c* nor *-k* is specified.
*klist* uses the following environment variables:
- **KRB5CCNAME** - Location of the Kerberos 5 credentials (ticket) cache.
+ **KRB5CCNAME**
+ Location of the default Kerberos 5 credentials (ticket)
+ cache, in the form *type*:*residual*. If no type prefix is
+ present, the **FILE** type is assumed. The type of the
+ default cache may determine the availability of a cache
+ collection; for instance, a default cache of type **DIR**
+ causes caches within the directory to be present in the
+ collection.
FILES
--- /dev/null
+kswitch - switch primary credential cache
+=========================================
+
+
+SYNOPSIS
+~~~~~~~~
+
+**kswitch** {**-c** *cachename* | **-p** *principal*}
+
+DESCRIPTION
+~~~~~~~~~~~
+
+*kswitch* makes the specified credential cache the primary cache for
+the collection, if a cache collection is available.
+
+
+OPTIONS
+~~~~~~~
+
+ **-c** *cachename*
+ Directly specifies the credential cache to be made primary.
+
+ **-p** *principal*
+ Causes the cache collection to be searched for a cache
+ containing credentials for *principal*. If one is found,
+ that collection is made primary.
+
+
+ENVIRONMENT
+~~~~~~~~~~~
+
+*kswitch* uses the following environment variables:
+
+ **KRB5CCNAME**
+ Location of the default Kerberos 5 credentials (ticket)
+ cache, in the form *type*:*residual*. If no type prefix is
+ present, the **FILE** type is assumed. The type of the
+ default cache may determine the availability of a cache
+ collection; for instance, a default cache of type **DIR**
+ causes caches within the directory to be present in the
+ collection.
+
+
+FILES
+~~~~~
+
+/tmp/krb5cc_[uid] - Default location of Kerberos 5 credentials cache ([*uid*] is the decimal UID of the user).
+
+
+SEE ALSO
+~~~~~~~~
+
+kinit(1), kdestroy(1), klist(1), kerberos(1)
mydir=clients
BUILDTOP=$(REL)..
-SUBDIRS= klist kinit kdestroy kpasswd ksu kvno kcpytkt kdeltkt
-WINSUBDIRS= klist kinit kdestroy kpasswd kvno kcpytkt kdeltkt
+SUBDIRS= klist kinit kdestroy kpasswd ksu kvno kcpytkt kdeltkt kswitch
+WINSUBDIRS= klist kinit kdestroy kpasswd kvno kcpytkt kdeltkt kswitch
NO_OUTPRE=1
kdestroy \- destroy Kerberos tickets
.SH SYNOPSIS
.B kdestroy
-[\fB\-q\fP] [\fB\-c\fP \fIcache_name]
+[\fB\-A\fP] [\fB\-q\fP] [\fB\-c\fP \fIcache_name]
.br
.SH DESCRIPTION
The
destroyed.
.SH OPTIONS
.TP
+.B \-A
+Destroys all caches in the collection, if a cache collection is
+available.
.B \-q
Run quietly. Normally
.B kdestroy
uses the following environment variables:
.TP "\w'.SM KRB5CCNAME\ \ 'u"
.SM KRB5CCNAME
-Location of the Kerberos 5 credentials (ticket) cache.
+Location of the default Kerberos 5 credentials (ticket) cache, in the
+form \fItype\fP:\fIresidual\fP. If no type prefix is present, the
+\fBFILE\fP type is assumed. The type of the default cache may
+determine the availability of a cache collection; for instance, a
+default cache of type \fBDIR\fP causes caches within the directory to
+be present in the collection.
.SH FILES
.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
/tmp/krb5cc_[uid]
{
#define KRB_AVAIL_STRING(x) ((x)?"available":"not available")
- fprintf(stderr, _("Usage: %s [-q] [-c cache_name]\n"), progname);
+ fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name]\n"), progname);
+ fprintf(stderr, _("\t-A destroy all credential caches in collection\n"));
fprintf(stderr, _("\t-q quiet mode\n"));
fprintf(stderr, _("\t-c specify name of credentials cache\n"));
exit(2);
krb5_error_code retval;
int c;
krb5_ccache cache = NULL;
+ krb5_cccol_cursor cursor;
char *cache_name = NULL;
int code = 0;
int errflg = 0;
int quiet = 0;
+ int all = 0;
setlocale(LC_MESSAGES, "");
progname = GET_PROGNAME(argv[0]);
- while ((c = getopt(argc, argv, "54qc:")) != -1) {
+ while ((c = getopt(argc, argv, "54Aqc:")) != -1) {
switch (c) {
+ case 'A':
+ all = 1;
+ break;
case 'q':
quiet = 1;
break;
exit(1);
}
+ if (all) {
+ code = krb5_cccol_cursor_new(kcontext, &cursor);
+ if (code) {
+ com_err(progname, code, _("while listing credential caches"));
+ exit(1);
+ }
+ while ((code = krb5_cccol_cursor_next(kcontext, cursor,
+ &cache)) == 0 && cache != NULL) {
+ code = krb5_cc_get_full_name(kcontext, cache, &cache_name);
+ if (code) {
+ com_err(progname, code, _("composing ccache name"));
+ exit(1);
+ }
+ code = krb5_cc_destroy(kcontext, cache);
+ if (code && code != KRB5_FCC_NOFILE) {
+ com_err(progname, code, _("while destroying cache %s"),
+ cache_name);
+ }
+ krb5_free_string(kcontext, cache_name);
+ }
+ krb5_cccol_cursor_free(kcontext, &cursor);
+ return 0;
+ }
+
if (cache_name) {
code = krb5_cc_resolve (kcontext, cache_name, &cache);
if (code != 0) {
The default credentials cache may vary between systems. If the
.B KRB5CCNAME
environment variable is set, its value is used to name the default
-ticket cache. Any existing contents of the cache are destroyed by
+ticket cache. If a principal name is specified and the type of the
+default credentials cache supports a collection (such as the DIR
+type), an existing cache containing credentials for the principal is
+selected or a new one is created and becomes the new primary cache.
+Otherwise, any existing contents of the default cache are destroyed by
.IR kinit .
.TP
\fB\-S\fP \fIservice_name\fP
uses the following environment variables:
.TP "\w'.SM KRB5CCNAME\ \ 'u"
.SM KRB5CCNAME
-Location of the Kerberos 5 credentials (ticket) cache.
+Location of the default Kerberos 5 credentials (ticket) cache, in the
+form \fItype\fP:\fIresidual\fP. If no type prefix is present, the
+\fBFILE\fP type is assumed. The type of the default cache may
+determine the availability of a cache collection; for instance, a
+default cache of type \fBDIR\fP causes caches within the directory to
+be present in the collection.
.SH FILES
.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
/tmp/krb5cc_[uid]
.B keytab
file.
.SH SEE ALSO
-klist(1), kdestroy(1), kerberos(1)
+klist(1), kdestroy(1), kswitch(1), kerberos(1)
krb5_ccache cc;
krb5_principal me;
char* name;
+ krb5_boolean switch_to_cache;
};
#ifdef GETOPT_LONG
{
krb5_error_code code = 0;
int flags = opts->enterprise ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0;
+ krb5_ccache defcache;
+ const char *deftype;
code = krb5_init_context(&k5->ctx);
if (code) {
return 0;
}
errctx = k5->ctx;
- if (opts->k5_cache_name)
- {
+
+ /* Parse specified principal name now if we got one. */
+ if (opts->principal_name) {
+ if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
+ flags, &k5->me))) {
+ com_err(progname, code, _("when parsing name %s"),
+ opts->principal_name);
+ return 0;
+ }
+ }
+
+ if (opts->k5_cache_name) {
code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
if (code != 0) {
com_err(progname, code, _("resolving ccache %s"),
fprintf(stderr, _("Using specified cache: %s\n"),
opts->k5_cache_name);
}
- }
- else
- {
- if ((code = krb5_cc_default(k5->ctx, &k5->cc))) {
+ } else {
+ if ((code = krb5_cc_default(k5->ctx, &defcache))) {
com_err(progname, code, _("while getting default ccache"));
return 0;
}
- if (opts->verbose) {
- fprintf(stderr, _("Using default cache: %s\n"),
- krb5_cc_get_name(k5->ctx, k5->cc));
+ deftype = krb5_cc_get_type(k5->ctx, defcache);
+ if (k5->me != NULL && krb5_cc_support_switch(k5->ctx, deftype)) {
+ /* Use an existing cache for the specified principal if we can. */
+ code = krb5_cc_cache_match(k5->ctx, k5->me, &k5->cc);
+ if (code != 0 && code != KRB5_CC_NOTFOUND) {
+ com_err(progname, code, _("while searching for ccache for %s"),
+ opts->principal_name);
+ krb5_cc_close(k5->ctx, defcache);
+ return 0;
+ }
+ if (code == KRB5_CC_NOTFOUND) {
+ code = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->cc);
+ if (code) {
+ com_err(progname, code, _("while generating new ccache"));
+ krb5_cc_close(k5->ctx, defcache);
+ return 0;
+ }
+ if (opts->verbose) {
+ fprintf(stderr, _("Using new cache: %s\n"),
+ krb5_cc_get_name(k5->ctx, k5->cc));
+ }
+ } else if (opts->verbose) {
+ fprintf(stderr, _("Using existing cache: %s\n"),
+ krb5_cc_get_name(k5->ctx, k5->cc));
+ }
+ krb5_cc_close(k5->ctx, defcache);
+ k5->switch_to_cache = 1;
+ } else {
+ k5->cc = defcache;
+ if (opts->verbose) {
+ fprintf(stderr, _("Using default cache: %s\n"),
+ krb5_cc_get_name(k5->ctx, k5->cc));
+ }
}
}
- if (opts->principal_name)
- {
- /* Use specified name */
- if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
- flags, &k5->me))) {
- com_err(progname, code, _("when parsing name %s"),
- opts->principal_name);
- return 0;
- }
- }
- else
- {
+ if (!k5->me) {
/* No principal name specified */
if (opts->anonymous) {
char *defrealm;
}
notix = 0;
+ if (k5->switch_to_cache) {
+ code = krb5_cc_switch(k5->ctx, k5->cc);
+ if (code) {
+ com_err(progname, code, _("while switching to new ccache"));
+ goto cleanup;
+ }
+ }
+
cleanup:
if (options)
krb5_get_init_creds_opt_free(k5->ctx, options);
.SH NAME
klist \- list cached Kerberos tickets
.SH SYNOPSIS
-\fBklist\fP [\fB\-e\fP] [[\fB\-c\fP] [\fB\-f\fP]
+\fBklist\fP [\fB\-e\fP] [[\fB\-c\fP] [\fB\-l\fP] [\fB\-A\fP] [\fB\-f\fP]
[\fB\-s\fP] [\fB\-a\fP [\fB\-n\fP]]]
[\fB\-k\fP [\fB\-t\fP] [\fB\-K\fP]]
[\fIcache_name\fP | \fIkeytab_name\fP]
.B \-k
is specified.
.TP
+.B \-l
+If a cache collection is available, displays a table summarizing the
+caches present in the collection.
+.TP
+.B \-A
+If a cache collection is available, displays the contents of all of
+the caches in the collection.
+.TP
.B \-f
shows the flags present in the credentials, using the following
abbreviations:
uses the following environment variables:
.TP "\w'.SM KRB5CCNAME\ \ 'u"
.SM KRB5CCNAME
-Location of the Kerberos 5 credentials (ticket) cache.
+Location of the default Kerberos 5 credentials (ticket) cache, in the
+form \fItype\fP:\fIresidual\fP. If no type prefix is present, the
+\fBFILE\fP type is assumed. The type of the default cache may
+determine the availability of a cache collection; for instance, a
+default cache of type \fBDIR\fP causes caches within the directory to
+be present in the collection.
.SH FILES
.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
/tmp/krb5cc_[uid]
int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
-int show_adtype = 0;
+int show_adtype = 0, show_all = 0, list_all = 0;
char *defname;
char *progname;
krb5_int32 now;
char * etype_string (krb5_enctype );
void show_credential (krb5_creds *);
-void do_ccache (char *);
+void list_all_ccaches (void);
+int list_ccache (krb5_ccache);
+void show_all_ccaches (void);
+void do_ccache_name (char *);
+int do_ccache (krb5_ccache);
void do_keytab (char *);
void printtime (time_t);
void one_addr (krb5_address *);
{
#define KRB_AVAIL_STRING(x) ((x)?"available":"not available")
- fprintf(stderr, _("Usage: %s [-e] [-V] [[-c] [-d] [-f] [-s] [-a [-n]]] "
- "[-k [-t] [-K]] [name]\n"), progname);
+ fprintf(stderr, _("Usage: %s [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] "
+ "[-a [-n]]] [-k [-t] [-K]] [name]\n"), progname);
fprintf(stderr, _("\t-c specifies credentials cache\n"));
fprintf(stderr, _("\t-k specifies keytab\n"));
fprintf(stderr, _("\t (Default is credentials cache)\n"));
+ fprintf(stderr, _("\t-l lists credential caches in collection\n"));
+ fprintf(stderr, _("\t-A shows content of all credential caches\n"));
fprintf(stderr, _("\t-e shows the encryption type\n"));
fprintf(stderr, _("\t-V shows the Kerberos version and exits\n"));
fprintf(stderr, _("\toptions for credential caches:\n"));
name = NULL;
mode = DEFAULT;
/* V=version so v can be used for verbose later if desired. */
- while ((c = getopt(argc, argv, "dfetKsnack45V")) != -1) {
+ while ((c = getopt(argc, argv, "dfetKsnack45lAV")) != -1) {
switch (c) {
case 'd':
show_adtype = 1;
break;
case '5':
break;
+ case 'l':
+ list_all = 1;
+ break;
+ case 'A':
+ show_all = 1;
+ break;
case 'V':
print_version = 1;
break;
if (mode == DEFAULT || mode == CCACHE) {
if (show_time || show_keys)
usage();
+ if ((show_all && list_all) || (status_only && list_all))
+ usage();
} else {
- if (show_flags || status_only || show_addresses)
+ if (show_flags || status_only || show_addresses ||
+ show_all || list_all)
usage();
}
exit(1);
}
- if (mode == DEFAULT || mode == CCACHE)
- do_ccache(name);
+ if (list_all)
+ list_all_ccaches();
+ else if (show_all)
+ show_all_ccaches();
+ else if (mode == DEFAULT || mode == CCACHE)
+ do_ccache_name(name);
else
do_keytab(name);
}
}
exit(0);
}
-void do_ccache(name)
- char *name;
+
+void
+list_all_ccaches(void)
{
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ;
- krb5_flags flags;
krb5_error_code code;
- int exit_status = 0;
+ krb5_ccache cache;
+ krb5_cccol_cursor cursor;
+ int exit_status;
+
+ code = krb5_cccol_cursor_new(kcontext, &cursor);
+ if (code) {
+ if (!status_only)
+ com_err(progname, code, _("while listing ccache collection"));
+ exit(1);
+ }
+
+ /* XXX Translating would disturb table alignment; skip for now. */
+ printf("%-30s %s\n", "Principal name", "Cache name");
+ printf("%-30s %s\n", "--------------", "----------");
+ exit_status = 1;
+ while (!(code = krb5_cccol_cursor_next(kcontext, cursor, &cache)) &&
+ cache != NULL) {
+ exit_status = list_ccache(cache) && exit_status;
+ krb5_cc_close(kcontext, cache);
+ }
+ krb5_cccol_cursor_free(kcontext, &cursor);
+ exit(exit_status);
+}
+
+int
+list_ccache(krb5_ccache cache)
+{
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ char *princname = NULL, *ccname = NULL;
+ int expired, status = 1;
+
+ code = krb5_cc_get_principal(kcontext, cache, &princ);
+ if (code) /* Uninitialized cache file, probably. */
+ goto cleanup;
+ code = krb5_unparse_name(kcontext, princ, &princname);
+ if (code)
+ goto cleanup;
+ code = krb5_cc_get_full_name(kcontext, cache, &ccname);
+ if (code)
+ goto cleanup;
+
+ status_only = 1;
+ expired = do_ccache(cache);
+
+ printf("%-30.30s %s", princname, ccname);
+ if (expired)
+ printf(" %s", _("(Expired)"));
+ printf("\n");
+
+ status = 0;
+cleanup:
+ krb5_free_principal(kcontext, princ);
+ free(princname);
+ free(ccname);
+ return status;
+}
- if (status_only)
- /* exit_status is set back to 0 if a valid tgt is found */
- exit_status = 1;
+void
+show_all_ccaches(void)
+{
+ krb5_error_code code;
+ krb5_ccache cache;
+ krb5_cccol_cursor cursor;
+ krb5_boolean first;
+ int exit_status;
+
+ code = krb5_cccol_cursor_new(kcontext, &cursor);
+ if (code) {
+ if (!status_only)
+ com_err(progname, code, _("while listing ccache collection"));
+ exit(1);
+ }
+ exit_status = 1;
+ first = TRUE;
+ while (!(code = krb5_cccol_cursor_next(kcontext, cursor, &cache)) &&
+ cache != NULL) {
+ if (!first)
+ printf("\n");
+ first = FALSE;
+ exit_status = do_ccache(cache) && exit_status;
+ krb5_cc_close(kcontext, cache);
+ }
+ krb5_cccol_cursor_free(kcontext, &cursor);
+ exit(exit_status);
+}
+
+void
+do_ccache_name(char *name)
+{
+ krb5_error_code code;
+ krb5_ccache cache;
if (name == NULL) {
if ((code = krb5_cc_default(kcontext, &cache))) {
exit(1);
}
}
+ exit(do_ccache(cache));
+}
+
+int
+do_ccache(krb5_ccache cache)
+{
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ krb5_principal princ;
+ krb5_flags flags;
+ krb5_error_code code;
+ int exit_status = 0;
+
+ /* For status_only, exit_status is reset to 0 if a valid tgt is found. */
+ exit_status = (status_only) ? 1 : 0;
flags = 0; /* turns off OPENCLOSE mode */
if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
krb5_cc_get_type(kcontext, cache),
krb5_cc_get_name(kcontext, cache));
}
- exit(1);
+ return 1;
}
if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
if (!status_only)
com_err(progname, code, _("while retrieving principal name"));
- exit(1);
+ return 1;
}
if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
if (!status_only)
com_err(progname, code, _("while unparsing principal name"));
- exit(1);
+ return 1;
}
if (!status_only) {
printf(_("Ticket cache: %s:%s\nDefault principal: %s\n\n"),
if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
if (!status_only)
com_err(progname, code, _("while starting to retrieve tickets"));
- exit(1);
+ return 1;
}
while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
if (krb5_is_config_principal(kcontext, creds.server))
if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
if (!status_only)
com_err(progname, code, _("while finishing ticket retrieval"));
- exit(1);
+ return 1;
}
flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
if (!status_only)
com_err(progname, code, _("while closing ccache"));
- exit(1);
+ return 1;
}
#ifdef KRB5_KRB4_COMPAT
if (name == NULL && !status_only)
do_v4_ccache(0);
#endif
- exit(exit_status);
+ return exit_status;
} else {
if (!status_only)
com_err(progname, code, _("while retrieving a ticket"));
- exit(1);
+ return 1;
}
}
--- /dev/null
+mydir=clients$(S)kswitch
+BUILDTOP=$(REL)..$(S)..
+DEFS=
+
+SRCS=kswitch.c
+
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc
+##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY
+
+##WIN32##KSWITCH=$(OUTPRE)kswitch.exe
+
+##WIN32##EXERES=$(KSWITCH:.exe=.res)
+
+##WIN32##$(EXERES): $(VERSIONRC)
+##WIN32## $(RC) $(RCFLAGS) -DKSWITCH_APP -fo $@ -r $**
+
+all-unix:: kswitch
+##WIN32##all-windows:: $(KSWITCH)
+
+kswitch: kswitch.o $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o $@ kswitch.o $(KRB5_BASE_LIBS)
+
+##WIN32##$(KSWITCH): $(OUTPRE)kswitch.obj $(BUILDTOP)\util\windows\$(OUTPRE)getopt.obj $(KLIB) $(CLIB) $(EXERES)
+##WIN32## link $(EXE_LINKOPTS) -out:$@ $**
+##WIN32## $(_VC_MANIFEST_EMBED_EXE)
+
+clean-unix::
+ $(RM) kswitch.o kswitch
+
+install-unix::
+ for f in kswitch; do \
+ $(INSTALL_PROGRAM) $$f \
+ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \
+ $(INSTALL_DATA) $(srcdir)/$$f.M \
+ $(DESTDIR)$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1; \
+ done
--- /dev/null
+#
+# Generated makefile dependencies follow.
+#
+$(OUTPRE)kswitch.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/krb5/preauth_plugin.h \
+ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
+ kswitch.c
--- /dev/null
+.\" clients/kswitch/kswitch.M
+.\"
+.\" Copyright 2011 by the Massachusetts Institute of Technology.
+.\"
+.\" Export of this software from the United States of America may
+.\" require a specific license from the United States Government.
+.\" It is the responsibility of any person or organization contemplating
+.\" export to obtain such a license before exporting.
+.\"
+.\" WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+.\" distribute this software and its documentation for any purpose and
+.\" without fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright notice and
+.\" this permission notice appear in supporting documentation, and that
+.\" the name of M.I.T. not be used in advertising or publicity pertaining
+.\" to distribution of the software without specific, written prior
+.\" permission. Furthermore if you modify this software you must label
+.\" your software as modified software and not distribute it in such a
+.\" fashion that it might be confused with the original M.I.T. software.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is" without express
+.\" or implied warranty.
+.\" "
+.TH KSWITCH 1
+.SH NAME
+kswitch \- switch primary credential cache
+.SH SYNOPSIS
+\fBkswitch\fP {\fB\-c\fP \fIcachename\fP | \fB\-p\fP \fIprincipal\fP}
+.SH DESCRIPTION
+.I kswitch
+makes the specified credential cache the primary cache for the
+collection, if a cache collection is available.
+.SH OPTIONS
+.TP
+.B \-c
+.I cachename
+directly specifies the credential cache to be made primary.
+.TP
+.B \-p
+.I principal
+causes the cache collection to be searched for a cache containing
+credentials for \fIprincipal\fP. If one is found, that collection is
+made primary.
+.SH ENVIRONMENT
+.B kswitch
+uses the following environment variables:
+.TP "\w'.SM KRB5CCNAME\ \ 'u"
+.SM KRB5CCNAME
+Location of the default Kerberos 5 credentials (ticket) cache, in the
+form \fItype\fP:\fIresidual\fP. If no type prefix is present, the
+\fBFILE\fP type is assumed. The type of the default cache may
+determine the availability of a cache collection; for instance, a
+default cache of type \fBDIR\fP causes caches within the directory to
+be present in the collection.
+.SH FILES
+.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
+/tmp/krb5cc_[uid]
+default location of Kerberos 5 credentials cache
+([uid] is the decimal UID of the user).
+.SH SEE ALSO
+kinit(1), kdestroy(1), klist(1), kerberos(1)
--- /dev/null
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* clients/kswitch/kswitch.c - Switch primary credential cache */
+/*
+ * Copyright 2011 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "k5-int.h"
+
+extern int optind;
+extern char *optarg;
+
+#ifndef _WIN32
+#define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
+#else
+#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
+#endif
+
+static char *progname;
+
+static void
+usage(void)
+{
+ fprintf(stderr, _("Usage: %s {-c cache_name | -p principal}\n"), progname);
+ fprintf(stderr, _("\t-c specify name of credentials cache\n"));
+ fprintf(stderr, _("\t-p specify name of principal\n"));
+ exit(2);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ int c;
+ krb5_ccache cache = NULL;
+ krb5_principal princ = NULL;
+ const char *cache_name = NULL, *princ_name = NULL;
+ krb5_boolean errflag = FALSE;
+
+ setlocale(LC_MESSAGES, "");
+ progname = GET_PROGNAME(argv[0]);
+
+ while ((c = getopt(argc, argv, "c:p:")) != -1) {
+ switch (c) {
+ case 'c':
+ case 'p':
+ if (cache_name || princ_name) {
+ fprintf(stderr, _("Only one -c or -p option allowed\n"));
+ errflag = TRUE;
+ } else if (c == 'c') {
+ cache_name = optarg;
+ } else {
+ princ_name = optarg;
+ }
+ break;
+ case '?':
+ default:
+ errflag = TRUE;
+ break;
+ }
+ }
+
+ if (optind != argc)
+ errflag = TRUE;
+
+ if (!cache_name && !princ_name) {
+ fprintf(stderr, _("One of -c or -p must be specified\n"));
+ errflag = TRUE;
+ }
+
+ if (errflag)
+ usage();
+
+ ret = krb5_init_context(&context);
+ if (ret) {
+ com_err(progname, ret, _("while initializing krb5"));
+ exit(1);
+ }
+
+ if (cache_name) {
+ ret = krb5_cc_resolve(context, cache_name, &cache);
+ if (ret != 0) {
+ com_err(progname, ret, _("while resolving %s"), cache_name);
+ exit(1);
+ }
+ } else {
+ ret = krb5_parse_name(context, princ_name, &princ);
+ if (ret) {
+ com_err(progname, ret, _("while parsing principal name %s"),
+ princ_name);
+ exit(1);
+ }
+ ret = krb5_cc_cache_match(context, princ, &cache);
+ if (ret) {
+ com_err(progname, ret, _("while searching for ccache for %s"),
+ princ_name);
+ exit(1);
+ }
+ }
+
+ ret = krb5_cc_switch(context, cache);
+ if (ret != 0) {
+ com_err(progname, ret, _("while switching to credential cache"));
+ exit(1);
+ }
+ return 0;
+}
plugins/authdata/greet_server
clients clients/klist clients/kinit clients/kvno
- clients/kdestroy clients/kpasswd clients/ksu
+ clients/kdestroy clients/kpasswd clients/ksu clients/kswitch
kadmin kadmin/cli kadmin/dbutil kadmin/ktutil kadmin/server
kadmin/testing kadmin/testing/scripts kadmin/testing/util
{
krb5_error_code ret;
krb5_cccol_cursor cursor;
- krb5_ccache cache;
+ krb5_ccache cache = NULL;
krb5_principal princ;
char *name;
krb5_boolean eq;
$(RUNPYTEST) $(srcdir)/t_keyrollover.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_renew.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_renprinc.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_cccol.py $(PYTESTFLAGS)
clean::
$(RM) kdc.conf
--- /dev/null
+# Copyright (C) 2011 by the Massachusetts Institute of Technology.
+# All rights reserved.
+
+# Export of this software from the United States of America may
+# require a specific license from the United States Government.
+# It is the responsibility of any person or organization contemplating
+# export to obtain such a license before exporting.
+#
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of M.I.T. not be used in advertising or publicity pertaining
+# to distribution of the software without specific, written prior
+# permission. Furthermore if you modify this software you must label
+# your software as modified software and not distribute it in such a
+# fashion that it might be confused with the original M.I.T. software.
+# M.I.T. makes no representations about the suitability of
+# this software for any purpose. It is provided "as is" without express
+# or implied warranty.
+
+#!/usr/bin/python
+from k5test import *
+
+realm = K5Realm(start_kadmind=False, create_user=False, create_host=False)
+
+# Make a directory collection and use it for client commands in both realms.
+ccdir = os.path.join(realm.testdir, 'cc')
+ccname = 'DIR:' + ccdir
+os.mkdir(ccdir)
+realm.env_client['KRB5CCNAME'] = ccname
+
+realm.addprinc('alice', password('alice'))
+realm.addprinc('bob', password('bob'))
+realm.addprinc('carol', password('carol'))
+
+realm.kinit('alice', password('alice'))
+output = realm.run_as_client([klist])
+if 'Default principal: alice@' not in output:
+ fail('Initial kinit failed to get credentials for alice.')
+realm.run_as_client([kdestroy])
+output = realm.run_as_client([klist], expected_code=1)
+if 'No credentials cache found' not in output:
+ fail('Initial kdestroy failed to destroy primary cache.')
+output = realm.run_as_client([klist, '-l'], expected_code=1)
+if not output.endswith('---\n') or output.count('\n') != 2:
+ fail('Initial kdestroy failed to empty cache collection.')
+
+realm.kinit('alice', password('alice'))
+realm.kinit('carol', password('carol'))
+output = realm.run_as_client([klist, '-l'])
+if '---\ncarol@' not in output or '\nalice@' not in output:
+ fail('klist -l did not show expected output after two kinits.')
+realm.kinit('alice', password('alice'))
+output = realm.run_as_client([klist, '-l'])
+if '---\nalice@' not in output or output.count('\n') != 4:
+ fail('klist -l did not show expected output after re-kinit for alice.')
+realm.kinit('bob', password('bob'))
+output = realm.run_as_client([klist, '-A'])
+if 'bob@' not in output.splitlines()[1] or 'alice@' not in output or \
+ 'carol' not in output or output.count('Default principal:') != 3:
+ fail('klist -A did not show expected output after kinit for bob.')
+realm.run_as_client([kswitch, '-p', 'carol'])
+output = realm.run_as_client([klist, '-l'])
+if '---\ncarol@' not in output or output.count('\n') != 5:
+ fail('klist -l did not show expected output after kswitch to carol.')
+realm.run_as_client([kdestroy])
+output = realm.run_as_client([klist, '-l'])
+if 'carol@' in output or 'bob@' not in output or output.count('\n') != 4:
+ fail('kdestroy failed to remove only primary ccache.')
+realm.run_as_client([kdestroy, '-A'])
+output = realm.run_as_client([klist, '-l'], expected_code=1)
+if not output.endswith('---\n') or output.count('\n') != 2:
+ fail('kdestroy -a failed to empty cache collection.')
+
+success('Credential cache collection tests.')
- ktutil
- kinit
- klist
+ - kswitch
- kvno
- kdestroy
- kpasswd
ktutil = os.path.join(buildtop, 'kadmin', 'ktutil', 'ktutil')
kinit = os.path.join(buildtop, 'clients', 'kinit', 'kinit')
klist = os.path.join(buildtop, 'clients', 'klist', 'klist')
+kswitch = os.path.join(buildtop, 'clients', 'kswitch', 'kswitch')
kvno = os.path.join(buildtop, 'clients', 'kvno', 'kvno')
kdestroy = os.path.join(buildtop, 'clients', 'kdestroy', 'kdestroy')
kpasswd = os.path.join(buildtop, 'clients', 'kpasswd', 'kpasswd')
os.path.join('clients', 'kpasswd'),
os.path.join('clients', 'ksu'),
os.path.join('clients', 'kvno'),
+ os.path.join('clients', 'kswitch'),
'slave'
]