int ll_flush_ctx(struct inode *inode)
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct lustre_sb_info *lsi = sbi->lsi;
CDEBUG(D_SEC, "flush context for user %d\n",
from_kuid(&init_user_ns, current_uid()));
+ obd_set_info_async(NULL, lsi->lsi_mgc->u.cli.cl_mgc_mgsexp,
+ sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
+ 0, NULL, NULL);
obd_set_info_async(NULL, sbi->ll_md_exp,
sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
0, NULL, NULL);
RETURN(rc);
}
+ if (KEY_IS(KEY_FLUSH_CTX)) {
+ struct obd_import *imp = class_exp2cliimp(exp);
+
+ sptlrpc_import_flush_my_ctx(imp);
+ RETURN(0);
+ }
+
#ifdef HAVE_SERVER_SUPPORT
rc = mgc_set_info_async_server(env, exp, keylen, key, vallen, val, set);
#endif
rscp->sc_target = target;
CDEBUG(D_SEC, "%s: server create rsc %p(%u->%s)\n",
- target->obd_name, rscp, rscp->sc_ctx.gsc_uid,
+ target->obd_name, rscp,
+ rscp->sc_ctx.gsc_mapped_uid != -1 ?
+ rscp->sc_ctx.gsc_mapped_uid :
+ rscp->sc_ctx.gsc_uid,
libcfs_nidstr(&req->rq_peer.nid));
if (rsip->si_out_handle.len > PTLRPC_GSS_MAX_HANDLE_SIZE) {
else
CDEBUG(D_SEC, "%s: create svc ctx %p: accept user %u from %s\n",
target->obd_name,
- grctx->src_ctx, grctx->src_ctx->gsc_uid,
+ grctx->src_ctx,
+ grctx->src_ctx->gsc_mapped_uid != -1 ?
+ grctx->src_ctx->gsc_mapped_uid :
+ grctx->src_ctx->gsc_uid,
libcfs_nidstr(&req->rq_peer.nid));
if (gw->gw_flags & LUSTRE_GSS_PACK_USER) {
CERROR("svc %u failed: major 0x%08x: req xid %llu ctx %p idx %#llx(%u->%s)\n",
gw->gw_svc, major, req->rq_xid, grctx->src_ctx,
- gss_handle_to_u64(&gw->gw_handle), grctx->src_ctx->gsc_uid,
+ gss_handle_to_u64(&gw->gw_handle),
+ grctx->src_ctx->gsc_mapped_uid != -1 ?
+ grctx->src_ctx->gsc_mapped_uid :
+ grctx->src_ctx->gsc_uid,
libcfs_nidstr(&req->rq_peer.nid));
error:
/* we only notify client in case of NO_CONTEXT/BAD_SIG, which
CDEBUG(D_SEC, "destroy svc ctx %p idx %#llx (%u->%s)\n",
grctx->src_ctx, gss_handle_to_u64(&gw->gw_handle),
- grctx->src_ctx->gsc_uid, libcfs_nidstr(&req->rq_peer.nid));
+ grctx->src_ctx->gsc_mapped_uid != -1 ?
+ grctx->src_ctx->gsc_mapped_uid :
+ grctx->src_ctx->gsc_uid,
+ libcfs_nidstr(&req->rq_peer.nid));
gss_svc_upcall_destroy_ctx(grctx->src_ctx);
grctx = gss_svc_ctx2reqctx(svc_ctx);
CWARN("gss svc invalidate ctx %p(%u)\n", grctx->src_ctx,
- grctx->src_ctx->gsc_uid);
+ grctx->src_ctx->gsc_mapped_uid != -1 ?
+ grctx->src_ctx->gsc_mapped_uid :
+ grctx->src_ctx->gsc_uid);
gss_svc_upcall_destroy_ctx(grctx->src_ctx);
EXIT;
}
break;
case LUSTRE_SP_MGS:
- case LUSTRE_SP_MGC:
if (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt &&
!req->rq_auth_usr_ost) {
/* The below message is checked in sanity-sec test_33 */
- DEBUG_REQ(D_ERROR, req, "faked source MGC/MGS");
+ DEBUG_REQ(D_ERROR, req, "faked source MGS");
svc_rc = SECSVC_DROP;
}
break;
+ case LUSTRE_SP_MGC: {
+ bool faked = false;
+
+ /* For krb, at most one of rq_auth_usr_root, rq_auth_usr_mdt,
+ * rq_auth_usr_ost can be non zero.
+ * For SSK, all of rq_auth_usr_root rq_auth_usr_mdt
+ * rq_auth_usr_ost must be 1 for server/root access, and all 0
+ * for user access.
+ */
+ switch (SPTLRPC_FLVR_MECH(req->rq_flvr.sf_rpc)) {
+ case SPTLRPC_MECH_GSS_KRB5:
+ if (req->rq_auth_usr_root + req->rq_auth_usr_mdt +
+ req->rq_auth_usr_ost > 1)
+ faked = true;
+ break;
+ case SPTLRPC_MECH_GSS_SK:
+ if ((!req->rq_auth_usr_root || !req->rq_auth_usr_mdt ||
+ !req->rq_auth_usr_ost) &&
+ (req->rq_auth_usr_root || req->rq_auth_usr_mdt ||
+ req->rq_auth_usr_ost))
+ faked = true;
+ break;
+ default:
+ faked = false;
+ }
+ if (faked) {
+ /* The below message is checked in sanity-sec test_33 */
+ DEBUG_REQ(D_ERROR, req, "faked source MGC");
+ svc_rc = SECSVC_DROP;
+ }
+ break;
+ }
case LUSTRE_SP_ANY:
default:
DEBUG_REQ(D_ERROR, req, "invalid source %u", req->rq_sp_from);
}
run_test 151 "secure mgs connection: server flavor control"
+exit_152() {
+ zconf_umount $HOSTNAME $MOUNT
+
+ # remove mgs rule
+ set_rule _mgs any any
+
+ zconf_mount $HOSTNAME $MOUNT
+ if [ "$MOUNT_2" ]; then
+ zconf_mount $HOSTNAME $MOUNT2
+ fi
+}
+
+test_152() {
+ local mount_opts
+ local count
+
+ (( MDS1_VERSION >= $(version_code 2.15.64) )) ||
+ skip "Need MDS >= 2.15.64 for user context with MGS"
+
+ stack_trap exit_152 EXIT
+
+ if is_mounted $MOUNT2; then
+ umount_client $MOUNT2 || error "umount $MOUNT2 failed"
+ fi
+
+ zconf_umount $HOSTNAME $MOUNT || error "umount $MOUNT failed"
+
+ # set mgs rule to only accept krb5p
+ set_rule _mgs any any krb5p
+
+ # start gss daemon on mgs node
+ combined_mgs_mds || start_gss_daemons $mgs_HOST $LSVCGSSD "-vvv"
+
+ # re-mount client with mgssec=krb5p
+ mount_opts="${MOUNT_OPTS:+$MOUNT_OPTS,}mgssec=krb5p"
+ zconf_mount $HOSTNAME $MOUNT $mount_opts ||
+ error "unable to mount client"
+
+ $RUNAS $LFS check mgts || error "check mgts as user failed"
+ $RUNAS grep lgssc /proc/keys
+
+ $RUNAS $LFS flushctx $MOUNT || error "flushctx as user failed"
+ $RUNAS grep lgssc /proc/keys
+ count=$($RUNAS grep lgssc /proc/keys | grep -v "Running as" | wc -l)
+ [[ $count == 0 ]] || error "remaining $count keys for user"
+}
+run_test 152 "secure mgs connection: user access"
+
test_200() {
local nid=$(lctl list_nids | grep ${NETTYPE} | head -n1)
local nidstr="peer_nid: ${nid},"
sname[name.length] = '\0';
gss_release_buffer(&min_stat, &name);
- if (lustre_svc == LUSTRE_GSS_SVC_MDS &&
+ if ((lustre_svc == LUSTRE_GSS_SVC_MDS ||
+ lustre_svc == LUSTRE_GSS_SVC_MGS) &&
lookup_id(client_name, sname, nid, &cred->cr_mapped_uid))
printerr(LL_DEBUG, "no id found for %s\n", sname);
if (host) {
if (lnet_nid2hostname(nid, namebuf, namebuf_size)) {
printerr(LL_ERR,
- "ERROR: failed to resolve hostname for %s/%s@%s from %016llx\n",
- sname, host, realm, nid);
+ "ERROR: failed to resolve hostname for %s/%s@%s from %s\n",
+ sname, host, realm, libcfs_nid2str(nid));
goto out_free;
}
if (strcasecmp(host, namebuf)) {
printerr(LL_ERR,
- "ERROR: %s/%s@%s claimed hostname doesn't match %s, nid %016llx\n",
+ "ERROR: %s/%s@%s claimed hostname doesn't match %s, nid %s\n",
sname, host, realm,
- namebuf, nid);
+ namebuf, libcfs_nid2str(nid));
goto out_free;
}
} else {
if (!strcmp(sname, GSSD_SERVICE_MDS) ||
!strcmp(sname, GSSD_SERVICE_OSS)) {
printerr(LL_ERR,
- "ERROR: %s@%s from %016llx doesn't bind with hostname\n",
- sname, realm, nid);
+ "ERROR: %s@%s from %s doesn't bind with hostname\n",
+ sname, realm, libcfs_nid2str(nid));
goto out_free;
}
}
/* Prevent access to unmapped user from remote realm */
if (cred->cr_mapped_uid == -1) {
printerr(LL_ERR,
- "ERROR: %s%s%s@%s from %016llx is remote but without mapping\n",
+ "ERROR: %s%s%s@%s from %s is remote but without mapping\n",
sname, host ? "/" : "",
- host ? host : "", realm, nid);
+ host ? host : "", realm,
+ libcfs_nid2str(nid));
break;
}
goto valid;
}
if (cred->cr_mapped_uid != -1) {
printerr(LL_INFO,
- "user %s from %016llx is mapped to %u\n",
- sname, nid,
+ "user %s from %s is mapped to %u\n",
+ sname, libcfs_nid2str(nid),
cred->cr_mapped_uid);
goto valid;
}
sname, cred->cr_uid);
goto valid;
}
- printerr(LL_ERR, "ERROR: invalid user, %s/%s@%s from %016llx\n",
- sname, host, realm, nid);
+ printerr(LL_ERR, "ERROR: invalid user, %s/%s@%s from %s\n",
+ sname, host, realm, libcfs_nid2str(nid));
break;
valid:
cred->cr_uid = 0;
cred->cr_usr_mds = 1;
}
+ if (cred->cr_mapped_uid != -1) {
+ printerr(LL_INFO,
+ "user %s from %s is mapped to %u\n",
+ sname, libcfs_nid2str(nid),
+ cred->cr_mapped_uid);
+ goto valid;
+ }
if (cred->cr_uid == -1) {
printerr(LL_ERR,
- "ERROR: svc %d doesn't accept user %s from %016llx\n",
- lustre_svc, sname, nid);
+ "ERROR: svc %d doesn't accept user %s from %s\n",
+ lustre_svc, sname, libcfs_nid2str(nid));
break;
}
res = 0;
out_free:
if (!res)
- printerr(LL_WARN, "%s: authenticated %s%s%s@%s from %016llx\n",
+ printerr(LL_WARN, "%s: authenticated %s%s%s@%s from %s\n",
lustre_svc_name[lustre_svc], sname,
- host ? "/" : "", host ? host : "", realm, nid);
+ host ? "/" : "", host ? host : "", realm,
+ libcfs_nid2str(nid));
free(sname);
return res;
}