Whamcloud - gitweb
branch: b_new_cmd
authorericm <ericm>
Wed, 18 Oct 2006 23:48:43 +0000 (23:48 +0000)
committerericm <ericm>
Wed, 18 Oct 2006 23:48:43 +0000 (23:48 +0000)
basic support for PAG, ported from HEAD.

20 files changed:
lustre/include/liblustre.h
lustre/include/lustre_disk.h
lustre/include/lustre_sec.h
lustre/kernel_patches/patches/pag-basic-2.6-rhel4.patch [new file with mode: 0644]
lustre/kernel_patches/series/2.6-rhel4.series
lustre/llite/llite_lib.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_request.c
lustre/obdclass/obd_mount.c
lustre/ptlrpc/gss/gss_cli_upcall.c
lustre/ptlrpc/gss/sec_gss.c
lustre/ptlrpc/sec.c
lustre/ptlrpc/sec_lproc.c
lustre/utils/Makefile.am
lustre/utils/gss/gssd_proc.c
lustre/utils/gss/krb5_util.c
lustre/utils/gss/krb5_util.h
lustre/utils/gss/lsupport.h
lustre/utils/gss/nfs-utils-1.0.10-lustre.diff
lustre/utils/lkinit.c [new file with mode: 0644]

index 17dbceb..3321d23 100644 (file)
@@ -585,6 +585,7 @@ struct task_struct {
         int state;
         struct signal pending;
         char comm[32];
+        unsigned long pag;
         int uid;
         int gid;
         int pid;
index 55cf2a4..afedbde 100644 (file)
@@ -141,6 +141,7 @@ struct lustre_mount_data {
         char      *lmd_profile;       /* client only */
         char      *lmd_sec_mdt;       /* sec from mdt (to ost/mdt) */
         char      *lmd_sec_cli;       /* sec from client (to ost/mdt) */
+        __u32      lmd_pag:1;         /* enable PAG */
         uid_t      lmd_nllu;          /* non-lustre-local-user id */
         gid_t      lmd_nllg;          /* non-lustre-local-group id */
         char      *lmd_opts;          /* lustre mount options (as opposed to 
index c99af98..bdfe6bc 100644 (file)
@@ -202,6 +202,7 @@ enum lustre_part {
 
 
 struct vfs_cred {
+        uint64_t        vc_pag;
         uint32_t        vc_uid;
         uint32_t        vc_gid;
 };
@@ -337,6 +338,7 @@ struct ptlrpc_sec_policy {
 #define PTLRPC_SEC_FL_REVERSE           0x0001 /* reverse sec */
 #define PTLRPC_SEC_FL_ROOTONLY          0x0002 /* treat everyone as root */
 #define PTLRPC_SEC_FL_BULK              0x0004 /* intensive bulk i/o expected */
+#define PTLRPC_SEC_FL_PAG               0x0008 /* PAG enabled */
 
 struct ptlrpc_sec {
         struct ptlrpc_sec_policy       *ps_policy;
@@ -358,6 +360,15 @@ struct ptlrpc_svc_ctx {
 };
 
 /*
+ * PAG
+ */
+#ifdef HAVE_LINUX_PAG
+#define CURRENT_PAG     ((uint64_t) current->pag)
+#else
+#define CURRENT_PAG     ((uint64_t) current->uid)
+#endif
+
+/*
  * user identity descriptor
  */
 #define LUSTRE_MAX_GROUPS               (128)
diff --git a/lustre/kernel_patches/patches/pag-basic-2.6-rhel4.patch b/lustre/kernel_patches/patches/pag-basic-2.6-rhel4.patch
new file mode 100644 (file)
index 0000000..e68df60
--- /dev/null
@@ -0,0 +1,74 @@
+--- linux-2.6.10-pag/arch/i386/kernel/entry.S.pag      2005-07-15 13:47:12.000000000 -0600
++++ linux-2.6.10-pag/arch/i386/kernel/entry.S  2005-07-18 11:18:45.000000000 -0600
+@@ -907,5 +907,7 @@
+       .long sys_add_key
+       .long sys_request_key
+       .long sys_keyctl
++      .long sys_newpag
++      .long sys_getpag                /* 289,290 temporay added for lustre */
+ syscall_table_size=(.-sys_call_table)
+--- linux-2.6.10-pag/fs/fcntl.c.pag    2005-07-15 14:23:32.000000000 -0600
++++ linux-2.6.10-pag/fs/fcntl.c        2005-07-18 11:41:21.000000000 -0600
+@@ -421,6 +421,17 @@
+ }
+ #endif
++asmlinkage long sys_newpag(void)
++{
++      get_random_bytes(&current->pag, sizeof(current->pag));
++      return 0;
++}
++
++asmlinkage long sys_getpag(void)
++{
++      return current->pag;
++}
++
+ /* Table to convert sigio signal codes into poll band bitmaps */
+ static long band_table[NSIGPOLL] = {
+--- linux-2.6.10-pag/include/linux/sched.h.pag 2005-07-15 13:35:27.000000000 -0600
++++ linux-2.6.10-pag/include/linux/sched.h     2005-07-15 13:38:02.000000000 -0600
+@@ -600,6 +600,7 @@
+ /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
+       unsigned long min_flt, maj_flt;
+ /* process credentials */
++      unsigned long pag;
+       uid_t uid,euid,suid,fsuid;
+       gid_t gid,egid,sgid,fsgid;
+       struct group_info *group_info;
+--- linux-2.6.10-pag/include/linux/syscalls.h.pag      2005-07-15 14:09:42.000000000 -0600
++++ linux-2.6.10-pag/include/linux/syscalls.h  2005-07-18 11:42:01.000000000 -0600
+@@ -506,4 +506,7 @@
+ asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
+                          unsigned long arg4, unsigned long arg5);
++asmlinkage long sys_newpag(void);
++asmlinkage long sys_getpag(void);
++
+ #endif
+--- linux-2.6.10-pag/include/linux/init_task.h.pag     2005-07-15 14:39:07.000000000 -0600
++++ linux-2.6.10-pag/include/linux/init_task.h 2005-07-15 14:41:45.000000000 -0600
+@@ -92,6 +92,7 @@
+       .real_timer     = {                                             \
+               .function       = it_real_fn                            \
+       },                                                              \
++      .pag            = -1,                                           \
+       .group_info     = &init_groups,                                 \
+       .cap_effective  = CAP_INIT_EFF_SET,                             \
+       .cap_inheritable = CAP_INIT_INH_SET,                            \
+--- linux-2.6.10-pag/include/asm-i386/unistd.h.pag     2005-07-15 13:55:46.000000000 -0600
++++ linux-2.6.10-pag/include/asm-i386/unistd.h 2005-07-18 11:43:10.000000000 -0600
+@@ -294,8 +294,10 @@
+ #define __NR_add_key          286
+ #define __NR_request_key      287
+ #define __NR_keyctl           288
++#define __NR_newpag           289
++#define __NR_getpag           290
+-#define NR_syscalls 289
++#define NR_syscalls 291
+ #ifndef __KERNEL_SYSCALLS_NO_ERRNO__
+ /*
index 709df80..69ccc0e 100644 (file)
@@ -30,3 +30,4 @@ raid5-serialize-ovelapping-reqs.patch
 jbd-stats-2.6.9.patch 
 bitops_ext2_find_next_le_bit-2.6.patch 
 proc-sleep-2.6.9.patch 
+pag-basic-2.6-rhel4.patch
index 41bb1be..04358e1 100644 (file)
@@ -150,6 +150,7 @@ static int ll_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp)
 
 static int client_common_fill_super(struct super_block *sb, 
                                     char *md, char *dt,
+                                    int mdt_pag,
                                     uid_t nllu, gid_t nllg)
 {
         struct inode *root = 0;
@@ -214,6 +215,10 @@ static int client_common_fill_super(struct super_block *sb,
                 data->ocd_connect_flags |= OBD_CONNECT_LCL_CLIENT;
         }
 
+        if (mdt_pag)
+                obd_set_info_async(obd->obd_self_export, 3, "pag",
+                                   0, NULL, NULL);
+
         err = obd_connect(NULL, &md_conn, obd, &sbi->ll_sb_uuid, data);
         if (err == -EBUSY) {
                 LCONSOLE_ERROR("An MDT (md %s) is performing recovery, of "
@@ -1060,6 +1065,7 @@ int ll_fill_super(struct super_block *sb)
 
         /* connections, registrations, sb setup */
         err = client_common_fill_super(sb, md, dt,
+                                       lsi->lsi_lmd->lmd_pag,
                                        lsi->lsi_lmd->lmd_nllu,
                                        lsi->lsi_lmd->lmd_nllg);
 
index 849ef09..59ef7dc 100644 (file)
@@ -2225,6 +2225,36 @@ int lmv_set_info_async(struct obd_export *exp, obd_count keylen,
 
                 RETURN(rc);
         }
+        if (KEY_IS("pag")) {
+                struct obd_export *exp;
+                int i, err = 0;
+
+                for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+                        exp = lmv->tgts[i].ltd_exp;
+
+                        if (exp == NULL) {
+                                struct obd_device *tgt_obd;
+
+                                tgt_obd = class_find_client_obd(
+                                                        &lmv->tgts[i].ltd_uuid,
+                                                        LUSTRE_MDC_NAME,
+                                                        &obd->obd_uuid);
+                                if (tgt_obd == NULL) {
+                                        CERROR("can't find obd %s\n",
+                                               lmv->tgts[i].ltd_uuid.uuid);
+                                        continue;
+                                }
+                                exp = tgt_obd->obd_self_export;
+                        }
+
+                        err = obd_set_info_async(exp, keylen, key, vallen,
+                                                 val, set);
+                        if (err && rc == 0)
+                                rc = err;
+                }
+
+                RETURN(rc);
+        }
 
         RETURN(-EINVAL);
 }
