rq_auth_remote:1, /* authed as remote user */
rq_auth_usr_root:1, /* authed as root */
rq_auth_usr_mdt:1, /* authed as mdt */
+ rq_auth_usr_ost:1, /* authed as ost */
/* security tfm flags */
rq_pack_udesc:1,
rq_pack_bulk:1,
/* gss hdr */
ghdr = lustre_msg_buf(msg, 0, sizeof(*ghdr));
ghdr->gh_version = PTLRPC_GSS_VERSION;
+ ghdr->gh_sp = (__u8) imp->imp_sec->ps_part;
ghdr->gh_flags = 0;
ghdr->gh_proc = PTLRPC_GSS_PROC_INIT;
ghdr->gh_seq = 0;
uid_t gsc_mapped_uid;
unsigned int gsc_usr_root:1,
gsc_usr_mds:1,
+ gsc_usr_oss:1,
gsc_remote:1,
gsc_reverse:1;
};
/* update reverse handle for root user */
sec2gsec(sec)->gs_rvs_hdl = gss_get_next_ctx_index();
- co_flags = "r";
+ switch (sec->ps_part) {
+ case LUSTRE_SP_MDT:
+ co_flags = "m";
+ break;
+ case LUSTRE_SP_OST:
+ co_flags = "o";
+ break;
+ case LUSTRE_SP_MGC:
+ co_flags = "rmo";
+ break;
+ case LUSTRE_SP_CLI:
+ co_flags = "r";
+ break;
+ case LUSTRE_SP_MGS:
+ default:
+ LBUG();
+ }
}
/* in case of setuid, key will be constructed as owner of fsuid/fsgid,
}
rsci.ctx.gsc_usr_mds = (tmp_int != 0);
+ /* oss user flag */
+ rv = get_int(&mesg, &tmp_int);
+ if (rv) {
+ CERROR("fail to get oss user flag\n");
+ goto out;
+ }
+ rsci.ctx.gsc_usr_oss = (tmp_int != 0);
+
/* mapped uid */
rv = get_int(&mesg, (int *) &rsci.ctx.gsc_mapped_uid);
if (rv) {
}
rsci.ctx.gsc_usr_mds = (tmp_int != 0);
+ /* oss user flag */
+ rv = get_int(&mesg, &tmp_int);
+ if (rv) {
+ CERROR("fail to get oss user flag\n");
+ goto out;
+ }
+ rsci.ctx.gsc_usr_oss = (tmp_int != 0);
+
/* mapped uid */
rv = get_int(&mesg, (int *) &rsci.ctx.gsc_mapped_uid);
if (rv) {
}
rsci.h.expiry_time = (time_t) ctx_expiry;
- /* FIXME */
- rsci.ctx.gsc_usr_root = 1;
- rsci.ctx.gsc_usr_mds= 1;
- rsci.ctx.gsc_reverse = 1;
+ if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0)
+ rsci.ctx.gsc_usr_mds = 1;
+ else if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0)
+ rsci.ctx.gsc_usr_oss = 1;
+ else
+ rsci.ctx.gsc_usr_root = 1;
rscp = rsc_update(&rsci, rscp);
if (rscp == NULL)
}
rsci.h.expiry_time = (time_t) ctx_expiry;
- /* FIXME */
- rsci.ctx.gsc_usr_root = 1;
- rsci.ctx.gsc_usr_mds= 1;
- rsci.ctx.gsc_reverse = 1;
+ if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0)
+ rsci.ctx.gsc_usr_mds = 1;
+ else if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0)
+ rsci.ctx.gsc_usr_oss = 1;
+ else
+ rsci.ctx.gsc_usr_root = 1;
rscp = rsc_lookup(&rsci, 1);
if (rscp == NULL) {
if (rc != SECSVC_OK)
RETURN(rc);
- if (grctx->src_ctx->gsc_usr_mds || grctx->src_ctx->gsc_usr_root)
+ if (grctx->src_ctx->gsc_usr_mds || grctx->src_ctx->gsc_usr_oss ||
+ grctx->src_ctx->gsc_usr_root)
CWARN("create svc ctx %p: user from %s authenticated as %s\n",
grctx->src_ctx, libcfs_nid2str(req->rq_peer.nid),
- grctx->src_ctx->gsc_usr_mds ? "mds" : "root");
+ grctx->src_ctx->gsc_usr_mds ? "mds" :
+ (grctx->src_ctx->gsc_usr_oss ? "oss" : "root"));
else
CWARN("create svc ctx %p: accept user %u from %s\n",
grctx->src_ctx, grctx->src_ctx->gsc_uid,
req->rq_auth_gss = 1;
req->rq_auth_remote = grctx->src_ctx->gsc_remote;
req->rq_auth_usr_mdt = grctx->src_ctx->gsc_usr_mds;
+ req->rq_auth_usr_ost = grctx->src_ctx->gsc_usr_oss;
req->rq_auth_usr_root = grctx->src_ctx->gsc_usr_root;
req->rq_auth_uid = grctx->src_ctx->gsc_uid;
req->rq_auth_mapped_uid = grctx->src_ctx->gsc_mapped_uid;
struct ptlrpc_cli_ctx *newctx)
{
struct sptlrpc_flavor old_flvr;
- char *reqmsg;
+ char *reqmsg = NULL; /* to workaround old gcc */
int reqmsg_size;
- int rc;
+ int rc = 0;
LASSERT(req->rq_reqmsg);
LASSERT(req->rq_reqlen);
/* save request message */
reqmsg_size = req->rq_reqlen;
- OBD_ALLOC(reqmsg, reqmsg_size);
- if (reqmsg == NULL)
- return -ENOMEM;
- memcpy(reqmsg, req->rq_reqmsg, reqmsg_size);
+ if (reqmsg_size != 0) {
+ OBD_ALLOC(reqmsg, reqmsg_size);
+ if (reqmsg == NULL)
+ return -ENOMEM;
+ memcpy(reqmsg, req->rq_reqmsg, reqmsg_size);
+ }
/* release old req/rep buf */
req->rq_cli_ctx = oldctx;
/* alloc new request buffer
* we don't need to alloc reply buffer here, leave it to the
- * rest procedure of ptlrpc
- */
- rc = sptlrpc_cli_alloc_reqbuf(req, reqmsg_size);
- if (!rc) {
- LASSERT(req->rq_reqmsg);
- memcpy(req->rq_reqmsg, reqmsg, reqmsg_size);
- } else {
- CWARN("failed to alloc reqbuf: %d\n", rc);
- req->rq_flvr = old_flvr;
- }
+ * rest procedure of ptlrpc */
+ if (reqmsg_size != 0) {
+ rc = sptlrpc_cli_alloc_reqbuf(req, reqmsg_size);
+ if (!rc) {
+ LASSERT(req->rq_reqmsg);
+ memcpy(req->rq_reqmsg, reqmsg, reqmsg_size);
+ } else {
+ CWARN("failed to alloc reqbuf: %d\n", rc);
+ req->rq_flvr = old_flvr;
+ }
- OBD_FREE(reqmsg, reqmsg_size);
+ OBD_FREE(reqmsg, reqmsg_size);
+ }
return rc;
}
/* if it's gss, we only interested in root ctx init */
if (req->rq_auth_gss &&
- !(req->rq_ctx_init && (req->rq_auth_usr_root ||
- req->rq_auth_usr_mdt))) {
+ !(req->rq_ctx_init &&
+ (req->rq_auth_usr_root || req->rq_auth_usr_mdt ||
+ req->rq_auth_usr_ost))) {
cfs_spin_unlock(&exp->exp_lock);
- CDEBUG(D_SEC, "is good but not root(%d:%d:%d:%d)\n",
+ CDEBUG(D_SEC, "is good but not root(%d:%d:%d:%d:%d)\n",
req->rq_auth_gss, req->rq_ctx_init,
- req->rq_auth_usr_root, req->rq_auth_usr_mdt);
+ req->rq_auth_usr_root, req->rq_auth_usr_mdt,
+ req->rq_auth_usr_ost);
return 0;
}
/* most cases should return here, we only interested in
* gss root ctx init */
if (!req->rq_auth_gss || !req->rq_ctx_init ||
- (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt)) {
+ (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt &&
+ !req->rq_auth_usr_ost)) {
cfs_spin_unlock(&exp->exp_lock);
return 0;
}
cfs_spin_unlock(&exp->exp_lock);
- CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u) with "
+ CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with "
"unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n",
exp, exp->exp_obd->obd_name,
req, req->rq_auth_gss, req->rq_ctx_init, req->rq_ctx_fini,
- req->rq_auth_usr_root, req->rq_auth_usr_mdt, req->rq_flvr.sf_rpc,
+ req->rq_auth_usr_root, req->rq_auth_usr_mdt, req->rq_auth_usr_ost,
+ req->rq_flvr.sf_rpc,
exp->exp_flvr.sf_rpc,
exp->exp_flvr_old[0].sf_rpc,
exp->exp_flvr_expire[0] ?
static int sptlrpc_svc_check_from(struct ptlrpc_request *req, int svc_rc)
{
- if (svc_rc == SECSVC_DROP)
- return SECSVC_DROP;
+ /* peer's claim is unreliable unless gss is being used */
+ if (!req->rq_auth_gss || svc_rc == SECSVC_DROP)
+ return svc_rc;
switch (req->rq_sp_from) {
case LUSTRE_SP_CLI:
+ if (req->rq_auth_usr_mdt || req->rq_auth_usr_ost) {
+ DEBUG_REQ(D_ERROR, req, "faked source CLI");
+ svc_rc = SECSVC_DROP;
+ }
+ break;
case LUSTRE_SP_MDT:
+ if (!req->rq_auth_usr_mdt) {
+ DEBUG_REQ(D_ERROR, req, "faked source MDT");
+ svc_rc = SECSVC_DROP;
+ }
+ break;
case LUSTRE_SP_OST:
- case LUSTRE_SP_MGC:
+ if (!req->rq_auth_usr_ost) {
+ DEBUG_REQ(D_ERROR, req, "faked source OST");
+ svc_rc = SECSVC_DROP;
+ }
+ break;
case LUSTRE_SP_MGS:
- case LUSTRE_SP_ANY:
+ case LUSTRE_SP_MGC:
+ if (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt &&
+ !req->rq_auth_usr_ost) {
+ DEBUG_REQ(D_ERROR, req, "faked source MGC/MGS");
+ svc_rc = SECSVC_DROP;
+ }
break;
+ case LUSTRE_SP_ANY:
default:
DEBUG_REQ(D_ERROR, req, "invalid source %u", req->rq_sp_from);
- return SECSVC_DROP;
- }
-
- if (!req->rq_auth_gss)
- return svc_rc;
-
- if (unlikely(req->rq_sp_from == LUSTRE_SP_ANY)) {
- CERROR("not specific part\n");
- return SECSVC_DROP;
- }
-
- /* from MDT, must be authenticated as MDT */
- if (unlikely(req->rq_sp_from == LUSTRE_SP_MDT &&
- !req->rq_auth_usr_mdt)) {
- DEBUG_REQ(D_ERROR, req, "fake source MDT");
- return SECSVC_DROP;
- }
-
- /* from OST, must be callback to MDT and CLI, the reverse sec
- * was from mdt/root keytab, so it should be MDT or root FIXME */
- if (unlikely(req->rq_sp_from == LUSTRE_SP_OST &&
- !req->rq_auth_usr_mdt && !req->rq_auth_usr_root)) {
- DEBUG_REQ(D_ERROR, req, "fake source OST");
- return SECSVC_DROP;
+ svc_rc = SECSVC_DROP;
}
return svc_rc;
uint64_t kup_nid;
char kup_tgt[64];
char kup_mech[16];
- int kup_is_root;
- int kup_is_mds;
+ unsigned int kup_is_root:1,
+ kup_is_mdt:1,
+ kup_is_ost:1;
};
/****************************************
* [1]: mech_name (string)
* [2]: uid (uint)
* [3]: gid (uint)
- * [4]: flags (chars) FMT: r-root; m-mds
+ * [4]: flags (string) FMT: r-root; m-mdt; o-ost
* [5]: lustre_svc (uint)
* [6]: target_nid (uint64)
* [7]: target_uuid (string)
if (strchr(data[4], 'r'))
uparam->kup_is_root = 1;
if (strchr(data[4], 'm'))
- uparam->kup_is_mds = 1;
+ uparam->kup_is_mdt = 1;
+ if (strchr(data[4], 'o'))
+ uparam->kup_is_ost = 1;
uparam->kup_svc = strtol(data[5], NULL, 0);
uparam->kup_nid = strtoll(data[6], NULL, 0);
strncpy(uparam->kup_tgt, data[7], sizeof(uparam->kup_tgt));
logmsg(LL_DEBUG, "parse call out info: secid %d, mech %s, ugid %u:%u "
- "is_root %d, is_mds %d, svc %d, nid 0x%Lx, tgt %s\n",
+ "is_root %d, is_mdt %d, is_ost %d, svc %d, nid 0x%Lx, tgt %s\n",
uparam->kup_secid, uparam->kup_mech,
uparam->kup_uid, uparam->kup_gid,
- uparam->kup_is_root, uparam->kup_is_mds, uparam->kup_svc,
- uparam->kup_nid, uparam->kup_tgt);
+ uparam->kup_is_root, uparam->kup_is_mdt, uparam->kup_is_ost,
+ uparam->kup_svc, uparam->kup_nid, uparam->kup_tgt);
return 0;
}
}
cred->lc_uid = uparam.kup_uid;
- cred->lc_fl_root = (uparam.kup_is_root != 0);
- cred->lc_fl_mds = (uparam.kup_is_mds != 0);
+ cred->lc_root_flags |= uparam.kup_is_root ? LGSS_ROOT_CRED_ROOT : 0;
+ cred->lc_root_flags |= uparam.kup_is_mdt ? LGSS_ROOT_CRED_MDT : 0;
+ cred->lc_root_flags |= uparam.kup_is_ost ? LGSS_ROOT_CRED_OST : 0;
cred->lc_tgt_nid = uparam.kup_nid;
cred->lc_tgt_svc = uparam.kup_svc;
* on it, and share it among all root sessions; otherswise link to
* session keyring.
*/
- if (cred->lc_fl_root || cred->lc_fl_mds)
+ if (cred->lc_root_flags != 0)
inst_keyring = 0;
else
inst_keyring = KEY_SPEC_SESSION_KEYRING;
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";
+const char *krb5_cred_oss_suffix = "lustre_oss";
char *krb5_this_realm = NULL;
char *krb5_keytab_file = "/etc/krb5.keytab";
char *krb5_cc_type = "FILE:";
char *krb5_cc_dir = "/tmp";
char *krb5_cred_prefix = "krb5cc_";
-char *krb5_cred_root_suffix = "lustre_root";
struct lgss_krb5_cred {
char kc_ccname[128];
static
int lkrb5_cc_check_tgt_princ(krb5_context ctx,
krb5_ccache ccache,
- krb5_principal princ)
+ krb5_principal princ,
+ unsigned int flag)
{
- logmsg(LL_TRACE, "principal: realm %.*s, type %d, size %d, name %.*s\n",
+ const char *princ_name;
+
+ logmsg(LL_DEBUG, "principal: realm %.*s, type %d, size %d, name %.*s\n",
krb5_princ_realm(ctx, princ)->length,
krb5_princ_realm(ctx, princ)->data,
krb5_princ_type(ctx, princ),
return -1;
}
- /* if it's mds service principal, or lustre_root principal
- * with host part, verify the hostname.
- * note we allow lustre_root without host part */
- if (lgss_krb5_strcmp(krb5_princ_name(ctx, princ),
- LGSS_SVC_MDS_STR) == 0) {
- if (svc_princ_verify_host(ctx, princ, LL_WARN)) {
- logmsg(LL_WARN, "mds service principal doesn't belong "
- "to this node\n");
+ /* check principal name */
+ switch (flag) {
+ case LGSS_ROOT_CRED_ROOT:
+ princ_name = LGSS_USR_ROOT_STR;
+ break;
+ case LGSS_ROOT_CRED_MDT:
+ princ_name = LGSS_SVC_MDS_STR;
+ break;
+ case LGSS_ROOT_CRED_OST:
+ princ_name = LGSS_SVC_OSS_STR;
+ break;
+ default:
+ lassert(0);
+ }
+
+ if (lgss_krb5_strcmp(krb5_princ_name(ctx, princ), princ_name)) {
+ logmsg(LL_WARN, "%.*s: we expect %s instead\n",
+ krb5_princ_name(ctx, princ)->length,
+ krb5_princ_name(ctx, princ)->data,
+ princ_name);
+ return -1;
+ }
+
+ /*
+ * verify the hostname part of the principal, except we do allow
+ * lustre_root without binding to a host.
+ */
+ if (krb5_princ_component(ctx, princ, 1) == NULL) {
+ if (flag != LGSS_ROOT_CRED_ROOT) {
+ logmsg(LL_WARN, "%.*s: missing hostname\n",
+ krb5_princ_name(ctx, princ)->length,
+ krb5_princ_name(ctx, princ)->data);
return -1;
}
- } else if (lgss_krb5_strcmp(krb5_princ_name(ctx, princ),
- LGSS_USR_ROOT_STR) == 0) {
- if (krb5_princ_component(ctx, princ, 1) != NULL &&
- svc_princ_verify_host(ctx, princ, LL_WARN)) {
- logmsg(LL_WARN, "lustre_root principal doesn't belong "
- "to this node\n");
+ } else {
+ if (svc_princ_verify_host(ctx, princ, LL_WARN)) {
+ logmsg(LL_DEBUG, "%.*s: doesn't belong to this node\n",
+ krb5_princ_name(ctx, princ)->length,
+ krb5_princ_name(ctx, princ)->data);
return -1;
}
- } else {
- logmsg(LL_WARN, "unexpected krb5 cc principal name %.*s\n",
- krb5_princ_name(ctx, princ)->length,
- krb5_princ_name(ctx, princ)->data);
- return -1;
}
logmsg(LL_TRACE, "principal is OK\n");
return 0;
}
-/*
- * find out whether current TGT cache is valid or not
+/**
+ * compose the TGT cc name, according to the root flags.
*/
static
-int lkrb5_check_root_tgt_cc(krb5_context ctx,
- krb5_ccache ccache,
- char *ccname)
+void get_root_tgt_ccname(char *ccname, int size, unsigned int flag)
+{
+ const char *suffix;
+
+ switch (flag) {
+ case LGSS_ROOT_CRED_ROOT:
+ suffix = krb5_cred_root_suffix;
+ break;
+ case LGSS_ROOT_CRED_MDT:
+ suffix = krb5_cred_mds_suffix;
+ break;
+ case LGSS_ROOT_CRED_OST:
+ suffix = krb5_cred_oss_suffix;
+ break;
+ default:
+ lassert(0);
+ }
+
+ snprintf(ccname, size, "%s%s/%s%s_%s",
+ krb5_cc_type, krb5_cc_dir, krb5_cred_prefix,
+ suffix, krb5_this_realm);
+}
+
+static
+int lkrb5_check_root_tgt_cc_base(krb5_context ctx,
+ krb5_ccache ccache,
+ char *ccname,
+ unsigned int flag)
{
- struct stat statbuf;
krb5_ccache tgt_ccache;
krb5_creds cred;
krb5_principal princ;
krb5_cc_cursor cursor;
krb5_error_code code;
- char *ccfile;
time_t now;
int rc = -1, found = 0;
- if (strncmp(ccname, krb5_cc_type, strlen(krb5_cc_type_file))) {
- logmsg(LL_ERR, "unexpected cc type\n");
- return -1;
- }
-
- ccfile = ccname + strlen(krb5_cc_type_file);
- logmsg(LL_TRACE, "cc file name: %s\n", ccfile);
-
- /* firstly make sure the cache file is there */
- if (stat(ccfile, &statbuf)) {
- logmsg(LL_DEBUG, "krb5 cc %s: %s\n", ccname, strerror(errno));
- return -1;
- }
-
/* prepare parsing the cache file */
code = krb5_cc_resolve(ctx, ccname, &tgt_ccache);
if (code) {
goto out_cc;
}
- if (lkrb5_cc_check_tgt_princ(ctx, tgt_ccache, princ)) {
- logmsg(LL_WARN, "cc principal is not valid\n");
+ if (lkrb5_cc_check_tgt_princ(ctx, tgt_ccache, princ, flag))
goto out_princ;
- }
/*
* find a valid entry
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)
+{
+ 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;
+ }
+
+ rc = lkrb5_check_root_tgt_cc_base(ctx, ccache, ccname, flag);
+ if (rc == 0)
+ return 0;
+ }
+
+ 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,
static
int lkrb5_refresh_root_tgt_cc(krb5_context ctx,
krb5_ccache ccache,
- const char *ccname)
+ unsigned int root_flags)
{
krb5_keytab kt;
krb5_keytab_entry kte;
krb5_kt_cursor cursor;
- krb5_principal princ = NULL, princ2;
+ krb5_principal princ = NULL;
krb5_error_code code;
- int general_root = 0;
+ char ccname[1024];
+ unsigned int flag = 0;
int rc = -1;
/* prepare parsing the keytab file */
/* iterate keytab to find proper a entry */
do {
+ krb5_data *princname;
+
code = krb5_kt_next_entry(ctx, kt, &kte, &cursor);
if (code != 0)
break;
if (!princ_is_local_realm(ctx, kte.principal))
continue;
- /* lustre_root[/host]@realm */
- if (lgss_krb5_strcmp(krb5_princ_name(ctx, kte.principal),
- LGSS_USR_ROOT_STR) == 0) {
- int tmp_general_root = 0;
-
- if (krb5_princ_component(ctx, kte.principal,1) == NULL){
- if (princ != NULL) {
- logmsg(LL_TRACE, "lustre_root: "
- "already picked one, skip\n");
- continue;
- }
-
- tmp_general_root = 1;
- } else {
- if (svc_princ_verify_host(ctx, kte.principal,
- LL_TRACE)) {
- logmsg(LL_TRACE, "lustre_root: "
- "doesn't belong to this node\n");
- continue;
- }
-
- if (princ != NULL && !general_root) {
- logmsg(LL_TRACE, "lustre_root: already "
- "have a host-specific one, "
- "skip\n");
- continue;
- }
- }
-
- code = krb5_copy_principal(ctx, kte.principal, &princ2);
- if (code) {
- logmsg(LL_ERR, "copy lustre_root princ: %s\n",
- krb5_err_msg(code));
- continue;
- }
-
- if (princ != NULL) {
- logmsg(LL_TRACE, "release a lustre_root one\n");
- krb5_free_principal(ctx, princ);
- }
- princ = princ2;
-
- general_root = tmp_general_root;
+ 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;
}
- /* lustre_mds/host@realm */
- if (lgss_krb5_strcmp(krb5_princ_name(ctx, kte.principal),
- LGSS_SVC_MDS_STR) == 0) {
- if (svc_princ_verify_host(ctx, kte.principal,
- LL_TRACE)) {
- logmsg(LL_TRACE, "mds service principal: "
- "doesn't belong to this node\n");
+ if (krb5_princ_component(ctx, kte.principal, 1) == NULL) {
+ if (flag != LGSS_ROOT_CRED_ROOT) {
+ logmsg(LL_TRACE, "no hostname, skip\n");
continue;
}
-
- /* select this one */
- code = krb5_copy_principal(ctx, kte.principal, &princ2);
- if (code) {
- logmsg(LL_ERR, "copy lustre_mds princ: %s\n",
- krb5_err_msg(code));
+ } else {
+ if (svc_princ_verify_host(ctx, kte.principal,
+ LL_TRACE)) {
+ logmsg(LL_TRACE, "doesn't belong to this "
+ "node, skip\n");
continue;
}
+ }
- if (princ != NULL) {
- logmsg(LL_TRACE, "release a lustre_root one\n");
- krb5_free_principal(ctx, princ);
- }
- princ = princ2;
- break;
+ 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);
krb5_kt_end_seq_get(ctx, kt, &cursor);
}
/* obtain root TGT */
+ get_root_tgt_ccname(ccname, sizeof(ccname), flag);
rc = lkrb5_get_root_tgt_keytab(ctx, ccache, kt, princ, ccname);
krb5_free_principal(ctx, princ);
krb5_ccache ccache;
krb5_error_code code;
struct lgss_krb5_cred *kcred;
- char tgtcc[1024];
int rc = -1;
lassert(krb5_this_realm != NULL);
kcred = (struct lgss_krb5_cred *) cred->lc_mech_cred;
- /* compose the TGT cc name */
- snprintf(tgtcc, sizeof(tgtcc), "%s%s/%s%s_%s",
- krb5_cc_type, krb5_cc_dir, krb5_cred_prefix,
- krb5_cred_root_suffix, krb5_this_realm);
- logmsg(LL_DEBUG, "root krb5 TGT ccname: %s\n", tgtcc);
-
/* compose the memory cc name, since the only user is myself,
- * the name could be fixed
- */
+ * 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);
*/
lgss_krb5_mutex_lock();
- rc = lkrb5_check_root_tgt_cc(ctx, ccache, tgtcc);
+ rc = lkrb5_check_root_tgt_cc(ctx, ccache, cred->lc_root_flags);
if (rc != 0)
- rc = lkrb5_refresh_root_tgt_cc(ctx, ccache, tgtcc);
+ rc = lkrb5_refresh_root_tgt_cc(ctx, ccache,
+ cred->lc_root_flags);
if (rc == 0)
rc = lgss_krb5_set_ccache_name(kcred->kc_ccname);
kcred->kc_remove = 0;
cred->lc_mech_cred = kcred;
- if (cred->lc_fl_root || cred->lc_fl_mds) {
+ if (cred->lc_root_flags != 0) {
if (lgss_krb5_get_local_realm())
return -1;
const char *lgss_svc_str[LGSS_SVC_MAX] = {
[LGSS_SVC_MGS] = LGSS_SVC_MGS_STR,
[LGSS_SVC_MDS] = LGSS_SVC_MDS_STR,
- [LGSS_SVC_OSS] = LGSS_SVC_OST_STR,
+ [LGSS_SVC_OSS] = LGSS_SVC_OSS_STR,
};
/****************************************
#define LGSS_SVC_MGS_STR "lustre_mgs"
#define LGSS_SVC_MDS_STR "lustre_mds"
-#define LGSS_SVC_OST_STR "lustre_oss"
+#define LGSS_SVC_OSS_STR "lustre_oss"
#define LGSS_USR_ROOT_STR "lustre_root"
typedef enum {
int (*lmt_using_cred)(struct lgss_cred *cred);
};
+enum {
+ LGSS_ROOT_CRED_ROOT = 0x01,
+ LGSS_ROOT_CRED_MDT = 0x02,
+ LGSS_ROOT_CRED_OST = 0x04,
+
+ LGSS_ROOT_CRED_NR = 3
+};
+
struct lgss_cred {
int lc_uid;
- unsigned int lc_fl_root:1,
- lc_fl_mds:1;
+ unsigned int lc_root_flags;
uint64_t lc_tgt_nid;
uint32_t lc_tgt_svc;
uint32_t cr_remote;
uint32_t cr_usr_root;
uint32_t cr_usr_mds;
+ uint32_t cr_usr_oss;
uid_t cr_uid;
uid_t cr_mapped_uid;
uid_t cr_gid;
qword_printint(f, cred->cr_remote);
qword_printint(f, cred->cr_usr_root);
qword_printint(f, cred->cr_usr_mds);
+ qword_printint(f, cred->cr_usr_oss);
qword_printint(f, cred->cr_mapped_uid);
qword_printint(f, cred->cr_uid);
qword_printint(f, cred->cr_gid);
gss_OID name_type = GSS_C_NO_OID;
struct passwd *pw;
- cred->cr_remote = cred->cr_usr_root = cred->cr_usr_mds = 0;
+ cred->cr_remote = 0;
+ cred->cr_usr_root = cred->cr_usr_mds = cred->cr_usr_oss = 0;
cred->cr_uid = cred->cr_mapped_uid = cred->cr_gid = -1;
maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
if (host)
*host++ = '\0';
- if (strcmp(sname, GSSD_SERVICE_OSS) == 0 ||
- strcmp(sname, GSSD_SERVICE_MGS) == 0) {
- printerr(0, "forbid %s as user name\n", sname);
+ if (strcmp(sname, GSSD_SERVICE_MGS) == 0) {
+ printerr(0, "forbid %s as a user name\n", sname);
goto out_free;
}
goto out_free;
}
} else {
- if (!strcmp(sname, GSSD_SERVICE_MDS)) {
- printerr(0, "ERROR: "GSSD_SERVICE_MDS"@%s from %016llx "
- "doesn't bind with hostname\n", realm, nid);
+ if (!strcmp(sname, GSSD_SERVICE_MDS) ||
+ !strcmp(sname, GSSD_SERVICE_OSS)) {
+ printerr(0, "ERROR: %s@%s from %016llx doesn't "
+ "bind with hostname\n", sname, realm, nid);
goto out_free;
}
}
- /* 2. check realm */
- if (!mds_local_realm || strcasecmp(mds_local_realm, realm)) {
- cred->cr_remote = 1;
-
- /* Allow mapped user from remote realm */
- if (cred->cr_mapped_uid != -1)
- res = 0;
- /* Allow OSS auth using client machine credential */
- else if (lustre_svc == LUSTRE_GSS_SVC_OSS &&
- !strcmp(sname, LUSTRE_ROOT_NAME))
- res = 0;
- /* Invalid remote user */
- else
- printerr(0, "ERROR: %s%s%s@%s from %016llx is remote "
- "but without mapping\n", sname,
- host ? "/" : "", host ? host : "", realm, nid);
+ /* 2. check realm and user */
+ switch (lustre_svc) {
+ case LUSTRE_GSS_SVC_MDS:
+ if (strcasecmp(mds_local_realm, realm)) {
+ cred->cr_remote = 1;
+
+ /* only allow mapped user from remote realm */
+ if (cred->cr_mapped_uid == -1) {
+ printerr(0, "ERROR: %s%s%s@%s from %016llx "
+ "is remote but without mapping\n",
+ sname, host ? "/" : "",
+ host ? host : "", realm, nid);
+ break;
+ }
+ } else {
+ if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_root = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_mds = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+ printerr(0, "ERROR: MDS doesn't accept "
+ "user "GSSD_SERVICE_OSS"\n");
+ break;
+ } else {
+ pw = getpwnam(sname);
+ if (pw != NULL) {
+ cred->cr_uid = pw->pw_uid;
+ printerr(2, "%s resolve to uid %u\n",
+ sname, cred->cr_uid);
+ } else if (cred->cr_mapped_uid != -1) {
+ printerr(2, "user %s from %016llx is "
+ "mapped to %u\n", sname, nid,
+ cred->cr_mapped_uid);
+ } else {
+ printerr(0, "ERROR: invalid user, "
+ "%s/%s@%s from %016llx\n",
+ sname, host, realm, nid);
+ break;
+ }
+ }
+ }
- /* skip local user check */
- goto out_free;
+ res = 0;
+ break;
+ case LUSTRE_GSS_SVC_MGS:
+ if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_oss = 1;
+ }
+ /* fall through */
+ case LUSTRE_GSS_SVC_OSS:
+ if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_root = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_mds = 1;
+ } else {
+ printerr(0, "ERROR: svc %d doesn't accept user %s"
+ "from %016llx\n", lustre_svc, sname, nid);
+ break;
+ }
+ res = 0;
+ break;
+ default:
+ assert(0);
}
- /* 3. check user */
- if (!(pw = getpwnam(sname))) {
- /* map lustre_root/lustre_mds to root user, which is subject
- * to further mapping by root-squash in kernel. */
- if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
- cred->cr_uid = 0;
- cred->cr_usr_root = 1;
- } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
- cred->cr_uid = 0;
- cred->cr_usr_mds = 1;
- } else {
- if (cred->cr_mapped_uid == -1) {
- printerr(0, "ERROR: invalid user, %s/%s@%s "
- "from %016llx\n", sname, host,
- realm, nid);
- goto out_free;
- }
- }
- printerr(2, "user %s from %016llx is mapped to %u\n",
- sname, nid, cred->cr_mapped_uid);
- } else {
- /* note: a mapped local user will go to here too */
- cred->cr_uid = pw->pw_uid;
- printerr(2, "%s resolve to uid %u\n", sname, cred->cr_uid);
- }
-
- res = 0;
out_free:
if (!res)
printerr(1, "%s: authenticated %s%s%s@%s from %016llx\n",