This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / fs / namei.c
index d2cab64..763e958 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/security.h>
 #include <linux/mount.h>
 #include <linux/audit.h>
+#include <linux/vs_base.h>
+
 #include <asm/namei.h>
 #include <asm/uaccess.h>
 
@@ -163,6 +165,9 @@ int vfs_permission(struct inode * inode, int mask)
 {
        umode_t                 mode = inode->i_mode;
 
+       if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN|VX_WATCH))
+               return -EACCES;
+
        if (mask & MAY_WRITE) {
                /*
                 * Nobody gets write access to a read-only fs.
@@ -208,6 +213,15 @@ int vfs_permission(struct inode * inode, int mask)
        return -EACCES;
 }
 
+static inline int xid_permission(struct inode *inode)
+{
+       if (inode->i_xid == 0)
+               return 0;
+       if (vx_check(inode->i_xid, VX_ADMIN|VX_WATCH|VX_IDENT))
+               return 0;
+       return -EACCES;
+}
+
 int permission(struct inode * inode,int mask, struct nameidata *nd)
 {
        int retval;
@@ -216,6 +230,8 @@ int permission(struct inode * inode,int mask, struct nameidata *nd)
        /* Ordinary permission routines do not understand MAY_APPEND. */
        submask = mask & ~MAY_APPEND;
 
+       if ((retval = xid_permission(inode)))
+               return retval;
        if (inode->i_op && inode->i_op->permission)
                retval = inode->i_op->permission(inode, submask, nd);
        else
@@ -1039,7 +1055,7 @@ static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir)
        if (IS_APPEND(dir))
                return -EPERM;
        if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
-           IS_IMMUTABLE(victim->d_inode))
+               IS_IXORUNLINK(victim->d_inode))
                return -EPERM;
        if (isdir) {
                if (!S_ISDIR(victim->d_inode->i_mode))
@@ -1759,7 +1775,7 @@ slashes:
        goto exit2;
 }
 
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
+int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
 {
        int error = may_create(dir, dentry, NULL);
 
@@ -1803,7 +1819,7 @@ asmlinkage long sys_symlink(const char __user * oldname, const char __user * new
                dentry = lookup_create(&nd, 0);
                error = PTR_ERR(dentry);
                if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from);
+                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
                        dput(dentry);
                }
                up(&nd.dentry->d_inode->i_sem);
@@ -1833,7 +1849,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
        /*
         * A link to an append-only or immutable file cannot be created.
         */
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
                return -EPERM;
        if (!dir->i_op || !dir->i_op->link)
                return -EPERM;