index b28d352..418bb1b 100644 (file)
@@ -1132,6 +1132,13 @@ int mdc_set_info_async(struct obd_export *exp, obd_count keylen,
                 RETURN(0);
         }
 
+        if (KEY_IS("pag")) {
+                struct client_obd *cliobd = &class_exp2obd(exp)->u.cli;
+
+                cliobd->cl_sec_conf.sfc_flags |= PTLRPC_SEC_FL_PAG;
+                RETURN(0);
+        }
+
         RETURN(rc);
 }
 
index 58c4672..10a30f2 100644 (file)
@@ -1936,6 +1936,9 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                         if (rc)
                                 goto invalid;
                         clear++;
+                } else if (strncmp(s1, "pag", 3) == 0) {
+                        lmd->lmd_pag = 1;
+                        clear++;
                 }
                 /* Linux 2.4 doesn't pass the device, so we stuck it at the
                    end of the options. */
index f9afadb..a67b297 100644 (file)
@@ -62,6 +62,7 @@ struct gss_upcall_msg_data {
         __u32                           gum_gid;
         __u32                           gum_svc;        /* MDS/OSS... */
         __u64                           gum_nid;        /* peer NID */
+        __u64                           gum_pag;
         __u8                            gum_obd[64];    /* client obd name */
 };
 
