Пример #1
0
static int chown_common(struct path *path, uid_t user, gid_t group)
{
	struct inode *inode = path->dentry->d_inode;
	int error;
	struct iattr newattrs;
	kuid_t uid;
	kgid_t gid;

	uid = make_kuid(current_user_ns(), user);
	gid = make_kgid(current_user_ns(), group);

	newattrs.ia_valid =  ATTR_CTIME;
	if (user != (uid_t) -1) {
		if (!uid_valid(uid))
			return -EINVAL;
		newattrs.ia_valid |= ATTR_UID;
		newattrs.ia_uid = uid;
	}
	if (group != (gid_t) -1) {
		if (!gid_valid(gid))
			return -EINVAL;
		newattrs.ia_valid |= ATTR_GID;
		newattrs.ia_gid = gid;
	}
	if (!S_ISDIR(inode->i_mode))
		newattrs.ia_valid |=
			ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
	mutex_lock(&inode->i_mutex);
	error = security_path_chown(path, uid, gid);
	if (!error)
		error = notify_change(path->dentry, &newattrs);
	mutex_unlock(&inode->i_mutex);

	return error;
}
Пример #2
0
static int gssx_dec_linux_creds(struct xdr_stream *xdr,
				struct svc_cred *creds)
{
	u32 length;
	__be32 *p;
	u32 tmp;
	u32 N;
	int i, err;

	p = xdr_inline_decode(xdr, 4);
	if (unlikely(p == NULL))
		return -ENOSPC;

	length = be32_to_cpup(p);

	if (length > (3 + NGROUPS_MAX) * sizeof(u32))
		return -ENOSPC;

	/* uid */
	err = get_host_u32(xdr, &tmp);
	if (err)
		return err;
	creds->cr_uid = make_kuid(&init_user_ns, tmp);

	/* gid */
	err = get_host_u32(xdr, &tmp);
	if (err)
		return err;
	creds->cr_gid = make_kgid(&init_user_ns, tmp);

	/* number of additional gid's */
	err = get_host_u32(xdr, &tmp);
	if (err)
		return err;
	N = tmp;
	if ((3 + N) * sizeof(u32) != length)
		return -EINVAL;
	creds->cr_group_info = groups_alloc(N);
	if (creds->cr_group_info == NULL)
		return -ENOMEM;

	/* gid's */
	for (i = 0; i < N; i++) {
		kgid_t kgid;
		err = get_host_u32(xdr, &tmp);
		if (err)
			goto out_free_groups;
		err = -EINVAL;
		kgid = make_kgid(&init_user_ns, tmp);
		if (!gid_valid(kgid))
			goto out_free_groups;
		creds->cr_group_info->gid[i] = kgid;
	}
	groups_sort(creds->cr_group_info);

	return 0;
out_free_groups:
	groups_free(creds->cr_group_info);
	return err;
}
Пример #3
0
static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
				     qid_t id)
{
	switch (cmd) {
	/* these commands do not require any special privilegues */
	case Q_GETFMT:
	case Q_SYNC:
	case Q_GETINFO:
	case Q_XGETQSTAT:
	case Q_XGETQSTATV:
	case Q_XQUOTASYNC:
		break;
	/* allow to query information for dquots we "own" */
	case Q_GETQUOTA:
	case Q_XGETQUOTA:
		if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
		    (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
			break;
		/*FALLTHROUGH*/
	default:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
	}

	return security_quotactl(cmd, type, id, sb);
}
Пример #4
0
static int recover_quota_data(struct inode *inode, struct page *page)
{
	struct f2fs_inode *raw = F2FS_INODE(page);
	struct iattr attr;
	uid_t i_uid = le32_to_cpu(raw->i_uid);
	gid_t i_gid = le32_to_cpu(raw->i_gid);
	int err;

	memset(&attr, 0, sizeof(attr));

	attr.ia_uid = make_kuid(inode->i_sb->s_user_ns, i_uid);
	attr.ia_gid = make_kgid(inode->i_sb->s_user_ns, i_gid);

	if (!uid_eq(attr.ia_uid, inode->i_uid))
		attr.ia_valid |= ATTR_UID;
	if (!gid_eq(attr.ia_gid, inode->i_gid))
		attr.ia_valid |= ATTR_GID;

	if (!attr.ia_valid)
		return 0;

	err = dquot_transfer(inode, &attr);
	if (err)
		set_sbi_flag(F2FS_I_SB(inode), SBI_QUOTA_NEED_REPAIR);
	return err;
}
Пример #5
0
static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
			  struct kstat *stat)
{
	unsigned int blkbits;

