/*==========================*/
static int select_krb5_ccache(const struct dirent *d);
-static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d);
+static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
+ struct dirent **d);
static int gssd_get_single_krb5_cred(krb5_context context,
krb5_keytab kt, struct gssd_k5_kt_princ *ple);
}
/*
- * Look in the ccachedir for files that look like they
+ * Look in directory "dirname" for files that look like they
* are Kerberos Credential Cache files for a given UID. Return
* non-zero and the dirent pointer for the entry most likely to be
* what we want. Otherwise, return zero and no dirent pointer.
* 1 => found an existing entry
*/
static int
-gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
+gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
{
struct dirent **namelist;
int n;
memset(&best_match_stat, 0, sizeof(best_match_stat));
*d = NULL;
- n = scandir(ccachedir, &namelist, select_krb5_ccache, 0);
+ n = scandir(dirname, &namelist, select_krb5_ccache, 0);
if (n < 0) {
- perror("scandir looking for krb5 credentials caches");
+ printerr(1, "Error doing scandir on directory '%s': %s\n",
+ dirname, strerror(errno));
}
else if (n > 0) {
char statname[1024];
printerr(3, "CC file '%s' being considered\n",
namelist[i]->d_name);
snprintf(statname, sizeof(statname),
- "%s/%s", ccachedir, namelist[i]->d_name);
+ "%s/%s", dirname, namelist[i]->d_name);
if (lstat(statname, &tmp_stat)) {
printerr(0, "Error doing stat on file '%s'\n",
statname);
u_int maj_stat, min_stat;
gss_cred_id_t credh;
gss_OID_set_desc desired_mechs;
- krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
+ krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5,
+ ENCTYPE_DES_CBC_MD4 };
int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
/* We only care about getting a krb5 cred */
&credh, NULL, NULL);
if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_acquire_cred",
- maj_stat, min_stat, &krb5oid);
+ if (get_verbosity() > 0)
+ pgsserr("gss_acquire_cred",
+ maj_stat, min_stat, &krb5oid);
return -1;
}
krb5_keytab kt,
struct gssd_k5_kt_princ *ple)
{
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
+ krb5_get_init_creds_opt *init_opts = NULL;
+#else
krb5_get_init_creds_opt options;
+#endif
+ krb5_get_init_creds_opt *opts;
krb5_creds my_creds;
krb5_ccache ccache = NULL;
char kt_name[BUFSIZ];
if ((krb5_unparse_name(context, ple->princ, &pname)))
pname = NULL;
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
+ code = krb5_get_init_creds_opt_alloc(context, &init_opts);
+ if (code) {
+ printerr(0, "ERROR: %s allocating gic options\n",
+ gssd_k5_err_msg(context, code));
+ goto out;
+ }
+ if (krb5_get_init_creds_opt_set_addressless(context, init_opts, 1))
+ printerr(0, "WARNING: Unable to set option for addressless "
+ "tickets. May have problems behind a NAT.\n");
+#ifdef TEST_SHORT_LIFETIME
+ /* set a short lifetime (for debugging only!) */
+ printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
+ krb5_get_init_creds_opt_set_tkt_life(init_opts, 5*60);
+#endif
+ opts = init_opts;
+
+#else /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS */
+
krb5_get_init_creds_opt_init(&options);
krb5_get_init_creds_opt_set_address_list(&options, NULL);
-
#ifdef TEST_SHORT_LIFETIME
/* set a short lifetime (for debugging only!) */
printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
krb5_get_init_creds_opt_set_tkt_life(&options, 5*60);
#endif
+ opts = &options;
+#endif
+
if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ,
- kt, 0, NULL, &options))) {
+ kt, 0, NULL, opts))) {
printerr(0, "WARNING: %s while getting initial ticket for "
"principal '%s' using keytab '%s'\n",
gssd_k5_err_msg(context, code),
cache_type = "FILE";
snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s",
cache_type,
- GSSD_DEFAULT_CRED_DIR, GSSD_DEFAULT_CRED_PREFIX,
+ ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX,
GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
ple->endtime = my_creds.times.endtime;
if (ple->ccname != NULL)
printerr(2, "Successfully obtained machine credentials for "
"principal '%s' stored in ccache '%s'\n", pname, cc_name);
out:
+#if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
+ if (init_opts)
+ krb5_get_init_creds_opt_free(context, init_opts);
+#endif
if (pname)
k5_free_unparsed_name(context, pname);
if (ccache)
* do the best we can.
*
* Returns:
- * void
+ * 0 => a ccache was found
+ * 1 => no ccache was found
*/
-void
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
+int
+gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
{
char buf[MAX_NETOBJ_SZ];
struct dirent *d;
printerr(2, "getting credentials for client with uid %u for "
"server %s\n", uid, servername);
memset(buf, 0, sizeof(buf));
- if (gssd_find_existing_krb5_ccache(uid, &d)) {
- snprintf(buf, sizeof(buf), "FILE:%s/%s",
- ccachedir, d->d_name);
+ if (gssd_find_existing_krb5_ccache(uid, dirname, &d)) {
+ snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
free(d);
}
else
- snprintf(buf, sizeof(buf), "FILE:%s/%s%u",
- ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
+ return 1;
printerr(2, "using %s as credentials cache for client with "
"uid %u for server %s\n", buf, uid, servername);
gssd_set_krb5_ccache_name(buf);
+ return 0;
}
/*