@@ -525,6 +526,7 @@ int gss_ctx_refresh_pipefs(struct ptlrpc_cli_ctx *ctx)
         gmsg->gum_data.gum_gid = 0; /* not used for now */
         gmsg->gum_data.gum_svc = import_to_gss_svc(imp);
         gmsg->gum_data.gum_nid = imp->imp_connection->c_peer.nid;
+        gmsg->gum_data.gum_pag = ctx->cc_vcred.vc_pag;
         strncpy(gmsg->gum_data.gum_obd, imp->imp_obd->obd_name,
                 sizeof(gmsg->gum_data.gum_obd));
 
index 808b4c5..13d8d20 100644 (file)
@@ -517,7 +517,7 @@ int gss_cli_ctx_refresh(struct ptlrpc_cli_ctx *ctx)
 static
 int gss_cli_ctx_match(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred)
 {
-        return (ctx->cc_vcred.vc_uid == vcred->vc_uid);
+        return (ctx->cc_vcred.vc_pag == vcred->vc_pag);
 }
 
 static
@@ -982,7 +982,9 @@ int gss_install_rvs_cli_ctx(struct gss_sec *gsec,
         int                      rc;
         ENTRY;
 
+        vcred.vc_pag = 0;
         vcred.vc_uid = 0;
+        vcred.vc_gid = 0;
 
         cli_ctx = gss_sec_create_ctx(&gsec->gs_base, &vcred);
         if (!cli_ctx)
index 6fee149..279615a 100644 (file)
@@ -373,7 +373,8 @@ void ctx_cache_gc(struct ptlrpc_sec *sec, struct hlist_head *freelist)
  * In any cases, never touch "eternal" contexts.
  */
 static
-int ctx_cache_flush(struct ptlrpc_sec *sec, uid_t uid, int grace, int force)
+int ctx_cache_flush(struct ptlrpc_sec *sec, uint64_t pag, uid_t uid,
+                    int grace, int force)
 {
         struct ptlrpc_cli_ctx *ctx;
         struct hlist_node *pos, *next;
@@ -391,8 +392,14 @@ int ctx_cache_flush(struct ptlrpc_sec *sec, uid_t uid, int grace, int force)
 
                         if (ctx_is_eternal(ctx))
                                 continue;
-                        if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
-                                continue;
+
+                        if (sec->ps_flags & PTLRPC_SEC_FL_PAG) {
+                                if (pag != -1 && pag != ctx->cc_vcred.vc_pag)
+                                        continue;
+                        } else {
+                                if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
+                                        continue;
+                        }
 
                         if (atomic_read(&ctx->cc_refcount) > 1) {
                                 busy++;
@@ -443,7 +450,7 @@ struct ptlrpc_cli_ctx * ctx_cache_lookup(struct ptlrpc_sec *sec,
 
         might_sleep();
 
-        hash = ctx_hash_index(sec, (__u64) vcred->vc_uid);
+        hash = ctx_hash_index(sec, vcred->vc_pag);
         LASSERT(hash < sec->ps_ccache_size);
         hash_head = &sec->ps_ccache[hash];
 
@@ -520,15 +527,26 @@ retry:
 static inline
 struct ptlrpc_cli_ctx *get_my_ctx(struct ptlrpc_sec *sec)
 {
-        struct vfs_cred vcred = { cfs_current()->uid, cfs_current()->gid };
+        struct vfs_cred vcred;
         int create = 1, remove_dead = 1;
 
-        if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
-                vcred.vc_uid = 0;
-                create = 0;
-                remove_dead = 0;
-        } else if (sec->ps_flags & PTLRPC_SEC_FL_ROOTONLY)
+        if (sec->ps_flags & (PTLRPC_SEC_FL_REVERSE | PTLRPC_SEC_FL_ROOTONLY)) {
+                vcred.vc_pag = 0;
                 vcred.vc_uid = 0;
+                vcred.vc_gid = 0;
+                if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
+                        create = 0;
+                        remove_dead = 0;
+                }
+        } else {
+                vcred.vc_pag = sec->ps_flags & PTLRPC_SEC_FL_PAG ?
+                               CURRENT_PAG : current->uid;
+                vcred.vc_uid = current->uid;
+                vcred.vc_gid = current->gid;
+                /* don't distinguash root from others in pag mode */
+                if (vcred.vc_uid == 0)
+                        vcred.vc_pag = 0;
+        }
 
         if (sec->ps_policy->sp_cops->lookup_ctx)
                 return sec->ps_policy->sp_cops->lookup_ctx(sec, &vcred);
@@ -622,7 +640,7 @@ void sptlrpc_ctx_replace(struct ptlrpc_sec *sec, struct ptlrpc_cli_ctx *new)
         unsigned int hash;
         ENTRY;
 
-        hash = ctx_hash_index(sec, (__u64) new->cc_vcred.vc_uid);
+        hash = ctx_hash_index(sec, new->cc_vcred.vc_pag);
         LASSERT(hash < sec->ps_ccache_size);
 
         spin_lock(&sec->ps_lock);
@@ -1243,7 +1261,7 @@ void sptlrpc_sec_put(struct ptlrpc_sec *sec)
                 return;
         }
 
-        ctx_cache_flush(sec, -1, 1, 1);
+        ctx_cache_flush(sec, -1, -1, 1, 1);
 
         if (atomic_dec_and_test(&sec->ps_busy))
                 sptlrpc_sec_destroy(sec);
@@ -1469,15 +1487,17 @@ void sptlrpc_import_flush_root_ctx(struct obd_import *imp)
         /* use 'grace' mode, it's crutial see explain in
          * sptlrpc_req_refresh_ctx()
          */
-        ctx_cache_flush(imp->imp_sec, 0, 1, 1);
+        ctx_cache_flush(imp->imp_sec, 0, 0, 1, 1);
 }
 
 void sptlrpc_import_flush_my_ctx(struct obd_import *imp)
 {
+        uint64_t pag = cfs_current()->uid == 0 ? 0 : CURRENT_PAG;
+
         if (imp == NULL || imp->imp_sec == NULL)
                 return;
 
-        ctx_cache_flush(imp->imp_sec, cfs_current()->uid, 1, 1);
+        ctx_cache_flush(imp->imp_sec, pag, cfs_current()->uid, 1, 1);
 }
 EXPORT_SYMBOL(sptlrpc_import_flush_my_ctx);
 
@@ -1486,7 +1506,7 @@ void sptlrpc_import_flush_all_ctx(struct obd_import *imp)
         if (imp == NULL || imp->imp_sec == NULL)
                 return;
 
-        ctx_cache_flush(imp->imp_sec, -1, 0, 1);
+        ctx_cache_flush(imp->imp_sec, -1, -1, 0, 1);
 }
 EXPORT_SYMBOL(sptlrpc_import_flush_all_ctx);
 