	stat->dev = inode->i_sb->s_dev;
	stat->ino = attr->ino;
	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
	stat->nlink = attr->nlink;
	stat->uid = make_kuid(&init_user_ns, attr->uid);
	stat->gid = make_kgid(&init_user_ns, attr->gid);
	stat->rdev = inode->i_rdev;
	stat->atime.tv_sec = attr->atime;
	stat->atime.tv_nsec = attr->atimensec;
	stat->mtime.tv_sec = attr->mtime;
	stat->mtime.tv_nsec = attr->mtimensec;
	stat->ctime.tv_sec = attr->ctime;
	stat->ctime.tv_nsec = attr->ctimensec;
	stat->size = attr->size;
	stat->blocks = attr->blocks;

	if (attr->blksize != 0)
		blkbits = ilog2(attr->blksize);
	else
		blkbits = inode->i_sb->s_blocksize_bits;

	stat->blksize = 1 << blkbits;
}
Пример #6
0
static int ovl_whiteout(struct dentry *upperdir, struct dentry *dentry)
{
	int err;
	struct dentry *newdentry;
	const struct cred *old_cred;
	struct cred *override_cred;

	/* FIXME: recheck lower dentry to see if whiteout is really needed */

	err = -ENOMEM;
	override_cred = ovl_prepare_creds(dentry->d_sb);
	if (!override_cred)
		goto out;

	override_cred->fsuid = make_kuid(override_cred->user_ns, 0);
	if (!uid_valid(override_cred->fsuid))
		override_cred->fsuid = GLOBAL_ROOT_UID;
	override_cred->fsgid = make_kgid(override_cred->user_ns, 0);
	if (!gid_valid(override_cred->fsgid))
		override_cred->fsgid = GLOBAL_ROOT_GID;
	old_cred = override_creds(override_cred);

	newdentry = lookup_one_len(dentry->d_name.name, upperdir,
				   dentry->d_name.len);
	err = PTR_ERR(newdentry);
	if (IS_ERR(newdentry))
		goto out_put_cred;

	/* Just been removed within the same locked region */
	WARN_ON(newdentry->d_inode);

	err = vfs_symlink(upperdir->d_inode, newdentry, ovl_whiteout_symlink);
	if (err)
		goto out_dput;

	ovl_dentry_version_inc(dentry->d_parent);

	err = ovl_do_setxattr(newdentry, ovl_whiteout_xattr, "y", 1, 0);
	if (err)
		vfs_unlink(upperdir->d_inode, newdentry, NULL);

out_dput:
	dput(newdentry);
out_put_cred:
	revert_creds(old_cred);
	put_cred(override_cred);
out:
	if (err) {
		/*
		 * There's no way to recover from failure to whiteout.
		 * What should we do?  Log a big fat error and... ?
		 */
		pr_err("overlayfs: ERROR - failed to whiteout '%s'\n",
		       dentry->d_name.name);
	}

	return err;
}
Пример #7
0
static __be32
nfsd4_ff_proc_layoutget(struct inode *inode, const struct svc_fh *fhp,
		struct nfsd4_layoutget *args)
{
	struct nfsd4_layout_seg *seg = &args->lg_seg;
	u32 device_generation = 0;
	int error;
	uid_t u;

	struct pnfs_ff_layout *fl;

	/*
	 * The super simple flex file server has 1 mirror, 1 data server,
	 * and 1 file handle. So instead of 4 allocs, do 1 for now.
	 * Zero it out for the stateid - don't want junk in there!
	 */
	error = -ENOMEM;
	fl = kzalloc(sizeof(*fl), GFP_KERNEL);
	if (!fl)
		goto out_error;
	args->lg_content = fl;

	/*
	 * Avoid layout commit, try to force the I/O to the DS,
	 * and for fun, cause all IOMODE_RW layout segments to
	 * effectively be WRITE only.
	 */
	fl->flags = FF_FLAGS_NO_LAYOUTCOMMIT | FF_FLAGS_NO_IO_THRU_MDS |
		    FF_FLAGS_NO_READ_IO;

	/* Do not allow a IOMODE_READ segment to have write pemissions */
	if (seg->iomode == IOMODE_READ) {
		u = from_kuid(&init_user_ns, inode->i_uid) + 1;
		fl->uid = make_kuid(&init_user_ns, u);
	} else
		fl->uid = inode->i_uid;
	fl->gid = inode->i_gid;

	error = nfsd4_set_deviceid(&fl->deviceid, fhp, device_generation);
	if (error)
		goto out_error;

	fl->fh.size = fhp->fh_handle.fh_size;
	memcpy(fl->fh.data, &fhp->fh_handle.fh_base, fl->fh.size);

	/* Give whole file layout segments */
	seg->offset = 0;
	seg->length = NFS4_MAX_UINT64;

