Whamcloud - gitweb
LU-17317 sec: add srpc_serverctx proc file 76/53376/7
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 5 Dec 2023 13:14:58 +0000 (14:14 +0100)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Feb 2024 07:13:10 +0000 (07:13 +0000)
GSS srpc contexts for client connections can already be dumped via
proc file <mdc,osc>.*.srpc_contexts.
This patch adds a new proc file to dump server side GSS srpc contexts,
e.g.:
mgs.MGS.gss.srpc_serverctx
mdt.testfs-MDT0000.gss.srpc_serverctx
obdfilter.testfs-OST0000.gss.srpc_serverctx

The GSS context information is dumped as YAML, with one line per
context, like this:
0000000013221bdf: { peer_nid: 192.168.56.206@tcp, uid: 0, ctxref: 1,
expire: 1707934985, delta: 3401, flags: [uptodate, cached], seq: 0,
win: 2048, key: 00000000, keyref: 0,
hdl: "0x5ae1a771fd57043:0x65a64972fda4e200",
mech: "krb5 (aes256-cts-hmac-sha1-96)" }

Because of this new syntax, sanity-sec test_28 needs to be fixed.

Test-Parameters: trivial
Test-Parameters: kerberos=true testlist=sanity-krb5
Test-Parameters: testgroup=review-dne-selinux-ssk-part-2
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I37da9ffe6dd5884006b36271185a4d7155ead65b
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53376
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Aurelien Degremont <adegremont@nvidia.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
12 files changed:
lustre/include/lustre_sec.h
lustre/include/obd.h
lustre/mdt/mdt_lproc.c
lustre/mgs/lproc_mgs.c
lustre/obdclass/lprocfs_status.c
lustre/ofd/lproc_ofd.c
lustre/ptlrpc/gss/gss_keyring.c
lustre/ptlrpc/gss/gss_svc_upcall.c
lustre/ptlrpc/gss/sec_gss.c
lustre/ptlrpc/sec.c
lustre/ptlrpc/service.c
lustre/tests/sanity-sec.sh

index 77f970e..d49c4c3 100644 (file)
@@ -1099,6 +1099,7 @@ int sptlrpc_import_sec_adapt(struct obd_import *imp,
                             struct sptlrpc_flavor *flvr);
 struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp);
 void sptlrpc_import_sec_put(struct obd_import *imp);
+int lprocfs_srpc_serverctx_seq_show(struct seq_file *m, void *data);
 
 int  sptlrpc_import_check_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_root_ctx(struct obd_import *imp);