index 5a6ec02..7ea1152 100644 (file)
@@ -57,6 +57,8 @@ void sec_flags2str(unsigned long flags, char *buf, int bufsize)
                 strncat(buf, "rootonly,", bufsize);
         if (flags & PTLRPC_SEC_FL_BULK)
                 strncat(buf, "bulk,", bufsize);
+        if (flags & PTLRPC_SEC_FL_PAG)
+                strncat(buf, "pag,", bufsize);
         if (buf[0] == '\0')
                 strncat(buf, "-,", bufsize);
 
index 29974ed..a0531be 100644 (file)
@@ -19,7 +19,7 @@ noinst_PROGRAMS = llog_reader lr_reader wirecheck wiretest lload obdio obdbarrie
 rootsbin_PROGRAMS = mount.lustre
 sbin_PROGRAMS = mkfs.lustre tunefs.lustre lctl \
        l_getidentity l_facl llverfs llverdev
-bin_PROGRAMS = lfs req_layout
+bin_PROGRAMS = lfs req_layout lkinit
 sbin_SCRIPTS = $(sbin_scripts)
 endif # UTILS
 
@@ -33,6 +33,8 @@ lfs_SOURCES = lfs.c parser.c obd.c
 lfs_LDADD := $(LIBREADLINE) liblustreapi.a $(LIBPTLCTL)
 lfs_DEPENDENCIES := $(LIBPTLCTL) liblustreapi.a 
 
