cifs: add separate cred_uid field to sesInfo
authorJeff Layton <jlayton@redhat.com>
Mon, 19 Jul 2010 22:00:17 +0000 (18:00 -0400)
committerSteve French <sfrench@us.ibm.com>
Mon, 2 Aug 2010 12:40:39 +0000 (12:40 +0000)
Right now, there's no clear separation between the uid that owns the
credentials used to do the mount and the overriding owner of the files
on that mount.

Add a separate cred_uid field that is set to the real uid
of the mount user. Unlike the linux_uid, the uid= option does not
override this parameter. The parm is sent to cifs.upcall, which can then
preferentially use the creduid= parm instead of the uid= parm for
finding credentials.

This is not the only way to solve this. We could try to do all of this
in kernel instead by having a module parameter that affects what gets
passed in the uid= field of the upcall. That said, we have a lot more
flexibility to change things in userspace so I think it probably makes
sense to do it this way.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifs_spnego.c
fs/cifs/cifsglob.h
fs/cifs/connect.c

index 379bd7d9c05f8ade3045f6c19a17f81b089c7a5a..6effccff85a50d742c23122ea155087c63191909 100644 (file)
@@ -143,6 +143,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        dp = description + strlen(description);
        sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
 
+       dp = description + strlen(description);
+       sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
+
        dp = description + strlen(description);
        sprintf(dp, ";user=%s", sesInfo->userName);
 
index 9b7cf9aa3a000655d4dd781025c67a34691dc1b2..59906146ad3634e89eb403530d2d592e3ac0216b 100644 (file)
@@ -214,7 +214,8 @@ struct cifsSesInfo {
        char *serverNOS;        /* name of network operating system of server */
        char *serverDomain;     /* security realm of server */
        int Suid;               /* remote smb uid  */
-       uid_t linux_uid;        /* local Linux uid */
+       uid_t linux_uid;        /* overriding owner of files on the mount */
+       uid_t cred_uid;         /* owner of credentials */
        int capabilities;
        char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
                                TCP names - will ipv6 and sctp addresses fit? */
index 399b60129b743d753f859d9e5b3a3d867d5a3ce0..52a7646cc7af5419f8e95dd1e16e41ae2904b3bb 100644 (file)
@@ -67,6 +67,7 @@ struct smb_vol {
        char *iocharset;  /* local code page for mapping to and from Unicode */
        char source_rfc1001_name[16]; /* netbios name of client */
        char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
+       uid_t cred_uid;
        uid_t linux_uid;
        gid_t linux_gid;
        mode_t file_mode;
@@ -832,7 +833,8 @@ cifs_parse_mount_options(char *options, const char *devname,
        /* null target name indicates to use *SMBSERVR default called name
           if we end up sending RFC1001 session initialize */
        vol->target_rfc1001_name[0] = 0;
-       vol->linux_uid = current_uid();  /* use current_euid() instead? */
+       vol->cred_uid = current_uid();
+       vol->linux_uid = current_uid();
        vol->linux_gid = current_gid();
 
        /* default to only allowing write access to owner of the mount */
@@ -1658,7 +1660,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
        list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
                switch (server->secType) {
                case Kerberos:
-                       if (vol->linux_uid != ses->linux_uid)
+                       if (vol->cred_uid != ses->cred_uid)
                                continue;
                        break;
                default:
@@ -1775,6 +1777,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
                if (ses->domainName)
                        strcpy(ses->domainName, volume_info->domainname);
        }
+       ses->cred_uid = volume_info->cred_uid;
        ses->linux_uid = volume_info->linux_uid;
        ses->overrideSecFlg = volume_info->secFlg;