#include <CoreFoundation/CoreFoundation.h>
#include <Kerberos/Kerberos.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
const char *program = NULL;
const char *cacheName = NULL;
const char *principalName = NULL;
static int options (int argc, char * const * argv);
static int usage (void);
static void printiferr (errcode_t err, const char *format, ...);
static void printerr (const char *format, ...);
static void vprinterr (const char *format, va_list args);
int main (int argc, char * const * argv)
{
int err = 0;
program = strrchr (argv[0], '/') ? strrchr (argv[0], '/') + 1 : argv[0];
if (!err) {
err = options (argc, argv);
}
if (cacheName) {
cc_context_t context = NULL;
cc_ccache_t cache = NULL;
if (!err) {
err = cc_initialize (&context, ccapi_version_4, nil, nil);
printiferr (err, "while initializing credentials cache");
}
if (!err) {
err = cc_context_open_ccache (context, cacheName, &cache);
printiferr(err, "while opening credentials cache '%s'\n", cacheName);
}
if (!err) {
err = cc_ccache_set_default (cache);
printiferr (err, "while setting ccache '%s' to the system default", cacheName);
}
if (cache ) { cc_ccache_release (cache); }
if (context) { cc_context_release (context); }
} else if (principalName) {
KLPrincipal principal = NULL;
if (!err) {
err = KLCreatePrincipalFromString (principalName, kerberosVersion_V5, &principal);
printiferr (err, "while creating KLPrincipal for '%s'", principalName);
}
if (!err) {
err = KLSetSystemDefaultCache (principal);
printiferr (err, "while setting the cache for principal '%s' to the system default",
principalName);
}
if (principal) { KLDisposePrincipal (principal); }
}
return err ? 1 : 0;
}
static int options (int argc, char * const * argv)
{
int option;
while ((option = getopt (argc, argv, "c:p:")) != -1) {
switch (option) {
case 'c':
if (cacheName) {
printerr ("Only one -c option allowed\n");
return usage ();
}
cacheName = optarg;
if (strncmp (cacheName, "API:", 4) == 0) {
if (strlen (cacheName) > 4) {
cacheName += 4;
} else {
printerr ("Invalid cache name '%s'\n", cacheName);
return usage ();
}
}
break;
case 'p':
if (principalName) {
printerr ("Only one -p option allowed\n");
return usage ();
}
principalName = optarg;
break;
default:
return usage ();
}
}
if (cacheName && principalName) {
printerr ("Only one of -c or -p allowed\n");
return usage ();
}
if (!cacheName && !principalName) {
printerr ("One of -c or -p must be specified\n");
return usage ();
}
if (argc - optind > 0) {
printerr ("Unknown option '%s'\n", argv[optind]);
return usage ();
}
return 0;
}
static int usage (void)
{
fprintf (stderr, "Usage: %s [-c cache_name | -p principal]\n", program);
fprintf (stderr, "\t-c specify name of credentials cache\n");
fprintf (stderr, "\t-p specify name of principal (Kerberos 5 format)\n");
return 2;
}
static void printiferr (errcode_t err, const char *format, ...)
{
if (err && (err != ccIteratorEnd) && (err != KRB5_CC_END)) {
va_list pvar;
va_start (pvar, format);
com_err_va (program, err, format, pvar);
va_end (pvar);
}
}
static void printerr (const char *format, ...)
{
va_list pvar;
va_start (pvar, format);
vprinterr (format, pvar);
va_end (pvar);
}
static void vprinterr (const char *format, va_list args)
{
fprintf (stderr, "%s: ", program);
vfprintf (stderr, format, args);
}