+lkinit_SOURCES = lkinit.c
+
 lload_SOURCES = lload.c 
 lload_LDADD := $(LIBREADLINE) $(LIBPTLCTL)
 lload_DEPENDENCIES := $(LIBPTLCTL)
index 53150da..e3bebb2 100644 (file)
@@ -899,7 +899,7 @@ int construct_service_name(struct clnt_info *clp,
 void
 handle_krb5_upcall(struct clnt_info *clp)
 {
-       gss_buffer_desc         token;
+       gss_buffer_desc         token = { 0, NULL };
        struct lgssd_upcall_data updata;
        struct lustre_gss_data  lgd;
        char                    **credlist = NULL;
@@ -907,19 +907,30 @@ handle_krb5_upcall(struct clnt_info *clp)
 
        printerr(2, "handling krb5 upcall\n");
 
+       memset(&lgd, 0, sizeof(lgd));
        lgd.lgd_rpc_err = -EPERM; /* default error code */
 
-       token.length = 0;
-       token.value = NULL;
-
        if (read(clp->krb5_fd, &updata, sizeof(updata)) != sizeof(updata)) {
                printerr(0, "WARNING: failed reading from krb5 "
                            "upcall pipe: %s\n", strerror(errno));
                goto out;
        }
 
-       printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, obd %s\n",
-                updata.seq, updata.uid, updata.svc, updata.nid, updata.obd);
+       printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, "
+                "pag %llx, obd %s\n", updata.seq, updata.uid, updata.svc,
+                updata.nid, updata.pag, updata.obd);
+
+       /* XXX in kernel pag is defined as "unsigned long", which might
+        * not keep original signed value after converted to u64.
+        */
+       if (updata.pag != updata.uid &&
+           ((updata.pag == 0xffffffffffffffffULL) ||
+            (updata.pag == 0xffffffff))) {
+               printerr(0, "uid %u: pag %llx not allowed\n",
+                        updata.uid, updata.pag);
+               lgd.lgd_rpc_err = -EPROTO;
+               goto out_return_error;
+       }
 
        if (updata.svc != LUSTRE_GSS_SVC_MDS &&
            updata.svc != LUSTRE_GSS_SVC_OSS) {
@@ -970,7 +981,8 @@ handle_krb5_upcall(struct clnt_info *clp)
        }
        else {
                /* Tell krb5 gss which credentials cache to use */
-               gssd_setup_krb5_user_gss_ccache(updata.uid, clp->servicename);
+               gssd_setup_krb5_user_gss_ccache(updata.pag, updata.uid,
+                                               clp->servicename);
 
                if ((gssd_create_lgd(clp, &lgd, &updata, AUTHTYPE_KRB5)) != 0) {
                        printerr(0, "WARNING: Failed to create krb5 context "
index 73477b9..ec65554 100644 (file)
@@ -748,14 +748,21 @@ parse_enctypes(char *enctypes)
  *     void
  */
 void
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
+gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername)
 {
        char                    buf[MAX_NETOBJ_SZ];
        struct dirent           *d;
 
-       printerr(2, "getting credentials for client with uid %u for "
-                   "server %s\n", uid, servername);
+       printerr(2, "getting credentials for client with pag %llx/uid %u for "
+                   "server %s\n", pag, uid, servername);
        memset(buf, 0, sizeof(buf));
+
+       if (pag != uid) {
+               snprintf(buf, sizeof(buf), "FILE:%s/%spag_%llx",
+                        ccachedir, GSSD_DEFAULT_CRED_PREFIX, pag);
+               goto set_ccname;
+       }
+
        if (gssd_find_existing_krb5_ccache(uid, &d)) {
                snprintf(buf, sizeof(buf), "FILE:%s/%s",
                        ccachedir, d->d_name);
@@ -766,6 +773,7 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
                        ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
        printerr(2, "using %s as credentials cache for client with "
                    "uid %u for server %s\n", buf, uid, servername);
+set_ccname:
        gssd_set_krb5_ccache_name(buf);
 }
 
index cf574df..e9221db 100644 (file)
@@ -18,7 +18,7 @@ struct gssd_k5_kt_princ {
 };
 
 
-void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
+void gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername);
 int  gssd_get_krb5_machine_cred_list(char ***list);
 int  gssd_refresh_krb5_machine_creds(void);
 void gssd_free_krb5_machine_cred_list(char **list);
index 1a15384..c310e16 100644 (file)
@@ -27,6 +27,7 @@ struct lgssd_upcall_data {
         uint32_t        gid;
         uint32_t        svc;
         uint64_t        nid;
+        uint64_t        pag;
         char            obd[64];
 };
 
index 3892cbc..fc10241 100644 (file)
@@ -1,5 +1,5 @@
 --- nfs-utils-1.0.10/utils/gssd/gssd_proc.c.lustre     2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/gssd_proc.c    2006-10-13 17:25:01.000000000 -0600
++++ nfs-utils-1.0.10/utils/gssd/gssd_proc.c    2006-10-18 16:14:14.000000000 -0600
 @@ -43,7 +43,6 @@
  #endif
  #include "config.h"
 +      close(fd);
 +      return 0;
 +}
++
 +static
 +int gssd_refresh_lgd(struct lustre_gss_data *lgd)
 +{
 +                              recv_tokenp = &gr.gr_token;
 +                      }
 +              }