	dprintk("GET: 0x%llx:0x%llx %d\n", seg->offset, seg->length,
		seg->iomode);
	return 0;

out_error:
	seg->length = 0;
	return nfserrno(error);
}
Пример #8
0
static int mknod_ptmx(struct super_block *sb)
{
	int mode;
	int rc = -ENOMEM;
	struct dentry *dentry;
	struct inode *inode;
	struct dentry *root = sb->s_root;
	struct pts_fs_info *fsi = DEVPTS_SB(sb);
	struct pts_mount_opts *opts = &fsi->mount_opts;
	kuid_t root_uid;
	kgid_t root_gid;

	root_uid = make_kuid(current_user_ns(), 0);
	root_gid = make_kgid(current_user_ns(), 0);
	if (!uid_valid(root_uid) || !gid_valid(root_gid))
		return -EINVAL;

	mutex_lock(&root->d_inode->i_mutex);

	/* If we have already created ptmx node, return */
	if (fsi->ptmx_dentry) {
		rc = 0;
		goto out;
	}

	dentry = d_alloc_name(root, "ptmx");
	if (!dentry) {
		printk(KERN_NOTICE "Unable to alloc dentry for ptmx node\n");
		goto out;
	}

	/*
	 * Create a new 'ptmx' node in this mount of devpts.
	 */
	inode = new_inode(sb);
	if (!inode) {
		printk(KERN_ERR "Unable to alloc inode for ptmx node\n");
		dput(dentry);
		goto out;
	}

	inode->i_ino = 2;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;

	mode = S_IFCHR|opts->ptmxmode;
	init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
	inode->i_uid = root_uid;
	inode->i_gid = root_gid;

	d_add(dentry, inode);

	fsi->ptmx_dentry = dentry;
	rc = 0;
out:
	mutex_unlock(&root->d_inode->i_mutex);
	return rc;
}
Пример #9
0
static bool
owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
	const struct xt_owner_match_info *info = par->matchinfo;
	const struct file *filp;
	struct sock *sk = skb_to_full_sk(skb);
	struct net *net = par->net;

	if (sk == NULL || sk->sk_socket == NULL)
		return (info->match ^ info->invert) == 0;
	else if (info->match & info->invert & XT_OWNER_SOCKET)
		/*
		 * Socket exists but user wanted ! --socket-exists.
		 * (Single ampersands intended.)
		 */
		return false;

	filp = sk->sk_socket->file;
	if (filp == NULL)
		return ((info->match ^ info->invert) &
		       (XT_OWNER_UID | XT_OWNER_GID)) == 0;

	if (info->match & XT_OWNER_UID) {
		kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
		kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
		if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
		     uid_lte(filp->f_cred->fsuid, uid_max)) ^
		    !(info->invert & XT_OWNER_UID))
			return false;
	}

	if (info->match & XT_OWNER_GID) {
		kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
		kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);
		if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
		     gid_lte(filp->f_cred->fsgid, gid_max)) ^
		    !(info->invert & XT_OWNER_GID))
			return false;
	}

	return true;
}
Пример #10
0
static __be32 *
decode_sattr(__be32 *p, struct iattr *iap)
{
	u32	tmp, tmp1;

	iap->ia_valid = 0;

	/* Sun client bug compatibility check: some sun clients seem to
	 * put 0xffff in the mode field when they mean 0xffffffff.
	 * Quoting the 4.4BSD nfs server code: Nah nah nah nah na nah.
	 */
	if ((tmp = ntohl(*p++)) != (u32)-1 && tmp != 0xffff) {
		iap->ia_valid |= ATTR_MODE;
		iap->ia_mode = tmp;
	}
	if ((tmp = ntohl(*p++)) != (u32)-1) {
		iap->ia_uid = make_kuid(&init_user_ns, tmp);
		if (uid_valid(iap->ia_uid))
			iap->ia_valid |= ATTR_UID;
	}
	if ((tmp = ntohl(*p++)) != (u32)-1) {
		iap->ia_gid = make_kgid(&init_user_ns, tmp);
		if (gid_valid(iap->ia_gid))
			iap->ia_valid |= ATTR_GID;
	}
	if ((tmp = ntohl(*p++)) != (u32)-1) {
		iap->ia_valid |= ATTR_SIZE;
		iap->ia_size = tmp;
	}
	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
		iap->ia_atime.tv_sec = tmp;
		iap->ia_atime.tv_nsec = tmp1 * 1000; 
	}
	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
		iap->ia_mtime.tv_sec = tmp;
		iap->ia_mtime.tv_nsec = tmp1 * 1000; 
		/*
		 * Passing the invalid value useconds=1000000 for mtime
		 * is a Sun convention for "set both mtime and atime to
		 * current server time".  It's needed to make permissions
		 * checks for the "touch" program across v2 mounts to
		 * Solaris and Irix boxes work correctly. See description of
		 * sattr in section 6.1 of "NFS Illustrated" by
		 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
		 */
		if (tmp1 == 1000000)
			iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET);
	}
	return p;
}
Пример #11
0
/* Return standard mode bits for table entry. */
static int net_ctl_permissions(struct ctl_table_header *head,
			       struct ctl_table *table)
{
	struct net *net = container_of(head->set, struct net, sysctls);
	kuid_t root_uid = make_kuid(net->user_ns, 0);
	kgid_t root_gid = make_kgid(net->user_ns, 0);

