/** @} lu_context */
+struct lu_ucred {
+ __u32 uc_valid;
+ __u32 uc_o_uid;
+ __u32 uc_o_gid;
+ __u32 uc_o_fsuid;
+ __u32 uc_o_fsgid;
+ __u32 uc_uid;
+ __u32 uc_gid;
+ __u32 uc_fsuid;
+ __u32 uc_fsgid;
+ __u32 uc_suppgids[2];
+ cfs_cap_t uc_cap;
+ __u32 uc_umask;
+ cfs_group_info_t *uc_ginfo;
+ struct md_identity *uc_identity;
+};
+struct lu_ucred *lu_ucred(const struct lu_env *env);
+struct lu_ucred *lu_ucred_check(const struct lu_env *env);
+struct lu_ucred *lu_ucred_assert(const struct lu_env *env);
+
/**
* Output site statistical counters into a buffer. Suitable for
* ll_rd_*()-style functions.
#define CFS_ACL_XATTR_COUNT(size, prefix) \
(((size) - sizeof(prefix ## _header)) / sizeof(prefix ## _entry))
-extern int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
- int want, posix_acl_xattr_entry *entry,
- int count);
+extern int lustre_posix_acl_permission(struct lu_ucred *mu, struct lu_attr *la,
+ int want, posix_acl_xattr_entry *entry,
+ int count);
extern int lustre_posix_acl_chmod_masq(posix_acl_xattr_entry *entry,
__u32 mode, int count);
extern int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry,
lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size,
posix_acl_xattr_header **out);
extern int
-lustre_posix_acl_xattr_id2client(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- posix_acl_xattr_header *header,
- int size, int flags);
+lustre_posix_acl_xattr_id2client(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ posix_acl_xattr_header *header,
+ int size, int flags);
extern void
lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size);
extern int
-lustre_ext_acl_xattr_id2server(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- ext_acl_xattr_header *header);
+lustre_ext_acl_xattr_id2server(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ ext_acl_xattr_header *header);
extern void
lustre_ext_acl_xattr_free(ext_acl_xattr_header *header);
extern int
extern void lustre_groups_from_list(cfs_group_info_t *ginfo, gid_t *glist);
extern void lustre_groups_sort(cfs_group_info_t *group_info);
-extern int lustre_in_group_p(struct md_ucred *mu, gid_t grp);
+extern int lustre_in_group_p(struct lu_ucred *mu, gid_t grp);
extern int lustre_idmap_add(struct lustre_idmap_table *t,
uid_t ruid, uid_t luid,
extern int lustre_idmap_del(struct lustre_idmap_table *t,
uid_t ruid, uid_t luid,
gid_t rgid, gid_t lgid);
-extern int lustre_idmap_lookup_uid(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- int reverse, uid_t uid);
-extern int lustre_idmap_lookup_gid(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- int reverse, gid_t gid);
+extern int lustre_idmap_lookup_uid(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ int reverse, uid_t uid);
+extern int lustre_idmap_lookup_gid(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ int reverse, gid_t gid);
extern struct lustre_idmap_table *lustre_idmap_init(void);
extern void lustre_idmap_fini(struct lustre_idmap_table *t);
UCRED_NEW = 2
};
-struct md_ucred {
- __u32 mu_valid;
- __u32 mu_o_uid;
- __u32 mu_o_gid;
- __u32 mu_o_fsuid;
- __u32 mu_o_fsgid;
- __u32 mu_uid;
- __u32 mu_gid;
- __u32 mu_fsuid;
- __u32 mu_fsgid;
- __u32 mu_suppgids[2];
- cfs_cap_t mu_cap;
- __u32 mu_umask;
- cfs_group_info_t *mu_ginfo;
- struct md_identity *mu_identity;
-};
-
enum {
MD_CAPAINFO_MAX = 5
};
* XXX should be moved into separate .h/.c together with all md security
* related definitions.
*/
-struct md_ucred *md_ucred(const struct lu_env *env);
struct md_capainfo *md_capainfo(const struct lu_env *env);
struct md_quota *md_quota(const struct lu_env *env);
.o_health_check = mdd_obd_health_check
};
-/* context key constructor/destructor: mdd_ucred_key_init, mdd_ucred_key_fini */
-LU_KEY_INIT_FINI(mdd_ucred, struct md_ucred);
-
-static struct lu_context_key mdd_ucred_key = {
- .lct_tags = LCT_SESSION,
- .lct_init = mdd_ucred_key_init,
- .lct_fini = mdd_ucred_key_fini
-};
-
-struct md_ucred *md_ucred(const struct lu_env *env)
-{
- LASSERT(env->le_ses != NULL);
- return lu_context_key_get(env->le_ses, &mdd_ucred_key);
-}
-EXPORT_SYMBOL(md_ucred);
-
/*
* context key constructor/destructor:
* mdd_capainfo_key_init, mdd_capainfo_key_fini
}
/* type constructor/destructor: mdd_type_init, mdd_type_fini */
-LU_TYPE_INIT_FINI(mdd, &mdd_thread_key, &mdd_ucred_key, &mdd_capainfo_key);
+LU_TYPE_INIT_FINI(mdd, &mdd_thread_key, &mdd_capainfo_key);
const struct md_device_operations mdd_ops = {
.mdo_statfs = mdd_statfs,
* VTX feature has been checked already, no need check again.
*/
static inline int mdd_is_sticky(const struct lu_env *env,
- struct mdd_object *pobj,
- struct mdd_object *cobj)
+ struct mdd_object *pobj,
+ struct mdd_object *cobj)
{
- struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
- struct md_ucred *uc = md_ucred(env);
- int rc;
+ struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
+ struct lu_ucred *uc = lu_ucred_assert(env);
+ int rc;
- if (pobj) {
- rc = mdd_la_get(env, pobj, tmp_la, BYPASS_CAPA);
- if (rc)
- return rc;
+ if (pobj) {
+ rc = mdd_la_get(env, pobj, tmp_la, BYPASS_CAPA);
+ if (rc)
+ return rc;
- if (!(tmp_la->la_mode & S_ISVTX) ||
- (tmp_la->la_uid == uc->mu_fsuid))
- return 0;
- }
+ if (!(tmp_la->la_mode & S_ISVTX) ||
+ (tmp_la->la_uid == uc->uc_fsuid))
+ return 0;
+ }
- rc = mdd_la_get(env, cobj, tmp_la, BYPASS_CAPA);
- if (rc)
- return rc;
+ rc = mdd_la_get(env, cobj, tmp_la, BYPASS_CAPA);
+ if (rc)
+ return rc;
- if (tmp_la->la_uid == uc->mu_fsuid)
- return 0;
+ if (tmp_la->la_uid == uc->uc_fsuid)
+ return 0;
- return !mdd_capable(uc, CFS_CAP_FOWNER);
+ return !mdd_capable(uc, CFS_CAP_FOWNER);
}
/*
}
static int __mdd_index_insert_only(const struct lu_env *env,
- struct mdd_object *pobj,
- const struct lu_fid *lf, const char *name,
- struct thandle *handle,
- struct lustre_capa *capa)
+ struct mdd_object *pobj,
+ const struct lu_fid *lf, const char *name,
+ struct thandle *handle,
+ struct lustre_capa *capa)
{
- struct dt_object *next = mdd_object_child(pobj);
- int rc;
- ENTRY;
+ struct dt_object *next = mdd_object_child(pobj);
+ int rc;
+ ENTRY;
- if (dt_try_as_dir(env, next)) {
- struct md_ucred *uc = md_ucred(env);
+ if (dt_try_as_dir(env, next)) {
+ struct lu_ucred *uc = lu_ucred_check(env);
+ int ignore_quota;
- rc = next->do_index_ops->dio_insert(env, next,
- (struct dt_rec*)lf,
- (const struct dt_key *)name,
- handle, capa, uc->mu_cap &
- CFS_CAP_SYS_RESOURCE_MASK);
- } else {
- rc = -ENOTDIR;
- }
- RETURN(rc);
+ ignore_quota = uc ? uc->uc_cap & CFS_CAP_SYS_RESOURCE_MASK : 1;
+ rc = next->do_index_ops->dio_insert(env, next,
+ (struct dt_rec*)lf,
+ (const struct dt_key *)name,
+ handle, capa, ignore_quota);
+ } else {
+ rc = -ENOTDIR;
+ }
+ RETURN(rc);
}
/* insert named index, add reference if isdir */
inserted = 1;
if (S_ISLNK(attr->la_mode)) {
- struct md_ucred *uc = md_ucred(env);
+ struct lu_ucred *uc = lu_ucred_assert(env);
struct dt_object *dt = mdd_object_child(son);
const char *target_name = spec->u.sp_symname;
int sym_len = strlen(target_name);
loff_t pos = 0;
buf = mdd_buf_get_const(env, target_name, sym_len);
- rc = dt->do_body_ops->dbo_write(env, dt, buf, &pos, handle,
- mdd_object_capa(env, son),
- uc->mu_cap &
- CFS_CAP_SYS_RESOURCE_MASK);
+ rc = dt->do_body_ops->dbo_write(env, dt, buf, &pos, handle,
+ mdd_object_capa(env, son),
+ uc->uc_cap &
+ CFS_CAP_SYS_RESOURCE_MASK);
if (rc == sym_len)
rc = 0;
#define mdd_cap_raised(c, flag) (mdd_cap_t(c) & MDD_CAP_TO_MASK(flag))
/* capable() is copied from linux kernel! */
-static inline int mdd_capable(struct md_ucred *uc, cfs_cap_t cap)
+static inline int mdd_capable(struct lu_ucred *uc, cfs_cap_t cap)
{
- if (mdd_cap_raised(uc->mu_cap, cap))
- return 1;
- return 0;
+ if (mdd_cap_raised(uc->uc_cap, cap))
+ return 1;
+ return 0;
}
int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
struct thandle *handle)
{
struct dt_object *next = mdd_object_child(o);
- struct md_ucred *uc = md_ucred(env);
+ struct lu_ucred *uc = lu_ucred(env);
__u32 saved;
int rc;
* LU-974 enforce client umask in creation.
* TODO: CMD needs to handle this for remote object.
*/
- saved = xchg(¤t->fs->umask, uc->mu_umask & S_IRWXUGO);
+ saved = xchg(¤t->fs->umask, uc->uc_umask & S_IRWXUGO);
rc = next->do_ops->do_create(env, next, attr, hint, dof, handle);
struct lu_attr *la, const unsigned long flags)
{
struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
- struct md_ucred *uc;
+ struct lu_ucred *uc;
int rc;
ENTRY;
if (la->la_valid & (LA_NLINK | LA_RDEV | LA_BLKSIZE))
RETURN(-EPERM);
- /* export destroy does not have ->le_ses, but we may want
- * to drop LUSTRE_SOM_FL. */
- if (!env->le_ses)
- RETURN(0);
-
- uc = md_ucred(env);
+ /* export destroy does not have ->le_ses, but we may want
+ * to drop LUSTRE_SOM_FL. */
+ uc = lu_ucred_check(env);
+ if (uc == NULL)
+ RETURN(0);
rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA);
if (rc)
unsigned int newflags = la->la_flags &
(LUSTRE_IMMUTABLE_FL | LUSTRE_APPEND_FL);
- if ((uc->mu_fsuid != tmp_la->la_uid) &&
- !mdd_capable(uc, CFS_CAP_FOWNER))
- RETURN(-EPERM);
+ if ((uc->uc_fsuid != tmp_la->la_uid) &&
+ !mdd_capable(uc, CFS_CAP_FOWNER))
+ RETURN(-EPERM);
/* XXX: the IMMUTABLE and APPEND_ONLY flags can
* only be changed by the relevant capability. */
!(flags & MDS_PERM_BYPASS))
RETURN(-EPERM);
- /* Check for setting the obj time. */
- if ((la->la_valid & (LA_MTIME | LA_ATIME | LA_CTIME)) &&
- !(la->la_valid & ~(LA_MTIME | LA_ATIME | LA_CTIME))) {
- if ((uc->mu_fsuid != tmp_la->la_uid) &&
- !mdd_capable(uc, CFS_CAP_FOWNER)) {
+ /* Check for setting the obj time. */
+ if ((la->la_valid & (LA_MTIME | LA_ATIME | LA_CTIME)) &&
+ !(la->la_valid & ~(LA_MTIME | LA_ATIME | LA_CTIME))) {
+ if ((uc->uc_fsuid != tmp_la->la_uid) &&
+ !mdd_capable(uc, CFS_CAP_FOWNER)) {
rc = mdd_permission_internal(env, obj, tmp_la,
MAY_WRITE);
- if (rc)
- RETURN(rc);
- }
- }
+ if (rc)
+ RETURN(rc);
+ }
+ }
if (la->la_valid & LA_KILL_SUID) {
la->la_valid &= ~LA_KILL_SUID;
/* Make sure a caller can chmod. */
if (la->la_valid & LA_MODE) {
if (!(flags & MDS_PERM_BYPASS) &&
- (uc->mu_fsuid != tmp_la->la_uid) &&
- !mdd_capable(uc, CFS_CAP_FOWNER))
- RETURN(-EPERM);
+ (uc->uc_fsuid != tmp_la->la_uid) &&
+ !mdd_capable(uc, CFS_CAP_FOWNER))
+ RETURN(-EPERM);
if (la->la_mode == (cfs_umode_t) -1)
la->la_mode = tmp_la->la_mode;
if (la->la_valid & LA_UID) {
if (la->la_uid == (uid_t) -1)
la->la_uid = tmp_la->la_uid;
- if (((uc->mu_fsuid != tmp_la->la_uid) ||
- (la->la_uid != tmp_la->la_uid)) &&
- !mdd_capable(uc, CFS_CAP_CHOWN))
- RETURN(-EPERM);
+ if (((uc->uc_fsuid != tmp_la->la_uid) ||
+ (la->la_uid != tmp_la->la_uid)) &&
+ !mdd_capable(uc, CFS_CAP_CHOWN))
+ RETURN(-EPERM);
/* If the user or group of a non-directory has been
* changed by a non-root user, remove the setuid bit.
if (la->la_valid & LA_GID) {
if (la->la_gid == (gid_t) -1)
la->la_gid = tmp_la->la_gid;
- if (((uc->mu_fsuid != tmp_la->la_uid) ||
- ((la->la_gid != tmp_la->la_gid) &&
- !lustre_in_group_p(uc, la->la_gid))) &&
- !mdd_capable(uc, CFS_CAP_CHOWN))
- RETURN(-EPERM);
+ if (((uc->uc_fsuid != tmp_la->la_uid) ||
+ ((la->la_gid != tmp_la->la_gid) &&
+ !lustre_in_group_p(uc, la->la_gid))) &&
+ !mdd_capable(uc, CFS_CAP_CHOWN))
+ RETURN(-EPERM);
/* Likewise, if the user or group of a non-directory
* has been changed by a non-root user, remove the
} else {
if (la->la_valid & (LA_SIZE | LA_BLOCKS)) {
if (!((flags & MDS_OPEN_OWNEROVERRIDE) &&
- (uc->mu_fsuid == tmp_la->la_uid)) &&
+ (uc->uc_fsuid == tmp_la->la_uid)) &&
!(flags & MDS_PERM_BYPASS)) {
rc = mdd_permission_internal(env, obj,
tmp_la, MAY_WRITE);
}
static int mdd_xattr_sanity_check(const struct lu_env *env,
- struct mdd_object *obj)
+ struct mdd_object *obj)
{
- struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
- struct md_ucred *uc = md_ucred(env);
- int rc;
- ENTRY;
+ struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la;
+ struct lu_ucred *uc = lu_ucred_assert(env);
+ int rc;
+ ENTRY;
- if (mdd_is_immutable(obj) || mdd_is_append(obj))
- RETURN(-EPERM);
+ if (mdd_is_immutable(obj) || mdd_is_append(obj))
+ RETURN(-EPERM);
- rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA);
- if (rc)
- RETURN(rc);
+ rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA);
+ if (rc)
+ RETURN(rc);
- if ((uc->mu_fsuid != tmp_la->la_uid) &&
- !mdd_capable(uc, CFS_CAP_FOWNER))
- RETURN(-EPERM);
+ if ((uc->uc_fsuid != tmp_la->la_uid) &&
+ !mdd_capable(uc, CFS_CAP_FOWNER))
+ RETURN(-EPERM);
- RETURN(rc);
+ RETURN(rc);
}
static int mdd_declare_xattr_set(const struct lu_env *env,
*/
int accmode(const struct lu_env *env, struct lu_attr *la, int flags)
{
- int res = 0;
-
- /* Sadly, NFSD reopens a file repeatedly during operation, so the
- * "acc_mode = 0" allowance for newly-created files isn't honoured.
- * NFSD uses the MDS_OPEN_OWNEROVERRIDE flag to say that a file
- * owner can write to a file even if it is marked readonly to hide
- * its brokenness. (bug 5781) */
- if (flags & MDS_OPEN_OWNEROVERRIDE) {
- struct md_ucred *uc = md_ucred(env);
-
- if ((uc == NULL) || (uc->mu_valid == UCRED_INIT) ||
- (la->la_uid == uc->mu_fsuid))
- return 0;
- }
+ int res = 0;
+
+ /* Sadly, NFSD reopens a file repeatedly during operation, so the
+ * "acc_mode = 0" allowance for newly-created files isn't honoured.
+ * NFSD uses the MDS_OPEN_OWNEROVERRIDE flag to say that a file
+ * owner can write to a file even if it is marked readonly to hide
+ * its brokenness. (bug 5781) */
+ if (flags & MDS_OPEN_OWNEROVERRIDE) {
+ struct lu_ucred *uc = lu_ucred_check(env);
+
+ if ((uc == NULL) || (la->la_uid == uc->uc_fsuid))
+ return 0;
+ }
- if (flags & FMODE_READ)
- res |= MAY_READ;
- if (flags & (FMODE_WRITE | MDS_OPEN_TRUNC | MDS_OPEN_APPEND))
- res |= MAY_WRITE;
- if (flags & MDS_FMODE_EXEC)
- res = MAY_EXEC;
- return res;
+ if (flags & FMODE_READ)
+ res |= MAY_READ;
+ if (flags & (FMODE_WRITE | MDS_OPEN_TRUNC | MDS_OPEN_APPEND))
+ res |= MAY_WRITE;
+ if (flags & MDS_FMODE_EXEC)
+ res = MAY_EXEC;
+ return res;
}
static int mdd_open_sanity_check(const struct lu_env *env,
* Now, flag -- O_NOATIME does not be packed by client.
*/
if (flag & O_NOATIME) {
- struct md_ucred *uc = md_ucred(env);
+ struct lu_ucred *uc = lu_ucred(env);
- if (uc && ((uc->mu_valid == UCRED_OLD) ||
- (uc->mu_valid == UCRED_NEW)) &&
- (uc->mu_fsuid != tmp_la->la_uid) &&
- !mdd_capable(uc, CFS_CAP_FOWNER))
- RETURN(-EPERM);
+ if (uc && ((uc->uc_valid == UCRED_OLD) ||
+ (uc->uc_valid == UCRED_NEW)) &&
+ (uc->uc_fsuid != tmp_la->la_uid) &&
+ !mdd_capable(uc, CFS_CAP_FOWNER))
+ RETURN(-EPERM);
}
#endif
struct lu_attr *la, int mask)
{
#ifdef CONFIG_FS_POSIX_ACL
- struct md_ucred *uc = md_ucred(env);
+ struct lu_ucred *uc = lu_ucred_assert(env);
posix_acl_xattr_header *head;
posix_acl_xattr_entry *entry;
struct lu_buf *buf;
int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
struct lu_attr *la, int mask, int role)
{
- struct md_ucred *uc = md_ucred(env);
+ struct lu_ucred *uc = lu_ucred(env);
__u32 mode;
int rc;
ENTRY;
if (mask == 0)
RETURN(0);
- /* These means unnecessary for permission check */
- if ((uc == NULL) || (uc->mu_valid == UCRED_INIT))
- RETURN(0);
+ /* These means unnecessary for permission check */
+ if ((uc == NULL) || (uc->uc_valid == UCRED_INIT))
+ RETURN(0);
- /* Invalid user credit */
- if (uc->mu_valid == UCRED_INVALID)
- RETURN(-EACCES);
+ /* Invalid user credit */
+ if (uc->uc_valid == UCRED_INVALID)
+ RETURN(-EACCES);
/*
* Nobody gets write access to an immutable file.
}
mode = la->la_mode;
- if (uc->mu_fsuid == la->la_uid) {
- mode >>= 6;
+ if (uc->uc_fsuid == la->la_uid) {
+ mode >>= 6;
} else {
if (mode & S_IRWXG) {
if (role != -1)
struct md_attr *ma, int mask)
{
struct mdd_object *mdd_pobj, *mdd_cobj;
- struct md_ucred *uc = NULL;
+ struct lu_ucred *uc = NULL;
struct lu_attr *la = &mdd_env_info(env)->mti_cattr;
int check_create, check_link;
int check_unlink;
}
if (!rc && (check_vtx_part || check_vtx_full)) {
- uc = md_ucred(env);
+ uc = lu_ucred_assert(env);
if (likely(!la)) {
la = &mdd_env_info(env)->mti_la;
rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA);
RETURN(rc);
}
- if (!(la->la_mode & S_ISVTX) || (la->la_uid == uc->mu_fsuid) ||
- (check_vtx_full && (ma->ma_attr.la_valid & LA_UID) &&
- (ma->ma_attr.la_uid == uc->mu_fsuid))) {
- ma->ma_attr_flags |= MDS_VTX_BYPASS;
+ if (!(la->la_mode & S_ISVTX) || (la->la_uid == uc->uc_fsuid) ||
+ (check_vtx_full && (ma->ma_attr.la_valid & LA_UID) &&
+ (ma->ma_attr.la_uid == uc->uc_fsuid))) {
+ ma->ma_attr_flags |= MDS_VTX_BYPASS;
} else {
ma->ma_attr_flags &= ~MDS_VTX_BYPASS;
if (check_vtx_full)
if (unlikely(!rc && check_rgetfacl)) {
if (likely(!uc))
- uc = md_ucred(env);
+ uc = lu_ucred_assert(env);
- if (la->la_uid != uc->mu_fsuid &&
- !mdd_capable(uc, CFS_CAP_FOWNER))
- rc = -EPERM;
+ if (la->la_uid != uc->uc_fsuid &&
+ !mdd_capable(uc, CFS_CAP_FOWNER))
+ rc = -EPERM;
}
RETURN(rc);
/* context key: mdt_thread_key */
LU_CONTEXT_KEY_DEFINE(mdt, LCT_MD_THREAD);
-struct md_ucred *mdt_ucred(const struct mdt_thread_info *info)
+struct lu_ucred *mdt_ucred(const struct mdt_thread_info *info)
{
- return md_ucred(info->mti_env);
+ return lu_ucred(info->mti_env);
+}
+
+struct lu_ucred *mdt_ucred_check(const struct mdt_thread_info *info)
+{
+ return lu_ucred_check(info->mti_env);
}
/**
int mdt_pack_remote_perm(struct mdt_thread_info *info, struct mdt_object *o,
void *buf)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred_check(info);
struct md_object *next = mdt_object_child(o);
struct mdt_remote_perm *perm = buf;
if (!exp_connect_rmtclient(info->mti_exp))
RETURN(-EBADE);
- if ((uc->mu_valid != UCRED_OLD) && (uc->mu_valid != UCRED_NEW))
- RETURN(-EINVAL);
+ if (uc == NULL)
+ RETURN(-EINVAL);
- perm->rp_uid = uc->mu_o_uid;
- perm->rp_gid = uc->mu_o_gid;
- perm->rp_fsuid = uc->mu_o_fsuid;
- perm->rp_fsgid = uc->mu_o_fsgid;
+ perm->rp_uid = uc->uc_o_uid;
+ perm->rp_gid = uc->uc_o_gid;
+ perm->rp_fsuid = uc->uc_o_fsuid;
+ perm->rp_fsgid = uc->uc_o_fsgid;
perm->rp_access_perm = 0;
if (mo_permission(info->mti_env, NULL, next, NULL, MAY_READ) == 0)
void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
{
struct ptlrpc_request *req = mdt_info_req(info);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_export_data *med = mdt_req2med(req);
struct lustre_idmap_table *idmap = med->med_idmap;
int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op)
{
struct ptlrpc_request *req = mdt_info_req(info);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred_check(info);
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_export_data *med = mdt_req2med(req);
struct lustre_idmap_table *idmap = med->med_idmap;
- if ((uc->mu_valid != UCRED_OLD) && (uc->mu_valid != UCRED_NEW))
- return -EINVAL;
+ if (uc == NULL)
+ return -EINVAL;
if (op != REINT_SETATTR) {
- if ((attr->la_valid & LA_UID) && (attr->la_uid != -1))
- attr->la_uid = uc->mu_fsuid;
- /* for S_ISGID, inherit gid from his parent, such work will be
- * done in cmm/mdd layer, here set all cases as uc->mu_fsgid. */
- if ((attr->la_valid & LA_GID) && (attr->la_gid != -1))
- attr->la_gid = uc->mu_fsgid;
+ if ((attr->la_valid & LA_UID) && (attr->la_uid != -1))
+ attr->la_uid = uc->uc_fsuid;
+ /* for S_ISGID, inherit gid from his parent, such work will be
+ * done in cmm/mdd layer, here set all cases as uc->uc_fsgid. */
+ if ((attr->la_valid & LA_GID) && (attr->la_gid != -1))
+ attr->la_gid = uc->uc_fsgid;
} else if (exp_connect_rmtclient(info->mti_exp)) {
/* NB: -1 case will be handled by mdt_fix_attr() later. */
if ((attr->la_valid & LA_UID) && (attr->la_uid != -1)) {
RETURN(0);
}
-struct md_ucred *mdt_ucred(const struct mdt_thread_info *info);
+struct lu_ucred *mdt_ucred(const struct mdt_thread_info *info);
+struct lu_ucred *mdt_ucred_check(const struct mdt_thread_info *info);
static inline int is_identity_get_disabled(struct upcall_cache *cache)
{
void mdt_exit_ucred(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
- struct mdt_device *mdt = info->mti_mdt;
-
- if (uc->mu_valid != UCRED_INIT) {
- uc->mu_suppgids[0] = uc->mu_suppgids[1] = -1;
- if (uc->mu_ginfo) {
- cfs_put_group_info(uc->mu_ginfo);
- uc->mu_ginfo = NULL;
- }
- if (uc->mu_identity) {
- mdt_identity_put(mdt->mdt_identity_cache,
- uc->mu_identity);
- uc->mu_identity = NULL;
- }
- uc->mu_valid = UCRED_INIT;
- }
+ struct lu_ucred *uc = mdt_ucred(info);
+ struct mdt_device *mdt = info->mti_mdt;
+
+ LASSERT(uc != NULL);
+ if (uc->uc_valid != UCRED_INIT) {
+ uc->uc_suppgids[0] = uc->uc_suppgids[1] = -1;
+ if (uc->uc_ginfo) {
+ cfs_put_group_info(uc->uc_ginfo);
+ uc->uc_ginfo = NULL;
+ }
+ if (uc->uc_identity) {
+ mdt_identity_put(mdt->mdt_identity_cache,
+ uc->uc_identity);
+ uc->uc_identity = NULL;
+ }
+ uc->uc_valid = UCRED_INIT;
+ }
}
static int match_nosquash_list(struct rw_semaphore *sem,
/* root_squash for inter-MDS operations */
static int mdt_root_squash(struct mdt_thread_info *info, lnet_nid_t peernid)
{
- struct md_ucred *ucred = mdt_ucred(info);
- ENTRY;
+ struct lu_ucred *ucred = mdt_ucred(info);
+ ENTRY;
- if (!info->mti_mdt->mdt_squash_uid || ucred->mu_fsuid)
- RETURN(0);
+ LASSERT(ucred != NULL);
+ if (!info->mti_mdt->mdt_squash_uid || ucred->uc_fsuid)
+ RETURN(0);
if (match_nosquash_list(&info->mti_mdt->mdt_squash_sem,
&info->mti_mdt->mdt_nosquash_nids,
RETURN(0);
}
- CDEBUG(D_OTHER, "squash req from %s, (%d:%d/%x)=>(%d:%d/%x)\n",
- libcfs_nid2str(peernid),
- ucred->mu_fsuid, ucred->mu_fsgid, ucred->mu_cap,
- info->mti_mdt->mdt_squash_uid, info->mti_mdt->mdt_squash_gid,
- 0);
+ CDEBUG(D_OTHER, "squash req from %s, (%d:%d/%x)=>(%d:%d/%x)\n",
+ libcfs_nid2str(peernid),
+ ucred->uc_fsuid, ucred->uc_fsgid, ucred->uc_cap,
+ info->mti_mdt->mdt_squash_uid, info->mti_mdt->mdt_squash_gid,
+ 0);
- ucred->mu_fsuid = info->mti_mdt->mdt_squash_uid;
- ucred->mu_fsgid = info->mti_mdt->mdt_squash_gid;
- ucred->mu_cap = 0;
- ucred->mu_suppgids[0] = -1;
- ucred->mu_suppgids[1] = -1;
+ ucred->uc_fsuid = info->mti_mdt->mdt_squash_uid;
+ ucred->uc_fsgid = info->mti_mdt->mdt_squash_gid;
+ ucred->uc_cap = 0;
+ ucred->uc_suppgids[0] = -1;
+ ucred->uc_suppgids[1] = -1;
- RETURN(0);
+ RETURN(0);
}
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
struct ptlrpc_request *req = mdt_info_req(info);
struct mdt_device *mdt = info->mti_mdt;
struct ptlrpc_user_desc *pud = req->rq_user_desc;
- struct md_ucred *ucred = mdt_ucred(info);
+ struct lu_ucred *ucred = mdt_ucred(info);
lnet_nid_t peernid = req->rq_peer.nid;
__u32 perm = 0;
__u32 remote = exp_connect_rmtclient(info->mti_exp);
LASSERT(req->rq_auth_gss);
LASSERT(!req->rq_auth_usr_mdt);
LASSERT(req->rq_user_desc);
+ LASSERT(ucred != NULL);
- ucred->mu_valid = UCRED_INVALID;
+ ucred->uc_valid = UCRED_INVALID;
- ucred->mu_o_uid = pud->pud_uid;
- ucred->mu_o_gid = pud->pud_gid;
- ucred->mu_o_fsuid = pud->pud_fsuid;
- ucred->mu_o_fsgid = pud->pud_fsgid;
+ ucred->uc_o_uid = pud->pud_uid;
+ ucred->uc_o_gid = pud->pud_gid;
+ ucred->uc_o_fsuid = pud->pud_fsuid;
+ ucred->uc_o_fsgid = pud->pud_fsgid;
- if (type == BODY_INIT) {
- struct mdt_body *body = (struct mdt_body *)buf;
+ if (type == BODY_INIT) {
+ struct mdt_body *body = (struct mdt_body *)buf;
- ucred->mu_suppgids[0] = body->suppgid;
- ucred->mu_suppgids[1] = -1;
- }
+ ucred->uc_suppgids[0] = body->suppgid;
+ ucred->uc_suppgids[1] = -1;
+ }
/* sanity check: we expect the uid which client claimed is true */
if (remote) {
"enabled!\n");
RETURN(-EACCES);
} else {
- ucred->mu_identity = NULL;
+ ucred->uc_identity = NULL;
perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
CFS_SETGRP_PERM;
}
if (IS_ERR(identity)) {
if (unlikely(PTR_ERR(identity) == -EREMCHG &&
!remote)) {
- ucred->mu_identity = NULL;
+ ucred->uc_identity = NULL;
perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
CFS_SETGRP_PERM;
} else {
RETURN(-EACCES);
}
} else {
- ucred->mu_identity = identity;
- perm = mdt_identity_get_perm(ucred->mu_identity,
- remote, peernid);
+ ucred->uc_identity = identity;
+ perm = mdt_identity_get_perm(ucred->uc_identity,
+ remote, peernid);
}
}
/* find out the setuid/setgid attempt */
setuid = (pud->pud_uid != pud->pud_fsuid);
- setgid = ((pud->pud_gid != pud->pud_fsgid) ||
- (ucred->mu_identity &&
- (pud->pud_gid != ucred->mu_identity->mi_gid)));
+ setgid = ((pud->pud_gid != pud->pud_fsgid) ||
+ (ucred->uc_identity &&
+ (pud->pud_gid != ucred->uc_identity->mi_gid)));
/* check permission of setuid */
if (setuid && !(perm & CFS_SETUID_PERM)) {
/* check permission of setgid */
if (setgid && !(perm & CFS_SETGID_PERM)) {
- CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
- "from %s\n", pud->pud_uid, pud->pud_gid,
- pud->pud_fsuid, pud->pud_fsgid,
- ucred->mu_identity->mi_gid, libcfs_nid2str(peernid));
- GOTO(out, rc = -EACCES);
+ CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
+ "from %s\n", pud->pud_uid, pud->pud_gid,
+ pud->pud_fsuid, pud->pud_fsgid,
+ ucred->uc_identity->mi_gid, libcfs_nid2str(peernid));
+ GOTO(out, rc = -EACCES);
}
/*
* NB: remote client not allowed to setgroups anyway.
*/
- if (!remote && perm & CFS_SETGRP_PERM) {
- if (pud->pud_ngroups) {
- /* setgroups for local client */
- ucred->mu_ginfo = cfs_groups_alloc(pud->pud_ngroups);
- if (!ucred->mu_ginfo) {
- CERROR("failed to alloc %d groups\n",
- pud->pud_ngroups);
- GOTO(out, rc = -ENOMEM);
- }
-
- lustre_groups_from_list(ucred->mu_ginfo,
- pud->pud_groups);
- lustre_groups_sort(ucred->mu_ginfo);
- } else {
- ucred->mu_ginfo = NULL;
- }
- } else {
- ucred->mu_suppgids[0] = -1;
- ucred->mu_suppgids[1] = -1;
- ucred->mu_ginfo = NULL;
- }
+ if (!remote && perm & CFS_SETGRP_PERM) {
+ if (pud->pud_ngroups) {
+ /* setgroups for local client */
+ ucred->uc_ginfo = cfs_groups_alloc(pud->pud_ngroups);
+ if (!ucred->uc_ginfo) {
+ CERROR("failed to alloc %d groups\n",
+ pud->pud_ngroups);
+ GOTO(out, rc = -ENOMEM);
+ }
+
+ lustre_groups_from_list(ucred->uc_ginfo,
+ pud->pud_groups);
+ lustre_groups_sort(ucred->uc_ginfo);
+ } else {
+ ucred->uc_ginfo = NULL;
+ }
+ } else {
+ ucred->uc_suppgids[0] = -1;
+ ucred->uc_suppgids[1] = -1;
+ ucred->uc_ginfo = NULL;
+ }
- ucred->mu_uid = pud->pud_uid;
- ucred->mu_gid = pud->pud_gid;
- ucred->mu_fsuid = pud->pud_fsuid;
- ucred->mu_fsgid = pud->pud_fsgid;
+ ucred->uc_uid = pud->pud_uid;
+ ucred->uc_gid = pud->pud_gid;
+ ucred->uc_fsuid = pud->pud_fsuid;
+ ucred->uc_fsgid = pud->pud_fsgid;
- /* process root_squash here. */
- mdt_root_squash(info, peernid);
+ /* process root_squash here. */
+ mdt_root_squash(info, peernid);
- /* remove fs privilege for non-root user. */
- if (ucred->mu_fsuid)
- ucred->mu_cap = pud->pud_cap & ~CFS_CAP_FS_MASK;
- else
- ucred->mu_cap = pud->pud_cap;
- if (remote && !(perm & CFS_RMTOWN_PERM))
- ucred->mu_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK |
- CFS_CAP_CHOWN_MASK);
- ucred->mu_valid = UCRED_NEW;
+ /* remove fs privilege for non-root user. */
+ if (ucred->uc_fsuid)
+ ucred->uc_cap = pud->pud_cap & ~CFS_CAP_FS_MASK;
+ else
+ ucred->uc_cap = pud->pud_cap;
+ if (remote && !(perm & CFS_RMTOWN_PERM))
+ ucred->uc_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK |
+ CFS_CAP_CHOWN_MASK);
+ ucred->uc_valid = UCRED_NEW;
- EXIT;
+ EXIT;
out:
- if (rc) {
- if (ucred->mu_ginfo) {
- cfs_put_group_info(ucred->mu_ginfo);
- ucred->mu_ginfo = NULL;
- }
- if (ucred->mu_identity) {
- mdt_identity_put(mdt->mdt_identity_cache,
- ucred->mu_identity);
- ucred->mu_identity = NULL;
- }
- }
+ if (rc) {
+ if (ucred->uc_ginfo) {
+ cfs_put_group_info(ucred->uc_ginfo);
+ ucred->uc_ginfo = NULL;
+ }
+ if (ucred->uc_identity) {
+ mdt_identity_put(mdt->mdt_identity_cache,
+ ucred->uc_identity);
+ ucred->uc_identity = NULL;
+ }
+ }
- return rc;
+ return rc;
}
int mdt_check_ucred(struct mdt_thread_info *info)
struct ptlrpc_request *req = mdt_info_req(info);
struct mdt_device *mdt = info->mti_mdt;
struct ptlrpc_user_desc *pud = req->rq_user_desc;
- struct md_ucred *ucred = mdt_ucred(info);
+ struct lu_ucred *ucred = mdt_ucred(info);
struct md_identity *identity = NULL;
lnet_nid_t peernid = req->rq_peer.nid;
__u32 perm = 0;
ENTRY;
- if ((ucred->mu_valid == UCRED_OLD) || (ucred->mu_valid == UCRED_NEW))
- RETURN(0);
+ LASSERT(ucred != NULL);
+ if ((ucred->uc_valid == UCRED_OLD) || (ucred->uc_valid == UCRED_NEW))
+ RETURN(0);
if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
RETURN(0);
}
static int old_init_ucred(struct mdt_thread_info *info,
- struct mdt_body *body)
+ struct mdt_body *body)
{
- struct md_ucred *uc = mdt_ucred(info);
- struct mdt_device *mdt = info->mti_mdt;
- struct md_identity *identity = NULL;
+ struct lu_ucred *uc = mdt_ucred(info);
+ struct mdt_device *mdt = info->mti_mdt;
+ struct md_identity *identity = NULL;
- ENTRY;
+ ENTRY;
- uc->mu_valid = UCRED_INVALID;
- uc->mu_o_uid = uc->mu_uid = body->uid;
- uc->mu_o_gid = uc->mu_gid = body->gid;
- uc->mu_o_fsuid = uc->mu_fsuid = body->fsuid;
- uc->mu_o_fsgid = uc->mu_fsgid = body->fsgid;
- uc->mu_suppgids[0] = body->suppgid;
- uc->mu_suppgids[1] = -1;
- uc->mu_ginfo = NULL;
- if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
- identity = mdt_identity_get(mdt->mdt_identity_cache,
- uc->mu_fsuid);
- if (IS_ERR(identity)) {
- if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
- identity = NULL;
- } else {
- CDEBUG(D_SEC, "Deny access without identity: "
- "uid %u\n", uc->mu_fsuid);
- RETURN(-EACCES);
- }
- }
- }
- uc->mu_identity = identity;
+ LASSERT(uc != NULL);
+ uc->uc_valid = UCRED_INVALID;
+ uc->uc_o_uid = uc->uc_uid = body->uid;
+ uc->uc_o_gid = uc->uc_gid = body->gid;
+ uc->uc_o_fsuid = uc->uc_fsuid = body->fsuid;
+ uc->uc_o_fsgid = uc->uc_fsgid = body->fsgid;
+ uc->uc_suppgids[0] = body->suppgid;
+ uc->uc_suppgids[1] = -1;
+ uc->uc_ginfo = NULL;
+ if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
+ identity = mdt_identity_get(mdt->mdt_identity_cache,
+ uc->uc_fsuid);
+ if (IS_ERR(identity)) {
+ if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
+ identity = NULL;
+ } else {
+ CDEBUG(D_SEC, "Deny access without identity: "
+ "uid %u\n", uc->uc_fsuid);
+ RETURN(-EACCES);
+ }
+ }
+ }
+ uc->uc_identity = identity;
- /* process root_squash here. */
- mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
+ /* process root_squash here. */
+ mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
- /* remove fs privilege for non-root user. */
- if (uc->mu_fsuid)
- uc->mu_cap = body->capability & ~CFS_CAP_FS_MASK;
- else
- uc->mu_cap = body->capability;
- uc->mu_valid = UCRED_OLD;
+ /* remove fs privilege for non-root user. */
+ if (uc->uc_fsuid)
+ uc->uc_cap = body->capability & ~CFS_CAP_FS_MASK;
+ else
+ uc->uc_cap = body->capability;
+ uc->uc_valid = UCRED_OLD;
- RETURN(0);
+ RETURN(0);
}
static int old_init_ucred_reint(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
- struct mdt_device *mdt = info->mti_mdt;
- struct md_identity *identity = NULL;
+ struct lu_ucred *uc = mdt_ucred(info);
+ struct mdt_device *mdt = info->mti_mdt;
+ struct md_identity *identity = NULL;
- ENTRY;
+ ENTRY;
- uc->mu_valid = UCRED_INVALID;
- uc->mu_o_uid = uc->mu_o_fsuid = uc->mu_uid = uc->mu_fsuid;
- uc->mu_o_gid = uc->mu_o_fsgid = uc->mu_gid = uc->mu_fsgid;
- uc->mu_ginfo = NULL;
- if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
- identity = mdt_identity_get(mdt->mdt_identity_cache,
- uc->mu_fsuid);
- if (IS_ERR(identity)) {
- if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
- identity = NULL;
- } else {
- CDEBUG(D_SEC, "Deny access without identity: "
- "uid %u\n", uc->mu_fsuid);
- RETURN(-EACCES);
- }
- }
- }
- uc->mu_identity = identity;
+ LASSERT(uc != NULL);
+ uc->uc_valid = UCRED_INVALID;
+ uc->uc_o_uid = uc->uc_o_fsuid = uc->uc_uid = uc->uc_fsuid;
+ uc->uc_o_gid = uc->uc_o_fsgid = uc->uc_gid = uc->uc_fsgid;
+ uc->uc_ginfo = NULL;
+ if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
+ identity = mdt_identity_get(mdt->mdt_identity_cache,
+ uc->uc_fsuid);
+ if (IS_ERR(identity)) {
+ if (unlikely(PTR_ERR(identity) == -EREMCHG)) {
+ identity = NULL;
+ } else {
+ CDEBUG(D_SEC, "Deny access without identity: "
+ "uid %u\n", uc->uc_fsuid);
+ RETURN(-EACCES);
+ }
+ }
+ }
+ uc->uc_identity = identity;
- /* process root_squash here. */
- mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
+ /* process root_squash here. */
+ mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
- /* remove fs privilege for non-root user. */
- if (uc->mu_fsuid)
- uc->mu_cap &= ~CFS_CAP_FS_MASK;
- uc->mu_valid = UCRED_OLD;
+ /* remove fs privilege for non-root user. */
+ if (uc->uc_fsuid)
+ uc->uc_cap &= ~CFS_CAP_FS_MASK;
+ uc->uc_valid = UCRED_OLD;
- RETURN(0);
+ RETURN(0);
}
int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body)
{
struct ptlrpc_request *req = mdt_info_req(info);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
- if ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))
- return 0;
+ LASSERT(uc != NULL);
+ if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW))
+ return 0;
mdt_exit_ucred(info);
int mdt_init_ucred_reint(struct mdt_thread_info *info)
{
struct ptlrpc_request *req = mdt_info_req(info);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
- if ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))
- return 0;
+ LASSERT(uc != NULL);
+ if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW))
+ return 0;
mdt_exit_ucred(info);
static int mdt_setattr_unpack_rec(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct md_attr *ma = &info->mti_attr;
struct lu_attr *la = &ma->ma_attr;
struct req_capsule *pill = info->mti_pill;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->sa_fsuid;
- uc->mu_fsgid = rec->sa_fsgid;
- uc->mu_cap = rec->sa_cap;
- uc->mu_suppgids[0] = rec->sa_suppgid;
- uc->mu_suppgids[1] = -1;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->sa_fsuid;
+ uc->uc_fsgid = rec->sa_fsgid;
+ uc->uc_cap = rec->sa_cap;
+ uc->uc_suppgids[0] = rec->sa_suppgid;
+ uc->uc_suppgids[1] = -1;
rr->rr_fid1 = &rec->sa_fid;
la->la_valid = mdt_attr_valid_xlate(attr_unpack(rec->sa_valid), rr, ma);
if (rc)
RETURN(rc);
- RETURN(mdt_setattr_unpack_rec(info));
+ rc = mdt_setattr_unpack_rec(info);
+ if (rc)
+ RETURN(rc);
+ RETURN(mdt_init_ucred_reint(info));
}
static int mdt_create_unpack(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_rec_create *rec;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->cr_fsuid;
- uc->mu_fsgid = rec->cr_fsgid;
- uc->mu_cap = rec->cr_cap;
- uc->mu_suppgids[0] = rec->cr_suppgid1;
- uc->mu_suppgids[1] = -1;
- uc->mu_umask = rec->cr_umask;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->cr_fsuid;
+ uc->uc_fsgid = rec->cr_fsgid;
+ uc->uc_cap = rec->cr_cap;
+ uc->uc_suppgids[0] = rec->cr_suppgid1;
+ uc->uc_suppgids[1] = -1;
+ uc->uc_umask = rec->cr_umask;
rr->rr_fid1 = &rec->cr_fid1;
rr->rr_fid2 = &rec->cr_fid2;
static int mdt_link_unpack(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_rec_link *rec;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->lk_fsuid;
- uc->mu_fsgid = rec->lk_fsgid;
- uc->mu_cap = rec->lk_cap;
- uc->mu_suppgids[0] = rec->lk_suppgid1;
- uc->mu_suppgids[1] = rec->lk_suppgid2;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->lk_fsuid;
+ uc->uc_fsgid = rec->lk_fsgid;
+ uc->uc_cap = rec->lk_cap;
+ uc->uc_suppgids[0] = rec->lk_suppgid1;
+ uc->uc_suppgids[1] = rec->lk_suppgid2;
attr->la_uid = rec->lk_fsuid;
attr->la_gid = rec->lk_fsgid;
static int mdt_unlink_unpack(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_rec_unlink *rec;
struct md_attr *ma = &info->mti_attr;
struct lu_attr *attr = &info->mti_attr.ma_attr;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->ul_fsuid;
- uc->mu_fsgid = rec->ul_fsgid;
- uc->mu_cap = rec->ul_cap;
- uc->mu_suppgids[0] = rec->ul_suppgid1;
- uc->mu_suppgids[1] = -1;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->ul_fsuid;
+ uc->uc_fsgid = rec->ul_fsgid;
+ uc->uc_cap = rec->ul_cap;
+ uc->uc_suppgids[0] = rec->ul_suppgid1;
+ uc->uc_suppgids[1] = -1;
attr->la_uid = rec->ul_fsuid;
attr->la_gid = rec->ul_fsgid;
static int mdt_rename_unpack(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_rec_rename *rec;
struct md_attr *ma = &info->mti_attr;
struct lu_attr *attr = &info->mti_attr.ma_attr;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->rn_fsuid;
- uc->mu_fsgid = rec->rn_fsgid;
- uc->mu_cap = rec->rn_cap;
- uc->mu_suppgids[0] = rec->rn_suppgid1;
- uc->mu_suppgids[1] = rec->rn_suppgid2;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->rn_fsuid;
+ uc->uc_fsgid = rec->rn_fsgid;
+ uc->uc_cap = rec->rn_cap;
+ uc->uc_suppgids[0] = rec->rn_suppgid1;
+ uc->uc_suppgids[1] = rec->rn_suppgid2;
attr->la_uid = rec->rn_fsuid;
attr->la_gid = rec->rn_fsgid;
static int mdt_open_unpack(struct mdt_thread_info *info)
{
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_rec_create *rec;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct req_capsule *pill = info->mti_pill;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->cr_fsuid;
- uc->mu_fsgid = rec->cr_fsgid;
- uc->mu_cap = rec->cr_cap;
- uc->mu_suppgids[0] = rec->cr_suppgid1;
- uc->mu_suppgids[1] = rec->cr_suppgid2;
- uc->mu_umask = rec->cr_umask;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->cr_fsuid;
+ uc->uc_fsgid = rec->cr_fsgid;
+ uc->uc_cap = rec->cr_cap;
+ uc->uc_suppgids[0] = rec->cr_suppgid1;
+ uc->uc_suppgids[1] = rec->cr_suppgid2;
+ uc->uc_umask = rec->cr_umask;
rr->rr_fid1 = &rec->cr_fid1;
rr->rr_fid2 = &rec->cr_fid2;
static int mdt_setxattr_unpack(struct mdt_thread_info *info)
{
struct mdt_reint_record *rr = &info->mti_rr;
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct req_capsule *pill = info->mti_pill;
struct mdt_rec_setxattr *rec;
if (rec == NULL)
RETURN(-EFAULT);
- uc->mu_fsuid = rec->sx_fsuid;
- uc->mu_fsgid = rec->sx_fsgid;
- uc->mu_cap = rec->sx_cap;
- uc->mu_suppgids[0] = rec->sx_suppgid1;
- uc->mu_suppgids[1] = -1;
+ /* This prior initialization is needed for old_init_ucred_reint() */
+ uc->uc_fsuid = rec->sx_fsuid;
+ uc->uc_fsgid = rec->sx_fsgid;
+ uc->uc_cap = rec->sx_cap;
+ uc->uc_suppgids[0] = rec->sx_suppgid1;
+ uc->uc_suppgids[1] = -1;
rr->rr_opcode = rec->sx_opcode;
rr->rr_fid1 = &rec->sx_fid;
mdt_client_compatibility(info);
if (rc == 0)
mdt_fix_reply(info);
+ mdt_exit_ucred(info);
RETURN(lustre_msg_get_status(req->rq_repmsg));
}
rc = mdt_fix_reply(info);
}
+ mdt_exit_ucred(info);
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_CLOSE_PACK))
RETURN(err_serious(-ENOMEM));
if (rc)
RETURN(err_serious(rc));
- if (mdt_check_resent(info, mdt_reconstruct_generic, NULL))
- RETURN(lustre_msg_get_status(req->rq_repmsg));
+ if (mdt_check_resent(info, mdt_reconstruct_generic, NULL)) {
+ mdt_exit_ucred(info);
+ RETURN(lustre_msg_get_status(req->rq_repmsg));
+ }
med = &info->mti_exp->exp_mdt_data;
spin_lock(&med->med_open_lock);
rc = info->mti_ioepoch->flags & MF_SOM_AU ?
-EAGAIN : 0;
mdt_empty_transno(info, rc);
- RETURN(rc);
- }
- RETURN(-ESTALE);
+ } else
+ rc = -ESTALE;
+ GOTO(error_ucred, rc);
}
LASSERT(mfd->mfd_mode == MDS_FMODE_EPOCH ||
info->mti_attr.ma_lmm_size = info->mti_mdt->mdt_max_mdsize;
OBD_ALLOC_LARGE(info->mti_attr.ma_lmm, info->mti_mdt->mdt_max_mdsize);
- if (info->mti_attr.ma_lmm == NULL)
- RETURN(-ENOMEM);
+ if (info->mti_attr.ma_lmm == NULL)
+ GOTO(error_ucred, rc = -ENOMEM);
rc = mdt_mfd_close(info, mfd);
OBD_FREE_LARGE(info->mti_attr.ma_lmm, info->mti_mdt->mdt_max_mdsize);
mdt_empty_transno(info, rc);
- RETURN(rc);
+error_ucred:
+ mdt_exit_ucred(info);
+ RETURN(rc);
}
{
struct ptlrpc_request *req = mdt_info_req(info);
struct mdt_export_data *med = mdt_req2med(req);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_body *reqbody;
struct mdt_body *repbody = NULL;
struct md_object *next;
if (reqbody == NULL)
RETURN(err_serious(-EFAULT));
- rc = mdt_init_ucred(info, reqbody);
+ rc = mdt_init_ucred(info, reqbody);
if (rc)
RETURN(err_serious(rc));
if (unlikely(!remote))
GOTO(out, rc = err_serious(-EINVAL));
- perm = mdt_identity_get_perm(uc->mu_identity, remote,
- req->rq_peer.nid);
+ perm = mdt_identity_get_perm(uc->uc_identity, remote,
+ req->rq_peer.nid);
if (!(perm & CFS_RMTACL_PERM))
GOTO(out, rc = err_serious(-EPERM));
{
struct ptlrpc_request *req = mdt_info_req(info);
struct mdt_export_data *med = mdt_req2med(req);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct lu_buf *buf = &info->mti_buf;
int rc;
ENTRY;
struct mdt_lock_handle *unused)
{
struct ptlrpc_request *req = mdt_info_req(info);
- struct md_ucred *uc = mdt_ucred(info);
+ struct lu_ucred *uc = mdt_ucred(info);
struct mdt_lock_handle *lh;
const struct lu_env *env = info->mti_env;
struct lu_buf *buf = &info->mti_buf;
CDEBUG(D_INODE, "%s xattr %s\n",
valid & OBD_MD_FLXATTR ? "set" : "remove", xattr_name);
- rc = mdt_init_ucred_reint(info);
+ rc = mdt_init_ucred_reint(info);
if (rc != 0)
RETURN(rc);
if (unlikely(!remote))
GOTO(out, rc = err_serious(-EINVAL));
- perm = mdt_identity_get_perm(uc->mu_identity, remote,
- req->rq_peer.nid);
+ perm = mdt_identity_get_perm(uc->uc_identity, remote,
+ req->rq_peer.nid);
if (!(perm & CFS_RMTACL_PERM))
GOTO(out, rc = err_serious(-EPERM));
}
if (unlikely(new_xattr != NULL))
lustre_posix_acl_xattr_free(new_xattr, xattr_len);
out:
- mdt_exit_ucred(info);
- return rc;
+ mdt_exit_ucred(info);
+ return rc;
}
/*
* Check permission based on POSIX ACL.
*/
-int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
- int want, posix_acl_xattr_entry *entry,
- int count)
+int lustre_posix_acl_permission(struct lu_ucred *mu, struct lu_attr *la,
+ int want, posix_acl_xattr_entry *entry,
+ int count)
{
posix_acl_xattr_entry *pa, *pe, *mask_obj;
posix_acl_xattr_entry ae, me;
switch (ae.e_tag) {
case ACL_USER_OBJ:
/* (May have been checked already) */
- if (la->la_uid == mu->mu_fsuid)
- goto check_perm;
+ if (la->la_uid == mu->uc_fsuid)
+ goto check_perm;
break;
case ACL_USER:
- if (ae.e_id == mu->mu_fsuid)
- goto mask;
+ if (ae.e_id == mu->uc_fsuid)
+ goto mask;
break;
case ACL_GROUP_OBJ:
if (lustre_in_group_p(mu, la->la_gid)) {
* @CFS_IC_UNMAPPED
* only unmapped ids are converted to "nobody".
*/
-int lustre_posix_acl_xattr_id2client(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- posix_acl_xattr_header *header,
- int size, int flags)
+int lustre_posix_acl_xattr_id2client(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ posix_acl_xattr_header *header,
+ int size, int flags)
{
int count, i;
__u32 id;
* mapped ids are converted to server-side ones,
* unmapped ones cause "EPERM" error.
*/
-int lustre_ext_acl_xattr_id2server(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- ext_acl_xattr_header *header)
+int lustre_ext_acl_xattr_id2server(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ ext_acl_xattr_header *header)
{
int i, count = le32_to_cpu(header->a_count);
}
EXPORT_SYMBOL(lustre_groups_sort);
-int lustre_in_group_p(struct md_ucred *mu, gid_t grp)
+int lustre_in_group_p(struct lu_ucred *mu, gid_t grp)
{
- int rc = 1;
+ int rc = 1;
- if (grp != mu->mu_fsgid) {
- cfs_group_info_t *group_info = NULL;
+ if (grp != mu->uc_fsgid) {
+ cfs_group_info_t *group_info = NULL;
- if (mu->mu_ginfo || !mu->mu_identity ||
- mu->mu_valid == UCRED_OLD)
- if (grp == mu->mu_suppgids[0] ||
- grp == mu->mu_suppgids[1])
- return 1;
+ if (mu->uc_ginfo || !mu->uc_identity ||
+ mu->uc_valid == UCRED_OLD)
+ if (grp == mu->uc_suppgids[0] ||
+ grp == mu->uc_suppgids[1])
+ return 1;
- if (mu->mu_ginfo)
- group_info = mu->mu_ginfo;
- else if (mu->mu_identity)
- group_info = mu->mu_identity->mi_ginfo;
+ if (mu->uc_ginfo)
+ group_info = mu->uc_ginfo;
+ else if (mu->uc_identity)
+ group_info = mu->uc_identity->mi_ginfo;
- if (!group_info)
- return 0;
+ if (!group_info)
+ return 0;
- lustre_get_group_info(group_info);
- rc = lustre_groups_search(group_info, grp);
- lustre_put_group_info(group_info);
- }
- return rc;
+ lustre_get_group_info(group_info);
+ rc = lustre_groups_search(group_info, grp);
+ lustre_put_group_info(group_info);
+ }
+ return rc;
}
EXPORT_SYMBOL(lustre_in_group_p);
}
EXPORT_SYMBOL(lustre_idmap_del);
-int lustre_idmap_lookup_uid(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- int reverse, uid_t uid)
+int lustre_idmap_lookup_uid(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ int reverse, uid_t uid)
{
- cfs_list_t *hash;
-
- if (mu && (mu->mu_valid == UCRED_OLD || mu->mu_valid == UCRED_NEW)) {
- if (!reverse) {
- if (uid == mu->mu_o_uid)
- return mu->mu_uid;
- else if (uid == mu->mu_o_fsuid)
- return mu->mu_fsuid;
- } else {
- if (uid == mu->mu_uid)
- return mu->mu_o_uid;
- else if (uid == mu->mu_fsuid)
- return mu->mu_o_fsuid;
- }
- }
+ cfs_list_t *hash;
+
+ if (mu && (mu->uc_valid == UCRED_OLD || mu->uc_valid == UCRED_NEW)) {
+ if (!reverse) {
+ if (uid == mu->uc_o_uid)
+ return mu->uc_uid;
+ else if (uid == mu->uc_o_fsuid)
+ return mu->uc_fsuid;
+ } else {
+ if (uid == mu->uc_uid)
+ return mu->uc_o_uid;
+ else if (uid == mu->uc_fsuid)
+ return mu->uc_o_fsuid;
+ }
+ }
if (t == NULL)
return CFS_IDMAP_NOTFOUND;
}
EXPORT_SYMBOL(lustre_idmap_lookup_uid);
-int lustre_idmap_lookup_gid(struct md_ucred *mu, struct lustre_idmap_table *t,
- int reverse, gid_t gid)
+int lustre_idmap_lookup_gid(struct lu_ucred *mu, struct lustre_idmap_table *t,
+ int reverse, gid_t gid)
{
- cfs_list_t *hash;
-
- if (mu && (mu->mu_valid == UCRED_OLD || mu->mu_valid == UCRED_NEW)) {
- if (!reverse) {
- if (gid == mu->mu_o_gid)
- return mu->mu_gid;
- else if (gid == mu->mu_o_fsgid)
- return mu->mu_fsgid;
- } else {
- if (gid == mu->mu_gid)
- return mu->mu_o_gid;
- else if (gid == mu->mu_fsgid)
- return mu->mu_o_fsgid;
- }
- }
+ cfs_list_t *hash;
+
+ if (mu && (mu->uc_valid == UCRED_OLD || mu->uc_valid == UCRED_NEW)) {
+ if (!reverse) {
+ if (gid == mu->uc_o_gid)
+ return mu->uc_gid;
+ else if (gid == mu->uc_o_fsgid)
+ return mu->uc_fsgid;
+ } else {
+ if (gid == mu->uc_gid)
+ return mu->uc_o_gid;
+ else if (gid == mu->uc_fsgid)
+ return mu->uc_o_fsgid;
+ }
+ }
if (t == NULL)
return CFS_IDMAP_NOTFOUND;
int llo_global_init(void);
void llo_global_fini(void);
+/* context key constructor/destructor: lu_ucred_key_init, lu_ucred_key_fini */
+LU_KEY_INIT_FINI(lu_ucred, struct lu_ucred);
+
+static struct lu_context_key lu_ucred_key = {
+ .lct_tags = LCT_SESSION,
+ .lct_init = lu_ucred_key_init,
+ .lct_fini = lu_ucred_key_fini
+};
+
+/**
+ * Get ucred key if session exists and ucred key is allocated on it.
+ * Return NULL otherwise.
+ */
+struct lu_ucred *lu_ucred(const struct lu_env *env)
+{
+ if (!env->le_ses)
+ return NULL;
+ return lu_context_key_get(env->le_ses, &lu_ucred_key);
+}
+EXPORT_SYMBOL(lu_ucred);
+
+/**
+ * Get ucred key and check if it is properly initialized.
+ * Return NULL otherwise.
+ */
+struct lu_ucred *lu_ucred_check(const struct lu_env *env)
+{
+ struct lu_ucred *uc = lu_ucred(env);
+ if (uc && uc->uc_valid != UCRED_OLD && uc->uc_valid != UCRED_NEW)
+ return NULL;
+ return uc;
+}
+EXPORT_SYMBOL(lu_ucred_check);
+
+/**
+ * Get ucred key, which must exist and must be properly initialized.
+ * Assert otherwise.
+ */
+struct lu_ucred *lu_ucred_assert(const struct lu_env *env)
+{
+ struct lu_ucred *uc = lu_ucred_check(env);
+ LASSERT(uc != NULL);
+ return uc;
+}
+EXPORT_SYMBOL(lu_ucred_assert);
+
/**
* Initialization of global lu_* data.
*/
result = lu_context_key_register(&lu_global_key);
if (result != 0)
return result;
+
+ LU_CONTEXT_KEY_INIT(&lu_ucred_key);
+ result = lu_context_key_register(&lu_ucred_key);
+ if (result != 0)
+ return result;
+
/*
* At this level, we don't know what tags are needed, so allocate them
* conservatively. This should not be too bad, because this
}
lu_context_key_degister(&lu_global_key);
+ lu_context_key_degister(&lu_ucred_key);
/*
* Tear shrinker environment down _after_ de-registering
RETURN(parent);
}
+static void echo_ucred_init(struct lu_env *env)
+{
+ struct lu_ucred *ucred = lu_ucred(env);
+
+ ucred->uc_valid = UCRED_INVALID;
+
+ ucred->uc_suppgids[0] = -1;
+ ucred->uc_suppgids[1] = -1;
+
+ ucred->uc_uid = ucred->uc_o_uid = cfs_curproc_uid();
+ ucred->uc_gid = ucred->uc_o_gid = cfs_curproc_gid();
+ ucred->uc_fsuid = ucred->uc_o_fsuid = cfs_curproc_fsuid();
+ ucred->uc_fsgid = ucred->uc_o_fsgid = cfs_curproc_fsgid();
+ ucred->uc_cap = cfs_curproc_cap_pack();
+
+ /* remove fs privilege for non-root user. */
+ if (ucred->uc_fsuid)
+ ucred->uc_cap &= ~CFS_CAP_FS_MASK;
+ ucred->uc_valid = UCRED_NEW;
+}
+
+static void echo_ucred_fini(struct lu_env *env)
+{
+ struct lu_ucred *ucred = lu_ucred(env);
+ ucred->uc_valid = UCRED_INIT;
+}
+
#define ECHO_MD_CTX_TAG (LCT_REMEMBER | LCT_MD_THREAD)
#define ECHO_MD_SES_TAG (LCT_REMEMBER | LCT_SESSION)
static int echo_md_handler(struct echo_device *ed, int command,
GOTO(out_name, rc = -EFAULT);
}
+ echo_ucred_init(env);
+
switch (command) {
case ECHO_MD_CREATE:
case ECHO_MD_MKDIR: {
rc = -EINVAL;
break;
}
+ echo_ucred_fini(env);
+
out_name:
if (name != NULL)
OBD_FREE(name, namelen + 1);