-+
 +              /* GSS_S_COMPLETE => check gss header verifier,
 +               * usually checked in gss_validate
 +               */
  
  /*
   * this code uses the userland rpcsec gss library to create a krb5
-@@ -667,27 +899,42 @@
+@@ -667,27 +899,53 @@
  void
  handle_krb5_upcall(struct clnt_info *clp)
  {
 -      CLIENT                  *rpc_clnt = NULL;
 -      AUTH                    *auth = NULL;
 -      struct authgss_private_data pd;
-       gss_buffer_desc         token;
+-      gss_buffer_desc         token;
++      gss_buffer_desc         token = { 0, NULL };
 +      struct lgssd_upcall_data updata;
 +      struct lustre_gss_data  lgd;
        char                    **credlist = NULL;
  
 -      printerr(1, "handling krb5 upcall\n");
 +      printerr(2, "handling krb5 upcall\n");
-+
-+      lgd.lgd_rpc_err = -EPERM; /* default error code */
  
-       token.length = 0;
-       token.value = NULL;
+-      token.length = 0;
+-      token.value = NULL;
 -      memset(&pd, 0, sizeof(struct authgss_private_data));
++      memset(&lgd, 0, sizeof(lgd));
++      lgd.lgd_rpc_err = -EPERM; /* default error code */
  
 -      if (read(clp->krb5_fd, &uid, sizeof(uid)) < sizeof(uid)) {
 -              printerr(0, "WARNING: failed reading uid from krb5 "
        }
  
 -      if (uid == 0) {
-+      printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, obd %s\n",
-+               updata.seq, updata.uid, updata.svc, updata.nid, updata.obd);
++      printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, "
++               "pag %llx, obd %s\n", updata.seq, updata.uid, updata.svc,
++               updata.nid, updata.pag, updata.obd);
++
++      /* XXX in kernel pag is defined as "unsigned long", which might
++       * not keep original signed value after converted to u64.
++       */
++      if (updata.pag != updata.uid &&
++          ((updata.pag == 0xffffffffffffffffULL) ||
++           (updata.pag == 0xffffffff))) {
++              printerr(0, "uid %u: pag %llx not allowed\n",
++                       updata.uid, updata.pag);
++              lgd.lgd_rpc_err = -EPROTO;
++              goto out_return_error;
++      }
 +
 +      if (updata.svc != LUSTRE_GSS_SVC_MDS &&
 +          updata.svc != LUSTRE_GSS_SVC_OSS) {
                int success = 0;
  
                /*
-@@ -695,75 +942,65 @@
+@@ -695,75 +953,66 @@
                 * of them until one works or we've tried them all
                 */
                if (gssd_get_krb5_machine_cred_list(&credlist)) {
        else {
                /* Tell krb5 gss which credentials cache to use */
 -              gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
-+              gssd_setup_krb5_user_gss_ccache(updata.uid, clp->servicename);
++              gssd_setup_krb5_user_gss_ccache(updata.pag, updata.uid,
++                                              clp->servicename);
  
 -              if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
 -                                                      AUTHTYPE_KRB5)) != 0) {
        goto out;
  }
  