	/* Allow network administrator to have same access as root. */
	if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
	    uid_eq(root_uid, current_euid())) {
		int mode = (table->mode >> 6) & 7;
		return (mode << 6) | (mode << 3) | mode;
	}
Пример #12
0
static int parse_id(const char **ep, struct authlist_entry *entry,
		    enum authlist_kind kind)
{
	struct user_namespace *ns = current_user_ns();
	/* decimal representation of 32-bit number fits in 10 chars */
	char sval[11];
	const char *p = *ep;
	char *xp = sval;
	int error;
	uid_t uid;
	gid_t gid;

	while (isdigit(*p)) {
		if (xp - sval >= sizeof(sval) - 1)
			return -EINVAL;
		*xp++ = *p++;
	}
	*xp = '\0';
	if (!sval[0] || !is_ws_eos(*p))
		return -EINVAL;

	switch (kind) {
	case AUTHLIST_KIND_UID:
	case AUTHLIST_KIND_NOUID:
		error = kstrtouint(sval, 10, &uid);
		if (error)
			return error;
		entry->kuid = make_kuid(ns, uid);
		if (!uid_valid(entry->kuid))
			return -EINVAL;
		break;

	case AUTHLIST_KIND_GID:
	case AUTHLIST_KIND_NOGID:
		error = kstrtouint(sval, 10, &gid);
		if (error)
			return error;
		entry->kgid = make_kgid(ns, gid);
		if (!gid_valid(entry->kgid))
			return -EINVAL;
		break;

	default:
		return -EINVAL;
	}

	entry->kind = kind;
	*ep = p;