index 4438d4e..6ed6020 100644 (file)
@@ -722,6 +722,7 @@ struct obd_device {
        struct lprocfs_stats            *obd_md_stats;
 
        struct dentry                   *obd_debugfs_entry;
+       struct dentry                   *obd_debugfs_gss_dir;
        struct proc_dir_entry   *obd_proc_entry;
        struct proc_dir_entry   *obd_proc_exports_entry;
        struct dentry                   *obd_svc_debugfs_entry;
index 48b6ae8..31d5f47 100644 (file)
@@ -1389,6 +1389,14 @@ static struct ldebugfs_vars ldebugfs_mdt_obd_vars[] = {
        { NULL }
 };
 
+LDEBUGFS_SEQ_FOPS_RO_TYPE(mdt, srpc_serverctx);
+
+static struct ldebugfs_vars ldebugfs_mdt_gss_vars[] = {
+       { .name =       "srpc_serverctx",
+         .fops =       &mdt_srpc_serverctx_fops        },
+       { NULL }
+};
+
 static int
 lprocfs_mdt_print_open_files(struct obd_export *exp, void *v)
 {
@@ -1534,6 +1542,12 @@ int mdt_tunables_init(struct mdt_device *mdt, const char *name)
                return rc;
        }
 
+       obd->obd_debugfs_gss_dir = debugfs_create_dir("gss",
+                                                     obd->obd_debugfs_entry);
+       if (obd->obd_debugfs_gss_dir)
+               ldebugfs_add_vars(obd->obd_debugfs_gss_dir,
+                                 ldebugfs_mdt_gss_vars, obd);
+
        obd->obd_proc_exports_entry = proc_mkdir("exports",
                                                 obd->obd_proc_entry);
        if (obd->obd_proc_exports_entry)
index 3d58463..082fb03 100644 (file)
@@ -218,6 +218,14 @@ static struct lprocfs_vars lprocfs_mgs_obd_vars[] = {
 LUSTRE_RO_ATTR(num_exports);
 LUSTRE_RO_ATTR(eviction_count);
 
+LDEBUGFS_SEQ_FOPS_RO_TYPE(ofd, srpc_serverctx);
+
+static struct ldebugfs_vars ldebugfs_ofd_gss_vars[] = {
+       { .name =       "srpc_serverctx",
+         .fops =       &ofd_srpc_serverctx_fops        },
+       { NULL }
+};
+
 static ssize_t fstype_show(struct kobject *kobj, struct attribute *attr,
                           char *buf)
 {
@@ -296,6 +304,12 @@ int lproc_mgs_setup(struct mgs_device *mgs, const char *osd_name)
                GOTO(out, rc);
         }
 
+       obd->obd_debugfs_gss_dir = debugfs_create_dir("gss",
+                                                     obd->obd_debugfs_entry);
+       if (obd->obd_debugfs_gss_dir)
+               ldebugfs_add_vars(obd->obd_debugfs_gss_dir,
+                                 ldebugfs_ofd_gss_vars, obd);
+
        obd->obd_proc_exports_entry = lprocfs_register("exports",
                                                       obd->obd_proc_entry,
                                                       NULL, NULL);
index 7ffbc42..3aa4b9e 100644 (file)
@@ -1142,6 +1142,9 @@ int lprocfs_obd_cleanup(struct obd_device *obd)
        if (!obd)
                return -EINVAL;
 
+       debugfs_remove_recursive(obd->obd_debugfs_gss_dir);
+       obd->obd_debugfs_gss_dir = NULL;
+
        if (obd->obd_proc_exports_entry) {
                /* Should be no exports left */
                lprocfs_remove(&obd->obd_proc_exports_entry);
index f03d8d1..b0c4210 100644 (file)
@@ -949,6 +949,14 @@ struct ldebugfs_vars ldebugfs_ofd_obd_vars[] = {
        { NULL }
 };
 
+LDEBUGFS_SEQ_FOPS_RO_TYPE(ofd, srpc_serverctx);
+
+static struct ldebugfs_vars ldebugfs_ofd_gss_vars[] = {
+       { .name =       "srpc_serverctx",
+         .fops =       &ofd_srpc_serverctx_fops        },
+       { NULL }
+};
+
 /**
  * Initialize OFD statistics counters
  *
@@ -1081,6 +1089,12 @@ int ofd_tunables_init(struct ofd_device *ofd)
                GOTO(tgt_cleanup, rc);
        }
 
+       obd->obd_debugfs_gss_dir = debugfs_create_dir("gss",
+                                                     obd->obd_debugfs_entry);
+       if (obd->obd_debugfs_gss_dir)
+               ldebugfs_add_vars(obd->obd_debugfs_gss_dir,
+                                 ldebugfs_ofd_gss_vars, obd);
+
        entry = lprocfs_register("exports", obd->obd_proc_entry, NULL, NULL);
        if (IS_ERR(entry)) {
                rc = PTR_ERR(entry);
index a4b5948..ad099d8 100644 (file)
@@ -1199,38 +1199,45 @@ int gss_sec_display_kr(struct ptlrpc_sec *sec, struct seq_file *seq)
        struct hlist_node *next;
        struct ptlrpc_cli_ctx *ctx;
        struct gss_cli_ctx *gctx;
+       struct ptlrpc_connection *conn;
        time64_t now = ktime_get_real_seconds();
 
        ENTRY;
        spin_lock(&sec->ps_lock);
        hlist_for_each_entry_safe(ctx, next, &gsec_kr->gsk_clist,
                                  cc_cache) {
-                struct key             *key;
-                char                    flags_str[40];
-                char                    mech[40];
+               struct key *key;
+               char flags_str[40];
+               char mech[40];
 
-                gctx = ctx2gctx(ctx);
-                key = ctx2gctx_keyring(ctx)->gck_key;
+               gctx = ctx2gctx(ctx);
+               key = ctx2gctx_keyring(ctx)->gck_key;
+               if (sec_is_reverse(sec) &&
+                   ctx->cc_sec && ctx->cc_sec->ps_import &&
+                   ctx->cc_sec->ps_import->imp_connection)
+                       conn = ctx->cc_sec->ps_import->imp_connection;
+               else
+                       conn = NULL;
 
-                gss_cli_ctx_flags2str(ctx->cc_flags,
-                                      flags_str, sizeof(flags_str));
+               gss_cli_ctx_flags2str(ctx->cc_flags,
+                                     flags_str, sizeof(flags_str));
 
-                if (gctx->gc_mechctx)
-                        lgss_display(gctx->gc_mechctx, mech, sizeof(mech));
-                else
-                        snprintf(mech, sizeof(mech), "N/A");
-                mech[sizeof(mech) - 1] = '\0';
+               if (gctx->gc_mechctx)
+                       lgss_display(gctx->gc_mechctx, mech, sizeof(mech));
+               else
+                       snprintf(mech, sizeof(mech), "N/A");
+               mech[sizeof(mech) - 1] = '\0';
 
                seq_printf(seq,
-                          "%p: uid %u, ref %d, expire %lld(%+lld), fl %s, seq %d, win %u, key %08x(ref %d), hdl %#llx:%#llx, mech: %s\n",
-                          ctx, ctx->cc_vcred.vc_uid,
-                          atomic_read(&ctx->cc_refcount),
+                          "- %p: { %s%s%suid: %u, ctxref: %d, expire: %lld, delta: %lld, flags: [%s], seq: %d, win: %u, key: %08x, keyref: %d, hdl: \"%#llx:%#llx\", mech: \"%s\" }\n",
+                          ctx, conn ? "peer_nid: " : "",
+                          conn ? libcfs_nidstr(&conn->c_peer.nid) : "",
+                          conn ? ", " : "",
+                          ctx->cc_vcred.vc_uid, atomic_read(&ctx->cc_refcount),
                           ctx->cc_expire,
                           ctx->cc_expire ?  ctx->cc_expire - now : 0,
-                          flags_str,
-                          atomic_read(&gctx->gc_seq),
-                          gctx->gc_win,
-                          key ? key->serial : 0,
+                          flags_str, atomic_read(&gctx->gc_seq),
+                          gctx->gc_win, key ? key->serial : 0,
                           key ? ll_read_key_usage(key) : 0,
                           gss_handle_to_u64(&gctx->gc_handle),
                           gss_handle_to_u64(&gctx->gc_svc_handle),
index 441afa3..d9072e9 100644 (file)
@@ -142,8 +142,8 @@ static __always_inline __u64 gss_hash_64(__u64 val, unsigned int bits)
 
 static inline unsigned long hash_mem_64(char *buf, int length, int bits)
 {
-       unsigned long hash = 0;
-       unsigned long l = 0;
+       __u64 hash = 0;
+       __u64 l = 0;
        int len = 0;
        unsigned char c;
 
@@ -157,8 +157,8 @@ static inline unsigned long hash_mem_64(char *buf, int length, int bits)
                l = (l << 8) | c;
                len++;
 
-               if ((len & (BITS_PER_LONG/8-1)) == 0)
-                       hash = gss_hash_64(hash^l, BITS_PER_LONG);
+               if ((len & (BITS_PER_LONG / 8 - 1)) == 0)
+                       hash = gss_hash_64(hash ^ l, BITS_PER_LONG);
        } while (len);
 
        return hash >> (BITS_PER_LONG - bits);
index fc2417b..5c88883 100644 (file)
@@ -588,19 +588,19 @@ void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize)
        buf[0] = '\0';
 
        if (flags & PTLRPC_CTX_NEW)
-               strlcat(buf, "new,", bufsize);
+               strlcat(buf, "new, ", bufsize);
        if (flags & PTLRPC_CTX_UPTODATE)
-               strlcat(buf, "uptodate,", bufsize);
+               strlcat(buf, "uptodate, ", bufsize);
        if (flags & PTLRPC_CTX_DEAD)
-               strlcat(buf, "dead,", bufsize);
+               strlcat(buf, "dead, ", bufsize);
        if (flags & PTLRPC_CTX_ERROR)
-               strlcat(buf, "error,", bufsize);
+               strlcat(buf, "error, ", bufsize);
        if (flags & PTLRPC_CTX_CACHED)
-               strlcat(buf, "cached,", bufsize);
+               strlcat(buf, "cached, ", bufsize);
        if (flags & PTLRPC_CTX_ETERNAL)
-               strlcat(buf, "eternal,", bufsize);
-       if (buf[0] == '\0')
-               strlcat(buf, "-,", bufsize);
+               strlcat(buf, "eternal, ", bufsize);
+       if (buf[strlen(buf) - 2] == ',')
+               buf[strlen(buf) - 2] = '\0';
 }
 
 int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req)
index 725a71f..f3ad28a 100644 (file)
@@ -1403,6 +1403,40 @@ struct ptlrpc_sec * sptlrpc_sec_create(struct obd_import *imp,
        RETURN(sec);
 }
 
+static int print_srpc_serverctx_seq(struct obd_export *exp, void *cb_data)
+{
+       struct seq_file *m = cb_data;
+       struct obd_import *imp = exp->exp_imp_reverse;
+       struct ptlrpc_sec *sec = NULL;
+
+       if (imp)
+               sec = sptlrpc_import_sec_ref(imp);
+       if (sec == NULL)
+               goto out;
+
+       if (sec->ps_policy->sp_cops->display)
+               sec->ps_policy->sp_cops->display(sec, m);
+
+       sptlrpc_sec_put(sec);
+out:
+       return 0;
+}
+
+int lprocfs_srpc_serverctx_seq_show(struct seq_file *m, void *data)
+{
+       struct obd_device *obd = m->private;
+       struct obd_export *exp, *n;
+
+       spin_lock(&obd->obd_dev_lock);
+       list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
+               print_srpc_serverctx_seq(exp, m);
+       }
+       spin_unlock(&obd->obd_dev_lock);
+
+       return 0;
+}
+EXPORT_SYMBOL(lprocfs_srpc_serverctx_seq_show);
+
 struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp)
 {
        struct ptlrpc_sec *sec;
index 9276b8d..c1bdf7b 100644 (file)
@@ -2093,6 +2093,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
        spin_unlock(&svcpt->scp_lock);
 
        /* go through security check/transform */
+       CDEBUG(D_RPCTRACE, "unwrap req x%llu\n", req->rq_xid);
        rc = sptlrpc_svc_unwrap_request(req);
        switch (rc) {
        case SECSVC_OK:
@@ -2238,6 +2239,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
        RETURN(1);
 
 err_req:
+       CDEBUG(D_RPCTRACE, "finish req x%llu\n", req->rq_xid);
        ptlrpc_server_finish_request(svcpt, req);
 
        RETURN(1);
index f8d1a1f..0b7fc17 100755 (executable)
@@ -2222,16 +2222,16 @@ test_28() {
                error "read before rotation failed"
        fi
        # store top key identity to ensure rotation has occurred
-       SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"|
-               head -1 | awk '{print $15}' | cut -c1-8)
+       SK_IDENTITY_OLD=$($LCTL get_param -n *.*.*srpc_contexts 2>/dev/null |
+                      head -n 1 | awk 'BEGIN{RS=", "} $1=="expire:"{print $2}')
        do_facet $SINGLEMDS lfs flushctx ||
                 error "could not run flushctx on $SINGLEMDS"
        sleep 5
        lfs flushctx || error "could not run flushctx on client"
        sleep 5
        # verify new key is in place
-       SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"|
-               head -1 | awk '{print $15}' | cut -c1-8)
+       SK_IDENTITY_NEW=$($LCTL get_param -n *.*.*srpc_contexts 2>/dev/null |
+                      head -n 1 | awk 'BEGIN{RS=", "} $1=="expire:"{print $2}')
        if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then
                error "key did not rotate correctly"
        fi