Beispiel #1
0
int
gr_acl_handle_rename(struct dentry *new_dentry,
		     struct dentry *parent_dentry,
		     const struct vfsmount *parent_mnt,
		     struct dentry *old_dentry,
		     struct inode *old_parent_inode,
		     struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags)
{
	__u32 comp1, comp2;
	int error = 0;

	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	if (flags & RENAME_EXCHANGE) {
		comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, parent_mnt);
		comp2 =
		    gr_search_file(old_dentry,
				   GR_READ | GR_WRITE | GR_AUDIT_READ |
				   GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
	} else if (d_is_negative(new_dentry)) {
		comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
					GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
					GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
		comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
				       GR_DELETE | GR_AUDIT_DELETE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, old_mnt);
	} else {
		comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
				       GR_CREATE | GR_DELETE |
				       GR_AUDIT_CREATE | GR_AUDIT_DELETE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, parent_mnt);
		comp2 =
		    gr_search_file(old_dentry,
				   GR_READ | GR_WRITE | GR_AUDIT_READ |
				   GR_DELETE | GR_AUDIT_DELETE |
				   GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
	}

	if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
	    ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
		gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
	else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
		 && !(comp2 & GR_SUPPRESS)) {
		gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
		error = -EACCES;
	} else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
		error = -EACCES;

	return error;
}
Beispiel #2
0
static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
{
	__u32 mode;

	mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);

	if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
		gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
		return mode;
	} else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
		gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
		return 0;
	} else if (unlikely((mode & (reqmode)) != (reqmode)))
		return 0;

	return (reqmode);
}
Beispiel #3
0
__u32
gr_acl_handle_creat(const struct dentry * dentry,
		    const struct dentry * p_dentry,
		    const struct vfsmount * p_mnt, int open_flags, int acc_mode,
		    const int imode)
{
	__u32 reqmode = GR_WRITE | GR_CREATE;
	__u32 mode;

	if (acc_mode & MAY_APPEND)
		reqmode |= GR_APPEND;
	// if a directory was required or the directory already exists, then
	// don't count this open as a read
	if ((acc_mode & MAY_READ) &&
	    !((open_flags & O_DIRECTORY) || d_is_dir(dentry)))
		reqmode |= GR_READ;
	if ((open_flags & O_CREAT) &&
	    ((imode & S_ISUID) || ((imode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))))
		reqmode |= GR_SETID;

	mode =
	    gr_check_create(dentry, p_dentry, p_mnt,
			    reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);

	if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
		gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
			       reqmode & GR_READ ? " reading" : "",
			       reqmode & GR_WRITE ? " writing" : reqmode &
			       GR_APPEND ? " appending" : "");
		return reqmode;
	} else
	    if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
	{
		gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
			       reqmode & GR_READ ? " reading" : "",
			       reqmode & GR_WRITE ? " writing" : reqmode &
			       GR_APPEND ? " appending" : "");
		return 0;
	} else if (unlikely((mode & reqmode) != reqmode))
		return 0;

	return reqmode;
}
Beispiel #4
0
__u32
gr_acl_handle_creat(const struct dentry * dentry,
		    const struct dentry * p_dentry,
		    const struct vfsmount * p_mnt, const int fmode,
		    const int imode)
{
	__u32 reqmode = GR_WRITE | GR_CREATE;
	__u32 mode;

	if (unlikely(fmode & O_APPEND))
		reqmode |= GR_APPEND;
	if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
		reqmode |= GR_READ;
	if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
		reqmode |= GR_SETID;

	mode =
	    gr_check_create(dentry, p_dentry, p_mnt,
			    reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);

	if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
		gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
			       reqmode & GR_READ ? " reading" : "",
			       reqmode & GR_WRITE ? " writing" : reqmode &
			       GR_APPEND ? " appending" : "");
		return reqmode;
	} else
	    if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
	{
		gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
			       reqmode & GR_READ ? " reading" : "",
			       reqmode & GR_WRITE ? " writing" : reqmode &
			       GR_APPEND ? " appending" : "");
		return 0;
	} else if (unlikely((mode & reqmode) != reqmode))
		return 0;

	return reqmode;
}
Beispiel #5
0
__u32
gr_acl_handle_symlink(const struct dentry * new_dentry,
		      const struct dentry * parent_dentry,
		      const struct vfsmount * parent_mnt, const char *from)
{
	__u32 needmode = GR_WRITE | GR_CREATE;
	__u32 mode;

	mode =
	    gr_check_create(new_dentry, parent_dentry, parent_mnt,
			    GR_CREATE | GR_AUDIT_CREATE |
			    GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);

	if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
		gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
		return mode;
	} else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
		gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
		return 0;
	} else if (unlikely((mode & needmode) != needmode))
		return 0;

	return (GR_WRITE | GR_CREATE);
}