	return 0;
}
Пример #13
0
static int parse_options(char *options, struct omfs_sb_info *sbi)
{
	char *p;
	substring_t args[MAX_OPT_ARGS];
	int option;

	if (!options)
		return 1;

	while ((p = strsep(&options, ",")) != NULL) {
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_uid:
			if (match_int(&args[0], &option))
				return 0;
			sbi->s_uid = make_kuid(current_user_ns(), option);
			if (!uid_valid(sbi->s_uid))
				return 0;
			break;
		case Opt_gid:
			if (match_int(&args[0], &option))
				return 0;
			sbi->s_gid = make_kgid(current_user_ns(), option);
			if (!gid_valid(sbi->s_gid))
				return 0;
			break;
		case Opt_umask:
			if (match_octal(&args[0], &option))
				return 0;
			sbi->s_fmask = sbi->s_dmask = option;
			break;
		case Opt_dmask:
			if (match_octal(&args[0], &option))
				return 0;
			sbi->s_dmask = option;
			break;
		case Opt_fmask:
			if (match_octal(&args[0], &option))
				return 0;
			sbi->s_fmask = option;
			break;
		default:
			return 0;
		}
	}
	return 1;
}
Пример #14
0
static int owner_check(const struct xt_mtchk_param *par)
{
	struct xt_owner_match_info *info = par->matchinfo;
	struct net *net = par->net;

	/* Only allow the common case where the userns of the writer
	 * matches the userns of the network namespace.
	 */
	if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) &&
	    (current_user_ns() != net->user_ns))
		return -EINVAL;

	/* Ensure the uids are valid */
	if (info->match & XT_OWNER_UID) {
		kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
		kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);

		if (!uid_valid(uid_min) || !uid_valid(uid_max) ||
		    (info->uid_max < info->uid_min) ||
		    uid_lt(uid_max, uid_min)) {
			return -EINVAL;
		}
	}

	/* Ensure the gids are valid */
	if (info->match & XT_OWNER_GID) {
		kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
		kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);

		if (!gid_valid(gid_min) || !gid_valid(gid_max) ||
		    (info->gid_max < info->gid_min) ||
		    gid_lt(gid_max, gid_min)) {
			return -EINVAL;
		}
	}

	return 0;
}
Пример #15
0
/* Do not directly use this function. Use ECRYPTFS_OVERRIDE_CRED() instead. */
const struct cred * ecryptfs_override_fsids(uid_t fsuid, gid_t fsgid)
{
	struct cred * cred; 
	const struct cred * old_cred; 

	cred = prepare_creds(); 
	if (!cred) 
		return NULL; 

	cred->fsuid = make_kuid(current_user_ns(), fsuid);
	cred->fsgid = make_kgid(current_user_ns(), fsgid);

	old_cred = override_creds(cred); 

	return old_cred; 
}
Пример #16
0
int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid)
{
	struct idmap *idmap = server->nfs_client->cl_idmap;
	__u32 id = -1;
	int ret = 0;

	if (!nfs_map_string_to_numeric(name, namelen, &id))
		ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap);
	if (ret == 0) {
		*uid = make_kuid(&init_user_ns, id);
		if (!uid_valid(*uid))
			ret = -ERANGE;
	}
	trace_nfs4_map_name_to_uid(name, namelen, id, ret);
	return ret;
}
Пример #17
0
static __be32 *
decode_sattr3(__be32 *p, struct iattr *iap)
{
	u32	tmp;

	iap->ia_valid = 0;

	if (*p++) {
		iap->ia_valid |= ATTR_MODE;
		iap->ia_mode = ntohl(*p++);
	}
	if (*p++) {
		iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
		if (uid_valid(iap->ia_uid))
			iap->ia_valid |= ATTR_UID;
	}
	if (*p++) {
		iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
		if (gid_valid(iap->ia_gid))
			iap->ia_valid |= ATTR_GID;
	}
	if (*p++) {
		u64	newsize;

		iap->ia_valid |= ATTR_SIZE;
		p = xdr_decode_hyper(p, &newsize);
		if (newsize <= NFS_OFFSET_MAX)
			iap->ia_size = newsize;
		else
			iap->ia_size = NFS_OFFSET_MAX;
	}
	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
		iap->ia_valid |= ATTR_ATIME;
	} else if (tmp == 2) {		/* set to client time */
		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
		iap->ia_atime.tv_sec = ntohl(*p++);
		iap->ia_atime.tv_nsec = ntohl(*p++);
	}
	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
		iap->ia_valid |= ATTR_MTIME;
	} else if (tmp == 2) {		/* set to client time */
		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
		iap->ia_mtime.tv_sec = ntohl(*p++);
		iap->ia_mtime.tv_nsec = ntohl(*p++);
	}
	return p;
}
Пример #18
0
static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
{
	substring_t args[MAX_OPT_ARGS];
	int option;
	int token;
	kuid_t uid;
	kgid_t gid;
	char *p;

	opts->mode = DEBUGFS_DEFAULT_MODE;

	while ((p = strsep(&data, ",")) != NULL) {
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_uid:
			if (match_int(&args[0], &option))
				return -EINVAL;
			uid = make_kuid(current_user_ns(), option);
			if (!uid_valid(uid))
				return -EINVAL;
			opts->uid = uid;
			break;
		case Opt_gid:
			if (match_int(&args[0], &option))
				return -EINVAL;
			gid = make_kgid(current_user_ns(), option);
			if (!gid_valid(gid))
				return -EINVAL;
			opts->gid = gid;
			break;
		case Opt_mode:
			if (match_octal(&args[0], &option))
				return -EINVAL;
			opts->mode = option & S_IALLUGO;
			break;
		/*
		 * We might like to report bad mount options here;
		 * but traditionally debugfs has ignored all mount options
		 */
		}
	}

	return 0;
}
Пример #19
0
void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid)
{
	valid &= oa->o_valid;

	if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
		CDEBUG(D_INODE, "valid "LPX64", new time "LPU64"/"LPU64"\n",
		       oa->o_valid, oa->o_mtime, oa->o_ctime);

	attr->ia_valid = 0;
	if (valid & OBD_MD_FLATIME) {
		LTIME_S(attr->ia_atime) = oa->o_atime;
		attr->ia_valid |= ATTR_ATIME;
	}
	if (valid & OBD_MD_FLMTIME) {
		LTIME_S(attr->ia_mtime) = oa->o_mtime;
		attr->ia_valid |= ATTR_MTIME;
	}
	if (valid & OBD_MD_FLCTIME) {
		LTIME_S(attr->ia_ctime) = oa->o_ctime;
		attr->ia_valid |= ATTR_CTIME;
	}
	if (valid & OBD_MD_FLSIZE) {
		attr->ia_size = oa->o_size;
		attr->ia_valid |= ATTR_SIZE;
	}
#if 0   /* you shouldn't be able to change a file's type with setattr */
	if (valid & OBD_MD_FLTYPE) {
		attr->ia_mode = (attr->ia_mode & ~S_IFMT)|(oa->o_mode & S_IFMT);
		attr->ia_valid |= ATTR_MODE;
	}
#endif
	if (valid & OBD_MD_FLMODE) {
		attr->ia_mode = (attr->ia_mode & S_IFMT)|(oa->o_mode & ~S_IFMT);
		attr->ia_valid |= ATTR_MODE;
		if (!in_group_p(make_kgid(&init_user_ns, oa->o_gid)) &&
		    !cfs_capable(CFS_CAP_FSETID))
			attr->ia_mode &= ~S_ISGID;
	}
	if (valid & OBD_MD_FLUID) {
		attr->ia_uid = make_kuid(&init_user_ns, oa->o_uid);
		attr->ia_valid |= ATTR_UID;
	}
	if (valid & OBD_MD_FLGID) {
		attr->ia_gid = make_kgid(&init_user_ns, oa->o_gid);
		attr->ia_valid |= ATTR_GID;
	}
}
Пример #20
0
static __inline__ int scm_check_creds(struct ucred *creds)
{
	const struct cred *cred = current_cred();
	kuid_t uid = make_kuid(cred->user_ns, creds->uid);
	kgid_t gid = make_kgid(cred->user_ns, creds->gid);

	if (!uid_valid(uid) || !gid_valid(gid))
		return -EINVAL;

	if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
	    ((uid_eq(uid, cred->uid)   || uid_eq(uid, cred->euid) ||
	      uid_eq(uid, cred->suid)) || capable(CAP_SETUID)) &&
	    ((gid_eq(gid, cred->gid)   || gid_eq(gid, cred->egid) ||
	      gid_eq(gid, cred->sgid)) || capable(CAP_SETGID))) {
	       return 0;
	}
	return -EPERM;
}
Пример #21
0
/* utility functions below */
void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
{
        int inode_type;
        /* inode's i_flags, i_ino are set by iget 
           XXX: is this all we need ??
           */
        switch (attr->va_type) {
        case C_VNON:
                inode_type  = 0;
                break;
        case C_VREG:
                inode_type = S_IFREG;
                break;
        case C_VDIR:
                inode_type = S_IFDIR;
                break;
        case C_VLNK:
                inode_type = S_IFLNK;
                break;
        default:
                inode_type = 0;
        }
	inode->i_mode |= inode_type;

	if (attr->va_mode != (u_short) -1)
	        inode->i_mode = attr->va_mode | inode_type;
        if (attr->va_uid != -1) 
	        inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid);
        if (attr->va_gid != -1)
	        inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid);
	if (attr->va_nlink != -1)
		set_nlink(inode, attr->va_nlink);
	if (attr->va_size != -1)
	        inode->i_size = attr->va_size;
	if (attr->va_size != -1)
		inode->i_blocks = (attr->va_size + 511) >> 9;
	if (attr->va_atime.tv_sec != -1) 
	        inode->i_atime = attr->va_atime;
	if (attr->va_mtime.tv_sec != -1)
	        inode->i_mtime = attr->va_mtime;
        if (attr->va_ctime.tv_sec != -1)
	        inode->i_ctime = attr->va_ctime;
}
Пример #22
0
static int hypfs_parse_options(char *options, struct super_block *sb)
{
	char *str;
	substring_t args[MAX_OPT_ARGS];
	kuid_t uid;
	kgid_t gid;

	if (!options)
		return 0;
	while ((str = strsep(&options, ",")) != NULL) {
		int token, option;
		struct hypfs_sb_info *hypfs_info = sb->s_fs_info;

		if (!*str)
			continue;
		token = match_token(str, hypfs_tokens, args);
		switch (token) {
		case opt_uid:
			if (match_int(&args[0], &option))
				return -EINVAL;
			uid = make_kuid(current_user_ns(), option);
			if (!uid_valid(uid))
				return -EINVAL;
			hypfs_info->uid = uid;
			break;
		case opt_gid:
			if (match_int(&args[0], &option))
				return -EINVAL;
			gid = make_kgid(current_user_ns(), option);
			if (!gid_valid(gid))
				return -EINVAL;
			hypfs_info->gid = gid;
			break;
		case opt_err:
		default:
			pr_err("%s is not a valid mount option\n", str);
			return -EINVAL;
		}
	}
	return 0;
}
Пример #23
0
void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
				   u64 attr_valid)
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	struct fuse_inode *fi = get_fuse_inode(inode);

	fi->attr_version = ++fc->attr_version;
	fi->i_time = attr_valid;

	inode->i_ino     = fuse_squash_ino(attr->ino);
	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
	set_nlink(inode, attr->nlink);
	inode->i_uid     = make_kuid(&init_user_ns, attr->uid);
	inode->i_gid     = make_kgid(&init_user_ns, attr->gid);
	inode->i_blocks  = attr->blocks;
	inode->i_atime.tv_sec   = attr->atime;
	inode->i_atime.tv_nsec  = attr->atimensec;
	/* mtime from server may be stale due to local buffered write */
	if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) {
		inode->i_mtime.tv_sec   = attr->mtime;
		inode->i_mtime.tv_nsec  = attr->mtimensec;
		inode->i_ctime.tv_sec   = attr->ctime;
		inode->i_ctime.tv_nsec  = attr->ctimensec;
	}

	if (attr->blksize != 0)
		inode->i_blkbits = ilog2(attr->blksize);
	else
		inode->i_blkbits = inode->i_sb->s_blocksize_bits;

	/*
	 * Don't set the sticky bit in i_mode, unless we want the VFS
	 * to check permissions.  This prevents failures due to the
	 * check in may_delete().
	 */
	fi->orig_i_mode = inode->i_mode;
	if (!fc->default_permissions)
		inode->i_mode &= ~S_ISVTX;

	fi->orig_ino = attr->ino;
}
Пример #24
0
Файл: open.c Проект: krzk/linux
static int chown_common(const struct path *path, uid_t user, gid_t group)
{
	struct inode *inode = path->dentry->d_inode;
	struct inode *delegated_inode = NULL;
	int error;
	struct iattr newattrs;
	kuid_t uid;
	kgid_t gid;

	uid = make_kuid(current_user_ns(), user);
	gid = make_kgid(current_user_ns(), group);

retry_deleg:
	newattrs.ia_valid =  ATTR_CTIME;
	if (user != (uid_t) -1) {
		if (!uid_valid(uid))
			return -EINVAL;
		newattrs.ia_valid |= ATTR_UID;
		newattrs.ia_uid = uid;
	}
	if (group != (gid_t) -1) {
		if (!gid_valid(gid))
			return -EINVAL;
		newattrs.ia_valid |= ATTR_GID;
		newattrs.ia_gid = gid;
	}
	if (!S_ISDIR(inode->i_mode))
		newattrs.ia_valid |=
			ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
	inode_lock(inode);
	error = security_path_chown(path, uid, gid);
	if (!error)
		error = notify_change(path->dentry, &newattrs, &delegated_inode);
	inode_unlock(inode);
	if (delegated_inode) {
		error = break_deleg_wait(&delegated_inode);
		if (!error)
			goto retry_deleg;
	}
	return error;
}
Пример #25
0
/*
 * Convert from xattr value to acl struct.
 */
