From e8cdee02acb7f2a12a977872e123de167c667f43 Mon Sep 17 00:00:00 2001 From: ericm Date: Wed, 18 Oct 2006 23:48:43 +0000 Subject: [PATCH] branch: b_new_cmd basic support for PAG, ported from HEAD. --- lustre/include/liblustre.h | 1 + lustre/include/lustre_disk.h | 1 + lustre/include/lustre_sec.h | 11 ++ .../patches/pag-basic-2.6-rhel4.patch | 74 +++++++++++++ lustre/kernel_patches/series/2.6-rhel4.series | 1 + lustre/llite/llite_lib.c | 6 ++ lustre/lmv/lmv_obd.c | 30 ++++++ lustre/mdc/mdc_request.c | 7 ++ lustre/obdclass/obd_mount.c | 3 + lustre/ptlrpc/gss/gss_cli_upcall.c | 2 + lustre/ptlrpc/gss/sec_gss.c | 4 +- lustre/ptlrpc/sec.c | 50 ++++++--- lustre/ptlrpc/sec_lproc.c | 2 + lustre/utils/Makefile.am | 4 +- lustre/utils/gss/gssd_proc.c | 26 +++-- lustre/utils/gss/krb5_util.c | 14 ++- lustre/utils/gss/krb5_util.h | 2 +- lustre/utils/gss/lsupport.h | 1 + lustre/utils/gss/nfs-utils-1.0.10-lustre.diff | 105 +++++++++++++----- lustre/utils/lkinit.c | 119 +++++++++++++++++++++ 20 files changed, 411 insertions(+), 52 deletions(-) create mode 100644 lustre/kernel_patches/patches/pag-basic-2.6-rhel4.patch create mode 100644 lustre/utils/lkinit.c diff --git a/lustre/include/liblustre.h b/lustre/include/liblustre.h index 17dbceb..3321d23 100644 --- a/lustre/include/liblustre.h +++ b/lustre/include/liblustre.h @@ -585,6 +585,7 @@ struct task_struct { int state; struct signal pending; char comm[32]; + unsigned long pag; int uid; int gid; int pid; diff --git a/lustre/include/lustre_disk.h b/lustre/include/lustre_disk.h index 55cf2a4..afedbde 100644 --- a/lustre/include/lustre_disk.h +++ b/lustre/include/lustre_disk.h @@ -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 diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index c99af98..bdfe6bc 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -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 index 0000000..e68df60 --- /dev/null +++ b/lustre/kernel_patches/patches/pag-basic-2.6-rhel4.patch @@ -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(¤t->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__ + /* diff --git a/lustre/kernel_patches/series/2.6-rhel4.series b/lustre/kernel_patches/series/2.6-rhel4.series index 709df80..69ccc0e 100644 --- a/lustre/kernel_patches/series/2.6-rhel4.series +++ b/lustre/kernel_patches/series/2.6-rhel4.series @@ -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 diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 41bb1be..04358e1 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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); diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 849ef09..59ef7dc 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -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); } diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index b28d352..418bb1be 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -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); } diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index 58c4672..10a30f2 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -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. */ diff --git a/lustre/ptlrpc/gss/gss_cli_upcall.c b/lustre/ptlrpc/gss/gss_cli_upcall.c index f9afadb..a67b297 100644 --- a/lustre/ptlrpc/gss/gss_cli_upcall.c +++ b/lustre/ptlrpc/gss/gss_cli_upcall.c @@ -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)); diff --git a/lustre/ptlrpc/gss/sec_gss.c b/lustre/ptlrpc/gss/sec_gss.c index 808b4c5..13d8d20 100644 --- a/lustre/ptlrpc/gss/sec_gss.c +++ b/lustre/ptlrpc/gss/sec_gss.c @@ -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) diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 6fee149..279615a 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -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); diff --git a/lustre/ptlrpc/sec_lproc.c b/lustre/ptlrpc/sec_lproc.c index 5a6ec02..7ea1152 100644 --- a/lustre/ptlrpc/sec_lproc.c +++ b/lustre/ptlrpc/sec_lproc.c @@ -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); diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 29974ed..a0531be 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -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) diff --git a/lustre/utils/gss/gssd_proc.c b/lustre/utils/gss/gssd_proc.c index 53150da..e3bebb2 100644 --- a/lustre/utils/gss/gssd_proc.c +++ b/lustre/utils/gss/gssd_proc.c @@ -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 " diff --git a/lustre/utils/gss/krb5_util.c b/lustre/utils/gss/krb5_util.c index 73477b9..ec65554 100644 --- a/lustre/utils/gss/krb5_util.c +++ b/lustre/utils/gss/krb5_util.c @@ -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); } diff --git a/lustre/utils/gss/krb5_util.h b/lustre/utils/gss/krb5_util.h index cf574df..e9221db 100644 --- a/lustre/utils/gss/krb5_util.h +++ b/lustre/utils/gss/krb5_util.h @@ -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); diff --git a/lustre/utils/gss/lsupport.h b/lustre/utils/gss/lsupport.h index 1a15384..c310e16 100644 --- a/lustre/utils/gss/lsupport.h +++ b/lustre/utils/gss/lsupport.h @@ -27,6 +27,7 @@ struct lgssd_upcall_data { uint32_t gid; uint32_t svc; uint64_t nid; + uint64_t pag; char obd[64]; }; diff --git a/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff b/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff index 3892cbc..fc10241 100644 --- a/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff +++ b/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff @@ -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" @@ -374,7 +374,7 @@ + close(fd); + return 0; +} - ++ +static +int gssd_refresh_lgd(struct lustre_gss_data *lgd) +{ @@ -449,7 +449,7 @@ + recv_tokenp = &gr.gr_token; + } + } -+ + + /* GSS_S_COMPLETE => check gss header verifier, + * usually checked in gss_validate + */ @@ -574,7 +574,7 @@ /* * 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) { @@ -582,7 +582,8 @@ - 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; @@ -590,12 +591,12 @@ - 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 " @@ -606,8 +607,21 @@ } - 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) { @@ -626,7 +640,7 @@ 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)) { @@ -670,7 +684,8 @@ 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) { @@ -726,7 +741,7 @@ goto out; } -@@ -774,6 +1011,7 @@ +@@ -774,6 +1023,7 @@ void handle_spkm3_upcall(struct clnt_info *clp) { @@ -734,7 +749,7 @@ 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; @@ -1439,8 +1454,8 @@ 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; @@ -1449,6 +1464,14 @@ 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); @@ -1486,7 +1509,7 @@ #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 #include @@ -1880,7 +1903,40 @@ } 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; } @@ -1900,7 +1956,7 @@ 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); @@ -1918,7 +1974,7 @@ } } -@@ -865,6 +997,7 @@ +@@ -865,6 +1005,7 @@ krb5_free_context(context); } @@ -1926,7 +1982,7 @@ #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 */ @@ -1961,8 +2017,8 @@ #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: + */ @@ -1992,6 +2048,7 @@ + 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 index 0000000..2fd92a2 --- /dev/null +++ b/lustre/utils/lkinit.c @@ -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 +#include +#include +#include +#include +#include + +#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; +} -- 1.8.3.1