}
}
-/*
- * NOTE
- * - currently we only support "normal" cache types: "FILE" and "MEMORY".
- */
-
#define krb5_err_msg(code) error_message(code)
-const char *krb5_cc_type_mem = "MEMORY:";
const char *krb5_cc_type_file = "FILE:";
const char *krb5_cred_root_suffix = "lustre_root";
const char *krb5_cred_mds_suffix = "lustre_mds";
suffix, krb5_this_realm);
}
-static
-int lkrb5_check_root_tgt_cc_base(krb5_context ctx,
- krb5_ccache ccache,
- char *ccname,
- unsigned int flag,
- uint64_t self_nid)
+static int lkrb5_check_root_tgt_cc_base(krb5_context ctx, char *ccname,
+ unsigned int flag, uint64_t self_nid)
{
- krb5_ccache tgt_ccache;
- krb5_creds cred;
- krb5_principal princ;
- krb5_cc_cursor cursor;
- krb5_error_code code;
- time_t now;
- int rc = -1, found = 0;
-
- /* prepare parsing the cache file */
- code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
- if (code) {
- logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
- ccname, krb5_err_msg(code));
- return -1;
- }
+ krb5_ccache tgt_ccache;
+ krb5_creds cred;
+ krb5_principal princ;
+ krb5_cc_cursor cursor;
+ krb5_error_code code;
+ time_t now;
+ int rc = -1, found = 0;
+
+ /* prepare parsing the cache file */
+ code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
+ if (code) {
+ logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
+ ccname, krb5_err_msg(code));
+ return -1;
+ }
- /* checks the principal */
- code = krb5_cc_get_principal(ctx, tgt_ccache, &princ);
- if (code) {
- logmsg(LL_ERR, "get cc principal: %s\n", krb5_err_msg(code));
- goto out_cc;
- }
+ /* checks the principal */
+ code = krb5_cc_get_principal(ctx, tgt_ccache, &princ);
+ if (code) {
+ logmsg(LL_ERR, "get cc principal: %s\n", krb5_err_msg(code));
+ goto out_cc;
+ }
if (lkrb5_cc_check_tgt_princ(ctx, tgt_ccache, princ, flag, self_nid))
goto out_princ;
- /*
- * find a valid entry
- */
- code = krb5_cc_start_seq_get(ctx, tgt_ccache, &cursor);
- if (code) {
- logmsg(LL_ERR, "start cc iteration: %s\n", krb5_err_msg(code));
- goto out_princ;
- }
+ /*
+ * find a valid entry
+ */
+ code = krb5_cc_start_seq_get(ctx, tgt_ccache, &cursor);
+ if (code) {
+ logmsg(LL_ERR, "start cc iteration: %s\n", krb5_err_msg(code));
+ goto out_princ;
+ }
- now = time(0);
- do {
- krb5_timestamp duration, delta;
+ now = time(0);
+ do {
+ krb5_timestamp duration, delta;
- code = krb5_cc_next_cred(ctx, tgt_ccache, &cursor, &cred);
- if (code != 0)
- break;
+ code = krb5_cc_next_cred(ctx, tgt_ccache, &cursor, &cred);
+ if (code != 0)
+ break;
- logmsg(LL_DEBUG, "cred: server realm %.*s, type %d, name %.*s; "
- "time (%lld-%lld, renew till %lld), valid %lld\n",
+ logmsg(LL_DEBUG,
+ "cred: server realm %.*s, type %d, name %.*s; time (%lld-%lld, renew till %lld), valid %lld\n",
krb5_princ_realm(ctx, cred.server)->length,
krb5_princ_realm(ctx, cred.server)->data,
krb5_princ_type(ctx, cred.server),
(long long)cred.times.renew_till,
(long long)(cred.times.endtime - now));
- /* FIXME
- * we found the princ type is always 0 (KRB5_NT_UNKNOWN), why???
- */
-
- /* FIXME how about inter-realm TGT??? FIXME */
- if (lgss_krb5_strcasecmp(krb5_princ_name(ctx, cred.server),
- "krbtgt"))
- continue;
-
- if (lgss_krb5_strcasecmp(krb5_princ_realm(ctx, cred.server),
- krb5_this_realm))
- continue;
-
- /* check validity of time */
- delta = 60 * 30; /* half an hour */
- duration = cred.times.endtime - cred.times.starttime;
- if (duration / 4 < delta)
- delta = duration / 4;
-
- if (cred.times.starttime <= now &&
- cred.times.endtime >= now + delta) {
- found = 1;
- break;
- }
- } while (1);
-
- if (!found) {
- logmsg(LL_DEBUG, "doesn't find good TGT cache\n");
- goto out_seq;
- }
-
- /* found a good cred, store it into @ccache */
- logmsg(LL_DEBUG, "found good TGT cache\n");
-
- code = krb5_cc_initialize(ctx, ccache, princ);
- if (code) {
- logmsg(LL_ERR, "init private cc: %s\n", krb5_err_msg(code));
- goto out_seq;
- }
-
- code = krb5_cc_store_cred(ctx, ccache, &cred);
- if (code) {
- logmsg(LL_ERR, "store private cred: %s\n", krb5_err_msg(code));
- goto out_seq;
- }
+ /* FIXME
+ * we found the princ type is always 0 (KRB5_NT_UNKNOWN), why???
+ */
+
+ /* FIXME how about inter-realm TGT??? FIXME */
+ if (lgss_krb5_strcasecmp(krb5_princ_name(ctx, cred.server),
+ "krbtgt"))
+ continue;
+
+ if (lgss_krb5_strcasecmp(krb5_princ_realm(ctx, cred.server),
+ krb5_this_realm))
+ continue;
+
+ /* check validity of time */
+ delta = 60 * 30; /* half an hour */
+ duration = cred.times.endtime - cred.times.starttime;
+ if (duration / 4 < delta)
+ delta = duration / 4;
+
+ if (cred.times.starttime <= now &&
+ cred.times.endtime >= now + delta) {
+ found = 1;
+ break;
+ }
+ } while (1);
- logmsg(LL_DEBUG, "store private ccache OK\n");
- rc = 0;
+ if (!found) {
+ logmsg(LL_DEBUG, "doesn't find good TGT cache\n");
+ goto out_seq;
+ }
+ logmsg(LL_DEBUG, "found good TGT cache\n");
+ rc = 0;
out_seq:
- krb5_cc_end_seq_get(ctx, tgt_ccache, &cursor);
+ krb5_cc_end_seq_get(ctx, tgt_ccache, &cursor);
out_princ:
- krb5_free_principal(ctx, princ);
+ krb5_free_principal(ctx, princ);
out_cc:
- krb5_cc_close(ctx, tgt_ccache);
+ krb5_cc_close(ctx, tgt_ccache);
- return rc;
+ return rc;
}
/**
* find out whether current TGT cache is valid or not
*/
-static
-int lkrb5_check_root_tgt_cc(krb5_context ctx,
- krb5_ccache ccache,
- unsigned int root_flags,
- uint64_t self_nid)
+static int lkrb5_check_root_tgt_cc(krb5_context ctx, unsigned int root_flags,
+ uint64_t self_nid)
{
- struct stat statbuf;
- unsigned int flag;
- char ccname[1024];
- char *ccfile;
- int i, rc;
-
- for (i = 0; i < LGSS_ROOT_CRED_NR; i++) {
- flag = 1 << i;
-
- if ((root_flags & flag) == 0)
- continue;
-
- get_root_tgt_ccname(ccname, sizeof(ccname), flag);
- logmsg(LL_DEBUG, "root krb5 TGT ccname: %s\n", ccname);
-
- /* currently we only support type "FILE", firstly make sure
- * the cache file is there */
- ccfile = ccname + strlen(krb5_cc_type);
- if (stat(ccfile, &statbuf)) {
- logmsg(LL_DEBUG, "krb5 cc %s: %s\n",
- ccname, strerror(errno));
- continue;
- }
+ char ccname[PATH_MAX];
+ struct stat statbuf;
+ unsigned int flag;
+ char *ccfile;
+ int i, rc;
+
+ for (i = 0; i < LGSS_ROOT_CRED_NR; i++) {
+ flag = 1 << i;
+
+ if ((root_flags & flag) == 0)
+ continue;
+
+ get_root_tgt_ccname(ccname, sizeof(ccname), flag);
+ logmsg(LL_DEBUG, "root krb5 TGT ccname: %s\n", ccname);
+
+ /* currently we only support type "FILE", firstly make sure
+ * the cache file is there
+ */
+ ccfile = ccname + strlen(krb5_cc_type);
+ if (stat(ccfile, &statbuf)) {
+ logmsg(LL_DEBUG, "krb5 cc %s: %s\n",
+ ccname, strerror(errno));
+ continue;
+ }
- rc = lkrb5_check_root_tgt_cc_base(ctx, ccache, ccname, flag,
- self_nid);
- if (rc == 0)
- return 0;
- }
+ rc = lkrb5_check_root_tgt_cc_base(ctx, ccname, flag, self_nid);
+ if (rc == 0)
+ return lgss_krb5_set_ccache_name(ccname);
+ }
- logmsg(LL_TRACE, "doesn't find a valid tgt cc\n");
- return -1;
+ logmsg(LL_TRACE, "doesn't find a valid tgt cc\n");
+ return -1;
}
-static
-int lkrb5_get_root_tgt_keytab(krb5_context ctx,
- krb5_ccache ccache,
- krb5_keytab kt,
- krb5_principal princ,
- const char *ccname)
+static int lkrb5_get_root_tgt_keytab(krb5_context ctx, krb5_keytab kt,
+ krb5_principal princ, const char *ccname)
{
- krb5_get_init_creds_opt opts;
- krb5_creds cred;
- krb5_ccache tgt_ccache;
- krb5_error_code code;
- int rc = -1;
-
- krb5_get_init_creds_opt_init(&opts);
- krb5_get_init_creds_opt_set_address_list(&opts, NULL);
- /*
- * by default krb5 library obtain ticket with lifetime shorter
- * than the max value. we can change it here if we want. but
- * seems not necessary now.
- *
- krb5_get_init_creds_opt_set_tkt_life(&opts, very-long-time);
- *
- */
-
- /*
- * obtain TGT and store into global ccache
- */
- code = krb5_get_init_creds_keytab(ctx, &cred, princ, kt,
- 0, NULL, &opts);
- if (code) {
- logmsg(LL_ERR, "failed to get root TGT for "
- "principal %.*s: %s\n",
- krb5_princ_name(ctx, princ)->length,
- krb5_princ_name(ctx, princ)->data,
- krb5_err_msg(code));
- return -1;
- }
-
- code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
- if (code) {
- logmsg(LL_ERR, "resolve cc %s: %s\n",
- ccname, krb5_err_msg(code));
- goto out_cred;
- }
+ krb5_get_init_creds_opt opts;
+ krb5_creds cred;
+ krb5_ccache tgt_ccache;
+ krb5_error_code code;
+ int rc = -1;
+
+ krb5_get_init_creds_opt_init(&opts);
+ krb5_get_init_creds_opt_set_address_list(&opts, NULL);
+ /*
+ * by default krb5 library obtain ticket with lifetime shorter
+ * than the max value. we can change it here if we want. but
+ * seems not necessary now.
+ *
+ * krb5_get_init_creds_opt_set_tkt_life(&opts, very-long-time);
+ *
+ */
+
+ /*
+ * obtain TGT and store into cache
+ */
+ code = krb5_get_init_creds_keytab(ctx, &cred, princ, kt,
+ 0, NULL, &opts);
+ if (code) {
+ logmsg(LL_ERR,
+ "failed to get root TGT for principal %.*s: %s\n",
+ krb5_princ_name(ctx, princ)->length,
+ krb5_princ_name(ctx, princ)->data,
+ krb5_err_msg(code));
+ return -1;
+ }
- code = krb5_cc_initialize(ctx, tgt_ccache, princ);
- if (code) {
- logmsg(LL_ERR, "initialize cc %s: %s\n",
- ccname, krb5_err_msg(code));
- goto out_cc;
- }
+ code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
+ if (code) {
+ logmsg(LL_ERR, "resolve cc %s: %s\n",
+ ccname, krb5_err_msg(code));
+ goto out_cred;
+ }
- code = krb5_cc_store_cred(ctx, tgt_ccache, &cred);
- if (code) {
- logmsg(LL_ERR, "store cred to cc %s: %s\n",
- ccname, krb5_err_msg(code));
- goto out_cc;
- }
+ code = krb5_cc_initialize(ctx, tgt_ccache, princ);
+ if (code) {
+ logmsg(LL_ERR, "initialize cc %s: %s\n",
+ ccname, krb5_err_msg(code));
+ goto out_cc;
+ }
- logmsg(LL_INFO, "installed TGT of %.*s in cc %s\n",
- krb5_princ_name(ctx, princ)->length,
- krb5_princ_name(ctx, princ)->data,
- ccname);
+ code = krb5_cc_store_cred(ctx, tgt_ccache, &cred);
+ if (code) {
+ logmsg(LL_ERR, "store cred to cc %s: %s\n",
+ ccname, krb5_err_msg(code));
+ goto out_cc;
+ }
- /*
- * now store the cred into my own cc too
- */
- code = krb5_cc_initialize(ctx, ccache, princ);
- if (code) {
- logmsg(LL_ERR, "init mem cc: %s\n", krb5_err_msg(code));
- goto out_cc;
- }
+ logmsg(LL_INFO, "installed TGT of %.*s in cc %s\n",
+ krb5_princ_name(ctx, princ)->length,
+ krb5_princ_name(ctx, princ)->data,
+ ccname);
- code = krb5_cc_store_cred(ctx, ccache, &cred);
- if (code) {
- logmsg(LL_ERR, "store mm cred: %s\n", krb5_err_msg(code));
- goto out_cc;
- }
+ rc = lgss_krb5_set_ccache_name(ccname);
- logmsg(LL_DEBUG, "stored TGT into mem cc OK\n");
- rc = 0;
out_cc:
- krb5_cc_close(ctx, tgt_ccache);
+ krb5_cc_close(ctx, tgt_ccache);
out_cred:
- krb5_free_cred_contents(ctx, &cred);
- return rc;
+ krb5_free_cred_contents(ctx, &cred);
+ return rc;
}
/*
* obtain a new root TGT
*/
-static
-int lkrb5_refresh_root_tgt_cc(krb5_context ctx,
- krb5_ccache ccache,
- unsigned int root_flags,
- uint64_t self_nid)
+static int lkrb5_refresh_root_tgt_cc(krb5_context ctx, unsigned int root_flags,
+ uint64_t self_nid)
{
- krb5_keytab kt;
- krb5_keytab_entry kte;
- krb5_kt_cursor cursor;
- krb5_principal princ = NULL;
- krb5_error_code code;
- char ccname[1024];
- unsigned int flag = 0;
- int rc = -1;
-
- /* prepare parsing the keytab file */
- code = krb5_kt_resolve(ctx, krb5_keytab_file, &kt);
- if (code) {
- logmsg(LL_ERR, "resolve keytab %s: %s\n",
- krb5_keytab_file, krb5_err_msg(code));
- return -1;
- }
+ krb5_keytab kt;
+ krb5_keytab_entry kte;
+ krb5_kt_cursor cursor;
+ krb5_principal princ = NULL;
+ krb5_error_code code;
+ char ccname[1024];
+ unsigned int flag = 0;
+ int rc = -1;
+
+ /* prepare parsing the keytab file */
+ code = krb5_kt_resolve(ctx, krb5_keytab_file, &kt);
+ if (code) {
+ logmsg(LL_ERR, "resolve keytab %s: %s\n",
+ krb5_keytab_file, krb5_err_msg(code));
+ return -1;
+ }
- code = krb5_kt_start_seq_get(ctx, kt, &cursor);
- if (code) {
- logmsg(LL_ERR, "start kt iteration: %s\n", krb5_err_msg(code));
- goto out_kt;
- }
+ code = krb5_kt_start_seq_get(ctx, kt, &cursor);
+ if (code) {
+ logmsg(LL_ERR, "start kt iteration: %s\n", krb5_err_msg(code));
+ goto out_kt;
+ }
/* iterate keytab to find proper an entry */
- do {
- krb5_data *princname;
-
- code = krb5_kt_next_entry(ctx, kt, &kte, &cursor);
- if (code != 0)
- break;
-
- logmsg(LL_TRACE, "kt entry: realm %.*s, type %d, "
- "size %d, name %.*s\n",
- krb5_princ_realm(ctx, kte.principal)->length,
- krb5_princ_realm(ctx, kte.principal)->data,
- krb5_princ_type(ctx, kte.principal),
- krb5_princ_size(ctx, kte.principal),
- krb5_princ_name(ctx, kte.principal)->length,
- krb5_princ_name(ctx, kte.principal)->data);
-
- if (!princ_is_local_realm(ctx, kte.principal))
- continue;
-
- princname = krb5_princ_name(ctx, kte.principal);
-
- if ((root_flags & LGSS_ROOT_CRED_ROOT) != 0 &&
- lgss_krb5_strcmp(princname, LGSS_USR_ROOT_STR) == 0) {
- flag = LGSS_ROOT_CRED_ROOT;
- } else if ((root_flags & LGSS_ROOT_CRED_MDT) != 0 &&
- lgss_krb5_strcmp(princname, LGSS_SVC_MDS_STR) == 0) {
- flag = LGSS_ROOT_CRED_MDT;
- } else if ((root_flags & LGSS_ROOT_CRED_OST) != 0 &&
- lgss_krb5_strcmp(princname, LGSS_SVC_OSS_STR) == 0) {
- flag = LGSS_ROOT_CRED_OST;
- } else {
- logmsg(LL_TRACE, "not what we want, skip\n");
- continue;
- }
+ do {
+ krb5_data *princname;
+
+ code = krb5_kt_next_entry(ctx, kt, &kte, &cursor);
+ if (code != 0)
+ break;
+
+ logmsg(LL_TRACE,
+ "kt entry: realm %.*s, type %d, size %d, name %.*s\n",
+ krb5_princ_realm(ctx, kte.principal)->length,
+ krb5_princ_realm(ctx, kte.principal)->data,
+ krb5_princ_type(ctx, kte.principal),
+ krb5_princ_size(ctx, kte.principal),
+ krb5_princ_name(ctx, kte.principal)->length,
+ krb5_princ_name(ctx, kte.principal)->data);
+
+ if (!princ_is_local_realm(ctx, kte.principal))
+ continue;
+
+ princname = krb5_princ_name(ctx, kte.principal);
+
+ if ((root_flags & LGSS_ROOT_CRED_ROOT) != 0 &&
+ lgss_krb5_strcmp(princname, LGSS_USR_ROOT_STR) == 0) {
+ flag = LGSS_ROOT_CRED_ROOT;
+ } else if ((root_flags & LGSS_ROOT_CRED_MDT) != 0 &&
+ lgss_krb5_strcmp(princname, LGSS_SVC_MDS_STR) == 0) {
+ flag = LGSS_ROOT_CRED_MDT;
+ } else if ((root_flags & LGSS_ROOT_CRED_OST) != 0 &&
+ lgss_krb5_strcmp(princname, LGSS_SVC_OSS_STR) == 0) {
+ flag = LGSS_ROOT_CRED_OST;
+ } else {
+ logmsg(LL_TRACE, "not what we want, skip\n");
+ continue;
+ }
- if (krb5_princ_component(ctx, kte.principal, 1) == NULL) {
- if (flag != LGSS_ROOT_CRED_ROOT) {
- logmsg(LL_TRACE, "no hostname, skip\n");
- continue;
- }
+ if (krb5_princ_component(ctx, kte.principal, 1) == NULL) {
+ if (flag != LGSS_ROOT_CRED_ROOT) {
+ logmsg(LL_TRACE, "no hostname, skip\n");
+ continue;
+ }
} else {
if (svc_princ_verify_host(ctx, kte.principal, self_nid,
LL_TRACE)) {
}
}
- code = krb5_copy_principal(ctx, kte.principal, &princ);
- if (code) {
- logmsg(LL_ERR, "copy princ: %s\n", krb5_err_msg(code));
- continue;
- }
+ code = krb5_copy_principal(ctx, kte.principal, &princ);
+ if (code) {
+ logmsg(LL_ERR, "copy princ: %s\n", krb5_err_msg(code));
+ continue;
+ }
- lassert(princ != NULL);
- break;
- } while (1);
+ lassert(princ != NULL);
+ break;
+ } while (1);
- krb5_kt_end_seq_get(ctx, kt, &cursor);
+ krb5_kt_end_seq_get(ctx, kt, &cursor);
- if (princ == NULL) {
- logmsg(LL_ERR, "can't find proper keytab entry\n");
- goto out_kt;
- }
+ if (princ == NULL) {
+ logmsg(LL_ERR, "can't find proper keytab entry\n");
+ goto out_kt;
+ }
- /* obtain root TGT */
- get_root_tgt_ccname(ccname, sizeof(ccname), flag);
- rc = lkrb5_get_root_tgt_keytab(ctx, ccache, kt, princ, ccname);
+ /* obtain root TGT */
+ get_root_tgt_ccname(ccname, sizeof(ccname), flag);
+ rc = lkrb5_get_root_tgt_keytab(ctx, kt, princ, ccname);
- krb5_free_principal(ctx, princ);
+ krb5_free_principal(ctx, princ);
out_kt:
- krb5_kt_close(ctx, kt);
- return rc;
+ krb5_kt_close(ctx, kt);
+ return rc;
}
-static
-int lkrb5_prepare_root_cred(struct lgss_cred *cred)
+static int lkrb5_prepare_root_cred(struct lgss_cred *cred)
{
- krb5_context ctx;
- krb5_ccache ccache;
- krb5_error_code code;
- struct lgss_krb5_cred *kcred;
- int rc = -1;
-
- lassert(krb5_this_realm != NULL);
-
- kcred = (struct lgss_krb5_cred *) cred->lc_mech_cred;
-
- /* compose the memory cc name, since the only user is myself,
- * the name could be fixed */
- snprintf(kcred->kc_ccname, sizeof(kcred->kc_ccname),
- "%s/self", krb5_cc_type_mem);
- logmsg(LL_TRACE, "private cc: %s\n", kcred->kc_ccname);
+ krb5_context ctx;
+ krb5_error_code code;
+ int rc = -1;
- code = krb5_init_context(&ctx);
- if (code) {
- logmsg(LL_ERR, "initialize krb5 context: %s\n",
- krb5_err_msg(code));
- return -1;
- }
+ lassert(krb5_this_realm != NULL);
- code = krb5_cc_resolve(ctx, kcred->kc_ccname, &ccache);
- if (code) {
- logmsg(LL_ERR, "resolve krb5 cc %s: %s\n",
- kcred->kc_ccname, krb5_err_msg(code));
- goto out_ctx;
- }
-
- /*
- * search and/or obtain root TGT credential.
- * it touched global (on-disk) tgt cache, do it inside mutex locking
- */
- lgss_krb5_mutex_lock();
+ code = krb5_init_context(&ctx);
+ if (code) {
+ logmsg(LL_ERR, "initialize krb5 context: %s\n",
+ krb5_err_msg(code));
+ return -1;
+ }
- rc = lkrb5_check_root_tgt_cc(ctx, ccache, cred->lc_root_flags,
+ /*
+ * search and/or obtain root TGT credential.
+ * it touched global (on-disk) tgt cache, do it inside mutex locking
+ */
+ lgss_krb5_mutex_lock();
+ rc = lkrb5_check_root_tgt_cc(ctx, cred->lc_root_flags,
cred->lc_self_nid);
if (rc != 0)
- rc = lkrb5_refresh_root_tgt_cc(ctx, ccache,
- cred->lc_root_flags,
+ rc = lkrb5_refresh_root_tgt_cc(ctx, cred->lc_root_flags,
cred->lc_self_nid);
- if (rc == 0)
- rc = lgss_krb5_set_ccache_name(kcred->kc_ccname);
+ lgss_krb5_mutex_unlock();
+ krb5_free_context(ctx);
- lgss_krb5_mutex_unlock();
-
- krb5_cc_close(ctx, ccache);
-out_ctx:
- krb5_free_context(ctx);
-
- logmsg(LL_DEBUG, "prepare root credentail %s\n", rc ? "failed" : "OK");
- return rc;
+ logmsg(LL_DEBUG, "prepare root credentail %s\n", rc ? "failed" : "OK");
+ return rc;
}
static