static struct posix_acl *ocfs2_acl_from_xattr(const void *value, size_t size)
{
	int n, count;
	struct posix_acl *acl;

	if (!value)
		return NULL;
	if (size < sizeof(struct posix_acl_entry))
		return ERR_PTR(-EINVAL);

	count = size / sizeof(struct posix_acl_entry);

	acl = posix_acl_alloc(count, GFP_NOFS);
	if (!acl)
		return ERR_PTR(-ENOMEM);
	for (n = 0; n < count; n++) {
		struct ocfs2_acl_entry *entry =
			(struct ocfs2_acl_entry *)value;

		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
		switch(acl->a_entries[n].e_tag) {
		case ACL_USER:
			acl->a_entries[n].e_uid =
				make_kuid(&init_user_ns,
					  le32_to_cpu(entry->e_id));
			break;
		case ACL_GROUP:
			acl->a_entries[n].e_gid =
				make_kgid(&init_user_ns,
					  le32_to_cpu(entry->e_id));
			break;
		default:
			break;
		}
		value += sizeof(struct posix_acl_entry);

	}
	return acl;
}
Пример #26
0
static int vvp_attr_update(const struct lu_env *env, struct cl_object *obj,
			   const struct cl_attr *attr, unsigned valid)
{
	struct inode *inode = vvp_object_inode(obj);

	if (valid & CAT_UID)
		inode->i_uid = make_kuid(&init_user_ns, attr->cat_uid);
	if (valid & CAT_GID)
		inode->i_gid = make_kgid(&init_user_ns, attr->cat_gid);
	if (valid & CAT_ATIME)
		inode->i_atime.tv_sec = attr->cat_atime;
	if (valid & CAT_MTIME)
		inode->i_mtime.tv_sec = attr->cat_mtime;
	if (valid & CAT_CTIME)
		inode->i_ctime.tv_sec = attr->cat_ctime;
	if (0 && valid & CAT_SIZE)
		i_size_write(inode, attr->cat_size);
	/* not currently necessary */
	if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE))
		mark_inode_dirty(inode);
	return 0;
}
Пример #27
0
void spd_proc_set_ids(struct proc_dir_entry *proc_entry)
{
    uid_t uid = 0;
    gid_t gid = 0;

#ifdef CONFIG_VPNCLIENT_PROC_UID
    uid = CONFIG_VPNCLIENT_PROC_UID;
#endif

#ifdef CONFIG_VPNCLIENT_PROC_GID
    gid = CONFIG_VPNCLIENT_PROC_GID;
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
    proc_entry->uid = uid;
    proc_entry->gid = gid;
#else
    proc_set_user(proc_entry,
                  make_kuid(current_user_ns(), uid),
                  make_kgid(current_user_ns(), gid));
#endif
}
Пример #28
0
void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
{
	valid &= src->o_valid;

	LASSERTF(!(valid & (OBD_MD_FLTYPE | OBD_MD_FLGENER | OBD_MD_FLFID |
			    OBD_MD_FLID | OBD_MD_FLGROUP)),
		 "object "DOSTID", valid %x\n", POSTID(&src->o_oi), valid);

	if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
		CDEBUG(D_INODE,
		       "valid %#llx, cur time %lu/%lu, new %llu/%llu\n",
		       src->o_valid, LTIME_S(dst->i_mtime),
		       LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime);

	if (valid & OBD_MD_FLATIME)
		LTIME_S(dst->i_atime) = src->o_atime;
	if (valid & OBD_MD_FLMTIME)
		LTIME_S(dst->i_mtime) = src->o_mtime;
	if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(dst->i_ctime))
		LTIME_S(dst->i_ctime) = src->o_ctime;
	if (valid & OBD_MD_FLSIZE)
		i_size_write(dst, src->o_size);
	if (valid & OBD_MD_FLBLOCKS) { /* allocation of space */
		dst->i_blocks = src->o_blocks;
		if (dst->i_blocks < src->o_blocks) /* overflow */
			dst->i_blocks = -1;

	}
	if (valid & OBD_MD_FLBLKSZ)
		dst->i_blkbits = ffs(src->o_blksize)-1;
	if (valid & OBD_MD_FLMODE)
		dst->i_mode = (dst->i_mode & S_IFMT) | (src->o_mode & ~S_IFMT);
	if (valid & OBD_MD_FLUID)
		dst->i_uid = make_kuid(&init_user_ns, src->o_uid);
	if (valid & OBD_MD_FLGID)
		dst->i_gid = make_kgid(&init_user_ns, src->o_gid);
	if (valid & OBD_MD_FLFLAGS)
		dst->i_flags = src->o_flags;
}
Пример #29
0
/*
 * Get the persistent keyring for a specific UID and link it to the nominated
 * keyring.
 */
