diff mbox

cifs: Add mount option named backup

Message ID 1313166821-9172-1-git-send-email-shirishpargonkar@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shirish Pargaonkar Aug. 12, 2011, 4:33 p.m. UTC
From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>


Add mount option backup.

It allows an authenticated user to access files with the intent to back them
up including their ACLs, who may not have access permission but has
"Backup files and directories user right" on them (by virtue of being part
of the built-in group Backup Operators.

If an authenticated user is not part of the built-in group Backup Operators
at the server, access to such files is denied.


Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
---
 fs/cifs/cifs_fs_sb.h |    1 +
 fs/cifs/cifsacl.c    |   18 +++++++++++++-----
 fs/cifs/cifsglob.h   |    4 +++-
 fs/cifs/connect.c    |    5 +++++
 fs/cifs/dir.c        |   11 +++++++++--
 fs/cifs/file.c       |   14 ++++++++++++--
 fs/cifs/link.c       |   18 +++++++++++++-----
 7 files changed, 56 insertions(+), 15 deletions(-)

Comments

Steve French Aug. 12, 2011, 5:19 p.m. UTC | #1
Shirish or Manoj,
Could you give a little more detail on the failure scenario
and which files and information can not be accessed?

A mount option may be the only choice, since there is
no equivalent for "open for backup intent" open flag,
and presumably no easy way to query whether a user is a member
of the "backup operators" group, but would a mount option be
a problem for other users of the same mount who don't have
backup operator privilege trying to open other files?

On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>
>
> Add mount option backup.
>
> It allows an authenticated user to access files with the intent to back them
> up including their ACLs, who may not have access permission but has
> "Backup files and directories user right" on them (by virtue of being part
> of the built-in group Backup Operators.
>
> If an authenticated user is not part of the built-in group Backup Operators
> at the server, access to such files is denied.
>
>
> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> ---
>  fs/cifs/cifs_fs_sb.h |    1 +
>  fs/cifs/cifsacl.c    |   18 +++++++++++++-----
>  fs/cifs/cifsglob.h   |    4 +++-
>  fs/cifs/connect.c    |    5 +++++
>  fs/cifs/dir.c        |   11 +++++++++--
>  fs/cifs/file.c       |   14 ++++++++++++--
>  fs/cifs/link.c       |   18 +++++++++++++-----
>  7 files changed, 56 insertions(+), 15 deletions(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 7260e11..8ba1b44 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -43,6 +43,7 @@
>  #define CIFS_MOUNT_STRICT_IO   0x40000 /* strict cache mode */
>  #define CIFS_MOUNT_RWPIDFORWARD        0x80000 /* use pid forwarding for rw */
>  #define CIFS_MOUNT_POSIXACL    0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
> +#define CIFS_MOUNT_CIFS_BACKUP 0x200000 /* open file with backup intent bit */
>
>  struct cifs_sb_info {
>        struct rb_root tlink_tree;
> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
> index d0f59fa..24bc2dd 100644
> --- a/fs/cifs/cifsacl.c
> +++ b/fs/cifs/cifsacl.c
> @@ -945,7 +945,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>  {
>        struct cifs_ntsd *pntsd = NULL;
>        int oplock = 0;
> -       int xid, rc;
> +       int xid, rc, create_options = 0;
>        __u16 fid;
>        struct cifs_tcon *tcon;
>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
> @@ -956,9 +956,13 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>        tcon = tlink_tcon(tlink);
>        xid = GetXid();
>
> -       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
> -                        &fid, &oplock, NULL, cifs_sb->local_nls,
> -                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
> +       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
> +                       create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (!rc) {
>                rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
>                CIFSSMBClose(xid, tcon, fid);
> @@ -995,7 +999,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>                struct cifs_ntsd *pnntsd, u32 acllen)
>  {
>        int oplock = 0;
> -       int xid, rc;
> +       int xid, rc, create_options = 0;
>        __u16 fid;
>        struct cifs_tcon *tcon;
>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
> @@ -1006,6 +1010,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>        tcon = tlink_tcon(tlink);
>        xid = GetXid();
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
>                         &fid, &oplock, NULL, cifs_sb->local_nls,
>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 95dad9d..3c6fd56 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -179,6 +179,7 @@ struct smb_vol {
>        bool noperm:1;
>        bool no_psx_acl:1; /* set if posix acl support should be disabled */
>        bool cifs_acl:1;
> +       bool cifs_backup:1; /* to indicates backup intent during file open */
>        bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
>        bool server_ino:1; /* use inode numbers from server ie UniqueId */
>        bool direct_io:1;
> @@ -219,7 +220,8 @@ struct smb_vol {
>                         CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
>                         CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
>                         CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
> -                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
> +                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
> +                        CIFS_MOUNT_CIFS_BACKUP)
>
>  #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
>                      MS_NODEV | MS_SYNCHRONOUS)
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 80c2e3a..352d6d6 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -883,6 +883,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>                        cFYI(1, "Null separator not allowed");
>                }
>        }
> +       vol->cifs_backup = 0; /* no backup intent */
>
>        while ((data = strsep(&options, separator)) != NULL) {
>                if (!*data)
> @@ -1405,6 +1406,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>                        vol->rwpidforward = 1;
>                } else if (strnicmp(data, "cifsacl", 7) == 0) {
>                        vol->cifs_acl = 1;
> +               } else if (strnicmp(data, "backup", 7) == 0) {
> +                       vol->cifs_backup = 1;
>                } else if (strnicmp(data, "nocifsacl", 9) == 0) {
>                        vol->cifs_acl = 0;
>                } else if (strnicmp(data, "acl", 3) == 0) {
> @@ -2763,6 +2766,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
>        if (pvolume_info->cifs_acl)
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
> +       if (pvolume_info->cifs_backup)
> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUP;
>        if (pvolume_info->override_uid)
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
>        if (pvolume_info->override_gid)
> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> index ae576fb..fbecde6 100644
> --- a/fs/cifs/dir.c
> +++ b/fs/cifs/dir.c
> @@ -243,6 +243,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
>         */
>        if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
>                create_options |= CREATE_OPTION_READONLY;
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>
>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
> @@ -357,6 +360,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>  {
>        int rc = -EPERM;
>        int xid;
> +       int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
>        struct cifs_sb_info *cifs_sb;
>        struct tcon_link *tlink;
>        struct cifs_tcon *pTcon;
> @@ -431,9 +435,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>                return rc;
>        }
>
> -       /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
> -                        GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
> +                        GENERIC_WRITE, create_options,
>                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (rc)
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 9f41a10..39b06c4 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -174,6 +174,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>        int rc;
>        int desiredAccess;
>        int disposition;
> +       int create_options = CREATE_NOT_DIR;
>        FILE_ALL_INFO *buf;
>
>        desiredAccess = cifs_convert_flags(f_flags);
> @@ -210,9 +211,13 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>        if (!buf)
>                return -ENOMEM;
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
> -                        desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
> +                        desiredAccess, create_options, pnetfid, poplock, buf,
>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
>                                 & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        else
> @@ -465,6 +470,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>        char *full_path = NULL;
>        int desiredAccess;
>        int disposition = FILE_OPEN;
> +       int create_options = CREATE_NOT_DIR;
>        __u16 netfid;
>
>        xid = GetXid();
> @@ -524,6 +530,10 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>
>        desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        /* Can not refresh inode by passing in file_info buf to be returned
>           by SMBOpen and then calling get_inode_info with returned buf
>           since file might have write behind data that needs to be flushed
> @@ -531,7 +541,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>           that inode was not dirty locally we could do this */
>
>        rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
> +                        create_options, &netfid, &oplock, NULL,
>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
>                                CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (rc) {
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index db3f18c..67e51b8 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -183,14 +183,20 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
>  static int
>  CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>                    const char *fromName, const char *toName,
> -                   const struct nls_table *nls_codepage, int remap)
> +                   struct cifs_sb_info *cifs_sb)
>  {
>        int rc;
>        int oplock = 0;
> +       int remap;
> +       int create_options = CREATE_NOT_DIR;
>        __u16 netfid = 0;
>        u8 *buf;
>        unsigned int bytes_written = 0;
>        struct cifs_io_parms io_parms;
> +       struct nls_table *nls_codepage;
> +
> +       nls_codepage = cifs_sb->local_nls;
> +       remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
>
>        buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>        if (!buf)
> @@ -202,8 +208,12 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>                return rc;
>        }
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
> +                        create_options, &netfid, &oplock, NULL,
>                         nls_codepage, remap);
>        if (rc != 0) {
>                kfree(buf);
> @@ -559,9 +569,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
>        /* BB what if DFS and this volume is on different share? BB */
>        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
>                rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
> -                                        cifs_sb->local_nls,
> -                                        cifs_sb->mnt_cifs_flags &
> -                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
> +                                       cifs_sb);
>        else if (pTcon->unix_ext)
>                rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
>                                           cifs_sb->local_nls);
> --
> 1.6.0.2
>
>
Shirish Pargaonkar Aug. 12, 2011, 7:25 p.m. UTC | #2
On Fri, Aug 12, 2011 at 12:19 PM, Steve French <smfrench@gmail.com> wrote:
> Shirish or Manoj,
> Could you give a little more detail on the failure scenario
> and which files and information can not be accessed?
>
> A mount option may be the only choice, since there is
> no equivalent for "open for backup intent" open flag,
> and presumably no easy way to query whether a user is a member
> of the "backup operators" group, but would a mount option be
> a problem for other users of the same mount who don't have
> backup operator privilege trying to open other files?
>
> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>
>>
>> Add mount option backup.
>>
>> It allows an authenticated user to access files with the intent to back them
>> up including their ACLs, who may not have access permission but has
>> "Backup files and directories user right" on them (by virtue of being part
>> of the built-in group Backup Operators.
>>
>> If an authenticated user is not part of the built-in group Backup Operators
>> at the server, access to such files is denied.
>>
>>
>> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> ---
>>  fs/cifs/cifs_fs_sb.h |    1 +
>>  fs/cifs/cifsacl.c    |   18 +++++++++++++-----
>>  fs/cifs/cifsglob.h   |    4 +++-
>>  fs/cifs/connect.c    |    5 +++++
>>  fs/cifs/dir.c        |   11 +++++++++--
>>  fs/cifs/file.c       |   14 ++++++++++++--
>>  fs/cifs/link.c       |   18 +++++++++++++-----
>>  7 files changed, 56 insertions(+), 15 deletions(-)
>>
>> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
>> index 7260e11..8ba1b44 100644
>> --- a/fs/cifs/cifs_fs_sb.h
>> +++ b/fs/cifs/cifs_fs_sb.h
>> @@ -43,6 +43,7 @@
>>  #define CIFS_MOUNT_STRICT_IO   0x40000 /* strict cache mode */
>>  #define CIFS_MOUNT_RWPIDFORWARD        0x80000 /* use pid forwarding for rw */
>>  #define CIFS_MOUNT_POSIXACL    0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
>> +#define CIFS_MOUNT_CIFS_BACKUP 0x200000 /* open file with backup intent bit */
>>
>>  struct cifs_sb_info {
>>        struct rb_root tlink_tree;
>> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
>> index d0f59fa..24bc2dd 100644
>> --- a/fs/cifs/cifsacl.c
>> +++ b/fs/cifs/cifsacl.c
>> @@ -945,7 +945,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>>  {
>>        struct cifs_ntsd *pntsd = NULL;
>>        int oplock = 0;
>> -       int xid, rc;
>> +       int xid, rc, create_options = 0;
>>        __u16 fid;
>>        struct cifs_tcon *tcon;
>>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
>> @@ -956,9 +956,13 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>>        tcon = tlink_tcon(tlink);
>>        xid = GetXid();
>>
>> -       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
>> -                        &fid, &oplock, NULL, cifs_sb->local_nls,
>> -                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>> +       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
>> +                       create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>        if (!rc) {
>>                rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
>>                CIFSSMBClose(xid, tcon, fid);
>> @@ -995,7 +999,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>>                struct cifs_ntsd *pnntsd, u32 acllen)
>>  {
>>        int oplock = 0;
>> -       int xid, rc;
>> +       int xid, rc, create_options = 0;
>>        __u16 fid;
>>        struct cifs_tcon *tcon;
>>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
>> @@ -1006,6 +1010,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>>        tcon = tlink_tcon(tlink);
>>        xid = GetXid();
>>
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>>        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
>>                         &fid, &oplock, NULL, cifs_sb->local_nls,
>>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
>> index 95dad9d..3c6fd56 100644
>> --- a/fs/cifs/cifsglob.h
>> +++ b/fs/cifs/cifsglob.h
>> @@ -179,6 +179,7 @@ struct smb_vol {
>>        bool noperm:1;
>>        bool no_psx_acl:1; /* set if posix acl support should be disabled */
>>        bool cifs_acl:1;
>> +       bool cifs_backup:1; /* to indicates backup intent during file open */
>>        bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
>>        bool server_ino:1; /* use inode numbers from server ie UniqueId */
>>        bool direct_io:1;
>> @@ -219,7 +220,8 @@ struct smb_vol {
>>                         CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
>>                         CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
>>                         CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
>> -                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
>> +                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
>> +                        CIFS_MOUNT_CIFS_BACKUP)
>>
>>  #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
>>                      MS_NODEV | MS_SYNCHRONOUS)
>> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
>> index 80c2e3a..352d6d6 100644
>> --- a/fs/cifs/connect.c
>> +++ b/fs/cifs/connect.c
>> @@ -883,6 +883,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>>                        cFYI(1, "Null separator not allowed");
>>                }
>>        }
>> +       vol->cifs_backup = 0; /* no backup intent */
>>
>>        while ((data = strsep(&options, separator)) != NULL) {
>>                if (!*data)
>> @@ -1405,6 +1406,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>>                        vol->rwpidforward = 1;
>>                } else if (strnicmp(data, "cifsacl", 7) == 0) {
>>                        vol->cifs_acl = 1;
>> +               } else if (strnicmp(data, "backup", 7) == 0) {
>> +                       vol->cifs_backup = 1;
>>                } else if (strnicmp(data, "nocifsacl", 9) == 0) {
>>                        vol->cifs_acl = 0;
>>                } else if (strnicmp(data, "acl", 3) == 0) {
>> @@ -2763,6 +2766,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
>>        if (pvolume_info->cifs_acl)
>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
>> +       if (pvolume_info->cifs_backup)
>> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUP;
>>        if (pvolume_info->override_uid)
>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
>>        if (pvolume_info->override_gid)
>> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
>> index ae576fb..fbecde6 100644
>> --- a/fs/cifs/dir.c
>> +++ b/fs/cifs/dir.c
>> @@ -243,6 +243,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
>>         */
>>        if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
>>                create_options |= CREATE_OPTION_READONLY;
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>
>>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
>> @@ -357,6 +360,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>  {
>>        int rc = -EPERM;
>>        int xid;
>> +       int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
>>        struct cifs_sb_info *cifs_sb;
>>        struct tcon_link *tlink;
>>        struct cifs_tcon *pTcon;
>> @@ -431,9 +435,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>                return rc;
>>        }
>>
>> -       /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>>        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
>> -                        GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
>> +                        GENERIC_WRITE, create_options,
>>                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
>>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>        if (rc)
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index 9f41a10..39b06c4 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -174,6 +174,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>>        int rc;
>>        int desiredAccess;
>>        int disposition;
>> +       int create_options = CREATE_NOT_DIR;
>>        FILE_ALL_INFO *buf;
>>
>>        desiredAccess = cifs_convert_flags(f_flags);
>> @@ -210,9 +211,13 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>>        if (!buf)
>>                return -ENOMEM;
>>
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
>> -                        desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
>> +                        desiredAccess, create_options, pnetfid, poplock, buf,
>>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
>>                                 & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>        else
>> @@ -465,6 +470,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>        char *full_path = NULL;
>>        int desiredAccess;
>>        int disposition = FILE_OPEN;
>> +       int create_options = CREATE_NOT_DIR;
>>        __u16 netfid;
>>
>>        xid = GetXid();
>> @@ -524,6 +530,10 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>
>>        desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
>>
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>>        /* Can not refresh inode by passing in file_info buf to be returned
>>           by SMBOpen and then calling get_inode_info with returned buf
>>           since file might have write behind data that needs to be flushed
>> @@ -531,7 +541,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>           that inode was not dirty locally we could do this */
>>
>>        rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
>> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
>> +                        create_options, &netfid, &oplock, NULL,
>>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
>>                                CIFS_MOUNT_MAP_SPECIAL_CHR);
>>        if (rc) {
>> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
>> index db3f18c..67e51b8 100644
>> --- a/fs/cifs/link.c
>> +++ b/fs/cifs/link.c
>> @@ -183,14 +183,20 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
>>  static int
>>  CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>>                    const char *fromName, const char *toName,
>> -                   const struct nls_table *nls_codepage, int remap)
>> +                   struct cifs_sb_info *cifs_sb)
>>  {
>>        int rc;
>>        int oplock = 0;
>> +       int remap;
>> +       int create_options = CREATE_NOT_DIR;
>>        __u16 netfid = 0;
>>        u8 *buf;
>>        unsigned int bytes_written = 0;
>>        struct cifs_io_parms io_parms;
>> +       struct nls_table *nls_codepage;
>> +
>> +       nls_codepage = cifs_sb->local_nls;
>> +       remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
>>
>>        buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>>        if (!buf)
>> @@ -202,8 +208,12 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>>                return rc;
>>        }
>>
>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>> +
>>        rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
>> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
>> +                        create_options, &netfid, &oplock, NULL,
>>                         nls_codepage, remap);
>>        if (rc != 0) {
>>                kfree(buf);
>> @@ -559,9 +569,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
>>        /* BB what if DFS and this volume is on different share? BB */
>>        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
>>                rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
>> -                                        cifs_sb->local_nls,
>> -                                        cifs_sb->mnt_cifs_flags &
>> -                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
>> +                                       cifs_sb);
>>        else if (pTcon->unix_ext)
>>                rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
>>                                           cifs_sb->local_nls);
>> --
>> 1.6.0.2
>>
>>
>
>
>
> --
> Thanks,
>
> Steve
>

On a Windows 2003 server, 'Back up files and directories policy is enabled
and user named 'mahalcrow' is added to that policy.

I mount a share from that Windows server by authenticating as user 'mahalcrow'.

# mount -t cifs //cifstest1/myshare /mnt/smb_b -o
backup,cifsacl,user=mahalcrow,pass=<passwd>

# ls -l /mnt/smb_b/testfile2
-rwx------ 1 administrator 10010 18 Aug  9 19:26 /mnt/smb_b/testfile2

# /tmp/getcifsacl /mnt/smb_b/testfile2
REVISION:0x1
CONTROL:0x9404
OWNER:CIFSTESTDOM\Administrator
GROUP:CIFSTESTDOM\Domain Users
ACL:CIFSTESTDOM\Administrator:ALLOWED/0x0/FULL

So with the backup intent create option during open (nt_create_andx),
an user who is neither owner of the file and not part of the only ACE
in the ACL of this file, can still access the file.


Now if  I remove this user, mahalcrow, from the policy 'Back up files
and directories' under
 Security Settings/Local Policies/user Rights Assignment/Security Options,
unmount and remount the share and then try to access the file
testfile2  from the
mounted share, it fails, even with the backup intent mount option.

# mount -t cifs //cifstest1/myshare /mnt/smb_b -o
backup,cifsacl,user=mahalcrow,pass=<passwd>
# ls -l /mnt/smb_b/testfile2
-rwxr-xr-x 1 root root 18 Aug  9 19:26 /mnt/smb_b/testfile2

# /tmp/getcifsacl /mnt/smb_b/testfile2
getxattr error: 95
REVISION:0x0
CONTROL:0x0


The change in policy on the server will not reflect on an existing smb
connection though,
if this user unmounts and remounts the same share, it would be effective.

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shirish Pargaonkar Aug. 12, 2011, 7:44 p.m. UTC | #3
On Fri, Aug 12, 2011 at 2:25 PM, Shirish Pargaonkar
<shirishpargaonkar@gmail.com> wrote:
> On Fri, Aug 12, 2011 at 12:19 PM, Steve French <smfrench@gmail.com> wrote:
>> Shirish or Manoj,
>> Could you give a little more detail on the failure scenario
>> and which files and information can not be accessed?
>>
>> A mount option may be the only choice, since there is
>> no equivalent for "open for backup intent" open flag,
>> and presumably no easy way to query whether a user is a member
>> of the "backup operators" group, but would a mount option be
>> a problem for other users of the same mount who don't have
>> backup operator privilege trying to open other files?
>>
>> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>>> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>>
>>>
>>> Add mount option backup.
>>>
>>> It allows an authenticated user to access files with the intent to back them
>>> up including their ACLs, who may not have access permission but has
>>> "Backup files and directories user right" on them (by virtue of being part
>>> of the built-in group Backup Operators.
>>>
>>> If an authenticated user is not part of the built-in group Backup Operators
>>> at the server, access to such files is denied.
>>>
>>>
>>> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>> ---
>>>  fs/cifs/cifs_fs_sb.h |    1 +
>>>  fs/cifs/cifsacl.c    |   18 +++++++++++++-----
>>>  fs/cifs/cifsglob.h   |    4 +++-
>>>  fs/cifs/connect.c    |    5 +++++
>>>  fs/cifs/dir.c        |   11 +++++++++--
>>>  fs/cifs/file.c       |   14 ++++++++++++--
>>>  fs/cifs/link.c       |   18 +++++++++++++-----
>>>  7 files changed, 56 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
>>> index 7260e11..8ba1b44 100644
>>> --- a/fs/cifs/cifs_fs_sb.h
>>> +++ b/fs/cifs/cifs_fs_sb.h
>>> @@ -43,6 +43,7 @@
>>>  #define CIFS_MOUNT_STRICT_IO   0x40000 /* strict cache mode */
>>>  #define CIFS_MOUNT_RWPIDFORWARD        0x80000 /* use pid forwarding for rw */
>>>  #define CIFS_MOUNT_POSIXACL    0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
>>> +#define CIFS_MOUNT_CIFS_BACKUP 0x200000 /* open file with backup intent bit */
>>>
>>>  struct cifs_sb_info {
>>>        struct rb_root tlink_tree;
>>> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
>>> index d0f59fa..24bc2dd 100644
>>> --- a/fs/cifs/cifsacl.c
>>> +++ b/fs/cifs/cifsacl.c
>>> @@ -945,7 +945,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>>>  {
>>>        struct cifs_ntsd *pntsd = NULL;
>>>        int oplock = 0;
>>> -       int xid, rc;
>>> +       int xid, rc, create_options = 0;
>>>        __u16 fid;
>>>        struct cifs_tcon *tcon;
>>>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
>>> @@ -956,9 +956,13 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>>>        tcon = tlink_tcon(tlink);
>>>        xid = GetXid();
>>>
>>> -       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
>>> -                        &fid, &oplock, NULL, cifs_sb->local_nls,
>>> -                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>> +       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
>>> +                       create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>>        if (!rc) {
>>>                rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
>>>                CIFSSMBClose(xid, tcon, fid);
>>> @@ -995,7 +999,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>>>                struct cifs_ntsd *pnntsd, u32 acllen)
>>>  {
>>>        int oplock = 0;
>>> -       int xid, rc;
>>> +       int xid, rc, create_options = 0;
>>>        __u16 fid;
>>>        struct cifs_tcon *tcon;
>>>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
>>> @@ -1006,6 +1010,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>>>        tcon = tlink_tcon(tlink);
>>>        xid = GetXid();
>>>
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>>        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
>>>                         &fid, &oplock, NULL, cifs_sb->local_nls,
>>>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
>>> index 95dad9d..3c6fd56 100644
>>> --- a/fs/cifs/cifsglob.h
>>> +++ b/fs/cifs/cifsglob.h
>>> @@ -179,6 +179,7 @@ struct smb_vol {
>>>        bool noperm:1;
>>>        bool no_psx_acl:1; /* set if posix acl support should be disabled */
>>>        bool cifs_acl:1;
>>> +       bool cifs_backup:1; /* to indicates backup intent during file open */
>>>        bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
>>>        bool server_ino:1; /* use inode numbers from server ie UniqueId */
>>>        bool direct_io:1;
>>> @@ -219,7 +220,8 @@ struct smb_vol {
>>>                         CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
>>>                         CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
>>>                         CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
>>> -                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
>>> +                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
>>> +                        CIFS_MOUNT_CIFS_BACKUP)
>>>
>>>  #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
>>>                      MS_NODEV | MS_SYNCHRONOUS)
>>> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
>>> index 80c2e3a..352d6d6 100644
>>> --- a/fs/cifs/connect.c
>>> +++ b/fs/cifs/connect.c
>>> @@ -883,6 +883,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>>>                        cFYI(1, "Null separator not allowed");
>>>                }
>>>        }
>>> +       vol->cifs_backup = 0; /* no backup intent */
>>>
>>>        while ((data = strsep(&options, separator)) != NULL) {
>>>                if (!*data)
>>> @@ -1405,6 +1406,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>>>                        vol->rwpidforward = 1;
>>>                } else if (strnicmp(data, "cifsacl", 7) == 0) {
>>>                        vol->cifs_acl = 1;
>>> +               } else if (strnicmp(data, "backup", 7) == 0) {
>>> +                       vol->cifs_backup = 1;
>>>                } else if (strnicmp(data, "nocifsacl", 9) == 0) {
>>>                        vol->cifs_acl = 0;
>>>                } else if (strnicmp(data, "acl", 3) == 0) {
>>> @@ -2763,6 +2766,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
>>>        if (pvolume_info->cifs_acl)
>>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
>>> +       if (pvolume_info->cifs_backup)
>>> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUP;
>>>        if (pvolume_info->override_uid)
>>>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
>>>        if (pvolume_info->override_gid)
>>> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
>>> index ae576fb..fbecde6 100644
>>> --- a/fs/cifs/dir.c
>>> +++ b/fs/cifs/dir.c
>>> @@ -243,6 +243,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
>>>         */
>>>        if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
>>>                create_options |= CREATE_OPTION_READONLY;
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>>
>>>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>>>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
>>> @@ -357,6 +360,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>>  {
>>>        int rc = -EPERM;
>>>        int xid;
>>> +       int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
>>>        struct cifs_sb_info *cifs_sb;
>>>        struct tcon_link *tlink;
>>>        struct cifs_tcon *pTcon;
>>> @@ -431,9 +435,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>>                return rc;
>>>        }
>>>
>>> -       /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>>        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
>>> -                        GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
>>> +                        GENERIC_WRITE, create_options,
>>>                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
>>>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>>        if (rc)
>>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>>> index 9f41a10..39b06c4 100644
>>> --- a/fs/cifs/file.c
>>> +++ b/fs/cifs/file.c
>>> @@ -174,6 +174,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>>>        int rc;
>>>        int desiredAccess;
>>>        int disposition;
>>> +       int create_options = CREATE_NOT_DIR;
>>>        FILE_ALL_INFO *buf;
>>>
>>>        desiredAccess = cifs_convert_flags(f_flags);
>>> @@ -210,9 +211,13 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>>>        if (!buf)
>>>                return -ENOMEM;
>>>
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>>>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
>>> -                        desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
>>> +                        desiredAccess, create_options, pnetfid, poplock, buf,
>>>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
>>>                                 & CIFS_MOUNT_MAP_SPECIAL_CHR);
>>>        else
>>> @@ -465,6 +470,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>>        char *full_path = NULL;
>>>        int desiredAccess;
>>>        int disposition = FILE_OPEN;
>>> +       int create_options = CREATE_NOT_DIR;
>>>        __u16 netfid;
>>>
>>>        xid = GetXid();
>>> @@ -524,6 +530,10 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>>
>>>        desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
>>>
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>>        /* Can not refresh inode by passing in file_info buf to be returned
>>>           by SMBOpen and then calling get_inode_info with returned buf
>>>           since file might have write behind data that needs to be flushed
>>> @@ -531,7 +541,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>>>           that inode was not dirty locally we could do this */
>>>
>>>        rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
>>> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
>>> +                        create_options, &netfid, &oplock, NULL,
>>>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
>>>                                CIFS_MOUNT_MAP_SPECIAL_CHR);
>>>        if (rc) {
>>> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
>>> index db3f18c..67e51b8 100644
>>> --- a/fs/cifs/link.c
>>> +++ b/fs/cifs/link.c
>>> @@ -183,14 +183,20 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
>>>  static int
>>>  CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>>>                    const char *fromName, const char *toName,
>>> -                   const struct nls_table *nls_codepage, int remap)
>>> +                   struct cifs_sb_info *cifs_sb)
>>>  {
>>>        int rc;
>>>        int oplock = 0;
>>> +       int remap;
>>> +       int create_options = CREATE_NOT_DIR;
>>>        __u16 netfid = 0;
>>>        u8 *buf;
>>>        unsigned int bytes_written = 0;
>>>        struct cifs_io_parms io_parms;
>>> +       struct nls_table *nls_codepage;
>>> +
>>> +       nls_codepage = cifs_sb->local_nls;
>>> +       remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
>>>
>>>        buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>>>        if (!buf)
>>> @@ -202,8 +208,12 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>>>                return rc;
>>>        }
>>>
>>> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
>>> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
>>> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>>> +
>>>        rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
>>> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
>>> +                        create_options, &netfid, &oplock, NULL,
>>>                         nls_codepage, remap);
>>>        if (rc != 0) {
>>>                kfree(buf);
>>> @@ -559,9 +569,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
>>>        /* BB what if DFS and this volume is on different share? BB */
>>>        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
>>>                rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
>>> -                                        cifs_sb->local_nls,
>>> -                                        cifs_sb->mnt_cifs_flags &
>>> -                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
>>> +                                       cifs_sb);
>>>        else if (pTcon->unix_ext)
>>>                rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
>>>                                           cifs_sb->local_nls);
>>> --
>>> 1.6.0.2
>>>
>>>
>>
>>
>>
>> --
>> Thanks,
>>
>> Steve
>>
>
> On a Windows 2003 server, 'Back up files and directories policy is enabled
> and user named 'mahalcrow' is added to that policy.
>
> I mount a share from that Windows server by authenticating as user 'mahalcrow'.
>
> # mount -t cifs //cifstest1/myshare /mnt/smb_b -o
> backup,cifsacl,user=mahalcrow,pass=<passwd>
>
> # ls -l /mnt/smb_b/testfile2
> -rwx------ 1 administrator 10010 18 Aug  9 19:26 /mnt/smb_b/testfile2
>
> # /tmp/getcifsacl /mnt/smb_b/testfile2
> REVISION:0x1
> CONTROL:0x9404
> OWNER:CIFSTESTDOM\Administrator
> GROUP:CIFSTESTDOM\Domain Users
> ACL:CIFSTESTDOM\Administrator:ALLOWED/0x0/FULL
>
> So with the backup intent create option during open (nt_create_andx),
> an user who is neither owner of the file and not part of the only ACE
> in the ACL of this file, can still access the file.
>
>
> Now if  I remove this user, mahalcrow, from the policy 'Back up files
> and directories' under
>  Security Settings/Local Policies/user Rights Assignment/Security Options,
> unmount and remount the share and then try to access the file
> testfile2  from the
> mounted share, it fails, even with the backup intent mount option.
>
> # mount -t cifs //cifstest1/myshare /mnt/smb_b -o
> backup,cifsacl,user=mahalcrow,pass=<passwd>
> # ls -l /mnt/smb_b/testfile2
> -rwxr-xr-x 1 root root 18 Aug  9 19:26 /mnt/smb_b/testfile2
>
> # /tmp/getcifsacl /mnt/smb_b/testfile2
> getxattr error: 95
> REVISION:0x0
> CONTROL:0x0
>
>
> The change in policy on the server will not reflect on an existing smb
> connection though,
> if this user unmounts and remounts the same share, it would be effective.
>
> Regards,
>
> Shirish
>