-@@ -774,6 +1011,7 @@
+@@ -774,6 +1023,7 @@
  void
  handle_spkm3_upcall(struct clnt_info *clp)
  {
        uid_t                   uid;
        CLIENT                  *rpc_clnt = NULL;
        AUTH                    *auth = NULL;
-@@ -825,4 +1063,5 @@
+@@ -825,4 +1075,5 @@
  out_return_error:
        do_error_downcall(clp->spkm3_fd, uid, -1);
        goto out;
        const gss_OID mech);
  int gssd_check_mechs(void);
 --- nfs-utils-1.0.10/utils/gssd/krb5_util.h.lustre     2006-10-13 16:02:38.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/krb5_util.h    2006-10-13 16:03:33.000000000 -0600
-@@ -10,6 +10,8 @@
++++ nfs-utils-1.0.10/utils/gssd/krb5_util.h    2006-10-17 20:13:38.000000000 -0600
+@@ -10,13 +10,15 @@
  struct gssd_k5_kt_princ {
        struct gssd_k5_kt_princ *next;
        krb5_principal princ;
        char *ccname;
        char *realm;
        krb5_timestamp endtime;
+ };
+-void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
++void gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername);
+ int  gssd_get_krb5_machine_cred_list(char ***list);
+ int  gssd_refresh_krb5_machine_creds(void);
+ void gssd_free_krb5_machine_cred_list(char **list);
 @@ -25,8 +27,32 @@
  void gssd_obtain_kernel_krb5_info(void);
  
  
  #endif /* KRB5_UTIL_H */
 --- nfs-utils-1.0.10/utils/gssd/krb5_util.c.lustre     2006-10-13 16:02:38.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/krb5_util.c    2006-10-13 16:03:33.000000000 -0600
++++ nfs-utils-1.0.10/utils/gssd/krb5_util.c    2006-10-18 11:56:30.000000000 -0600
 @@ -99,12 +99,14 @@
  #include <rpc/rpc.h>
  #include <sys/types.h>
        }
  
        if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) {
-@@ -695,7 +816,18 @@
+@@ -627,14 +748,21 @@
+  *    void
+  */
+ void
+-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
++gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername)
+ {
+       char                    buf[MAX_NETOBJ_SZ];
+       struct dirent           *d;
+-      printerr(2, "getting credentials for client with uid %u for "
+-                  "server %s\n", uid, servername);
++      printerr(2, "getting credentials for client with pag %llx/uid %u for "
++                  "server %s\n", pag, uid, servername);
+       memset(buf, 0, sizeof(buf));
++
++      if (pag != uid) {
++              snprintf(buf, sizeof(buf), "FILE:%s/%spag_%llx",
++                       ccachedir, GSSD_DEFAULT_CRED_PREFIX, pag);
++              goto set_ccname;
++      }
++
+       if (gssd_find_existing_krb5_ccache(uid, &d)) {
+               snprintf(buf, sizeof(buf), "FILE:%s/%s",
+                       ccachedir, d->d_name);
+@@ -645,6 +773,7 @@
+                       ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
+       printerr(2, "using %s as credentials cache for client with "
+                   "uid %u for server %s\n", buf, uid, servername);
++set_ccname:
+       gssd_set_krb5_ccache_name(buf);
+ }
+@@ -695,7 +824,18 @@
                goto out;
        }
  
  
        if ((code = krb5_kt_resolve(context, keytabfile, &kt))) {
                printerr(0, "ERROR: %s while resolving keytab '%s'\n",
-@@ -710,12 +842,12 @@
+@@ -710,12 +850,12 @@
                if (gssd_k5_kt_princ_list == NULL) {
                        printerr(0, "ERROR: No usable keytab entries found in "
                                    "keytab '%s'\n", keytabfile);
                }
        }
  
-@@ -865,6 +997,7 @@
+@@ -865,6 +1005,7 @@
        krb5_free_context(context);
  }
  
  #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
  /*
   * this routine obtains a credentials handle via gss_acquire_cred()
-@@ -920,6 +1053,7 @@
+@@ -920,6 +1061,7 @@
        return 0;
  }
  #endif        /* HAVE_SET_ALLOWABLE_ENCTYPES */
  #include "gss_oids.h"
  #include "err_util.h"
 --- nfs-utils-1.0.10/utils/gssd/lsupport.h.lustre      2006-10-13 16:03:33.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/lsupport.h     2006-10-13 17:24:45.000000000 -0600