long keyctl_get_persistent(uid_t _uid, key_serial_t destid)
{
	struct user_namespace *ns = current_user_ns();
	key_ref_t dest_ref;
	kuid_t uid;
	long ret;

	/* -1 indicates the current user */
	if (_uid == (uid_t)-1) {
		uid = current_uid();
	} else {
		uid = make_kuid(ns, _uid);
		if (!uid_valid(uid))
			return -EINVAL;

		/* You can only see your own persistent cache if you're not
		 * sufficiently privileged.
		 */
		if (!uid_eq(uid, current_uid()) &&
		    !uid_eq(uid, current_euid()) &&
		    !ns_capable(ns, CAP_SETUID))
			return -EPERM;
	}

	/* There must be a destination keyring */
	dest_ref = lookup_user_key(destid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE);
	if (IS_ERR(dest_ref))
		return PTR_ERR(dest_ref);
	if (key_ref_to_ptr(dest_ref)->type != &key_type_keyring) {
		ret = -ENOTDIR;
		goto out_put_dest;
	}

	ret = key_get_persistent(ns, uid, dest_ref);

out_put_dest:
	key_ref_put(dest_ref);
	return ret;
}
Пример #30
0
static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
			  struct kstat *stat)
{
	unsigned int blkbits;
	struct fuse_conn *fc = get_fuse_conn(inode);