Oh, forgot to mention, that without this mount option,  backup,
access to file fails.

# ls -l /mnt/smb_b/testfile2
ls: cannot access /mnt/smb_b/testfile2: Permission denied


So this mount option backup, alongwith cifsacl mount option, now enables a
program/tool like robocopy to function as it should.
If and how a user is shut out from any of such accesses is upto the
cifs/smb server.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shirish Pargaonkar Aug. 22, 2011, 1:33 p.m. UTC | #4
On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>
>
> Add mount option backup.
>
> It allows an authenticated user to access files with the intent to back them
> up including their ACLs, who may not have access permission but has
> "Backup files and directories user right" on them (by virtue of being part
> of the built-in group Backup Operators.
>
> If an authenticated user is not part of the built-in group Backup Operators
> at the server, access to such files is denied.
>
>
> Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> ---
>  fs/cifs/cifs_fs_sb.h |    1 +
>  fs/cifs/cifsacl.c    |   18 +++++++++++++-----
>  fs/cifs/cifsglob.h   |    4 +++-
>  fs/cifs/connect.c    |    5 +++++
>  fs/cifs/dir.c        |   11 +++++++++--
>  fs/cifs/file.c       |   14 ++++++++++++--
>  fs/cifs/link.c       |   18 +++++++++++++-----
>  7 files changed, 56 insertions(+), 15 deletions(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 7260e11..8ba1b44 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -43,6 +43,7 @@
>  #define CIFS_MOUNT_STRICT_IO   0x40000 /* strict cache mode */
>  #define CIFS_MOUNT_RWPIDFORWARD        0x80000 /* use pid forwarding for rw */
>  #define CIFS_MOUNT_POSIXACL    0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
> +#define CIFS_MOUNT_CIFS_BACKUP 0x200000 /* open file with backup intent bit */
>
>  struct cifs_sb_info {
>        struct rb_root tlink_tree;
> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
> index d0f59fa..24bc2dd 100644
> --- a/fs/cifs/cifsacl.c
> +++ b/fs/cifs/cifsacl.c
> @@ -945,7 +945,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>  {
>        struct cifs_ntsd *pntsd = NULL;
>        int oplock = 0;
> -       int xid, rc;
> +       int xid, rc, create_options = 0;
>        __u16 fid;
>        struct cifs_tcon *tcon;
>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
> @@ -956,9 +956,13 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
>        tcon = tlink_tcon(tlink);
>        xid = GetXid();
>
> -       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
> -                        &fid, &oplock, NULL, cifs_sb->local_nls,
> -                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
> +       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
> +                       create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (!rc) {
>                rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
>                CIFSSMBClose(xid, tcon, fid);
> @@ -995,7 +999,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>                struct cifs_ntsd *pnntsd, u32 acllen)
>  {
>        int oplock = 0;
> -       int xid, rc;
> +       int xid, rc, create_options = 0;
>        __u16 fid;
>        struct cifs_tcon *tcon;
>        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
> @@ -1006,6 +1010,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
>        tcon = tlink_tcon(tlink);
>        xid = GetXid();
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
>                         &fid, &oplock, NULL, cifs_sb->local_nls,
>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 95dad9d..3c6fd56 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -179,6 +179,7 @@ struct smb_vol {
>        bool noperm:1;
>        bool no_psx_acl:1; /* set if posix acl support should be disabled */
>        bool cifs_acl:1;
> +       bool cifs_backup:1; /* to indicates backup intent during file open */
>        bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
>        bool server_ino:1; /* use inode numbers from server ie UniqueId */
>        bool direct_io:1;
> @@ -219,7 +220,8 @@ struct smb_vol {
>                         CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
>                         CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
>                         CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
> -                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
> +                        CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
> +                        CIFS_MOUNT_CIFS_BACKUP)
>
>  #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
>                      MS_NODEV | MS_SYNCHRONOUS)
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 80c2e3a..352d6d6 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -883,6 +883,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>                        cFYI(1, "Null separator not allowed");
>                }
>        }
> +       vol->cifs_backup = 0; /* no backup intent */
>
>        while ((data = strsep(&options, separator)) != NULL) {
>                if (!*data)
> @@ -1405,6 +1406,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>                        vol->rwpidforward = 1;
>                } else if (strnicmp(data, "cifsacl", 7) == 0) {
>                        vol->cifs_acl = 1;
> +               } else if (strnicmp(data, "backup", 7) == 0) {
> +                       vol->cifs_backup = 1;
>                } else if (strnicmp(data, "nocifsacl", 9) == 0) {
>                        vol->cifs_acl = 0;
>                } else if (strnicmp(data, "acl", 3) == 0) {
> @@ -2763,6 +2766,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
>        if (pvolume_info->cifs_acl)
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
> +       if (pvolume_info->cifs_backup)
> +               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUP;
>        if (pvolume_info->override_uid)
>                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
>        if (pvolume_info->override_gid)
> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> index ae576fb..fbecde6 100644
> --- a/fs/cifs/dir.c
> +++ b/fs/cifs/dir.c
> @@ -243,6 +243,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
>         */
>        if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
>                create_options |= CREATE_OPTION_READONLY;
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
>
>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
> @@ -357,6 +360,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>  {
>        int rc = -EPERM;
>        int xid;
> +       int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
>        struct cifs_sb_info *cifs_sb;
>        struct tcon_link *tlink;
>        struct cifs_tcon *pTcon;
> @@ -431,9 +435,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>                return rc;
>        }
>
> -       /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
> -                        GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
> +                        GENERIC_WRITE, create_options,
>                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
>                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (rc)
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 9f41a10..39b06c4 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -174,6 +174,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>        int rc;
>        int desiredAccess;
>        int disposition;
> +       int create_options = CREATE_NOT_DIR;
>        FILE_ALL_INFO *buf;
>
>        desiredAccess = cifs_convert_flags(f_flags);
> @@ -210,9 +211,13 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
>        if (!buf)
>                return -ENOMEM;
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        if (tcon->ses->capabilities & CAP_NT_SMBS)
>                rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
> -                        desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
> +                        desiredAccess, create_options, pnetfid, poplock, buf,
>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
>                                 & CIFS_MOUNT_MAP_SPECIAL_CHR);
>        else
> @@ -465,6 +470,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>        char *full_path = NULL;
>        int desiredAccess;
>        int disposition = FILE_OPEN;
> +       int create_options = CREATE_NOT_DIR;
>        __u16 netfid;
>
>        xid = GetXid();
> @@ -524,6 +530,10 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>
>        desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        /* Can not refresh inode by passing in file_info buf to be returned
>           by SMBOpen and then calling get_inode_info with returned buf
>           since file might have write behind data that needs to be flushed
> @@ -531,7 +541,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
>           that inode was not dirty locally we could do this */
>
>        rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
> +                        create_options, &netfid, &oplock, NULL,
>                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
>                                CIFS_MOUNT_MAP_SPECIAL_CHR);
>        if (rc) {
> diff --git a/fs/cifs/link.c b/fs/cifs/link.c
> index db3f18c..67e51b8 100644
> --- a/fs/cifs/link.c
> +++ b/fs/cifs/link.c
> @@ -183,14 +183,20 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
>  static int
>  CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>                    const char *fromName, const char *toName,
> -                   const struct nls_table *nls_codepage, int remap)
> +                   struct cifs_sb_info *cifs_sb)
>  {
>        int rc;
>        int oplock = 0;
> +       int remap;
> +       int create_options = CREATE_NOT_DIR;
>        __u16 netfid = 0;
>        u8 *buf;
>        unsigned int bytes_written = 0;
>        struct cifs_io_parms io_parms;
> +       struct nls_table *nls_codepage;
> +
> +       nls_codepage = cifs_sb->local_nls;
> +       remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
>
>        buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
>        if (!buf)
> @@ -202,8 +208,12 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
>                return rc;
>        }
>
> +       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
> +                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
> +               create_options |= CREATE_OPEN_BACKUP_INTENT;
> +
>        rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
> -                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
> +                        create_options, &netfid, &oplock, NULL,
>                         nls_codepage, remap);
>        if (rc != 0) {
>                kfree(buf);
> @@ -559,9 +569,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
>        /* BB what if DFS and this volume is on different share? BB */
>        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
>                rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
> -                                        cifs_sb->local_nls,
> -                                        cifs_sb->mnt_cifs_flags &
> -                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
> +                                       cifs_sb);
>        else if (pTcon->unix_ext)
>                rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
>                                           cifs_sb->local_nls);
> --
> 1.6.0.2
>
>