-@@ -0,0 +1,88 @@
++++ nfs-utils-1.0.10/utils/gssd/lsupport.h     2006-10-17 19:46:49.000000000 -0600
+@@ -0,0 +1,89 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + */
 +        uint32_t        gid;
 +        uint32_t        svc;
 +        uint64_t        nid;
++        uint64_t        pag;
 +        char            obd[64];
 +};
 +
diff --git a/lustre/utils/lkinit.c b/lustre/utils/lkinit.c
new file mode 100644 (file)
index 0000000..2fd92a2
--- /dev/null
@@ -0,0 +1,119 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/unistd.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef __NR_newpag
+#define __NR_newpag            289
+#define __NR_getpag            290
+#endif
+
+_syscall0(int, newpag);
+_syscall0(int, getpag);
+
+void usage(const char *exe)
+{
+       printf("Usage: %s -k \"parameters_to_kinit\" command line\n", exe);
+       exit(1);
+}
+
+int check_kopt(const char *opt)
+{
+        /* FIXME check "-c" here */
+        return 0;
+}
+
+#define CMD_BUFSIZE    4096
+
+int main(int argc, char *argv[])
+{
+        extern char *optarg;
+        int opt, i;
+       unsigned long pag;
+        char kopt[CMD_BUFSIZE];
+        char kcmd[CMD_BUFSIZE];
+       char cmd[CMD_BUFSIZE];
+
+        kopt[0] = '\0';
+        cmd[0] = '\0';
+
+        if (getuid() == 0) {
+                fprintf(stderr, "root user don't want to use lkinit\n");
+                return 1;
+        }
+
+       newpag();
+       pag = getpag();
+
+        snprintf(kcmd, CMD_BUFSIZE, "kinit -c /tmp/krb5cc_pag_%lx", pag);
+
+        while ((opt = getopt(argc, argv, "k:")) != -1) {
+                switch (opt) {
+                case 'k':
+                        if (check_kopt(optarg)) {
+                                fprintf(stderr, "Can't specify cache file\n");
+                                return 1;
+                        }
+
+                        snprintf(kcmd, CMD_BUFSIZE,
+                                 "kinit -c /tmp/krb5cc_pag_%lx %s",
+                                 pag, optarg);
+                        break;
+                default:
+                        usage(argv[0]);
+                }
+        }
+
+       if (optind >= argc) {
+               snprintf(cmd, CMD_BUFSIZE, "/bin/sh");
+       } else {
+                for (i = optind; i < argc; i++) {
+                        if (i != optind)
+                                strncat(cmd, " ", CMD_BUFSIZE);
+                        strncat(cmd, argv[i], CMD_BUFSIZE);
+                }
+       }
+
+        if (system(kcmd)) {
+                fprintf(stderr, "can't get kerberos TGT\n");
+                return 1;
+        }
+
+        if (system(cmd))
+                fprintf(stderr, "execute error\n");
+
+        /* flush in-kernel credential cache */
+        snprintf(cmd, CMD_BUFSIZE, "lfs flushctx");
+        if (system(cmd))
+                fprintf(stderr, "failed to flush in-kernel credential\n");
+
+        /* flush user-space credential cache */
+        snprintf(kcmd, CMD_BUFSIZE, "kdestroy -c /tmp/krb5cc_pag_%lx", pag);
+        system(kcmd);
+
+       return 0;
+}