	/* see the comment in fuse_change_attributes() */
	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
		attr->size = i_size_read(inode);
		attr->mtime = inode->i_mtime.tv_sec;
		attr->mtimensec = inode->i_mtime.tv_nsec;
		attr->ctime = inode->i_ctime.tv_sec;
		attr->ctimensec = inode->i_ctime.tv_nsec;
	}

	stat->dev = inode->i_sb->s_dev;
	stat->ino = attr->ino;
	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
	stat->nlink = attr->nlink;
	stat->uid = make_kuid(&init_user_ns, attr->uid);
	stat->gid = make_kgid(&init_user_ns, attr->gid);
	stat->rdev = inode->i_rdev;
	stat->atime.tv_sec = attr->atime;
	stat->atime.tv_nsec = attr->atimensec;
	stat->mtime.tv_sec = attr->mtime;
	stat->mtime.tv_nsec = attr->mtimensec;
	stat->ctime.tv_sec = attr->ctime;
	stat->ctime.tv_nsec = attr->ctimensec;
	stat->size = attr->size;
	stat->blocks = attr->blocks;

	if (attr->blksize != 0)
		blkbits = ilog2(attr->blksize);
	else
		blkbits = inode->i_sb->s_blocksize_bits;

	stat->blksize = 1 << blkbits;
}