Jeff,  Steve,

Any comments on this patch (and manpage patch in cifs-utils)?

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Aug. 23, 2011, 1:15 p.m. UTC | #5
On Mon, 22 Aug 2011 08:33:49 -0500
Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:

> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >
> >
> > Add mount option backup.
> >
> > It allows an authenticated user to access files with the intent to back them
> > up including their ACLs, who may not have access permission but has
> > "Backup files and directories user right" on them (by virtue of being part
> > of the built-in group Backup Operators.
> >
> > If an authenticated user is not part of the built-in group Backup Operators
> > at the server, access to such files is denied.
> >
> >
> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> > ---
>
> 
> Jeff,  Steve,
> 
> Any comments on this patch (and manpage patch in cifs-utils)?
> 

This seems like a really nasty kludge. It doesn't seem like the
implications of this have been carefully considered.

What happens I mount with the "backup" flag and do not have the
necessary permissions on the server to use the flag in an open? Will
this new flag be mutually exclusive with "multiuser"?

One idea that might be better is to come up with way to mark certain
(unix) users with the appropriate flag. If all the backup users were in
a certan group, for instance, then you could use that info to decide
whether to set the flag in the open calls.
Shirish Pargaonkar Aug. 23, 2011, 1:34 p.m. UTC | #6
On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Mon, 22 Aug 2011 08:33:49 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >
>> >
>> > Add mount option backup.
>> >
>> > It allows an authenticated user to access files with the intent to back them
>> > up including their ACLs, who may not have access permission but has
>> > "Backup files and directories user right" on them (by virtue of being part
>> > of the built-in group Backup Operators.
>> >
>> > If an authenticated user is not part of the built-in group Backup Operators
>> > at the server, access to such files is denied.
>> >
>> >
>> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> > ---
>>
>>
>> Jeff,  Steve,
>>
>> Any comments on this patch (and manpage patch in cifs-utils)?
>>
>
> This seems like a really nasty kludge. It doesn't seem like the
> implications of this have been carefully considered.
>
> What happens I mount with the "backup" flag and do not have the
> necessary permissions on the server to use the flag in an open? Will
> this new flag be mutually exclusive with "multiuser"?

If an authenticated user on the server does not have
necessary permission (by virtue of not being in a
pertinent registry setting or any other means that a
server employs), then open would fail as it should.
Because the intent to mount a share with this option
for an authenticated user is to have access to all the
files for backup for that user.

I am not sure about the   mulituser   option. Need to
dwell on that for a while.

>
> One idea that might be better is to come up with way to mark certain
> (unix) users with the appropriate flag. If all the backup users were in
> a certan group, for instance, then you could use that info to decide
> whether to set the flag in the open calls.
>
> --
> Jeff Layton <jlayton@samba.org>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shirish Pargaonkar Aug. 24, 2011, 1:16 a.m. UTC | #7
On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Mon, 22 Aug 2011 08:33:49 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >
>> >
>> > Add mount option backup.
>> >
>> > It allows an authenticated user to access files with the intent to back them
>> > up including their ACLs, who may not have access permission but has
>> > "Backup files and directories user right" on them (by virtue of being part
>> > of the built-in group Backup Operators.
>> >
>> > If an authenticated user is not part of the built-in group Backup Operators
>> > at the server, access to such files is denied.
>> >
>> >
>> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> > ---
>>
>>
>> Jeff,  Steve,
>>
>> Any comments on this patch (and manpage patch in cifs-utils)?
>>
>
> This seems like a really nasty kludge. It doesn't seem like the
> implications of this have been carefully considered.
>
> What happens I mount with the "backup" flag and do not have the
> necessary permissions on the server to use the flag in an open? Will
> this new flag be mutually exclusive with "multiuser"?

I think this mount option should be mutually exclusive with multiuser.

>
> One idea that might be better is to come up with way to mark certain
> (unix) users with the appropriate flag. If all the backup users were in
> a certan group, for instance, then you could use that info to decide
> whether to set the flag in the open calls.

I think it would be simple and cleanerm for server to enforce the
access privileges since it can.

The intended use of this mount option is only for authenticated
user that are known to have the "Backup files and directories"
user right.

>
> --
> Jeff Layton <jlayton@samba.org>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve French Aug. 26, 2011, 6:52 p.m. UTC | #8
We have had a few requests for optionally sending the
"FILE_OPEN_FOR_BACKUP_INTENT"
flag on open - as it is used by various CIFS servers (including Windows)
to allow certain privileged users to backup files more easily (see quote
from MS-CIFS protocol specification below).

There are few reasonable ways that I see to optionally request that such a flag
be sent on the wire, given that POSIX AFAIK has no exact equivalent open flag,
and it is unreasonable to expect that applications would be recoded to
add support
for a new flag like this until other file systems have equivalents.

One way would be to allow an ioctl or /proc/sys or /proc/fs setting
that turns on
(or off) the flag - but it is hard to imagine how that would help
since the flag is specified on open.

A more obvious way, following Shirish's suggestion of a "backup" mount.  All
opens on this mount would get the backup intent flag set - and since opens
with this flag require a privileged user (with the "backup operator" right)
the idea suggested below is to forbid "multiuser" behavior on such a mount.
If you mount a cifs share for backup - all opens are done with the userid
specified on the mount and with the backup intent flag.  That seems
workable - and appears to address the user requirement.

If any other approach for sending this flag makes more sense though
it would be helpful to get suggestions ...


On Wed, Aug 24, 2011 at 9:53 PM, Shirish Pargaonkar
<shirishpargaonkar@gmail.com> wrote:
> On Tue, Aug 23, 2011 at 8:44 PM, Steve French <smfrench@gmail.com> wrote:
>> I agree - but want to have a stronger argument why multiuser doesn't
>> make sense and would conflict.  We need to establish whether:
>> 1) opens with backup intent can fail, where a normal open (without the
>> flag) would work
>
> I think this can happen, based on this description in MS-CIFS.
>
> FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
> The file is being opened or created for the purposes of either a
> backup or a restore operation. Thus, the server can make appropriate
> checks to ensure that the caller is capable of overriding whatever
> security checks have been placed on the file to allow a backup or
> restore operation to occur. The server can check for certain access
> rights to the file before checking the DesiredAccess field.
>
>> 2) whether there are users for which backup intent opens will always
>> work (or work no differently than the same open without the flag) - no
>> matter who the owner of the file.
>>
>> If the latter is true then we can make the argument that for "backup"
>> mounts you can only use one user.
>
> So the latter is true and a case of backup mount option being
> mutually exclusive to multiuser option.
Shirish Pargaonkar Aug. 29, 2011, 9:24 p.m. UTC | #9
On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Mon, 22 Aug 2011 08:33:49 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >
>> >
>> > Add mount option backup.
>> >
>> > It allows an authenticated user to access files with the intent to back them
>> > up including their ACLs, who may not have access permission but has
>> > "Backup files and directories user right" on them (by virtue of being part
>> > of the built-in group Backup Operators.
>> >
>> > If an authenticated user is not part of the built-in group Backup Operators
>> > at the server, access to such files is denied.
>> >
>> >
>> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> > ---
>>
>>
>> Jeff,  Steve,
>>
>> Any comments on this patch (and manpage patch in cifs-utils)?
>>
>
> This seems like a really nasty kludge. It doesn't seem like the
> implications of this have been carefully considered.
>
> What happens I mount with the "backup" flag and do not have the
> necessary permissions on the server to use the flag in an open? Will
> this new flag be mutually exclusive with "multiuser"?
>
> One idea that might be better is to come up with way to mark certain
> (unix) users with the appropriate flag. If all the backup users were in
> a certan group, for instance, then you could use that info to decide
> whether to set the flag in the open calls.
>
> --
> Jeff Layton <jlayton@samba.org>
>

Jeff, one comment, it is not the (unix) user that matters, it is the
user on the server (authenticated) user at the server because the
user right to access a file in backup mode can be granted only
to a user at the server.

I think care should be taken to make sure that backup and
multiuser are mutually exclusive mount options in mount.cifs.

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Aug. 30, 2011, 12:29 a.m. UTC | #10
On Mon, 29 Aug 2011 16:24:33 -0500
Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:

> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> > On Mon, 22 Aug 2011 08:33:49 -0500
> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
> >
> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> >
> >> >
> >> > Add mount option backup.
> >> >
> >> > It allows an authenticated user to access files with the intent to back them
> >> > up including their ACLs, who may not have access permission but has
> >> > "Backup files and directories user right" on them (by virtue of being part
> >> > of the built-in group Backup Operators.
> >> >
> >> > If an authenticated user is not part of the built-in group Backup Operators
> >> > at the server, access to such files is denied.
> >> >
> >> >
> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> > ---
> >>
> >>
> >> Jeff,  Steve,
> >>
> >> Any comments on this patch (and manpage patch in cifs-utils)?
> >>
> >
> > This seems like a really nasty kludge. It doesn't seem like the
> > implications of this have been carefully considered.
> >
> > What happens I mount with the "backup" flag and do not have the
> > necessary permissions on the server to use the flag in an open? Will
> > this new flag be mutually exclusive with "multiuser"?
> >
> > One idea that might be better is to come up with way to mark certain
> > (unix) users with the appropriate flag. If all the backup users were in
> > a certan group, for instance, then you could use that info to decide
> > whether to set the flag in the open calls.
> >
> > --
> > Jeff Layton <jlayton@samba.org>
> >
> 
> Jeff, one comment, it is not the (unix) user that matters, it is the
> user on the server (authenticated) user at the server because the
> user right to access a file in backup mode can be granted only
> to a user at the server.
> 

Right, I realize that.

> I think care should be taken to make sure that backup and
> multiuser are mutually exclusive mount options in mount.cifs.
> 

My objection here is more fundamental...

This patchset lends itself to a single, specific use. You can create a
mount that you want to use for backups. Typically, when running backups
like this you also intend for this mount to be used by only one (unix)
user.

Adding a "backup" option is tantamount to adding extra privileges to
this mount for anyone who accesses it. However, it's not clear to me
how these extra privileges will be secured from other users that don't
necessarily need them.

It seems to me that it would be far more useful to find a way to only
add these extra "backup" permissions for certain unix users that are
accessing the mount.

Does that make sense?
Steve French Aug. 30, 2011, 1:11 a.m. UTC | #11
On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
> On Mon, 29 Aug 2011 16:24:33 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
>> > On Mon, 22 Aug 2011 08:33:49 -0500
>> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>> >
>> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> >
>> >> >
>> >> > Add mount option backup.
>> >> >
>> >> > It allows an authenticated user to access files with the intent to back them
>> >> > up including their ACLs, who may not have access permission but has
>> >> > "Backup files and directories user right" on them (by virtue of being part
>> >> > of the built-in group Backup Operators.
>> >> >
>> >> > If an authenticated user is not part of the built-in group Backup Operators
>> >> > at the server, access to such files is denied.
>> >> >
>> >> >
>> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> > ---
>> >>
>> >>
>> >> Jeff,  Steve,
>> >>
>> >> Any comments on this patch (and manpage patch in cifs-utils)?
>> >>
>> >
>> > This seems like a really nasty kludge. It doesn't seem like the
>> > implications of this have been carefully considered.
>> >
>> > What happens I mount with the "backup" flag and do not have the
>> > necessary permissions on the server to use the flag in an open? Will
>> > this new flag be mutually exclusive with "multiuser"?
>> >
>> > One idea that might be better is to come up with way to mark certain
>> > (unix) users with the appropriate flag. If all the backup users were in
>> > a certan group, for instance, then you could use that info to decide
>> > whether to set the flag in the open calls.
>> >
>> > --
>> > Jeff Layton <jlayton@samba.org>
>> >
>>
>> Jeff, one comment, it is not the (unix) user that matters, it is the
>> user on the server (authenticated) user at the server because the
>> user right to access a file in backup mode can be granted only
>> to a user at the server.
>>
>
> Right, I realize that.
>
>> I think care should be taken to make sure that backup and
>> multiuser are mutually exclusive mount options in mount.cifs.
>>
>
> My objection here is more fundamental...
>
> This patchset lends itself to a single, specific use. You can create a
> mount that you want to use for backups. Typically, when running backups
> like this you also intend for this mount to be used by only one (unix)
> user.
>
> Adding a "backup" option is tantamount to adding extra privileges to
> this mount for anyone who accesses it. However, it's not clear to me
> how these extra privileges will be secured from other users that don't
> necessarily need them.
>
> It seems to me that it would be far more useful to find a way to only
> add these extra "backup" permissions for certain unix users that are
> accessing the mount.
>
> Does that make sense?

I don't object to defaulting backup mounts to mode 0700 if that is what
you are suggesting ...?
Jeff Layton Aug. 30, 2011, 10:25 a.m. UTC | #12
On Mon, 29 Aug 2011 20:11:13 -0500
Steve French <smfrench@gmail.com> wrote:

> On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
> > On Mon, 29 Aug 2011 16:24:33 -0500
> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
> >
> >> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> >> > On Mon, 22 Aug 2011 08:33:49 -0500
> >> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
> >> >
> >> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> >> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> >> >
> >> >> >
> >> >> > Add mount option backup.
> >> >> >
> >> >> > It allows an authenticated user to access files with the intent to back them
> >> >> > up including their ACLs, who may not have access permission but has
> >> >> > "Backup files and directories user right" on them (by virtue of being part
> >> >> > of the built-in group Backup Operators.
> >> >> >
> >> >> > If an authenticated user is not part of the built-in group Backup Operators
> >> >> > at the server, access to such files is denied.
> >> >> >
> >> >> >
> >> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> >> > ---
> >> >>
> >> >>
> >> >> Jeff,  Steve,
> >> >>
> >> >> Any comments on this patch (and manpage patch in cifs-utils)?
> >> >>
> >> >
> >> > This seems like a really nasty kludge. It doesn't seem like the
> >> > implications of this have been carefully considered.
> >> >
> >> > What happens I mount with the "backup" flag and do not have the
> >> > necessary permissions on the server to use the flag in an open? Will
> >> > this new flag be mutually exclusive with "multiuser"?
> >> >
> >> > One idea that might be better is to come up with way to mark certain
> >> > (unix) users with the appropriate flag. If all the backup users were in
> >> > a certan group, for instance, then you could use that info to decide
> >> > whether to set the flag in the open calls.
> >> >
> >> > --
> >> > Jeff Layton <jlayton@samba.org>
> >> >
> >>
> >> Jeff, one comment, it is not the (unix) user that matters, it is the
> >> user on the server (authenticated) user at the server because the
> >> user right to access a file in backup mode can be granted only
> >> to a user at the server.
> >>
> >
> > Right, I realize that.
> >
> >> I think care should be taken to make sure that backup and
> >> multiuser are mutually exclusive mount options in mount.cifs.
> >>
> >
> > My objection here is more fundamental...
> >
> > This patchset lends itself to a single, specific use. You can create a
> > mount that you want to use for backups. Typically, when running backups
> > like this you also intend for this mount to be used by only one (unix)
> > user.
> >
> > Adding a "backup" option is tantamount to adding extra privileges to
> > this mount for anyone who accesses it. However, it's not clear to me
> > how these extra privileges will be secured from other users that don't
> > necessarily need them.
> >
> > It seems to me that it would be far more useful to find a way to only
> > add these extra "backup" permissions for certain unix users that are
> > accessing the mount.
> >
> > Does that make sense?
> 
> I don't object to defaulting backup mounts to mode 0700 if that is what
> you are suggesting ...?
> 

That's not at all what I'm suggesting. What if unix extensions are in
force? Relying on local permissions enforcement to prevent access to
the mount is always very problematic.
Shirish Pargaonkar Aug. 30, 2011, 2:03 p.m. UTC | #13
On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
> On Mon, 29 Aug 2011 16:24:33 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
>> > On Mon, 22 Aug 2011 08:33:49 -0500
>> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>> >
>> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> >
>> >> >
>> >> > Add mount option backup.
>> >> >
>> >> > It allows an authenticated user to access files with the intent to back them
>> >> > up including their ACLs, who may not have access permission but has
>> >> > "Backup files and directories user right" on them (by virtue of being part
>> >> > of the built-in group Backup Operators.
>> >> >
>> >> > If an authenticated user is not part of the built-in group Backup Operators
>> >> > at the server, access to such files is denied.
>> >> >
>> >> >
>> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> > ---
>> >>
>> >>
>> >> Jeff,  Steve,
>> >>
>> >> Any comments on this patch (and manpage patch in cifs-utils)?
>> >>
>> >
>> > This seems like a really nasty kludge. It doesn't seem like the
>> > implications of this have been carefully considered.
>> >
>> > What happens I mount with the "backup" flag and do not have the
>> > necessary permissions on the server to use the flag in an open? Will
>> > this new flag be mutually exclusive with "multiuser"?
>> >
>> > One idea that might be better is to come up with way to mark certain
>> > (unix) users with the appropriate flag. If all the backup users were in
>> > a certan group, for instance, then you could use that info to decide
>> > whether to set the flag in the open calls.
>> >
>> > --
>> > Jeff Layton <jlayton@samba.org>
>> >
>>
>> Jeff, one comment, it is not the (unix) user that matters, it is the
>> user on the server (authenticated) user at the server because the
>> user right to access a file in backup mode can be granted only
>> to a user at the server.
>>
>
> Right, I realize that.
>
>> I think care should be taken to make sure that backup and
>> multiuser are mutually exclusive mount options in mount.cifs.
>>
>
> My objection here is more fundamental...
>
> This patchset lends itself to a single, specific use. You can create a
> mount that you want to use for backups. Typically, when running backups
> like this you also intend for this mount to be used by only one (unix)
> user.
>
> Adding a "backup" option is tantamount to adding extra privileges to
> this mount for anyone who accesses it. However, it's not clear to me
> how these extra privileges will be secured from other users that don't
> necessarily need them.
>
> It seems to me that it would be far more useful to find a way to only
> add these extra "backup" permissions for certain unix users that are
> accessing the mount.
>
> Does that make sense?
>
> --
> Jeff Layton <jlayton@samba.org>
>

Jeff, definitely. Thanks.  I think one way might be to specify an
user or uid and restrict the usage of that mount to that user id?
So you can specify mount option as  either backup=userxyz
or backup=1001 perhaps?

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton Aug. 30, 2011, 2:52 p.m. UTC | #14
On Tue, 30 Aug 2011 09:03:05 -0500
Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:

> On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
> > On Mon, 29 Aug 2011 16:24:33 -0500
> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
> >
> >> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
> >> > On Mon, 22 Aug 2011 08:33:49 -0500
> >> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
> >> >
> >> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
> >> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> >> >
> >> >> >
> >> >> > Add mount option backup.
> >> >> >
> >> >> > It allows an authenticated user to access files with the intent to back them
> >> >> > up including their ACLs, who may not have access permission but has
> >> >> > "Backup files and directories user right" on them (by virtue of being part
> >> >> > of the built-in group Backup Operators.
> >> >> >
> >> >> > If an authenticated user is not part of the built-in group Backup Operators
> >> >> > at the server, access to such files is denied.
> >> >> >
> >> >> >
> >> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
> >> >> > ---
> >> >>
> >> >>
> >> >> Jeff,  Steve,
> >> >>
> >> >> Any comments on this patch (and manpage patch in cifs-utils)?
> >> >>
> >> >
> >> > This seems like a really nasty kludge. It doesn't seem like the
> >> > implications of this have been carefully considered.
> >> >
> >> > What happens I mount with the "backup" flag and do not have the
> >> > necessary permissions on the server to use the flag in an open? Will
> >> > this new flag be mutually exclusive with "multiuser"?
> >> >
> >> > One idea that might be better is to come up with way to mark certain
> >> > (unix) users with the appropriate flag. If all the backup users were in
> >> > a certan group, for instance, then you could use that info to decide
> >> > whether to set the flag in the open calls.
> >> >
> >> > --
> >> > Jeff Layton <jlayton@samba.org>
> >> >
> >>
> >> Jeff, one comment, it is not the (unix) user that matters, it is the
> >> user on the server (authenticated) user at the server because the
> >> user right to access a file in backup mode can be granted only
> >> to a user at the server.
> >>
> >
> > Right, I realize that.
> >
> >> I think care should be taken to make sure that backup and
> >> multiuser are mutually exclusive mount options in mount.cifs.
> >>
> >
> > My objection here is more fundamental...
> >
> > This patchset lends itself to a single, specific use. You can create a
> > mount that you want to use for backups. Typically, when running backups
> > like this you also intend for this mount to be used by only one (unix)
> > user.
> >
> > Adding a "backup" option is tantamount to adding extra privileges to
> > this mount for anyone who accesses it. However, it's not clear to me
> > how these extra privileges will be secured from other users that don't
> > necessarily need them.
> >
> > It seems to me that it would be far more useful to find a way to only
> > add these extra "backup" permissions for certain unix users that are
> > accessing the mount.
> >
> > Does that make sense?
> >
> > --
> > Jeff Layton <jlayton@samba.org>
> >
> 
> Jeff, definitely. Thanks.  I think one way might be to specify an
> user or uid and restrict the usage of that mount to that user id?
> So you can specify mount option as  either backup=userxyz
> or backup=1001 perhaps?
> 

Sure, that might be reasonable.

Since backup privileges are tied to a group on the server, we could
also mirror that semantic on the client. Have a backup=<gid> and turn
on the backup flag for any unix user who is in that group. That would
seem to allow for better integration with things like nss_winbind.
Steve French Aug. 30, 2011, 5:09 p.m. UTC | #15
On Tue, Aug 30, 2011 at 9:52 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Tue, 30 Aug 2011 09:03:05 -0500
> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>
>> On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
>> > On Mon, 29 Aug 2011 16:24:33 -0500
>> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>> >
>> >> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
>> >> > On Mon, 22 Aug 2011 08:33:49 -0500
>> >> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>> >> >
>> >> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>> >> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> >> >
>> >> >> >
>> >> >> > Add mount option backup.
>> >> >> >
>> >> >> > It allows an authenticated user to access files with the intent to back them
>> >> >> > up including their ACLs, who may not have access permission but has
>> >> >> > "Backup files and directories user right" on them (by virtue of being part
>> >> >> > of the built-in group Backup Operators.
>> >> >> >
>> >> >> > If an authenticated user is not part of the built-in group Backup Operators
>> >> >> > at the server, access to such files is denied.
>> >> >> >
>> >> >> >
>> >> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>> >> >> > ---
>> >> >>
>> >> >>
>> >> >> Jeff,  Steve,
>> >> >>
>> >> >> Any comments on this patch (and manpage patch in cifs-utils)?
>> >> >>
>> >> >
>> >> > This seems like a really nasty kludge. It doesn't seem like the
>> >> > implications of this have been carefully considered.
>> >> >
>> >> > What happens I mount with the "backup" flag and do not have the
>> >> > necessary permissions on the server to use the flag in an open? Will
>> >> > this new flag be mutually exclusive with "multiuser"?
>> >> >
>> >> > One idea that might be better is to come up with way to mark certain
>> >> > (unix) users with the appropriate flag. If all the backup users were in
>> >> > a certan group, for instance, then you could use that info to decide
>> >> > whether to set the flag in the open calls.
>> >> >
>> >> > --
>> >> > Jeff Layton <jlayton@samba.org>
>> >> >
>> >>
>> >> Jeff, one comment, it is not the (unix) user that matters, it is the
>> >> user on the server (authenticated) user at the server because the
>> >> user right to access a file in backup mode can be granted only
>> >> to a user at the server.
>> >>
>> >
>> > Right, I realize that.
>> >
>> >> I think care should be taken to make sure that backup and
>> >> multiuser are mutually exclusive mount options in mount.cifs.
>> >>
>> >
>> > My objection here is more fundamental...
>> >
>> > This patchset lends itself to a single, specific use. You can create a
>> > mount that you want to use for backups. Typically, when running backups
>> > like this you also intend for this mount to be used by only one (unix)
>> > user.
>> >
>> > Adding a "backup" option is tantamount to adding extra privileges to
>> > this mount for anyone who accesses it. However, it's not clear to me
>> > how these extra privileges will be secured from other users that don't
>> > necessarily need them.
>> >
>> > It seems to me that it would be far more useful to find a way to only
>> > add these extra "backup" permissions for certain unix users that are
>> > accessing the mount.
>> >
>> > Does that make sense?
>> >
>> > --
>> > Jeff Layton <jlayton@samba.org>
>> >
>>
>> Jeff, definitely. Thanks.  I think one way might be to specify an
>> user or uid and restrict the usage of that mount to that user id?
>> So you can specify mount option as  either backup=userxyz
>> or backup=1001 perhaps?
>>
>
> Sure, that might be reasonable.
>
> Since backup privileges are tied to a group on the server, we could
> also mirror that semantic on the client. Have a backup=<gid> and turn
> on the backup flag for any unix user who is in that group. That would
> seem to allow for better integration with things like nss_winbind.

That seems like a good idea - although I prefer that it allow
uid and/or gid to be specified for easier usability
Shirish Pargaonkar Aug. 30, 2011, 5:32 p.m. UTC | #16
On Tue, Aug 30, 2011 at 12:09 PM, Steve French <smfrench@gmail.com> wrote:
> On Tue, Aug 30, 2011 at 9:52 AM, Jeff Layton <jlayton@samba.org> wrote:
>> On Tue, 30 Aug 2011 09:03:05 -0500
>> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>
>>> On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
>>> > On Mon, 29 Aug 2011 16:24:33 -0500
>>> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>> >
>>> >> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
>>> >> > On Mon, 22 Aug 2011 08:33:49 -0500
>>> >> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>> >> >
>>> >> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>>> >> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>> >> >> >
>>> >> >> >
>>> >> >> > Add mount option backup.
>>> >> >> >
>>> >> >> > It allows an authenticated user to access files with the intent to back them
>>> >> >> > up including their ACLs, who may not have access permission but has
>>> >> >> > "Backup files and directories user right" on them (by virtue of being part
>>> >> >> > of the built-in group Backup Operators.
>>> >> >> >
>>> >> >> > If an authenticated user is not part of the built-in group Backup Operators
>>> >> >> > at the server, access to such files is denied.
>>> >> >> >
>>> >> >> >
>>> >> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>> >> >> > ---
>>> >> >>
>>> >> >>
>>> >> >> Jeff,  Steve,
>>> >> >>
>>> >> >> Any comments on this patch (and manpage patch in cifs-utils)?
>>> >> >>
>>> >> >
>>> >> > This seems like a really nasty kludge. It doesn't seem like the
>>> >> > implications of this have been carefully considered.
>>> >> >
>>> >> > What happens I mount with the "backup" flag and do not have the
>>> >> > necessary permissions on the server to use the flag in an open? Will
>>> >> > this new flag be mutually exclusive with "multiuser"?
>>> >> >
>>> >> > One idea that might be better is to come up with way to mark certain
>>> >> > (unix) users with the appropriate flag. If all the backup users were in
>>> >> > a certan group, for instance, then you could use that info to decide
>>> >> > whether to set the flag in the open calls.
>>> >> >
>>> >> > --
>>> >> > Jeff Layton <jlayton@samba.org>
>>> >> >
>>> >>
>>> >> Jeff, one comment, it is not the (unix) user that matters, it is the
>>> >> user on the server (authenticated) user at the server because the
>>> >> user right to access a file in backup mode can be granted only
>>> >> to a user at the server.
>>> >>
>>> >
>>> > Right, I realize that.
>>> >
>>> >> I think care should be taken to make sure that backup and
>>> >> multiuser are mutually exclusive mount options in mount.cifs.
>>> >>
>>> >
>>> > My objection here is more fundamental...
>>> >
>>> > This patchset lends itself to a single, specific use. You can create a
>>> > mount that you want to use for backups. Typically, when running backups
>>> > like this you also intend for this mount to be used by only one (unix)
>>> > user.
>>> >
>>> > Adding a "backup" option is tantamount to adding extra privileges to
>>> > this mount for anyone who accesses it. However, it's not clear to me
>>> > how these extra privileges will be secured from other users that don't
>>> > necessarily need them.
>>> >
>>> > It seems to me that it would be far more useful to find a way to only
>>> > add these extra "backup" permissions for certain unix users that are
>>> > accessing the mount.
>>> >
>>> > Does that make sense?
>>> >
>>> > --
>>> > Jeff Layton <jlayton@samba.org>
>>> >
>>>
>>> Jeff, definitely. Thanks.  I think one way might be to specify an
>>> user or uid and restrict the usage of that mount to that user id?
>>> So you can specify mount option as  either backup=userxyz
>>> or backup=1001 perhaps?
>>>
>>
>> Sure, that might be reasonable.
>>
>> Since backup privileges are tied to a group on the server, we could
>> also mirror that semantic on the client. Have a backup=<gid> and turn
>> on the backup flag for any unix user who is in that group. That would
>> seem to allow for better integration with things like nss_winbind.
>
> That seems like a good idea - although I prefer that it allow
> uid and/or gid to be specified for easier usability
>
>
>
> --
> Thanks,
>
> Steve
>

Steve, how would we be able to distinguish between uids and gids?
The same id e.g 1001, could be either an uid or a gid!
The same applies to a name, it could be a group as well as
an user name.

Regards,

Shirish
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Steve French Aug. 30, 2011, 5:54 p.m. UTC | #17
On Tue, Aug 30, 2011 at 12:32 PM, Shirish Pargaonkar
<shirishpargaonkar@gmail.com> wrote:
> On Tue, Aug 30, 2011 at 12:09 PM, Steve French <smfrench@gmail.com> wrote:
>> On Tue, Aug 30, 2011 at 9:52 AM, Jeff Layton <jlayton@samba.org> wrote:
>>> On Tue, 30 Aug 2011 09:03:05 -0500
>>> Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>>
>>>> On Mon, Aug 29, 2011 at 7:29 PM, Jeff Layton <jlayton@samba.org> wrote:
>>>> > On Mon, 29 Aug 2011 16:24:33 -0500
>>>> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>>> >
>>>> >> On Tue, Aug 23, 2011 at 8:15 AM, Jeff Layton <jlayton@samba.org> wrote:
>>>> >> > On Mon, 22 Aug 2011 08:33:49 -0500
>>>> >> > Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:
>>>> >> >
>>>> >> >> On Fri, Aug 12, 2011 at 11:33 AM,  <shirishpargaonkar@gmail.com> wrote:
>>>> >> >> > From: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > Add mount option backup.
>>>> >> >> >
>>>> >> >> > It allows an authenticated user to access files with the intent to back them
>>>> >> >> > up including their ACLs, who may not have access permission but has
>>>> >> >> > "Backup files and directories user right" on them (by virtue of being part
>>>> >> >> > of the built-in group Backup Operators.
>>>> >> >> >
>>>> >> >> > If an authenticated user is not part of the built-in group Backup Operators
>>>> >> >> > at the server, access to such files is denied.
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
>>>> >> >> > ---
>>>> >> >>
>>>> >> >>
>>>> >> >> Jeff,  Steve,
>>>> >> >>
>>>> >> >> Any comments on this patch (and manpage patch in cifs-utils)?
>>>> >> >>
>>>> >> >
>>>> >> > This seems like a really nasty kludge. It doesn't seem like the
>>>> >> > implications of this have been carefully considered.
>>>> >> >
>>>> >> > What happens I mount with the "backup" flag and do not have the
>>>> >> > necessary permissions on the server to use the flag in an open? Will
>>>> >> > this new flag be mutually exclusive with "multiuser"?
>>>> >> >
>>>> >> > One idea that might be better is to come up with way to mark certain
>>>> >> > (unix) users with the appropriate flag. If all the backup users were in
>>>> >> > a certan group, for instance, then you could use that info to decide
>>>> >> > whether to set the flag in the open calls.
>>>> >> >
>>>> >> > --
>>>> >> > Jeff Layton <jlayton@samba.org>
>>>> >> >
>>>> >>
>>>> >> Jeff, one comment, it is not the (unix) user that matters, it is the
>>>> >> user on the server (authenticated) user at the server because the
>>>> >> user right to access a file in backup mode can be granted only
>>>> >> to a user at the server.
>>>> >>
>>>> >
>>>> > Right, I realize that.
>>>> >
>>>> >> I think care should be taken to make sure that backup and
>>>> >> multiuser are mutually exclusive mount options in mount.cifs.
>>>> >>
>>>> >
>>>> > My objection here is more fundamental...
>>>> >
>>>> > This patchset lends itself to a single, specific use. You can create a
>>>> > mount that you want to use for backups. Typically, when running backups
>>>> > like this you also intend for this mount to be used by only one (unix)
>>>> > user.
>>>> >
>>>> > Adding a "backup" option is tantamount to adding extra privileges to
>>>> > this mount for anyone who accesses it. However, it's not clear to me
>>>> > how these extra privileges will be secured from other users that don't
>>>> > necessarily need them.
>>>> >
>>>> > It seems to me that it would be far more useful to find a way to only
>>>> > add these extra "backup" permissions for certain unix users that are
>>>> > accessing the mount.
>>>> >
>>>> > Does that make sense?
>>>> >
>>>> > --
>>>> > Jeff Layton <jlayton@samba.org>
>>>> >
>>>>
>>>> Jeff, definitely. Thanks.  I think one way might be to specify an
>>>> user or uid and restrict the usage of that mount to that user id?
>>>> So you can specify mount option as  either backup=userxyz
>>>> or backup=1001 perhaps?
>>>>
>>>
>>> Sure, that might be reasonable.
>>>
>>> Since backup privileges are tied to a group on the server, we could
>>> also mirror that semantic on the client. Have a backup=<gid> and turn
>>> on the backup flag for any unix user who is in that group. That would
>>> seem to allow for better integration with things like nss_winbind.
>>
>> That seems like a good idea - although I prefer that it allow
>> uid and/or gid to be specified for easier usability
>>
>>
>>
>> --
>> Thanks,
>>
>> Steve
>>
>
> Steve, how would we be able to distinguish between uids and gids?
> The same id e.g 1001, could be either an uid or a gid!
> The same applies to a name, it could be a group as well as
> an user name.
One option - allow them to distinguished via different mount option:

presumably "backupuid="    and "backupgid="    If we choose to retain
"backup" as a mount option as well - then when neither backupuid nor
backupgid is specified then the uid of the process mounting would be
used as "backupuid" with no backupgid implied by default.
diff mbox

Patch

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 7260e11..8ba1b44 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -43,6 +43,7 @@ 
 #define CIFS_MOUNT_STRICT_IO	0x40000 /* strict cache mode */
 #define CIFS_MOUNT_RWPIDFORWARD	0x80000 /* use pid forwarding for rw */
 #define CIFS_MOUNT_POSIXACL	0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
+#define CIFS_MOUNT_CIFS_BACKUP	0x200000 /* open file with backup intent bit */
 
 struct cifs_sb_info {
 	struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index d0f59fa..24bc2dd 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -945,7 +945,7 @@  static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
 {
 	struct cifs_ntsd *pntsd = NULL;
 	int oplock = 0;
-	int xid, rc;
+	int xid, rc, create_options = 0;
 	__u16 fid;
 	struct cifs_tcon *tcon;
 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -956,9 +956,13 @@  static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
 	tcon = tlink_tcon(tlink);
 	xid = GetXid();
 
-	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
-			 &fid, &oplock, NULL, cifs_sb->local_nls,
-			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
+	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
+			create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (!rc) {
 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
 		CIFSSMBClose(xid, tcon, fid);
@@ -995,7 +999,7 @@  static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
 		struct cifs_ntsd *pnntsd, u32 acllen)
 {
 	int oplock = 0;
-	int xid, rc;
+	int xid, rc, create_options = 0;
 	__u16 fid;
 	struct cifs_tcon *tcon;
 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -1006,6 +1010,10 @@  static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
 	tcon = tlink_tcon(tlink);
 	xid = GetXid();
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
 	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
 			 &fid, &oplock, NULL, cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 95dad9d..3c6fd56 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -179,6 +179,7 @@  struct smb_vol {
 	bool noperm:1;
 	bool no_psx_acl:1; /* set if posix acl support should be disabled */
 	bool cifs_acl:1;
+	bool cifs_backup:1; /* to indicates backup intent during file open */
 	bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
 	bool server_ino:1; /* use inode numbers from server ie UniqueId */
 	bool direct_io:1;
@@ -219,7 +220,8 @@  struct smb_vol {
 			 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
 			 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
 			 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
-			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
+			 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
+			 CIFS_MOUNT_CIFS_BACKUP)
 
 #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
 		      MS_NODEV | MS_SYNCHRONOUS)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 80c2e3a..352d6d6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -883,6 +883,7 @@  cifs_parse_mount_options(const char *mountdata, const char *devname,
 			cFYI(1, "Null separator not allowed");
 		}
 	}
+	vol->cifs_backup = 0; /* no backup intent */
 
 	while ((data = strsep(&options, separator)) != NULL) {
 		if (!*data)
@@ -1405,6 +1406,8 @@  cifs_parse_mount_options(const char *mountdata, const char *devname,
 			vol->rwpidforward = 1;
 		} else if (strnicmp(data, "cifsacl", 7) == 0) {
 			vol->cifs_acl = 1;
+		} else if (strnicmp(data, "backup", 7) == 0) {
+			vol->cifs_backup = 1;
 		} else if (strnicmp(data, "nocifsacl", 9) == 0) {
 			vol->cifs_acl = 0;
 		} else if (strnicmp(data, "acl", 3) == 0) {
@@ -2763,6 +2766,8 @@  void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
 	if (pvolume_info->cifs_acl)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
+	if (pvolume_info->cifs_backup)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUP;
 	if (pvolume_info->override_uid)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
 	if (pvolume_info->override_gid)
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index ae576fb..fbecde6 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -243,6 +243,9 @@  cifs_create(struct inode *inode, struct dentry *direntry, int mode,
 	 */
 	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
 		create_options |= CREATE_OPTION_READONLY;
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
 
 	if (tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
@@ -357,6 +360,7 @@  int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 {
 	int rc = -EPERM;
 	int xid;
+	int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
 	struct cifs_sb_info *cifs_sb;
 	struct tcon_link *tlink;
 	struct cifs_tcon *pTcon;
@@ -431,9 +435,12 @@  int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
 		return rc;
 	}
 
-	/* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
 	rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
-			 GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
+			 GENERIC_WRITE, create_options,
 			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 9f41a10..39b06c4 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -174,6 +174,7 @@  cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
 	int rc;
 	int desiredAccess;
 	int disposition;
+	int create_options = CREATE_NOT_DIR;
 	FILE_ALL_INFO *buf;
 
 	desiredAccess = cifs_convert_flags(f_flags);
@@ -210,9 +211,13 @@  cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
 	if (!buf)
 		return -ENOMEM;
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
 	if (tcon->ses->capabilities & CAP_NT_SMBS)
 		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
-			 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
+			 desiredAccess, create_options, pnetfid, poplock, buf,
 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
 				 & CIFS_MOUNT_MAP_SPECIAL_CHR);
 	else
@@ -465,6 +470,7 @@  static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
 	char *full_path = NULL;
 	int desiredAccess;
 	int disposition = FILE_OPEN;
+	int create_options = CREATE_NOT_DIR;
 	__u16 netfid;
 
 	xid = GetXid();
@@ -524,6 +530,10 @@  static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
 
 	desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
 	/* Can not refresh inode by passing in file_info buf to be returned
 	   by SMBOpen and then calling get_inode_info with returned buf
 	   since file might have write behind data that needs to be flushed
@@ -531,7 +541,7 @@  static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
 	   that inode was not dirty locally we could do this */
 
 	rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
-			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
+			 create_options, &netfid, &oplock, NULL,
 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
 				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index db3f18c..67e51b8 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -183,14 +183,20 @@  CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
 static int
 CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
 		    const char *fromName, const char *toName,
-		    const struct nls_table *nls_codepage, int remap)
+		    struct cifs_sb_info *cifs_sb)
 {
 	int rc;
 	int oplock = 0;
+	int remap;
+	int create_options = CREATE_NOT_DIR;
 	__u16 netfid = 0;
 	u8 *buf;
 	unsigned int bytes_written = 0;
 	struct cifs_io_parms io_parms;
+	struct nls_table *nls_codepage;
+
+	nls_codepage = cifs_sb->local_nls;
+	remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
 
 	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
 	if (!buf)
@@ -202,8 +208,12 @@  CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
 		return rc;
 	}
 
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL &&
+			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUP)
+		create_options |= CREATE_OPEN_BACKUP_INTENT;
+
 	rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
-			 CREATE_NOT_DIR, &netfid, &oplock, NULL,
+			 create_options, &netfid, &oplock, NULL,
 			 nls_codepage, remap);
 	if (rc != 0) {
 		kfree(buf);
@@ -559,9 +569,7 @@  cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
 	/* BB what if DFS and this volume is on different share? BB */
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
 		rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
-					 cifs_sb->local_nls,
-					 cifs_sb->mnt_cifs_flags &
-						CIFS_MOUNT_MAP_SPECIAL_CHR);
+					cifs_sb);
 	else if (pTcon->unix_ext)
 		rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
 					   cifs_sb->local_nls);