From 44f3d772c1ace979163c52b70ec392b81b45e39c Mon Sep 17 00:00:00 2001 From: ericm Date: Thu, 7 Jul 2005 17:41:19 +0000 Subject: [PATCH] land b_hd_sec on HEAD. various security fixes. --- lustre/include/linux/lustre_net.h | 18 ++- lustre/include/linux/lustre_sec.h | 261 +++++++++++++++++++++++--------------- lustre/include/linux/obd.h | 2 +- lustre/ldlm/ldlm_lib.c | 24 +--- lustre/llite/llite_internal.h | 3 +- lustre/llite/llite_lib.c | 18 +++ lustre/llite/super25.c | 3 +- lustre/lmv/lmv_obd.c | 1 + lustre/lov/lov_obd.c | 2 +- lustre/mdc/mdc_request.c | 33 ++--- lustre/mds/handler.c | 31 ++--- lustre/mds/mds_lib.c | 85 ++++++++----- lustre/mds/mds_lmv.c | 7 + lustre/mds/mds_lov.c | 13 +- lustre/osc/osc_request.c | 33 ++--- lustre/ptlrpc/client.c | 5 + lustre/ptlrpc/service.c | 2 + lustre/sec/gss/gss_internal.h | 46 +++++-- lustre/sec/gss/gss_krb5_mech.c | 12 +- lustre/sec/gss/sec_gss.c | 93 +++++++------- lustre/sec/gss/svcsec_gss.c | 126 +++++++++++------- lustre/sec/sec.c | 175 ++++++++++++++++--------- lustre/sec/sec_null.c | 13 +- lustre/sec/svcsec.c | 52 ++++---- lustre/sec/svcsec_null.c | 11 +- lustre/utils/lustre_cfg.c | 2 +- 26 files changed, 639 insertions(+), 432 deletions(-) diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index 4267dd6..e2bb14a 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -313,13 +313,17 @@ struct ptlrpc_request { __u64 rq_xid; struct list_head rq_replay_list; - struct ptlrpc_cred *rq_cred; /* client side credit */ - struct ptlrpc_svcsec *rq_svcsec; /* server side security */ - /* XXX temporarily put here XXX */ - void *rq_sec_svcdata; /* server security data */ - unsigned int rq_remote_realm;/* from remote realm */ - uid_t rq_auth_uid; - uid_t rq_mapped_uid; + struct ptlrpc_cred *rq_cred; /* client side */ + struct ptlrpc_svcsec *rq_svcsec; /* server side */ + /* flavor of request, on both client & server */ + __u32 rq_req_secflvr; + /* server side security tracking data, need cleanup */ + void *rq_svcsec_data; /* server security data */ + unsigned int rq_remote_realm:1, /* from remote realm */ + rq_auth_usr_mds:1, /* auth as mds svc cred */ + rq_auth_usr_oss:1; /* auth as oss svc cred */ + uid_t rq_auth_uid; + uid_t rq_mapped_uid; char *rq_reqbuf; /* backend request buffer */ int rq_reqbuf_len; /* backend request buffer length */ diff --git a/lustre/include/linux/lustre_sec.h b/lustre/include/linux/lustre_sec.h index e452316..6fc831f 100644 --- a/lustre/include/linux/lustre_sec.h +++ b/lustre/include/linux/lustre_sec.h @@ -22,6 +22,112 @@ #ifndef __LINUX_SEC_H_ #define __LINUX_SEC_H_ +enum ptlrpcs_major_flavors { + PTLRPCS_FLVR_MAJOR_NULL = 0, + PTLRPCS_FLVR_MAJOR_GSS = 1, + PTLRPCS_FLVR_MAJOR_MAX, +}; + +enum ptlrpcs_null_minor_flavors { + PTLRPCS_FLVR_MINOR_NULL = 0, + PTLRPCS_FLVR_MINOR_NULL_MAX, +}; +enum ptlrpcs_gss_minor_flavors { + PTLRPCS_FLVR_MINOR_GSS_NONE = 0, + PTLRPCS_FLVR_MINOR_GSS_KRB5 = 1, + PTLRPCS_FLVR_MINOR_GSS_MAX, +}; + +enum ptlrpcs_security_type { + PTLRPCS_SVC_NONE = 0, /* no security */ + PTLRPCS_SVC_AUTH = 1, /* authentication */ + PTLRPCS_SVC_PRIV = 2, /* privacy */ + PTLRPCS_SVC_MAX, +}; + +/* + * flavor compose/extract + */ +#define SEC_FLAVOR_MAJOR_OFFSET (24) +#define SEC_FLAVOR_RESERVE_OFFSET (16) +#define SEC_FLAVOR_SVC_OFFSET (8) +#define SEC_FLAVOR_MINOR_OFFSET (0) + +#define SEC_MAKE_FLAVOR(major, minor, svc) \ + (((__u32)(major) << SEC_FLAVOR_MAJOR_OFFSET) | \ + ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \ + ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET)) + +#define SEC_MAKE_SUBFLAVOR(minor, svc) \ + (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \ + ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET)) + +#define SEC_FLAVOR_MAJOR(flavor) \ + ((((__u32)(flavor)) >> SEC_FLAVOR_MAJOR_OFFSET) & 0xFF) +#define SEC_FLAVOR_MINOR(flavor) \ + ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFF) +#define SEC_FLAVOR_SVC(flavor) \ + ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xFF) +#define SEC_FLAVOR_SUB(flavor) \ + ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFFFF) + +/* + * general gss flavors + */ +#define PTLRPCS_FLVR_GSS_NONE \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_NONE, \ + PTLRPCS_SVC_NONE) +#define PTLRPCS_FLVR_GSS_AUTH \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_NONE, \ + PTLRPCS_SVC_AUTH) +#define PTLRPCS_FLVR_GSS_PRIV \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_NONE, \ + PTLRPCS_SVC_PRIV) + +/* + * gss subflavors + */ +#define PTLRPCS_SUBFLVR_KRB5 \ + SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_NONE) +#define PTLRPCS_SUBFLVR_KRB5I \ + SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_AUTH) +#define PTLRPCS_SUBFLVR_KRB5P \ + SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_PRIV) + +/* + * "end user" flavors + */ +#define PTLRPCS_FLVR_NULL \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL, \ + PTLRPCS_FLVR_MINOR_NULL, \ + PTLRPCS_SVC_NONE) +#define PTLRPCS_FLVR_KRB5 \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_NONE) +#define PTLRPCS_FLVR_KRB5I \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_AUTH) +#define PTLRPCS_FLVR_KRB5P \ + SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \ + PTLRPCS_FLVR_MINOR_GSS_KRB5, \ + PTLRPCS_SVC_PRIV) + +#define PTLRPCS_FLVR_INVALID (-1) + +__u32 ptlrpcs_name2flavor(const char *name); +char *ptlrpcs_flavor2name(__u32 flavor); + + +#ifdef __KERNEL__ + /* forward declaration */ struct obd_import; struct ptlrpc_request; @@ -30,30 +136,18 @@ struct ptlrpc_credops; struct ptlrpc_sec; struct ptlrpc_secops; -#define PTLRPC_SEC_MAX_FLAVORS (4) - -typedef struct ptlrpcs_flavor_s { - __u32 flavor; - __u32 subflavor; -} ptlrpcs_flavor_t; typedef struct { struct list_head list; - ptlrpcs_flavor_t sec; + __u32 flavor; } deny_sec_t; -enum ptlrpcs_security_type { - PTLRPC_SEC_TYPE_NONE = 0, /* no security */ - PTLRPC_SEC_TYPE_AUTH = 1, /* authentication */ - PTLRPC_SEC_TYPE_PRIV = 2, /* privacy */ -}; - /* * This header is prepended at any on-wire ptlrpc packets */ struct ptlrpcs_wire_hdr { __u32 flavor; - __u32 sectype; + __u32 unused; __u32 msg_len; __u32 sec_len; }; @@ -78,50 +172,39 @@ __u8 *buf_to_sec_data(void *buf) return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len); } -enum ptlrpcs_flavors { - PTLRPC_SEC_NULL = 0, - PTLRPC_SEC_GSS = 1, -}; - #define PTLRPC_SEC_GSS_VERSION (1) -enum ptlrpcs_gss_subflavors { - PTLRPC_SEC_GSS_KRB5 = 0, - PTLRPC_SEC_GSS_KRB5I = 1, - PTLRPC_SEC_GSS_KRB5P = 2, -}; - enum ptlrpcs_gss_proc { - PTLRPC_GSS_PROC_DATA = 0, - PTLRPC_GSS_PROC_INIT = 1, - PTLRPC_GSS_PROC_CONTINUE_INIT = 2, - PTLRPC_GSS_PROC_DESTROY = 3, - PTLRPC_GSS_PROC_ERR = 4, + PTLRPCS_GSS_PROC_DATA = 0, + PTLRPCS_GSS_PROC_INIT = 1, + PTLRPCS_GSS_PROC_CONTINUE_INIT = 2, + PTLRPCS_GSS_PROC_DESTROY = 3, + PTLRPCS_GSS_PROC_ERR = 4, }; enum ptlrpcs_gss_svc { - PTLRPC_GSS_SVC_NONE = 1, - PTLRPC_GSS_SVC_INTEGRITY = 2, - PTLRPC_GSS_SVC_PRIVACY = 3, + PTLRPCS_GSS_SVC_NONE = 1, + PTLRPCS_GSS_SVC_INTEGRITY = 2, + PTLRPCS_GSS_SVC_PRIVACY = 3, }; enum ptlrpcs_error { - PTLRPCS_OK = 0, - PTLRPCS_BADCRED = 1, - PTLRPCS_REJECTEDCRED = 2, - PTLRPCS_BADVERF = 3, - PTLRPCS_REJECTEDVERF = 4, - PTLRPCS_TOOWEAK = 5, + PTLRPCS_OK = 0, + PTLRPCS_BADCRED = 1, + PTLRPCS_REJECTEDCRED = 2, + PTLRPCS_BADVERF = 3, + PTLRPCS_REJECTEDVERF = 4, + PTLRPCS_TOOWEAK = 5, /* GSS errors */ - PTLRPCS_GSS_CREDPROBLEM = 13, - PTLRPCS_GSS_CTXPROBLEM = 14, + PTLRPCS_GSS_CREDPROBLEM = 13, + PTLRPCS_GSS_CTXPROBLEM = 14, }; struct vfs_cred { - __u64 vc_pag; - uid_t vc_uid; - gid_t vc_gid; - struct group_info *vc_ginfo; + __u64 vc_pag; + uid_t vc_uid; + gid_t vc_gid; + struct group_info *vc_ginfo; }; struct ptlrpc_credops { @@ -163,7 +246,7 @@ struct ptlrpc_cred { }; struct ptlrpc_secops { - struct ptlrpc_sec * (*create_sec) (ptlrpcs_flavor_t *flavor, + struct ptlrpc_sec * (*create_sec) (__u32 flavor, const char *pipe_dir, void *pipe_data); void (*destroy_sec) (struct ptlrpc_sec *sec); @@ -182,8 +265,10 @@ struct ptlrpc_secops { struct ptlrpc_request *req); /* security payload size estimation */ int (*est_req_payload)(struct ptlrpc_sec *sec, + struct ptlrpc_request *req, int msgsize); int (*est_rep_payload)(struct ptlrpc_sec *sec, + struct ptlrpc_request *req, int msgsize); }; @@ -191,10 +276,13 @@ struct ptlrpc_sec_type { struct module *pst_owner; char *pst_name; atomic_t pst_inst; /* instance, debug only */ - ptlrpcs_flavor_t pst_flavor; + __u32 pst_flavor; /* major flavor */ struct ptlrpc_secops *pst_ops; }; +#define PTLRPC_SEC_FL_MDS 0x0001 /* outgoing from MDS */ +#define PTLRPC_SEC_FL_REVERSE 0x0002 /* reverse sec */ + #define PTLRPC_CREDCACHE_NR 8 #define PTLRPC_CREDCACHE_MASK (PTLRPC_CREDCACHE_NR - 1) @@ -202,22 +290,22 @@ struct ptlrpc_sec { struct ptlrpc_sec_type *ps_type; struct list_head ps_credcache[PTLRPC_CREDCACHE_NR]; spinlock_t ps_lock; /* protect cred cache */ - __u32 ps_sectype; - ptlrpcs_flavor_t ps_flavor; + __u32 ps_flavor; atomic_t ps_refcount; atomic_t ps_credcount; struct obd_import *ps_import; /* actual security model need initialize following fields */ unsigned long ps_expire; /* cache expire interval */ unsigned long ps_nextgc; /* next gc time */ - unsigned int ps_flags; + unsigned long ps_flags; }; /* sec.c */ int ptlrpcs_register(struct ptlrpc_sec_type *type); int ptlrpcs_unregister(struct ptlrpc_sec_type *type); -struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor, +struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor, + unsigned long flags, struct obd_import *import, const char *pipe_dir, void *pipe_data); @@ -277,9 +365,10 @@ static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred) return 1; } -static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec, +static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req, int datasize) { + struct ptlrpc_sec *sec = req->rq_cred->pc_sec; struct ptlrpc_secops *ops; LASSERT(sec); @@ -288,14 +377,15 @@ static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec, ops = sec->ps_type->pst_ops; if (ops->est_req_payload) - return ops->est_req_payload(sec, datasize); + return ops->est_req_payload(sec, req, datasize); else return 0; } -static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec, +static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req, int datasize) { + struct ptlrpc_sec *sec = req->rq_cred->pc_sec; struct ptlrpc_secops *ops; LASSERT(sec); @@ -304,33 +394,27 @@ static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec, ops = sec->ps_type->pst_ops; if (ops->est_rep_payload) - return ops->est_rep_payload(sec, datasize); + return ops->est_rep_payload(sec, req, datasize); else return 0; } static inline int add_deny_security(char *sec, struct list_head *head) { - int rc = 0; - deny_sec_t *p_deny_sec = NULL; + deny_sec_t *p_deny_sec = NULL; + int rc = 0; LASSERT(sec != NULL); OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec)); - if (p_deny_sec == NULL) return -ENOMEM; - - if (strcmp(sec, "null") == 0) { - p_deny_sec->sec.flavor = PTLRPC_SEC_NULL; - p_deny_sec->sec.subflavor = PTLRPC_SEC_NULL; - }else if (strcmp(sec, "krb5i") == 0) { - p_deny_sec->sec.flavor = PTLRPC_SEC_GSS; - p_deny_sec->sec.subflavor = PTLRPC_SEC_GSS_KRB5I; - }else if (strcmp(sec, "krb5p") == 0) { - p_deny_sec->sec.flavor = PTLRPC_SEC_GSS; - p_deny_sec->sec.subflavor = PTLRPC_SEC_GSS_KRB5P; - }else{ - CERROR("unrecognized security type %s\n", (char*) sec); - GOTO(out, rc = -EINVAL); + if (p_deny_sec == NULL) + return -ENOMEM; + + p_deny_sec->flavor = ptlrpcs_name2flavor(sec); + if (p_deny_sec->flavor == PTLRPCS_FLVR_INVALID) { + CERROR("unrecognized security type %s\n", (char*) sec); + rc = -EINVAL; + goto out; } list_add_tail(&p_deny_sec->list, head); @@ -377,7 +461,7 @@ struct ptlrpc_reply_state; struct ptlrpc_svcsec { struct module *pss_owner; char *pss_name; - ptlrpcs_flavor_t pss_flavor; + __u32 pss_flavor; /* major flavor */ int pss_sec_size; int (*accept) (struct ptlrpc_request *req, @@ -398,37 +482,6 @@ struct ptlrpc_svcsec { #define SVC_LOGIN 4 #define SVC_LOGOUT 5 -/* FIXME - * this should be a gss internal structure. fix these when we - * sort out the flavor issues. - */ - -typedef struct rawobj_s { - __u32 len; - __u8 *data; -} rawobj_t; - -/* on-the-wire gss cred: */ -struct rpc_gss_wire_cred { - __u32 gc_v; /* version */ - __u32 gc_proc; /* control procedure */ - __u32 gc_seq; /* sequence number */ - __u32 gc_svc; /* service */ - rawobj_t gc_ctx; /* context handle */ -}; - -struct gss_svc_data { - __u32 subflavor; /* XXX */ - /* decoded gss client cred: */ - struct rpc_gss_wire_cred clcred; - /* internal used status */ - unsigned int is_init:1, - is_init_continue:1, - is_err_notify:1, - is_fini:1; - int reserve_len; -}; - int svcsec_register(struct ptlrpc_svcsec *ss); int svcsec_unregister(struct ptlrpc_svcsec *ss); int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res); @@ -449,4 +502,6 @@ void svcsec_free_reply_state(struct ptlrpc_reply_state *rs); int svcsec_null_init(void); int svcsec_null_exit(void); +#endif /* __KERNEL__ */ + #endif /* __LINUX_SEC_H_ */ diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index f75d73f..91bd1a7 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -284,7 +284,7 @@ struct client_obd { /* security flavors */ __u32 cl_sec_flavor; - __u32 cl_sec_subflavor; + unsigned long cl_sec_flags; //struct llog_canceld_ctxt *cl_llcd; /* it's included by obd_llog_ctxt */ void *cl_llcd_offset; diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index b9f030b..249ed21 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -542,14 +542,13 @@ static inline int ptlrpc_peer_is_local(struct ptlrpc_peer *peer) * EPERM found, refuse */ -static int check_deny_list(struct list_head *head, ptlrpcs_flavor_t *p_flavor) +static int check_deny_list(struct list_head *head, __u32 flavor) { deny_sec_t *p_deny_sec = NULL; deny_sec_t *n_deny_sec = NULL; list_for_each_entry_safe(p_deny_sec, n_deny_sec, head, list) { - if ((p_deny_sec->sec.flavor == p_flavor->flavor) && - (p_deny_sec->sec.subflavor == p_flavor->subflavor)) + if (p_deny_sec->flavor == flavor) return -EPERM; } return 0; @@ -557,27 +556,18 @@ static int check_deny_list(struct list_head *head, ptlrpcs_flavor_t *p_flavor) int target_check_deny_sec(struct obd_device *target, struct ptlrpc_request *req) { - struct gss_svc_data *svcdata; - ptlrpcs_flavor_t flavor; + __u32 flavor; int rc = 0; - /* XXX hacking */ - svcdata = (struct gss_svc_data *) req->rq_sec_svcdata; - if (svcdata == NULL) { - flavor.flavor = PTLRPC_SEC_NULL; - flavor.subflavor = 0; - } else { - flavor.flavor = PTLRPC_SEC_GSS; - flavor.subflavor = svcdata->subflavor; - } + flavor = req->rq_req_secflvr; if (!strcmp(target->obd_type->typ_name, LUSTRE_MDS_NAME)) { spin_lock(&target->u.mds.mds_denylist_lock); - rc = check_deny_list(&target->u.mds.mds_denylist, &flavor); + rc = check_deny_list(&target->u.mds.mds_denylist, flavor); spin_unlock(&target->u.mds.mds_denylist_lock); } else if (!strcmp(target->obd_type->typ_name, "obdfilter")) { spin_lock(&target->u.filter.fo_denylist_lock); - rc = check_deny_list(&target->u.filter.fo_denylist, &flavor); + rc = check_deny_list(&target->u.filter.fo_denylist, flavor); spin_unlock(&target->u.filter.fo_denylist_lock); } @@ -931,7 +921,7 @@ ptlrpc_clone_req( struct ptlrpc_request *orig_req) memcpy(copy_reqmsg, orig_req->rq_reqmsg, orig_req->rq_reqlen); /* the copied req takes over the reply state and security data */ orig_req->rq_reply_state = NULL; - orig_req->rq_sec_svcdata = NULL; + orig_req->rq_svcsec_data = NULL; copy_req->rq_reqmsg = copy_reqmsg; class_export_get(copy_req->rq_export); diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index b2103ca..eaef944 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -73,7 +73,7 @@ struct ll_sb_info { struct ll_ra_info ll_ra_info; - unsigned int ll_remote; /* remote client? */ + unsigned int ll_remote; /* remote client? */ /* times spent waiting for locks in each call site. These are * all protected by the ll_lock */ @@ -331,6 +331,7 @@ struct dentry *ll_fh_to_dentry(struct super_block *sb, __u32 *data, int len, int ll_dentry_to_fh(struct dentry *, __u32 *datap, int *lenp, int need_parent); int null_if_equal(struct ldlm_lock *lock, void *data); int ll_process_config_update(struct ll_sb_info *sbi, int clean); +int ll_show_options(struct seq_file *m, struct vfsmount *mnt); int ll_flush_cred(struct inode *inode); /* llite/special.c */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 52f4c7f..ba7ddd3 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1771,6 +1772,23 @@ int ll_prep_inode(struct obd_export *dt_exp, struct obd_export *md_exp, RETURN(rc); } +int ll_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + struct ll_sb_info *sbi = ll_s2sbi(mnt->mnt_sb); + struct lustre_mount_data *lmd = sbi->ll_lmd; + + if (lmd) { + seq_printf(m, ",mds_sec=%s,oss_sec=%s", + lmd->lmd_mds_security, lmd->lmd_oss_security); + } + seq_printf(m, ",%s", sbi->ll_remote ? "remote" : "local"); + if (sbi->ll_remote && lmd) { + seq_printf(m, ",nllu=%u:%u", lmd->lmd_nllu, lmd->lmd_nllg); + } + + return 0; +} + int ll_get_fid(struct obd_export *exp, struct lustre_id *idp, char *filename, struct lustre_id *ret) { diff --git a/lustre/llite/super25.c b/lustre/llite/super25.c index b5557f1..8ed5ca5 100644 --- a/lustre/llite/super25.c +++ b/lustre/llite/super25.c @@ -113,7 +113,8 @@ struct super_operations lustre_super_operations = .put_super = lustre_put_super, .statfs = ll_statfs, .umount_begin = ll_umount_begin, - .umount_lustre = ll_umount_lustre + .umount_lustre = ll_umount_lustre, + .show_options = ll_show_options, }; struct file_system_type lustre_lite_fs_type = { diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index cd8e337..13f11a6 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1926,6 +1926,7 @@ int lmv_set_info(struct obd_export *exp, obd_count keylen, /* maybe this could be default */ if ((keylen == strlen("sec") && strcmp(key, "sec") == 0) || + (keylen == strlen("sec_flags") && strcmp(key, "sec_flags") == 0) || (keylen == strlen("nllu") && strcmp(key, "nllu") == 0)) { struct obd_export *exp; int rc = 0, err, i; diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 077872a..74a1a5f 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2091,7 +2091,7 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen, } else if (KEY_IS("unlinked") || KEY_IS("unrecovery")) { if (vallen != 0) RETURN(-EINVAL); - } else if (KEY_IS("sec")) { + } else if (KEY_IS("sec") || KEY_IS("sec_flags")) { struct lov_tgt_desc *tgt; struct obd_export *exp; int rc = 0, err, i; diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index c526d75..b417b82 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -806,26 +806,19 @@ int mdc_set_info(struct obd_export *exp, obd_count keylen, memcmp(key, "sec", keylen) == 0) { struct client_obd *cli = &exp->exp_obd->u.cli; - if (vallen == strlen("null") && - memcmp(val, "null", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_NULL; - cli->cl_sec_subflavor = 0; - RETURN(0); - } - if (vallen == strlen("krb5i") && - memcmp(val, "krb5i", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_GSS; - cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5I; - RETURN(0); - } - if (vallen == strlen("krb5p") && - memcmp(val, "krb5p", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_GSS; - cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5P; - RETURN(0); + cli->cl_sec_flavor = ptlrpcs_name2flavor(val); + if (cli->cl_sec_flavor == PTLRPCS_FLVR_INVALID) { + CERROR("unrecognized security type %s\n", (char*) val); + RETURN(-EINVAL); } - CERROR("unrecognized security type %s\n", (char*) val); - rc = -EINVAL; + + RETURN(0); + } else if (keylen == strlen("sec_flags") && + memcmp(key, "sec_flags", keylen) == 0) { + struct client_obd *cli = &exp->exp_obd->u.cli; + + cli->cl_sec_flags = *((unsigned long *) val); + RETURN(0); } else if (keylen == strlen("flush_cred") && memcmp(key, "flush_cred", keylen) == 0) { struct client_obd *cli = &exp->exp_obd->u.cli; @@ -833,7 +826,7 @@ int mdc_set_info(struct obd_export *exp, obd_count keylen, if (cli->cl_import) ptlrpcs_import_flush_creds(cli->cl_import, *((uid_t *) val)); - rc = 0; + RETURN(0); } else if (keylen == strlen("async") && memcmp(key, "async", keylen) == 0) { struct client_obd *cl = &exp->exp_obd->u.cli; if (vallen != sizeof(int)) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 7b1fe3e..49c5db0 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -3654,31 +3654,24 @@ static int mds_cleanup(struct obd_device *obd, int flags) OBD_FREE(p_deny_sec, sizeof(*p_deny_sec)); } spin_unlock(&mds->mds_denylist_lock); - if(mds->mds_mds_sec) - OBD_FREE(mds->mds_mds_sec, strlen(mds->mds_mds_sec) + 1); - if(mds->mds_ost_sec) - OBD_FREE(mds->mds_ost_sec, strlen(mds->mds_ost_sec) + 1); RETURN(0); } static int set_security(const char *value, char **sec) { - int rc = 0; - - if (!strcmp(value, "null") || - !strcmp(value, "krb5i") || - !strcmp(value, "krb5p")) { - OBD_ALLOC(*sec, strlen(value) + 1); - if(!*sec) - RETURN(-ENOMEM); - memcpy(*sec, value, strlen(value) + 1); - } else { - CERROR("Unrecognized value, force use NULL\n"); - rc = -EINVAL; + if (!strcmp(value, "null")) + *sec = "null"; + else if (!strcmp(value, "krb5i")) + *sec = "krb5i"; + else if (!strcmp(value, "krb5p")) + *sec = "krb5p"; + else { + CERROR("Unrecognized security flavor %s\n", value); + return -EINVAL; } - return rc; + return 0; } static int mds_process_config(struct obd_device *obd, obd_count len, void *buf) @@ -3711,11 +3704,9 @@ static int mds_process_config(struct obd_device *obd, obd_count len, void *buf) } break; } - default: { + default: CERROR("Unknown command: %d\n", lcfg->lcfg_command); GOTO(out, rc = -EINVAL); - - } } out: RETURN(rc); diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c index 2f6f470..c5bc62f 100644 --- a/lustre/mds/mds_lib.c +++ b/lustre/mds/mds_lib.c @@ -47,6 +47,7 @@ #include #include +#include #include #include "mds_internal.h" @@ -876,6 +877,9 @@ static inline void drop_ucred_lsd(struct lvfs_ucred *ucred) * root could set any group_info if we allowed setgroups, while * normal user only could 'reduce' their group members -- which * is somewhat expensive. + * + * authenticated as mds user (using mds service credential) could + * bypass all checkings. */ int mds_init_ucred(struct lvfs_ucred *ucred, struct ptlrpc_request *req, @@ -894,46 +898,56 @@ int mds_init_ucred(struct lvfs_ucred *ucred, LASSERT(rsd); LASSERT(rsd->rsd_ngroups <= LUSTRE_MAX_GROUPS); - /* XXX We'v no dedicated bits indicating whether GSS is used, - * and authenticated/mapped uid is valid. currently we suppose - * gss must initialize rq_sec_svcdata. - */ - if (req->rq_sec_svcdata && req->rq_auth_uid == -1) { + if (SEC_FLAVOR_MAJOR(req->rq_req_secflvr) == PTLRPCS_FLVR_MAJOR_GSS && + (SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_AUTH || + SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV)) + strong_sec = 1; + else + strong_sec = 0; + + LASSERT(!(req->rq_remote_realm && !strong_sec)); + + if (strong_sec && req->rq_auth_uid == -1) { CWARN("user not authenticated, deny access\n"); RETURN(-EPERM); } - strong_sec = (req->rq_auth_uid != -1); - LASSERT(!(req->rq_remote_realm && !strong_sec)); + if (req->rq_auth_usr_mds) + goto get_lsd; - /* if we use strong authentication for a local client, we - * expect the uid which client claimed is true. + /* if we use strong authentication, we expect the uid which + * client claimed is true. */ - if (!med->med_remote && strong_sec && - req->rq_auth_uid != rsd->rsd_uid) { - CWARN("nid "LPX64": UID %u was authenticated while client " - "claimed %u, enforce to be %u\n", - peernid, req->rq_auth_uid, rsd->rsd_uid, - req->rq_auth_uid); - if (rsd->rsd_uid != rsd->rsd_fsuid) - rsd->rsd_uid = req->rq_auth_uid; - else - rsd->rsd_uid = rsd->rsd_fsuid = req->rq_auth_uid; - } + if (strong_sec) { + if (!med->med_remote) { + if (req->rq_auth_uid != rsd->rsd_uid) { + CERROR("local client "LPU64": auth uid %u " + "while client claim %u:%u/%u:%u\n", + peernid, req->rq_auth_uid, + rsd->rsd_uid, rsd->rsd_gid, + rsd->rsd_fsuid, rsd->rsd_fsgid); + RETURN(-EPERM); + } + } else { + if (req->rq_mapped_uid == MDS_IDMAP_NOTFOUND) { + CWARN("no mapping found, deny\n"); + RETURN(-EPERM); + } - if (med->med_remote) { - int rc; + if (mds_req_secdesc_do_map(med, rsd)) + RETURN(-EPERM); - if (req->rq_mapped_uid == MDS_IDMAP_NOTFOUND) { - CWARN("no mapping found, deny\n"); - RETURN(-EPERM); + if (req->rq_mapped_uid != rsd->rsd_uid) { + CERROR("remote client "LPU64": auth uid %u " + "while client claim %u:%u/%u:%u\n", + peernid, req->rq_auth_uid, + rsd->rsd_uid, rsd->rsd_gid, + rsd->rsd_fsuid, rsd->rsd_fsgid); + } } - - rc = mds_req_secdesc_do_map(med, rsd); - if (rc) - RETURN(rc); } +get_lsd: /* now lsd come into play */ ucred->luc_ginfo = NULL; ucred->luc_lsd = lsd = mds_get_lsd(rsd->rsd_uid); @@ -943,13 +957,16 @@ int mds_init_ucred(struct lvfs_ucred *ucred, RETURN(-EPERM); } + lsd_perms = mds_lsd_get_perms(lsd, med->med_remote, 0, peernid); + + if (req->rq_auth_usr_mds) + goto squash_root; + /* find out the setuid/setgid attempt */ setuid = (rsd->rsd_uid != rsd->rsd_fsuid); setgid = (rsd->rsd_gid != rsd->rsd_fsgid || rsd->rsd_gid != lsd->lsd_gid); - lsd_perms = mds_lsd_get_perms(lsd, med->med_remote, 0, peernid); - /* check permission of setuid */ if (setuid && !(lsd_perms & LSD_PERM_SETUID)) { CWARN("mds blocked setuid attempt (%u -> %u) from "LPU64"\n", @@ -959,11 +976,13 @@ int mds_init_ucred(struct lvfs_ucred *ucred, /* check permission of setgid */ if (setgid && !(lsd_perms & LSD_PERM_SETGID)) { - CWARN("mds blocked setgid attempt (%u/%u -> %u) from "LPU64"\n", - rsd->rsd_gid, rsd->rsd_fsgid, lsd->lsd_gid, peernid); + CWARN("mds blocked setgid attempt (%u:%u/%u:%u -> %u) from " + LPU64"\n", rsd->rsd_uid, rsd->rsd_gid, + rsd->rsd_fsuid, rsd->rsd_fsgid, lsd->lsd_gid, peernid); RETURN(-EPERM); } +squash_root: root_squashed = mds_squash_root(mds, rsd, &peernid); /* remove privilege for non-root user */ diff --git a/lustre/mds/mds_lmv.c b/lustre/mds/mds_lmv.c index a660e41..880665b 100644 --- a/lustre/mds/mds_lmv.c +++ b/lustre/mds/mds_lmv.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "mds_internal.h" @@ -53,6 +54,7 @@ int mds_md_connect(struct obd_device *obd, char *md_name) { struct mds_obd *mds = &obd->u.mds; struct lustre_handle conn = {0}; + unsigned long sec_flags = PTLRPC_SEC_FL_MDS; int rc, value; __u32 valsize; ENTRY; @@ -125,6 +127,11 @@ int mds_md_connect(struct obd_device *obd, char *md_name) GOTO(err_reg, rc); } + rc = obd_set_info(mds->mds_md_exp, strlen("sec_flags"), "sec_flags", + sizeof(sec_flags), &sec_flags); + if (rc) + GOTO(err_reg, rc); + mds->mds_md_connected = 1; up(&mds->mds_md_sem); RETURN(0); diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 2270fd7..a1f624a 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "mds_internal.h" @@ -239,6 +240,7 @@ int mds_dt_connect(struct obd_device *obd, char *lov_name) { struct mds_obd *mds = &obd->u.mds; struct lustre_handle conn = { 0 }; + unsigned long sec_flags = PTLRPC_SEC_FL_MDS; int i, rc = 0; ENTRY; @@ -259,14 +261,21 @@ int mds_dt_connect(struct obd_device *obd, char *lov_name) if (mds->mds_ost_sec) { rc = obd_set_info(mds->mds_dt_obd->obd_self_export, strlen("sec"), "sec", - strlen(mds->mds_ost_sec), - mds->mds_ost_sec); + strlen(mds->mds_ost_sec), mds->mds_ost_sec); if (rc) { mds->mds_dt_obd = ERR_PTR(rc); RETURN(rc); } } + rc = obd_set_info(mds->mds_dt_obd->obd_self_export, + strlen("sec_flags"), "sec_flags", + sizeof(sec_flags), &sec_flags); + if (rc) { + mds->mds_dt_obd = ERR_PTR(rc); + RETURN(rc); + } + CDEBUG(D_HA, "obd: %s osc: %s lov_name: %s\n", obd->obd_name, mds->mds_dt_obd->obd_name, lov_name); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 2d565f6..4dc4bf9 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2924,26 +2924,21 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen, memcmp(key, "sec", keylen) == 0) { struct client_obd *cli = &exp->exp_obd->u.cli; - if (vallen == strlen("null") && - memcmp(val, "null", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_NULL; - cli->cl_sec_subflavor = 0; - RETURN(0); - } - if (vallen == strlen("krb5i") && - memcmp(val, "krb5i", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_GSS; - cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5I; - RETURN(0); - } - if (vallen == strlen("krb5p") && - memcmp(val, "krb5p", vallen) == 0) { - cli->cl_sec_flavor = PTLRPC_SEC_GSS; - cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5P; - RETURN(0); + cli->cl_sec_flavor = ptlrpcs_name2flavor(val); + if (cli->cl_sec_flavor == PTLRPCS_FLVR_INVALID) { + CERROR("unrecognized security flavor %s\n", (char*) val); + RETURN(-EINVAL); } - CERROR("unrecognized security type %s\n", (char*) val); - RETURN(-EINVAL); + + RETURN(0); + } + + if (keylen == strlen("sec_flags") && + memcmp(key, "sec_flags", keylen) == 0) { + struct client_obd *cli = &exp->exp_obd->u.cli; + + cli->cl_sec_flags = *((unsigned long *) val); + RETURN(0); } if (keylen == strlen("flush_cred") && diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index 4269bc5..60ec79c 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -217,6 +217,11 @@ struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, __u32 version, if (request->rq_ptlrpcs_err) GOTO(out_cred, rc = -EPERM); + /* set default sec flavor for this req. in the future we might need + * increase security strengh, e.g. AUTH -> PRIV + */ + request->rq_req_secflvr = imp->imp_sec->ps_flavor; + rc = lustre_pack_request(request, count, lengths, bufs); if (rc) { CERROR("cannot pack request %d\n", rc); diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 234a063..8bc6212 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -461,6 +461,8 @@ ptlrpc_server_handle_request (struct ptlrpc_service *svc) request->rq_auth_uid = -1; request->rq_mapped_uid = -1; request->rq_remote_realm = 0; + request->rq_auth_usr_mds = 0; + request->rq_auth_usr_oss = 0; secrc = svcsec_accept(request, &sec_err); switch(secrc) { diff --git a/lustre/sec/gss/gss_internal.h b/lustre/sec/gss/gss_internal.h index c605633..eadb6e4 100644 --- a/lustre/sec/gss/gss_internal.h +++ b/lustre/sec/gss/gss_internal.h @@ -89,14 +89,13 @@ crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) struct ptlrpc_sec; struct ptlrpc_cred; -/* rawobj stuff */ -int rawobj_alloc(rawobj_t *obj, char *buf, int len); -void rawobj_free(rawobj_t *obj); -int rawobj_equal(rawobj_t *a, rawobj_t *b); -int rawobj_dup(rawobj_t *dest, rawobj_t *src); -int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen); -int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen); -int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen); +/* + * rawobj stuff + */ +typedef struct rawobj_s { + __u32 len; + __u8 *data; +} rawobj_t; typedef struct rawobj_buf_s { __u32 dataoff; @@ -105,6 +104,14 @@ typedef struct rawobj_buf_s { __u8 *buf; } rawobj_buf_t; +int rawobj_alloc(rawobj_t *obj, char *buf, int len); +void rawobj_free(rawobj_t *obj); +int rawobj_equal(rawobj_t *a, rawobj_t *b); +int rawobj_dup(rawobj_t *dest, rawobj_t *src); +int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen); +int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen); +int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen); + /* * mark of the interface between kernel and lgssd/lsvcgssd */ @@ -116,6 +123,27 @@ typedef struct rawobj_buf_s { #define LUSTRE_GSS_SVC_MDS 0 #define LUSTRE_GSS_SVC_OSS 1 + +/* on-the-wire gss cred: */ +struct rpc_gss_wire_cred { + __u32 gc_v; /* version */ + __u32 gc_proc; /* control procedure */ + __u32 gc_seq; /* sequence number */ + __u32 gc_svc; /* service */ + rawobj_t gc_ctx; /* context handle */ +}; + +struct gss_svc_data { + /* decoded gss client cred: */ + struct rpc_gss_wire_cred clcred; + /* internal used status */ + unsigned int is_init:1, + is_init_continue:1, + is_err_notify:1, + is_fini:1; + int reserve_len; +}; + /* * data types in gss header */ @@ -152,7 +180,7 @@ struct gss_cl_ctx { struct gss_cred { struct ptlrpc_cred gc_base; - ptlrpcs_flavor_t gc_flavor; + __u32 gc_flavor; struct gss_cl_ctx *gc_ctx; }; diff --git a/lustre/sec/gss/gss_krb5_mech.c b/lustre/sec/gss/gss_krb5_mech.c index 3597223..f363223 100644 --- a/lustre/sec/gss/gss_krb5_mech.c +++ b/lustre/sec/gss/gss_krb5_mech.c @@ -263,21 +263,21 @@ static struct gss_api_ops gss_kerberos_ops = { static struct subflavor_desc gss_kerberos_sfs[] = { { - .subflavor = PTLRPC_SEC_GSS_KRB5, + .subflavor = PTLRPCS_SUBFLVR_KRB5, .qop = 0, - .service = PTLRPC_SEC_TYPE_NONE, + .service = PTLRPCS_SVC_NONE, .name = "krb5" }, { - .subflavor = PTLRPC_SEC_GSS_KRB5I, + .subflavor = PTLRPCS_SUBFLVR_KRB5I, .qop = 0, - .service = PTLRPC_SEC_TYPE_AUTH, + .service = PTLRPCS_SVC_AUTH, .name = "krb5i" }, { - .subflavor = PTLRPC_SEC_GSS_KRB5P, + .subflavor = PTLRPCS_SUBFLVR_KRB5P, .qop = 0, - .service = PTLRPC_SEC_TYPE_PRIV, + .service = PTLRPCS_SVC_PRIV, .name = "krb5p" } }; diff --git a/lustre/sec/gss/sec_gss.c b/lustre/sec/gss/sec_gss.c index d5f83c1..8bd4f02 100644 --- a/lustre/sec/gss/sec_gss.c +++ b/lustre/sec/gss/sec_gss.c @@ -76,10 +76,13 @@ struct rpc_clnt; #include "gss_internal.h" #include "gss_api.h" -#define GSS_CREDCACHE_EXPIRE (60) /* 1 minute */ +#define GSS_CREDCACHE_EXPIRE (30 * 60) /* 30 minute */ +/* not used now */ +#if 0 #define GSS_CRED_EXPIRE (8 * 60 * 60) /* 8 hours */ #define GSS_CRED_SIGN_SIZE (1024) #define GSS_CRED_VERIFY_SIZE (56) +#endif #define LUSTRE_PIPEDIR "/lustre" @@ -113,8 +116,7 @@ static int secinit_compose_request(struct obd_import *imp, /* security wire hdr */ hdr = buf_to_sec_hdr(buf); - hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS); - hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_NONE); + hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_NONE); hdr->msg_len = cpu_to_le32(lmsg_size); hdr->sec_len = cpu_to_le32(8 * 4 + token_size); @@ -137,10 +139,10 @@ static int secinit_compose_request(struct obd_import *imp, /* gss hdr */ *p++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* gss version */ - *p++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); /* subflavor */ - *p++ = cpu_to_le32(PTLRPC_GSS_PROC_INIT); /* proc */ + *p++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); /* subflavor */ + *p++ = cpu_to_le32(PTLRPCS_GSS_PROC_INIT); /* proc */ *p++ = cpu_to_le32(0); /* seq */ - *p++ = cpu_to_le32(PTLRPC_GSS_SVC_NONE); /* service */ + *p++ = cpu_to_le32(PTLRPCS_GSS_SVC_NONE); /* service */ *p++ = cpu_to_le32(0); /* context handle */ /* plus lustre svc type */ @@ -175,7 +177,6 @@ static int secinit_parse_reply(char *repbuf, int replen, } hdr->flavor = le32_to_cpu(hdr->flavor); - hdr->sectype = le32_to_cpu(hdr->sectype); hdr->msg_len = le32_to_cpu(hdr->msg_len); hdr->sec_len = le32_to_cpu(hdr->sec_len); @@ -183,8 +184,7 @@ static int secinit_parse_reply(char *repbuf, int replen, sec_len = le32_to_cpu(p[3]); /* sanity checks */ - if (hdr->flavor != PTLRPC_SEC_GSS || - hdr->sectype != PTLRPC_SEC_TYPE_NONE) { + if (hdr->flavor != PTLRPCS_FLVR_GSS_NONE) { CERROR("unexpected reply\n"); return -EINVAL; } @@ -972,10 +972,10 @@ static int gss_cred_sign(struct ptlrpc_cred *cred, spin_unlock(&ctx->gc_seq_lock); *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* version */ - *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); /* subflavor */ + *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); /* subflavor */ *vp++ = cpu_to_le32(ctx->gc_proc); /* proc */ *vp++ = cpu_to_le32(seqnum); /* seq */ - *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_INTEGRITY); /* service */ + *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_INTEGRITY); /* service */ vlen -= 5 * 4; if (rawobj_serialize(&ctx->gc_wire_ctx, &vp, &vlen)) { @@ -1044,10 +1044,10 @@ static int gss_cred_verify(struct ptlrpc_cred *cred, vlen -= 3 * 4; switch (proc) { - case PTLRPC_GSS_PROC_DATA: + case PTLRPCS_GSS_PROC_DATA: seq = le32_to_cpu(*vp++); svc = le32_to_cpu(*vp++); - if (svc != PTLRPC_GSS_SVC_INTEGRITY) { + if (svc != PTLRPCS_GSS_SVC_INTEGRITY) { CERROR("Unknown svc %d\n", svc); RETURN(-EPROTO); } @@ -1097,7 +1097,7 @@ static int gss_cred_verify(struct ptlrpc_cred *cred, proc_data_out: gss_put_ctx(ctx); break; - case PTLRPC_GSS_PROC_ERR: + case PTLRPCS_GSS_PROC_ERR: major = le32_to_cpu(*vp++); minor = le32_to_cpu(*vp++); /* server return NO_CONTEXT might be caused by context expire @@ -1172,10 +1172,10 @@ static int gss_cred_seal(struct ptlrpc_cred *cred, spin_unlock(&ctx->gc_seq_lock); *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); /* version */ - *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5P); /* subflavor */ + *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5P); /* subflavor */ *vp++ = cpu_to_le32(ctx->gc_proc); /* proc */ *vp++ = cpu_to_le32(seqnum); /* seq */ - *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_PRIVACY); /* service */ + *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_PRIVACY); /* service */ vlen -= 5 * 4; if (rawobj_serialize(&ctx->gc_wire_ctx, &vp, &vlen)) { @@ -1256,8 +1256,8 @@ static int gss_cred_unseal(struct ptlrpc_cred *cred, vlen -= 5 * 4; switch (proc) { - case PTLRPC_GSS_PROC_DATA: - if (svc != PTLRPC_GSS_SVC_PRIVACY) { + case PTLRPCS_GSS_PROC_DATA: + if (svc != PTLRPCS_GSS_SVC_PRIVACY) { CERROR("Unknown svc %d\n", svc); RETURN(-EPROTO); } @@ -1346,14 +1346,16 @@ static void destroy_gss_context(struct ptlrpc_cred *cred) atomic_inc(&cred->pc_refcount); gcred = container_of(cred, struct gss_cred, gc_base); - gcred->gc_ctx->gc_proc = PTLRPC_GSS_PROC_DESTROY; + gcred->gc_ctx->gc_proc = PTLRPCS_GSS_PROC_DESTROY; CDEBUG(D_SEC, "client destroy gss cred %p(%u@%s)\n", gcred, cred->pc_uid, imp->imp_target_uuid.uuid); lmsg_size = lustre_msg_size(0, NULL); + req.rq_req_secflvr = cred->pc_sec->ps_flavor; + req.rq_cred = cred; req.rq_reqbuf_len = sizeof(*hdr) + lmsg_size + - ptlrpcs_est_req_payload(cred->pc_sec, lmsg_size); + ptlrpcs_est_req_payload(&req, lmsg_size); OBD_ALLOC(req.rq_reqbuf, req.rq_reqbuf_len); if (!req.rq_reqbuf) { @@ -1365,8 +1367,7 @@ static void destroy_gss_context(struct ptlrpc_cred *cred) /* wire hdr */ hdr = buf_to_sec_hdr(req.rq_reqbuf); - hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS); - hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_AUTH); + hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_AUTH); hdr->msg_len = cpu_to_le32(lmsg_size); hdr->sec_len = cpu_to_le32(0); @@ -1633,7 +1634,7 @@ static struct rpc_pipe_ops gss_upcall_ops = { *********************************************/ static -struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor, +struct ptlrpc_sec* gss_create_sec(__u32 flavor, const char *pipe_dir, void *pipe_data) { @@ -1642,10 +1643,11 @@ struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor, #ifdef __KERNEL__ char *pos; int pipepath_len; + uid_t save_uid; #endif ENTRY; - LASSERT(flavor->flavor == PTLRPC_SEC_GSS); + LASSERT(SEC_FLAVOR_MAJOR(flavor) == PTLRPCS_FLVR_MAJOR_GSS); OBD_ALLOC(gsec, sizeof(*gsec)); if (!gsec) { @@ -1653,9 +1655,9 @@ struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor, RETURN(NULL); } - gsec->gs_mech = kgss_subflavor_to_mech(flavor->subflavor); + gsec->gs_mech = kgss_subflavor_to_mech(SEC_FLAVOR_SUB(flavor)); if (!gsec->gs_mech) { - CERROR("subflavor %d not found\n", flavor->subflavor); + CERROR("subflavor 0x%x not found\n", flavor); goto err_free; } @@ -1670,6 +1672,10 @@ struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor, if (!gsec->gs_pipepath) goto err_mech_put; + /* pipe rpc require root permission */ + save_uid = current->fsuid; + current->fsuid = 0; + sprintf(gsec->gs_pipepath, LUSTRE_PIPEDIR"/%s", pipe_dir); if (IS_ERR(rpc_mkdir(gsec->gs_pipepath, NULL))) { CERROR("can't make pipedir %s\n", gsec->gs_pipepath); @@ -1689,22 +1695,12 @@ struct ptlrpc_sec* gss_create_sec(ptlrpcs_flavor_t *flavor, #endif sec = &gsec->gs_base; - - switch (flavor->subflavor) { - case PTLRPC_SEC_GSS_KRB5I: - sec->ps_sectype = PTLRPC_SEC_TYPE_AUTH; - break; - case PTLRPC_SEC_GSS_KRB5P: - sec->ps_sectype = PTLRPC_SEC_TYPE_PRIV; - break; - default: - LBUG(); - } - sec->ps_expire = GSS_CREDCACHE_EXPIRE; sec->ps_nextgc = get_seconds() + sec->ps_expire; sec->ps_flags = 0; + current->fsuid = save_uid; + CDEBUG(D_SEC, "Create GSS security instance at %p(external %p)\n", gsec, sec); RETURN(sec); @@ -1716,6 +1712,7 @@ err_rmdir: *pos = 0; rpc_rmdir(gsec->gs_pipepath); err_free_path: + current->fsuid = save_uid; OBD_FREE(gsec->gs_pipepath, pipepath_len); err_mech_put: #endif @@ -1783,12 +1780,14 @@ struct ptlrpc_cred * gss_create_cred(struct ptlrpc_sec *sec, RETURN(cred); } -static int gss_estimate_payload(struct ptlrpc_sec *sec, int msgsize) +static int gss_estimate_payload(struct ptlrpc_sec *sec, + struct ptlrpc_request *req, + int msgsize) { - switch (sec->ps_sectype) { - case PTLRPC_SEC_TYPE_AUTH: + switch (SEC_FLAVOR_SVC(req->rq_req_secflvr)) { + case PTLRPCS_SVC_AUTH: return GSS_MAX_AUTH_PAYLOAD; - case PTLRPC_SEC_TYPE_PRIV: + case PTLRPCS_SVC_PRIV: return size_round16(GSS_MAX_AUTH_PAYLOAD + msgsize + GSS_PRIVBUF_PREFIX_LEN + GSS_PRIVBUF_SUFFIX_LEN); @@ -1809,9 +1808,9 @@ static int gss_alloc_reqbuf(struct ptlrpc_sec *sec, /* In PRIVACY mode, lustre message is always 0 (already encoded into * security payload). */ - privacy = sec->ps_sectype == PTLRPC_SEC_TYPE_PRIV; + privacy = (SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV); msg_payload = privacy ? 0 : lmsg_size; - sec_payload = gss_estimate_payload(sec, lmsg_size); + sec_payload = gss_estimate_payload(sec, req, lmsg_size); rc = sec_alloc_reqbuf(sec, req, msg_payload, sec_payload); if (rc) @@ -1845,7 +1844,7 @@ static void gss_free_reqbuf(struct ptlrpc_sec *sec, LASSERT(req->rq_reqmsg); LASSERT(req->rq_reqlen); - privacy = sec->ps_sectype == PTLRPC_SEC_TYPE_PRIV; + privacy = SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV; if (privacy) { buf = (char *) req->rq_reqmsg - GSS_PRIVBUF_PREFIX_LEN; LASSERT(buf < req->rq_reqbuf || @@ -1870,9 +1869,9 @@ static struct ptlrpc_secops gss_secops = { static struct ptlrpc_sec_type gss_type = { .pst_owner = THIS_MODULE, - .pst_name = "GSS_SEC", + .pst_name = "sec.gss", .pst_inst = ATOMIC_INIT(0), - .pst_flavor = {PTLRPC_SEC_GSS, 0}, + .pst_flavor = PTLRPCS_FLVR_MAJOR_GSS, .pst_ops = &gss_secops, }; diff --git a/lustre/sec/gss/svcsec_gss.c b/lustre/sec/gss/svcsec_gss.c index 05f2122..5958518 100644 --- a/lustre/sec/gss/svcsec_gss.c +++ b/lustre/sec/gss/svcsec_gss.c @@ -389,7 +389,9 @@ struct gss_svc_seq_data { struct rsc { struct cache_head h; rawobj_t handle; - __u32 remote_realm; + __u32 remote_realm:1, + auth_usr_mds:1, + auth_usr_oss:1; struct vfs_cred cred; uid_t mapped_uid; struct gss_svc_seq_data seqdata; @@ -484,7 +486,7 @@ static int rsc_parse(struct cache_detail *cd, /* contexthandle expiry [ uid gid N mechname * ...mechdata... ] */ char *buf = mesg; - int len, rv; + int len, rv, tmp_int; struct rsc *rsci, *res = NULL; time_t expiry; int status = -EINVAL; @@ -510,11 +512,28 @@ static int rsc_parse(struct cache_detail *cd, goto out; /* remote flag */ - rv = get_int(&mesg, (int *)&rsci->remote_realm); + rv = get_int(&mesg, &tmp_int); if (rv) { CERROR("fail to get remote flag\n"); goto out; } + rsci->remote_realm = (tmp_int != 0); + + /* mds user flag */ + rv = get_int(&mesg, &tmp_int); + if (rv) { + CERROR("fail to get mds user flag\n"); + goto out; + } + rsci->auth_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->auth_usr_oss = (tmp_int != 0); /* mapped uid */ rv = get_int(&mesg, (int *)&rsci->mapped_uid); @@ -803,7 +822,7 @@ static int gss_pack_err_notify(struct ptlrpc_request *req, __u32 major, __u32 minor) { - struct gss_svc_data *svcdata = req->rq_sec_svcdata; + struct gss_svc_data *svcdata = req->rq_svcsec_data; __u32 reslen, *resp, *reslenp; char nidstr[PTL_NALFMT_SIZE]; const __u32 secdata_len = 7 * 4; @@ -828,8 +847,8 @@ gss_pack_err_notify(struct ptlrpc_request *req, resp = (__u32 *) req->rq_reply_state->rs_repbuf; /* header */ - *resp++ = cpu_to_le32(PTLRPC_SEC_GSS); - *resp++ = cpu_to_le32(PTLRPC_SEC_TYPE_NONE); + *resp++ = cpu_to_le32(PTLRPCS_FLVR_GSS_NONE); + *resp++ = cpu_to_le32(PTLRPCS_SVC_NONE); *resp++ = cpu_to_le32(req->rq_replen); reslenp = resp++; @@ -842,8 +861,8 @@ gss_pack_err_notify(struct ptlrpc_request *req, * obj1(fake), obj2(fake) */ *resp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); - *resp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); - *resp++ = cpu_to_le32(PTLRPC_GSS_PROC_ERR); + *resp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); + *resp++ = cpu_to_le32(PTLRPCS_GSS_PROC_ERR); *resp++ = cpu_to_le32(major); *resp++ = cpu_to_le32(minor); *resp++ = 0; @@ -883,7 +902,7 @@ gss_svcsec_handle_init(struct ptlrpc_request *req, __u32 *secdata, __u32 seclen, enum ptlrpcs_error *res) { - struct gss_svc_data *svcdata = req->rq_sec_svcdata; + struct gss_svc_data *svcdata = req->rq_svcsec_data; struct rsc *rsci; struct rsi *rsikey, *rsip; rawobj_t tmpobj; @@ -984,8 +1003,8 @@ gss_svcsec_handle_init(struct ptlrpc_request *req, /* header */ resp = (__u32 *) req->rq_reply_state->rs_repbuf; - *resp++ = cpu_to_le32(PTLRPC_SEC_GSS); - *resp++ = cpu_to_le32(PTLRPC_SEC_TYPE_NONE); + *resp++ = cpu_to_le32(PTLRPCS_FLVR_GSS_NONE); + *resp++ = cpu_to_le32(PTLRPCS_SVC_NONE); *resp++ = cpu_to_le32(req->rq_replen); reslenp = resp++; @@ -1023,10 +1042,23 @@ gss_svcsec_handle_init(struct ptlrpc_request *req, *res = PTLRPCS_OK; - req->rq_auth_uid = rsci->cred.vc_uid; req->rq_remote_realm = rsci->remote_realm; + req->rq_auth_usr_mds = rsci->auth_usr_mds; + req->rq_auth_usr_oss = rsci->auth_usr_oss; + req->rq_auth_uid = rsci->cred.vc_uid; req->rq_mapped_uid = rsci->mapped_uid; + if (req->rq_auth_usr_mds) { + CWARN("usr from %s authenticated as mds svc cred\n", + portals_nid2str(req->rq_peer.peer_ni->pni_number, + req->rq_peer.peer_id.nid, nidstr)); + } + if (req->rq_auth_usr_oss) { + CWARN("usr from %s authenticated as oss svc cred\n", + portals_nid2str(req->rq_peer.peer_ni->pni_number, + req->rq_peer.peer_id.nid, nidstr)); + } + /* This is simplified since right now we doesn't support * INIT_CONTINUE yet. */ @@ -1075,7 +1107,7 @@ gss_svcsec_handle_data(struct ptlrpc_request *req, } switch (gc->gc_svc) { - case PTLRPC_GSS_SVC_INTEGRITY: + case PTLRPCS_GSS_SVC_INTEGRITY: major = gss_svc_verify_request(req, rsci, gc, secdata, seclen); if (major == GSS_S_COMPLETE) break; @@ -1084,7 +1116,7 @@ gss_svcsec_handle_data(struct ptlrpc_request *req, portals_nid2str(req->rq_peer.peer_ni->pni_number, req->rq_peer.peer_id.nid, nidstr)); goto notify_err; - case PTLRPC_GSS_SVC_PRIVACY: + case PTLRPCS_GSS_SVC_PRIVACY: major = gss_svc_unseal_request(req, rsci, gc, secdata, seclen); if (major == GSS_S_COMPLETE) break; @@ -1098,8 +1130,10 @@ gss_svcsec_handle_data(struct ptlrpc_request *req, GOTO(out, rc = SVC_DROP); } - req->rq_auth_uid = rsci->cred.vc_uid; req->rq_remote_realm = rsci->remote_realm; + req->rq_auth_usr_mds = rsci->auth_usr_mds; + req->rq_auth_usr_oss = rsci->auth_usr_oss; + req->rq_auth_uid = rsci->cred.vc_uid; req->rq_mapped_uid = rsci->mapped_uid; *res = PTLRPCS_OK; @@ -1122,7 +1156,7 @@ gss_svcsec_handle_destroy(struct ptlrpc_request *req, __u32 *secdata, __u32 seclen, enum ptlrpcs_error *res) { - struct gss_svc_data *svcdata = req->rq_sec_svcdata; + struct gss_svc_data *svcdata = req->rq_svcsec_data; struct rsc *rsci; char nidstr[PTL_NALFMT_SIZE]; int rc; @@ -1137,7 +1171,7 @@ gss_svcsec_handle_destroy(struct ptlrpc_request *req, RETURN(SVC_DROP); } - if (gc->gc_svc != PTLRPC_GSS_SVC_INTEGRITY) { + if (gc->gc_svc != PTLRPCS_GSS_SVC_INTEGRITY) { CERROR("service %d is not supported in destroy.\n", gc->gc_svc); GOTO(out, rc = SVC_DROP); @@ -1179,7 +1213,7 @@ gss_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) struct gss_svc_data *svcdata; struct rpc_gss_wire_cred *gc; struct ptlrpcs_wire_hdr *sec_hdr; - __u32 seclen, *secdata, version; + __u32 subflavor, seclen, *secdata, version; int rc; ENTRY; @@ -1190,7 +1224,7 @@ gss_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) *res = PTLRPCS_BADCRED; sec_hdr = buf_to_sec_hdr(req->rq_reqbuf); - LASSERT(sec_hdr->flavor == PTLRPC_SEC_GSS); + LASSERT(SEC_FLAVOR_MAJOR(sec_hdr->flavor) == PTLRPCS_FLVR_MAJOR_GSS); seclen = req->rq_reqbuf_len - sizeof(*sec_hdr) - sec_hdr->msg_len; secdata = (__u32 *) buf_to_sec_data(req->rq_reqbuf); @@ -1206,26 +1240,26 @@ gss_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) RETURN(SVC_DROP); } - LASSERT(!req->rq_sec_svcdata); + LASSERT(!req->rq_svcsec_data); OBD_ALLOC(svcdata, sizeof(*svcdata)); if (!svcdata) { CERROR("fail to alloc svcdata\n"); RETURN(SVC_DROP); } - req->rq_sec_svcdata = svcdata; + req->rq_svcsec_data = svcdata; gc = &svcdata->clcred; /* Now secdata/seclen is what we want to parse */ version = le32_to_cpu(*secdata++); /* version */ - svcdata->subflavor = le32_to_cpu(*secdata++); /* subflavor */ + subflavor = le32_to_cpu(*secdata++); /* subflavor */ gc->gc_proc = le32_to_cpu(*secdata++); /* proc */ gc->gc_seq = le32_to_cpu(*secdata++); /* seq */ gc->gc_svc = le32_to_cpu(*secdata++); /* service */ seclen -= 5 * 4; CDEBUG(D_SEC, "wire gss_hdr: %u/%u/%u/%u/%u\n", - version, svcdata->subflavor, gc->gc_proc, + version, subflavor, gc->gc_proc, gc->gc_seq, gc->gc_svc); if (version != PTLRPC_SEC_GSS_VERSION) { @@ -1257,9 +1291,9 @@ gss_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) } err_free: - if (rc == SVC_DROP && req->rq_sec_svcdata) { - OBD_FREE(req->rq_sec_svcdata, sizeof(struct gss_svc_data)); - req->rq_sec_svcdata = NULL; + if (rc == SVC_DROP && req->rq_svcsec_data) { + OBD_FREE(req->rq_svcsec_data, sizeof(struct gss_svc_data)); + req->rq_svcsec_data = NULL; } RETURN(rc); @@ -1269,7 +1303,7 @@ static int gss_svcsec_authorize(struct ptlrpc_request *req) { struct ptlrpc_reply_state *rs = req->rq_reply_state; - struct gss_svc_data *gsd = (struct gss_svc_data *)req->rq_sec_svcdata; + struct gss_svc_data *gsd = (struct gss_svc_data *)req->rq_svcsec_data; struct rpc_gss_wire_cred *gc = &gsd->clcred; struct rsc *rscp; struct ptlrpcs_wire_hdr *sec_hdr; @@ -1304,7 +1338,7 @@ gss_svcsec_authorize(struct ptlrpc_request *req) sec_hdr = (struct ptlrpcs_wire_hdr *) rs->rs_repbuf; switch (gc->gc_svc) { - case PTLRPC_GSS_SVC_INTEGRITY: + case PTLRPCS_GSS_SVC_INTEGRITY: /* prepare various pointers */ lmsg.len = req->rq_replen; lmsg.data = (__u8 *) (rs->rs_repbuf + sizeof(*sec_hdr)); @@ -1312,17 +1346,16 @@ gss_svcsec_authorize(struct ptlrpc_request *req) vlen = rs->rs_repbuf_len - sizeof(*sec_hdr) - lmsg.len; seclen = vlen; - sec_hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS); - sec_hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_AUTH); + sec_hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_AUTH); sec_hdr->msg_len = cpu_to_le32(req->rq_replen); /* standard gss hdr */ LASSERT(vlen >= 7 * 4); *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); - *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); + *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); *vp++ = cpu_to_le32(RPC_GSS_PROC_DATA); *vp++ = cpu_to_le32(gc->gc_seq); - *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_INTEGRITY); + *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_INTEGRITY); *vp++ = 0; /* fake ctx handle */ vpsave = vp++; /* reserve size */ vlen -= 7 * 4; @@ -1340,22 +1373,21 @@ gss_svcsec_authorize(struct ptlrpc_request *req) sec_hdr->sec_len = cpu_to_le32(seclen); rs->rs_repdata_len += size_round(seclen); break; - case PTLRPC_GSS_SVC_PRIVACY: + case PTLRPCS_GSS_SVC_PRIVACY: vp = (__u32 *) (rs->rs_repbuf + sizeof(*sec_hdr)); vlen = rs->rs_repbuf_len - sizeof(*sec_hdr); seclen = vlen; - sec_hdr->flavor = cpu_to_le32(PTLRPC_SEC_GSS); - sec_hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_PRIV); + sec_hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_GSS_PRIV); sec_hdr->msg_len = cpu_to_le32(0); /* standard gss hdr */ LASSERT(vlen >= 7 * 4); *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_VERSION); - *vp++ = cpu_to_le32(PTLRPC_SEC_GSS_KRB5I); + *vp++ = cpu_to_le32(PTLRPCS_FLVR_KRB5I); *vp++ = cpu_to_le32(RPC_GSS_PROC_DATA); *vp++ = cpu_to_le32(gc->gc_seq); - *vp++ = cpu_to_le32(PTLRPC_GSS_SVC_PRIVACY); + *vp++ = cpu_to_le32(PTLRPCS_GSS_SVC_PRIVACY); *vp++ = 0; /* fake ctx handle */ vpsave = vp++; /* reserve size */ vlen -= 7 * 4; @@ -1396,7 +1428,7 @@ static void gss_svcsec_cleanup_req(struct ptlrpc_svcsec *svcsec, struct ptlrpc_request *req) { - struct gss_svc_data *gsd = (struct gss_svc_data *) req->rq_sec_svcdata; + struct gss_svc_data *gsd = (struct gss_svc_data *) req->rq_svcsec_data; if (!gsd) { CDEBUG(D_SEC, "no svc_data present. do nothing\n"); @@ -1407,7 +1439,7 @@ void gss_svcsec_cleanup_req(struct ptlrpc_svcsec *svcsec, * to the incoming packet buffer, so don't need free it */ OBD_FREE(gsd, sizeof(*gsd)); - req->rq_sec_svcdata = NULL; + req->rq_svcsec_data = NULL; return; } @@ -1416,7 +1448,7 @@ int gss_svcsec_est_payload(struct ptlrpc_svcsec *svcsec, struct ptlrpc_request *req, int msgsize) { - struct gss_svc_data *svcdata = req->rq_sec_svcdata; + struct gss_svc_data *svcdata = req->rq_svcsec_data; ENTRY; /* just return the pre-set reserve_len for init/fini/err cases. @@ -1438,10 +1470,10 @@ int gss_svcsec_est_payload(struct ptlrpc_svcsec *svcsec, CDEBUG(D_SEC, "is_fini, reserver size 0\n"); RETURN(0); } else { - if (svcdata->clcred.gc_svc == PTLRPC_GSS_SVC_NONE || - svcdata->clcred.gc_svc == PTLRPC_GSS_SVC_INTEGRITY) + if (svcdata->clcred.gc_svc == PTLRPCS_GSS_SVC_NONE || + svcdata->clcred.gc_svc == PTLRPCS_GSS_SVC_INTEGRITY) RETURN(size_round(GSS_MAX_AUTH_PAYLOAD)); - else if (svcdata->clcred.gc_svc == PTLRPC_GSS_SVC_PRIVACY) + else if (svcdata->clcred.gc_svc == PTLRPCS_GSS_SVC_PRIVACY) RETURN(size_round16(GSS_MAX_AUTH_PAYLOAD + msgsize + GSS_PRIVBUF_PREFIX_LEN + GSS_PRIVBUF_SUFFIX_LEN)); @@ -1458,7 +1490,7 @@ int gss_svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec, struct ptlrpc_request *req, int msgsize) { - struct gss_svc_data *gsd = (struct gss_svc_data *) req->rq_sec_svcdata; + struct gss_svc_data *gsd = (struct gss_svc_data *) req->rq_svcsec_data; struct ptlrpc_reply_state *rs; int msg_payload, sec_payload; int privacy, rc; @@ -1471,7 +1503,7 @@ int gss_svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec, LASSERT(gsd); if (!gsd->is_init && !gsd->is_init_continue && !gsd->is_fini && !gsd->is_err_notify && - gsd->clcred.gc_svc == PTLRPC_GSS_SVC_PRIVACY) + gsd->clcred.gc_svc == PTLRPCS_GSS_SVC_PRIVACY) privacy = 1; else privacy = 0; @@ -1542,8 +1574,8 @@ void gss_svcsec_free_repbuf(struct ptlrpc_svcsec *svcsec, struct ptlrpc_svcsec svcsec_gss = { .pss_owner = THIS_MODULE, - .pss_name = "GSS_SVCSEC", - .pss_flavor = {PTLRPC_SEC_GSS, 0}, + .pss_name = "svcsec.gss", + .pss_flavor = PTLRPCS_FLVR_MAJOR_GSS, .accept = gss_svcsec_accept, .authorize = gss_svcsec_authorize, .alloc_repbuf = gss_svcsec_alloc_repbuf, diff --git a/lustre/sec/sec.c b/lustre/sec/sec.c index 5701a7d..ce8d203 100644 --- a/lustre/sec/sec.c +++ b/lustre/sec/sec.c @@ -41,18 +41,18 @@ #include static spinlock_t sectypes_lock = SPIN_LOCK_UNLOCKED; -static struct ptlrpc_sec_type *sectypes[PTLRPC_SEC_MAX_FLAVORS] = { +static struct ptlrpc_sec_type *sectypes[PTLRPCS_FLVR_MAJOR_MAX] = { NULL, }; int ptlrpcs_register(struct ptlrpc_sec_type *type) { - __u32 flavor = type->pst_flavor.flavor; + __u32 flavor = type->pst_flavor; LASSERT(type->pst_name); LASSERT(type->pst_ops); - if (flavor >= PTLRPC_SEC_MAX_FLAVORS) + if (flavor >= PTLRPCS_FLVR_MAJOR_MAX) return -EINVAL; spin_lock(§ypes_lock); @@ -64,49 +64,46 @@ int ptlrpcs_register(struct ptlrpc_sec_type *type) atomic_set(&type->pst_inst, 0); spin_unlock(§ypes_lock); - CWARN("Security module %s registered\n", type->pst_name); + CDEBUG(D_SEC, "%s: registered\n", type->pst_name); return 0; } int ptlrpcs_unregister(struct ptlrpc_sec_type *type) { - __u32 flavor = type->pst_flavor.flavor; + __u32 major = type->pst_flavor; - if (flavor >= PTLRPC_SEC_MAX_FLAVORS) - return -EINVAL; + LASSERT(major < PTLRPCS_FLVR_MAJOR_MAX); spin_lock(§ypes_lock); - if (!sectypes[flavor]) { + if (!sectypes[major]) { spin_unlock(§ypes_lock); + CERROR("%s: already unregistered?\n", type->pst_name); return -EINVAL; } - if (sectypes[flavor] != type) { - CERROR("invalid unregister\n"); - return -EINVAL; - } + LASSERT(sectypes[major] == type); if (atomic_read(&type->pst_inst)) { - CERROR("sec module %s still have instance %d\n", + CERROR("%s: still have %d, instances\n", type->pst_name, atomic_read(&type->pst_inst)); spin_unlock(§ypes_lock); return -EINVAL; } - CDEBUG(D_SEC, "Security module %s unregistered\n", type->pst_name); - sectypes[flavor] = NULL; + sectypes[major] = NULL; spin_unlock(§ypes_lock); + CDEBUG(D_SEC, "%s: unregistered\n", type->pst_name); return 0; } static -struct ptlrpc_sec_type * ptlrpcs_flavor2type(ptlrpcs_flavor_t *flavor) +struct ptlrpc_sec_type * ptlrpcs_flavor2type(__u32 flavor) { struct ptlrpc_sec_type *type; - __u32 major = flavor->flavor; + __u32 major = SEC_FLAVOR_MAJOR(flavor); - if (major >= PTLRPC_SEC_MAX_FLAVORS) + if (major >= PTLRPCS_FLVR_MAJOR_MAX) return NULL; spin_lock(§ypes_lock); @@ -123,6 +120,37 @@ void ptlrpcs_type_put(struct ptlrpc_sec_type *type) module_put(type->pst_owner); } +__u32 ptlrpcs_name2flavor(const char *name) +{ + if (!strcmp(name, "null")) + return PTLRPCS_FLVR_NULL; + if (!strcmp(name, "krb5")) + return PTLRPCS_FLVR_KRB5; + if (!strcmp(name, "krb5i")) + return PTLRPCS_FLVR_KRB5I; + if (!strcmp(name, "krb5p")) + return PTLRPCS_FLVR_KRB5P; + + return PTLRPCS_FLVR_INVALID; +} + +char *ptlrpcs_flavor2name(__u32 flavor) +{ + switch (flavor) { + case PTLRPCS_FLVR_NULL: + return "null"; + case PTLRPCS_FLVR_KRB5: + return "krb5"; + case PTLRPCS_FLVR_KRB5I: + return "krb5i"; + case PTLRPCS_FLVR_KRB5P: + return "krb5p"; + default: + CERROR("invalid flavor 0x%x\n", flavor); + } + return "unknown"; +} + /*********************************************** * credential cache helpers * ***********************************************/ @@ -132,7 +160,10 @@ void ptlrpcs_init_credcache(struct ptlrpc_sec *sec) int i; for (i = 0; i < PTLRPC_CREDCACHE_NR; i++) INIT_LIST_HEAD(&sec->ps_credcache[i]); - sec->ps_nextgc = get_seconds() + (sec->ps_expire >> 1); + + /* ps_nextgc == 0 means never do gc */ + if (sec->ps_nextgc) + sec->ps_nextgc = get_seconds() + (sec->ps_expire >> 1); } /* @@ -319,7 +350,8 @@ retry: spin_lock(&sec->ps_lock); /* do gc if expired */ - if (remove_dead && time_after(get_seconds(), sec->ps_nextgc)) + if (remove_dead && + sec->ps_nextgc && time_after(get_seconds(), sec->ps_nextgc)) ptlrpcs_credcache_gc(sec, &freelist); list_for_each_entry_safe(cred, n, &sec->ps_credcache[hash], pc_hash) { @@ -380,8 +412,13 @@ static struct ptlrpc_cred *get_cred(struct ptlrpc_sec *sec) /* XXX * for now we simply let PAG == real uid */ - vcred.vc_pag = (__u64) current->uid; - vcred.vc_uid = current->uid; + if (sec->ps_flags & (PTLRPC_SEC_FL_MDS | PTLRPC_SEC_FL_REVERSE)) { + vcred.vc_pag = 0; + vcred.vc_uid = 0; + } else { + vcred.vc_pag = (__u64) current->uid; + vcred.vc_uid = current->uid; + } return cred_cache_lookup(sec, &vcred, 1, 1); } @@ -616,9 +653,9 @@ int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req) CDEBUG(D_SEC, "wrap req %p\n", req); cred = req->rq_cred; - switch (cred->pc_sec->ps_sectype) { - case PTLRPC_SEC_TYPE_NONE: - case PTLRPC_SEC_TYPE_AUTH: + switch (SEC_FLAVOR_SVC(req->rq_req_secflvr)) { + case PTLRPCS_SVC_NONE: + case PTLRPCS_SVC_AUTH: if (req->rq_req_wrapped) { CDEBUG(D_SEC, "req %p(o%u,x"LPU64",t"LPU64") " "already signed, resend?\n", req, @@ -635,7 +672,7 @@ int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req) if (!rc) req->rq_req_wrapped = 1; break; - case PTLRPC_SEC_TYPE_PRIV: + case PTLRPCS_SVC_PRIV: if (req->rq_req_wrapped) { CDEBUG(D_SEC, "req %p(o%u,x"LPU64",t"LPU64") " "already encrypted, resend?\n", req, @@ -684,17 +721,21 @@ int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req) sec_hdr = (struct ptlrpcs_wire_hdr *) req->rq_repbuf; sec_hdr->flavor = le32_to_cpu(sec_hdr->flavor); - sec_hdr->sectype = le32_to_cpu(sec_hdr->sectype); sec_hdr->msg_len = le32_to_cpu(sec_hdr->msg_len); sec_hdr->sec_len = le32_to_cpu(sec_hdr->sec_len); - CDEBUG(D_SEC, "req %p, cred %p, flavor %u, sectype %u\n", - req, cred, sec_hdr->flavor, sec_hdr->sectype); + CDEBUG(D_SEC, "req %p, cred %p, flavor 0x%x\n", + req, cred, sec_hdr->flavor); sec = cred->pc_sec; - if (sec_hdr->flavor != sec->ps_flavor.flavor) { - CERROR("unmatched flavor %u while expect %u\n", - sec_hdr->flavor, sec->ps_flavor.flavor); + + /* only compare major flavor, reply might use different subflavor. + */ + if (SEC_FLAVOR_MAJOR(sec_hdr->flavor) != + SEC_FLAVOR_MAJOR(req->rq_req_secflvr)) { + CERROR("got major flavor %u while expect %u\n", + SEC_FLAVOR_MAJOR(sec_hdr->flavor), + SEC_FLAVOR_MAJOR(req->rq_req_secflvr)); RETURN(-EPROTO); } @@ -706,14 +747,14 @@ int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req) RETURN(-EPROTO); } - switch (sec_hdr->sectype) { - case PTLRPC_SEC_TYPE_NONE: - case PTLRPC_SEC_TYPE_AUTH: { + switch (SEC_FLAVOR_SVC(sec_hdr->flavor)) { + case PTLRPCS_SVC_NONE: + case PTLRPCS_SVC_AUTH: { LASSERT(cred->pc_ops->verify); rc = cred->pc_ops->verify(cred, req); LASSERT(rc || req->rq_repmsg || req->rq_ptlrpcs_restart); break; - case PTLRPC_SEC_TYPE_PRIV: + case PTLRPCS_SVC_PRIV: LASSERT(cred->pc_ops->unseal); rc = cred->pc_ops->unseal(cred, req); LASSERT(rc || req->rq_repmsg || req->rq_ptlrpcs_restart); @@ -730,7 +771,8 @@ int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req) * security APIs * **************************************************/ -struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor, +struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor, + unsigned long flags, struct obd_import *import, const char *pipe_dir, void *pipe_data) @@ -741,7 +783,7 @@ struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor, type = ptlrpcs_flavor2type(flavor); if (!type) { - CDEBUG(D_SEC, "invalid major flavor %u\n", flavor->flavor); + CERROR("invalid flavor 0x%x\n", flavor); RETURN(NULL); } @@ -750,7 +792,8 @@ struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor, spin_lock_init(&sec->ps_lock); ptlrpcs_init_credcache(sec); sec->ps_type = type; - sec->ps_flavor = *flavor; + sec->ps_flavor = flavor; + sec->ps_flags = flags; sec->ps_import = class_import_get(import); atomic_set(&sec->ps_refcount, 1); atomic_set(&sec->ps_credcount, 0); @@ -790,9 +833,9 @@ void ptlrpcs_sec_put(struct ptlrpc_sec *sec) if (ncred == 0) { ptlrpcs_sec_destroy(sec); } else { - CWARN("sec %p(%s) is no usage while %d cred still " + CWARN("%s %p is no usage while %d cred still " "holded, destroy delayed\n", - sec, sec->ps_type->pst_name, + sec->ps_type->pst_name, sec, atomic_read(&sec->ps_credcount)); } } @@ -821,8 +864,7 @@ int sec_alloc_reqbuf(struct ptlrpc_sec *sec, } hdr = buf_to_sec_hdr(req->rq_reqbuf); - hdr->flavor = cpu_to_le32(sec->ps_flavor.flavor); - hdr->sectype = cpu_to_le32(sec->ps_sectype); + hdr->flavor = cpu_to_le32(req->rq_req_secflvr); hdr->msg_len = msgsize; /* security length will be filled later */ @@ -926,8 +968,9 @@ int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize) RETURN(ops->alloc_repbuf(sec, req, msgsize)); /* default allocation scheme */ - msg_payload = sec->ps_sectype == PTLRPC_SEC_TYPE_PRIV ? 0 : msgsize; - sec_payload = size_round(ptlrpcs_est_rep_payload(sec, msgsize)); + msg_payload = SEC_FLAVOR_SVC(req->rq_req_secflvr) == PTLRPCS_SVC_PRIV ? + 0 : msgsize; + sec_payload = size_round(ptlrpcs_est_rep_payload(req, msgsize)); req->rq_repbuf_len = sizeof(struct ptlrpcs_wire_hdr) + msg_payload + sec_payload; @@ -970,7 +1013,8 @@ void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req) int ptlrpcs_import_get_sec(struct obd_import *imp) { - ptlrpcs_flavor_t flavor = {PTLRPC_SEC_NULL, 0}; + __u32 flavor = PTLRPCS_FLVR_NULL; + unsigned long flags = 0; char *pipedir = NULL; ENTRY; @@ -988,26 +1032,30 @@ int ptlrpcs_import_get_sec(struct obd_import *imp) !strcmp(imp->imp_obd->obd_type->typ_name, "osc")) { struct client_obd *cli = &imp->imp_obd->u.cli; - if (cli->cl_sec_flavor == PTLRPC_SEC_GSS) { - CWARN("select security gss/%s for %s(%s)\n", - cli->cl_sec_subflavor == PTLRPC_SEC_GSS_KRB5I ? - "krb5i" : "krb5p", - imp->imp_obd->obd_type->typ_name, - imp->imp_obd->obd_name); - flavor.flavor = cli->cl_sec_flavor; - flavor.subflavor = cli->cl_sec_subflavor; - pipedir = imp->imp_obd->obd_name; - } else if (cli->cl_sec_flavor == PTLRPC_SEC_NULL) { + switch (SEC_FLAVOR_MAJOR(cli->cl_sec_flavor)) { + case PTLRPCS_FLVR_MAJOR_NULL: CWARN("select security null for %s(%s)\n", - imp->imp_obd->obd_type->typ_name, - imp->imp_obd->obd_name); - } else { - CWARN("unknown security flavor for mdc(%s), " - "use 'null'\n", imp->imp_obd->obd_name); + imp->imp_obd->obd_type->typ_name, + imp->imp_obd->obd_name); + break; + case PTLRPCS_FLVR_MAJOR_GSS: + CWARN("select security %s for %s(%s)\n", + ptlrpcs_flavor2name(cli->cl_sec_flavor), + imp->imp_obd->obd_type->typ_name, + imp->imp_obd->obd_name); + flavor = cli->cl_sec_flavor; + pipedir = imp->imp_obd->obd_name; + break; + default: + CWARN("unknown security flavor for %s(%s), use null\n", + imp->imp_obd->obd_type->typ_name, + imp->imp_obd->obd_name); } + + flags = cli->cl_sec_flags; } - imp->imp_sec = ptlrpcs_sec_create(&flavor, imp, pipedir, imp); + imp->imp_sec = ptlrpcs_sec_create(flavor, flags, imp, pipedir, imp); if (!imp->imp_sec) RETURN(-EINVAL); else @@ -1096,6 +1144,9 @@ EXPORT_SYMBOL(svcsec_put); EXPORT_SYMBOL(svcsec_alloc_reply_state); EXPORT_SYMBOL(svcsec_free_reply_state); +EXPORT_SYMBOL(ptlrpcs_name2flavor); +EXPORT_SYMBOL(ptlrpcs_flavor2name); + MODULE_AUTHOR("Cluster File Systems, Inc. "); MODULE_DESCRIPTION("Lustre Security Support"); MODULE_LICENSE("GPL"); diff --git a/lustre/sec/sec_null.c b/lustre/sec/sec_null.c index a05485c..bda2d1b 100644 --- a/lustre/sec/sec_null.c +++ b/lustre/sec/sec_null.c @@ -92,22 +92,21 @@ static struct ptlrpc_credops null_credops = { }; static -struct ptlrpc_sec* null_create_sec(ptlrpcs_flavor_t *flavor, +struct ptlrpc_sec* null_create_sec(__u32 flavor, const char *pipe_dir, void *pipe_data) { struct ptlrpc_sec *sec; ENTRY; - LASSERT(flavor->flavor == PTLRPC_SEC_NULL); + LASSERT(SEC_FLAVOR_MAJOR(flavor) == PTLRPCS_FLVR_MAJOR_NULL); OBD_ALLOC(sec, sizeof(*sec)); if (!sec) RETURN(ERR_PTR(-ENOMEM)); - sec->ps_sectype = PTLRPC_SEC_TYPE_NONE; - sec->ps_expire = (-1UL >> 1); /* never expire */ - sec->ps_nextgc = (-1UL >> 1); + sec->ps_expire = 0; /* never expire */ + sec->ps_nextgc = 0; /* never do gc */ sec->ps_flags = 0; CDEBUG(D_SEC, "Create NULL security module at %p\n", sec); @@ -159,9 +158,9 @@ static struct ptlrpc_secops null_secops = { static struct ptlrpc_sec_type null_type = { .pst_owner = THIS_MODULE, - .pst_name = "NULL_SEC", + .pst_name = "sec.null", .pst_inst = ATOMIC_INIT(0), - .pst_flavor = {PTLRPC_SEC_NULL, 0}, + .pst_flavor = PTLRPCS_FLVR_MAJOR_NULL, .pst_ops = &null_secops, }; diff --git a/lustre/sec/svcsec.c b/lustre/sec/svcsec.c index 4a7029c..6356fd2 100644 --- a/lustre/sec/svcsec.c +++ b/lustre/sec/svcsec.c @@ -38,48 +38,47 @@ #include static spinlock_t svcsecs_lock = SPIN_LOCK_UNLOCKED; -static struct ptlrpc_svcsec *svcsecs[PTLRPC_SEC_MAX_FLAVORS] = { +static struct ptlrpc_svcsec *svcsecs[PTLRPCS_FLVR_MAJOR_MAX] = { NULL, }; int svcsec_register(struct ptlrpc_svcsec *sec) { - __u32 flavor = sec->pss_flavor.flavor; + __u32 major = sec->pss_flavor; - if (flavor >= PTLRPC_SEC_MAX_FLAVORS) + if (major >= PTLRPCS_FLVR_MAJOR_MAX) return -EINVAL; spin_lock(&svcsecs_lock); - if (svcsecs[flavor]) { + if (svcsecs[major]) { spin_unlock(&svcsecs_lock); return -EALREADY; } - svcsecs[flavor] = sec; + svcsecs[major] = sec; spin_unlock(&svcsecs_lock); - CDEBUG(D_SEC, "Registered svc security module %s\n", sec->pss_name); + CWARN("%s: registered\n", sec->pss_name); return 0; } int svcsec_unregister(struct ptlrpc_svcsec *sec) { - __u32 flavor = sec->pss_flavor.flavor; + __u32 major = sec->pss_flavor; - if (flavor >= PTLRPC_SEC_MAX_FLAVORS) - return -EINVAL; + LASSERT(major < PTLRPCS_FLVR_MAJOR_MAX); spin_lock(&svcsecs_lock); - if (!svcsecs[flavor]) { + if (!svcsecs[major]) { spin_unlock(&svcsecs_lock); return -EINVAL; } - LASSERT(svcsecs[flavor] == sec); + LASSERT(svcsecs[major] == sec); - CDEBUG(D_SEC, "Unregistered svc security module %s\n", sec->pss_name); - svcsecs[flavor] = NULL; + svcsecs[major] = NULL; spin_unlock(&svcsecs_lock); + CWARN("%s: unregistered\n", sec->pss_name); return 0; } @@ -87,12 +86,13 @@ static struct ptlrpc_svcsec * flavor2svcsec(__u32 flavor) { struct ptlrpc_svcsec *sec; + __u32 major = SEC_FLAVOR_MAJOR(flavor); - if (flavor >= PTLRPC_SEC_MAX_FLAVORS) + if (major >= PTLRPCS_FLVR_MAJOR_MAX) return NULL; spin_lock(&svcsecs_lock); - sec = svcsecs[flavor]; + sec = svcsecs[major]; if (sec && !try_module_get(sec->pss_owner)) sec = NULL; spin_unlock(&svcsecs_lock); @@ -201,18 +201,18 @@ int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) sec_hdr = (struct ptlrpcs_wire_hdr *) req->rq_reqbuf; sec_hdr->flavor = le32_to_cpu(sec_hdr->flavor); - sec_hdr->sectype = le32_to_cpu(sec_hdr->sectype); sec_hdr->msg_len = le32_to_cpu(sec_hdr->msg_len); sec_hdr->sec_len = le32_to_cpu(sec_hdr->sec_len); /* sanity check */ - switch (sec_hdr->sectype) { - case PTLRPC_SEC_TYPE_NONE: - case PTLRPC_SEC_TYPE_AUTH: - case PTLRPC_SEC_TYPE_PRIV: + switch (SEC_FLAVOR_SVC(sec_hdr->flavor)) { + case PTLRPCS_SVC_NONE: + case PTLRPCS_SVC_AUTH: + case PTLRPCS_SVC_PRIV: break; default: - CERROR("unknown security type %d\n", sec_hdr->sectype); + CERROR("unknown security svc %d\n", + SEC_FLAVOR_SVC(sec_hdr->flavor)); RETURN(SVC_DROP); } @@ -228,8 +228,14 @@ int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) CERROR("drop msg: unsupported flavor %d\n", sec_hdr->flavor); RETURN(SVC_DROP); } - LASSERT(sec->accept); + /* flavor in the wire header might not be the real "end user" flavor, + * we set it here anyway, later accept() might override with correct + * value. + */ + req->rq_req_secflvr = sec_hdr->flavor; + + LASSERT(sec->accept); rc = sec->accept(req, res); switch (rc) { @@ -261,7 +267,7 @@ void svcsec_cleanup_req(struct ptlrpc_request *req) ENTRY; LASSERT(svcsec); - LASSERT(svcsec->cleanup_req || !req->rq_sec_svcdata); + LASSERT(svcsec->cleanup_req || !req->rq_svcsec_data); if (svcsec->cleanup_req) svcsec->cleanup_req(svcsec, req); diff --git a/lustre/sec/svcsec_null.c b/lustre/sec/svcsec_null.c index 5e7eed8..7fe25e7 100644 --- a/lustre/sec/svcsec_null.c +++ b/lustre/sec/svcsec_null.c @@ -43,7 +43,7 @@ int null_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(req->rq_reqbuf); ENTRY; - LASSERT(hdr->flavor == PTLRPC_SEC_NULL); + LASSERT(SEC_FLAVOR_MAJOR(hdr->flavor) == PTLRPCS_FLVR_MAJOR_NULL); if (hdr->sec_len != 0) { CERROR("security payload %d not zero\n", hdr->sec_len); @@ -51,6 +51,8 @@ int null_svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res) RETURN(SVC_DROP); } + req->rq_req_secflvr = PTLRPCS_FLVR_NULL; + req->rq_reqmsg = (struct lustre_msg *)(hdr + 1); req->rq_reqlen = hdr->msg_len; *res = PTLRPCS_OK; @@ -70,8 +72,7 @@ int null_svcsec_authorize(struct ptlrpc_request *req) LASSERT(rs->rs_repbuf_len >= 4 * 4); hdr = buf_to_sec_hdr(rs->rs_repbuf); - hdr->flavor = cpu_to_le32(PTLRPC_SEC_NULL); - hdr->sectype = cpu_to_le32(PTLRPC_SEC_TYPE_AUTH); + hdr->flavor = cpu_to_le32(PTLRPCS_FLVR_NULL); hdr->msg_len = cpu_to_le32(req->rq_replen); hdr->sec_len = cpu_to_le32(0); @@ -81,8 +82,8 @@ int null_svcsec_authorize(struct ptlrpc_request *req) static struct ptlrpc_svcsec null_svcsec = { .pss_owner = THIS_MODULE, - .pss_name = "NULL_SVCSEC", - .pss_flavor = {PTLRPC_SEC_NULL, 0}, + .pss_name = "svcsec.null", + .pss_flavor = PTLRPCS_FLVR_MAJOR_NULL, .accept = null_svcsec_accept, .authorize = null_svcsec_authorize, }; diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index e0bc881..acb3bee 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -722,7 +722,7 @@ int jt_lcfg_set_security(int argc, char **argv) fprintf(stderr, "%s: please use 'cfg_device name' to set the " "device name for config commands.\n", jt_cmdname(argv[0])); - return -EINVAL; + return -EINVAL; } lustre_cfg_bufs_reset(&bufs, lcfg_devname); -- 1.8.3.1