aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-04-30 16:13:06 -0400
committerSteve French <sfrench@us.ibm.com>2007-04-30 16:13:06 -0400
commit4523cc3044d1bc7fcf3d7fee75d62bc76b8e1abb (patch)
tree31c2b6c0a81f14ec812d09586eb8ef5a586743cb /fs/cifs/connect.c
parent984acfe1cfb613257a15f30b3cf60ae7e4ed8f06 (diff)
[CIFS] UID/GID override on CIFS mounts to Samba
When CIFS Unix Extensions are negotiated we get the Unix uid and gid owners of the file from the server (on the Unix Query Path Info levels), but if the server's uids don't match the client uid's users were having to disable the Unix Extensions (which turned off features they still wanted). The changeset patch allows users to override uid and/or gid for file/directory owner with a default uid and/or gid specified at mount (as is often done when mounting from Linux cifs client to Windows server). This changeset also displays the uid and gid used by default in /proc/mounts (if applicable). Also cleans up code by adding some of the missing spaces after "if" keywords per-kernel style guidelines (as suggested by Randy Dunlap when he reviewed the patch). Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c79
1 files changed, 43 insertions, 36 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c1af1599568..1f4bc718170 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -75,6 +75,8 @@ struct smb_vol {
75 unsigned retry:1; 75 unsigned retry:1;
76 unsigned intr:1; 76 unsigned intr:1;
77 unsigned setuids:1; 77 unsigned setuids:1;
78 unsigned override_uid:1;
79 unsigned override_gid:1;
78 unsigned noperm:1; 80 unsigned noperm:1;
79 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ 81 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
80 unsigned cifs_acl:1; 82 unsigned cifs_acl:1;
@@ -972,7 +974,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
972 } 974 }
973 if ((temp_len = strnlen(value, 300)) < 300) { 975 if ((temp_len = strnlen(value, 300)) < 300) {
974 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 976 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
975 if(vol->UNC == NULL) 977 if (vol->UNC == NULL)
976 return 1; 978 return 1;
977 strcpy(vol->UNC,value); 979 strcpy(vol->UNC,value);
978 if (strncmp(vol->UNC, "//", 2) == 0) { 980 if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1009,12 +1011,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1009 return 1; /* needs_arg; */ 1011 return 1; /* needs_arg; */
1010 } 1012 }
1011 if ((temp_len = strnlen(value, 1024)) < 1024) { 1013 if ((temp_len = strnlen(value, 1024)) < 1024) {
1012 if(value[0] != '/') 1014 if (value[0] != '/')
1013 temp_len++; /* missing leading slash */ 1015 temp_len++; /* missing leading slash */
1014 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); 1016 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
1015 if(vol->prepath == NULL) 1017 if (vol->prepath == NULL)
1016 return 1; 1018 return 1;
1017 if(value[0] != '/') { 1019 if (value[0] != '/') {
1018 vol->prepath[0] = '/'; 1020 vol->prepath[0] = '/';
1019 strcpy(vol->prepath+1,value); 1021 strcpy(vol->prepath+1,value);
1020 } else 1022 } else
@@ -1030,7 +1032,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1030 return 1; /* needs_arg; */ 1032 return 1; /* needs_arg; */
1031 } 1033 }
1032 if (strnlen(value, 65) < 65) { 1034 if (strnlen(value, 65) < 65) {
1033 if(strnicmp(value,"default",7)) 1035 if (strnicmp(value,"default",7))
1034 vol->iocharset = value; 1036 vol->iocharset = value;
1035 /* if iocharset not set load_nls_default used by caller */ 1037 /* if iocharset not set load_nls_default used by caller */
1036 cFYI(1, ("iocharset set to %s",value)); 1038 cFYI(1, ("iocharset set to %s",value));
@@ -1042,11 +1044,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1042 if (value && *value) { 1044 if (value && *value) {
1043 vol->linux_uid = 1045 vol->linux_uid =
1044 simple_strtoul(value, &value, 0); 1046 simple_strtoul(value, &value, 0);
1047 vol->override_uid = 1;
1045 } 1048 }
1046 } else if (strnicmp(data, "gid", 3) == 0) { 1049 } else if (strnicmp(data, "gid", 3) == 0) {
1047 if (value && *value) { 1050 if (value && *value) {
1048 vol->linux_gid = 1051 vol->linux_gid =
1049 simple_strtoul(value, &value, 0); 1052 simple_strtoul(value, &value, 0);
1053 vol->override_gid = 1;
1050 } 1054 }
1051 } else if (strnicmp(data, "file_mode", 4) == 0) { 1055 } else if (strnicmp(data, "file_mode", 4) == 0) {
1052 if (value && *value) { 1056 if (value && *value) {
@@ -1101,7 +1105,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1101 } 1105 }
1102 /* The string has 16th byte zero still from 1106 /* The string has 16th byte zero still from
1103 set at top of the function */ 1107 set at top of the function */
1104 if((i==15) && (value[i] != 0)) 1108 if ((i==15) && (value[i] != 0))
1105 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); 1109 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1106 } 1110 }
1107 } else if (strnicmp(data, "servern", 7) == 0) { 1111 } else if (strnicmp(data, "servern", 7) == 0) {
@@ -1125,7 +1129,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1125 } 1129 }
1126 /* The string has 16th byte zero still from 1130 /* The string has 16th byte zero still from
1127 set at top of the function */ 1131 set at top of the function */
1128 if((i==15) && (value[i] != 0)) 1132 if ((i==15) && (value[i] != 0))
1129 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); 1133 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1130 } 1134 }
1131 } else if (strnicmp(data, "credentials", 4) == 0) { 1135 } else if (strnicmp(data, "credentials", 4) == 0) {
@@ -1232,13 +1236,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1232 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); 1236 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1233 } 1237 }
1234 if (vol->UNC == NULL) { 1238 if (vol->UNC == NULL) {
1235 if(devname == NULL) { 1239 if (devname == NULL) {
1236 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); 1240 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1237 return 1; 1241 return 1;
1238 } 1242 }
1239 if ((temp_len = strnlen(devname, 300)) < 300) { 1243 if ((temp_len = strnlen(devname, 300)) < 300) {
1240 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); 1244 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1241 if(vol->UNC == NULL) 1245 if (vol->UNC == NULL)
1242 return 1; 1246 return 1;
1243 strcpy(vol->UNC,devname); 1247 strcpy(vol->UNC,devname);
1244 if (strncmp(vol->UNC, "//", 2) == 0) { 1248 if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1813,7 +1817,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1813 if (srvTcp) { 1817 if (srvTcp) {
1814 cFYI(1, ("Existing tcp session with server found")); 1818 cFYI(1, ("Existing tcp session with server found"));
1815 } else { /* create socket */ 1819 } else { /* create socket */
1816 if(volume_info.port) 1820 if (volume_info.port)
1817 sin_server.sin_port = htons(volume_info.port); 1821 sin_server.sin_port = htons(volume_info.port);
1818 else 1822 else
1819 sin_server.sin_port = 0; 1823 sin_server.sin_port = 0;
@@ -1829,7 +1833,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1829 if (rc < 0) { 1833 if (rc < 0) {
1830 cERROR(1, 1834 cERROR(1,
1831 ("Error connecting to IPv4 socket. Aborting operation")); 1835 ("Error connecting to IPv4 socket. Aborting operation"));
1832 if(csocket != NULL) 1836 if (csocket != NULL)
1833 sock_release(csocket); 1837 sock_release(csocket);
1834 kfree(volume_info.UNC); 1838 kfree(volume_info.UNC);
1835 kfree(volume_info.password); 1839 kfree(volume_info.password);
@@ -1863,7 +1867,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1863 srvTcp->tcpStatus = CifsNew; 1867 srvTcp->tcpStatus = CifsNew;
1864 init_MUTEX(&srvTcp->tcpSem); 1868 init_MUTEX(&srvTcp->tcpSem);
1865 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); 1869 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1866 if( IS_ERR(srvTcp->tsk) ) { 1870 if ( IS_ERR(srvTcp->tsk) ) {
1867 rc = PTR_ERR(srvTcp->tsk); 1871 rc = PTR_ERR(srvTcp->tsk);
1868 cERROR(1,("error %d create cifsd thread", rc)); 1872 cERROR(1,("error %d create cifsd thread", rc));
1869 srvTcp->tsk = NULL; 1873 srvTcp->tsk = NULL;
@@ -1909,7 +1913,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1909 int len = strlen(volume_info.domainname); 1913 int len = strlen(volume_info.domainname);
1910 pSesInfo->domainName = 1914 pSesInfo->domainName =
1911 kmalloc(len + 1, GFP_KERNEL); 1915 kmalloc(len + 1, GFP_KERNEL);
1912 if(pSesInfo->domainName) 1916 if (pSesInfo->domainName)
1913 strcpy(pSesInfo->domainName, 1917 strcpy(pSesInfo->domainName,
1914 volume_info.domainname); 1918 volume_info.domainname);
1915 } 1919 }
@@ -1919,7 +1923,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1919 /* BB FIXME need to pass vol->secFlgs BB */ 1923 /* BB FIXME need to pass vol->secFlgs BB */
1920 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); 1924 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1921 up(&pSesInfo->sesSem); 1925 up(&pSesInfo->sesSem);
1922 if(!rc) 1926 if (!rc)
1923 atomic_inc(&srvTcp->socketUseCount); 1927 atomic_inc(&srvTcp->socketUseCount);
1924 } else 1928 } else
1925 kfree(volume_info.password); 1929 kfree(volume_info.password);
@@ -1927,7 +1931,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1927 1931
1928 /* search for existing tcon to this server share */ 1932 /* search for existing tcon to this server share */
1929 if (!rc) { 1933 if (!rc) {
1930 if(volume_info.rsize > CIFSMaxBufSize) { 1934 if (volume_info.rsize > CIFSMaxBufSize) {
1931 cERROR(1,("rsize %d too large, using MaxBufSize", 1935 cERROR(1,("rsize %d too large, using MaxBufSize",
1932 volume_info.rsize)); 1936 volume_info.rsize));
1933 cifs_sb->rsize = CIFSMaxBufSize; 1937 cifs_sb->rsize = CIFSMaxBufSize;
@@ -1936,11 +1940,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1936 else /* default */ 1940 else /* default */
1937 cifs_sb->rsize = CIFSMaxBufSize; 1941 cifs_sb->rsize = CIFSMaxBufSize;
1938 1942
1939 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 1943 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1940 cERROR(1,("wsize %d too large using 4096 instead", 1944 cERROR(1,("wsize %d too large using 4096 instead",
1941 volume_info.wsize)); 1945 volume_info.wsize));
1942 cifs_sb->wsize = 4096; 1946 cifs_sb->wsize = 4096;
1943 } else if(volume_info.wsize) 1947 } else if (volume_info.wsize)
1944 cifs_sb->wsize = volume_info.wsize; 1948 cifs_sb->wsize = volume_info.wsize;
1945 else 1949 else
1946 cifs_sb->wsize = 1950 cifs_sb->wsize =
@@ -1953,14 +1957,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1953 conjunction with 52K kvec constraint on arch with 4K 1957 conjunction with 52K kvec constraint on arch with 4K
1954 page size */ 1958 page size */
1955 1959
1956 if(cifs_sb->rsize < 2048) { 1960 if (cifs_sb->rsize < 2048) {
1957 cifs_sb->rsize = 2048; 1961 cifs_sb->rsize = 2048;
1958 /* Windows ME may prefer this */ 1962 /* Windows ME may prefer this */
1959 cFYI(1,("readsize set to minimum 2048")); 1963 cFYI(1,("readsize set to minimum 2048"));
1960 } 1964 }
1961 /* calculate prepath */ 1965 /* calculate prepath */
1962 cifs_sb->prepath = volume_info.prepath; 1966 cifs_sb->prepath = volume_info.prepath;
1963 if(cifs_sb->prepath) { 1967 if (cifs_sb->prepath) {
1964 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 1968 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1965 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); 1969 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1966 volume_info.prepath = NULL; 1970 volume_info.prepath = NULL;
@@ -1973,24 +1977,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1973 cFYI(1,("file mode: 0x%x dir mode: 0x%x", 1977 cFYI(1,("file mode: 0x%x dir mode: 0x%x",
1974 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); 1978 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1975 1979
1976 if(volume_info.noperm) 1980 if (volume_info.noperm)
1977 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 1981 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1978 if(volume_info.setuids) 1982 if (volume_info.setuids)
1979 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; 1983 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1980 if(volume_info.server_ino) 1984 if (volume_info.server_ino)
1981 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; 1985 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1982 if(volume_info.remap) 1986 if (volume_info.remap)
1983 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; 1987 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1984 if(volume_info.no_xattr) 1988 if (volume_info.no_xattr)
1985 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 1989 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1986 if(volume_info.sfu_emul) 1990 if (volume_info.sfu_emul)
1987 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 1991 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1988 if(volume_info.nobrl) 1992 if (volume_info.nobrl)
1989 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 1993 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1990 if(volume_info.cifs_acl) 1994 if (volume_info.cifs_acl)
1991 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 1995 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1992 1996 if (volume_info.override_uid)
1993 if(volume_info.direct_io) { 1997 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
1998 if (volume_info.override_gid)
1999 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2000 if (volume_info.direct_io) {
1994 cFYI(1,("mounting share using direct i/o")); 2001 cFYI(1,("mounting share using direct i/o"));
1995 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2002 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1996 } 2003 }
@@ -2043,7 +2050,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2043 } 2050 }
2044 } 2051 }
2045 } 2052 }
2046 if(pSesInfo) { 2053 if (pSesInfo) {
2047 if (pSesInfo->capabilities & CAP_LARGE_FILES) { 2054 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2048 sb->s_maxbytes = (u64) 1 << 63; 2055 sb->s_maxbytes = (u64) 1 << 63;
2049 } else 2056 } else
@@ -2057,11 +2064,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2057 if (rc) { 2064 if (rc) {
2058 /* if session setup failed, use count is zero but 2065 /* if session setup failed, use count is zero but
2059 we still need to free cifsd thread */ 2066 we still need to free cifsd thread */
2060 if(atomic_read(&srvTcp->socketUseCount) == 0) { 2067 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2061 spin_lock(&GlobalMid_Lock); 2068 spin_lock(&GlobalMid_Lock);
2062 srvTcp->tcpStatus = CifsExiting; 2069 srvTcp->tcpStatus = CifsExiting;
2063 spin_unlock(&GlobalMid_Lock); 2070 spin_unlock(&GlobalMid_Lock);
2064 if(srvTcp->tsk) { 2071 if (srvTcp->tsk) {
2065 send_sig(SIGKILL,srvTcp->tsk,1); 2072 send_sig(SIGKILL,srvTcp->tsk,1);
2066 kthread_stop(srvTcp->tsk); 2073 kthread_stop(srvTcp->tsk);
2067 } 2074 }
@@ -2076,7 +2083,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2076 int temp_rc; 2083 int temp_rc;
2077 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 2084 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2078 /* if the socketUseCount is now zero */ 2085 /* if the socketUseCount is now zero */
2079 if((temp_rc == -ESHUTDOWN) && 2086 if ((temp_rc == -ESHUTDOWN) &&
2080 (pSesInfo->server) && (pSesInfo->server->tsk)) { 2087 (pSesInfo->server) && (pSesInfo->server->tsk)) {
2081 send_sig(SIGKILL,pSesInfo->server->tsk,1); 2088 send_sig(SIGKILL,pSesInfo->server->tsk,1);
2082 kthread_stop(pSesInfo->server->tsk); 2089 kthread_stop(pSesInfo->server->tsk);
@@ -2140,7 +2147,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2140 __u16 count; 2147 __u16 count;
2141 2148
2142 cFYI(1, ("In sesssetup")); 2149 cFYI(1, ("In sesssetup"));
2143 if(ses == NULL) 2150 if (ses == NULL)
2144 return -EINVAL; 2151 return -EINVAL;
2145 user = ses->userName; 2152 user = ses->userName;
2146 domain = ses->domainName; 2153 domain = ses->domainName;
@@ -2195,7 +2202,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2195 *bcc_ptr = 0; 2202 *bcc_ptr = 0;
2196 bcc_ptr++; 2203 bcc_ptr++;
2197 } 2204 }
2198 if(user == NULL) 2205 if (user == NULL)
2199 bytes_returned = 0; /* skip null user */ 2206 bytes_returned = 0; /* skip null user */
2200 else 2207 else
2201 bytes_returned = 2208 bytes_returned =
@@ -2229,7 +2236,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2229 bcc_ptr += 2 * bytes_returned; 2236 bcc_ptr += 2 * bytes_returned;
2230 bcc_ptr += 2; 2237 bcc_ptr += 2;
2231 } else { 2238 } else {
2232 if(user != NULL) { 2239 if (user != NULL) {
2233 strncpy(bcc_ptr, user, 200); 2240 strncpy(bcc_ptr, user, 200);
2234 bcc_ptr += strnlen(user, 200); 2241 bcc_ptr += strnlen(user, 200);
2235 } 2242 }