[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>
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c1af159..1f4bc71 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -75,6 +75,8 @@
 	unsigned retry:1;
 	unsigned intr:1;
 	unsigned setuids:1;
+	unsigned override_uid:1;
+	unsigned override_gid:1;
 	unsigned noperm:1;
 	unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
 	unsigned cifs_acl:1;
@@ -972,7 +974,7 @@
 			}
 			if ((temp_len = strnlen(value, 300)) < 300) {
 				vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
-				if(vol->UNC == NULL)
+				if (vol->UNC == NULL)
 					return 1;
 				strcpy(vol->UNC,value);
 				if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1009,12 +1011,12 @@
                                 return 1;       /* needs_arg; */
                         }
                         if ((temp_len = strnlen(value, 1024)) < 1024) {
-				if(value[0] != '/')
+				if (value[0] != '/')
 					temp_len++;  /* missing leading slash */
                                 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
-                                if(vol->prepath == NULL)
+                                if (vol->prepath == NULL)
                                         return 1;
-				if(value[0] != '/') {
+				if (value[0] != '/') {
 					vol->prepath[0] = '/';
 	                                strcpy(vol->prepath+1,value);
 				} else
@@ -1030,7 +1032,7 @@
 				return 1;	/* needs_arg; */
 			}
 			if (strnlen(value, 65) < 65) {
-				if(strnicmp(value,"default",7))
+				if (strnicmp(value,"default",7))
 					vol->iocharset = value;
 				/* if iocharset not set load_nls_default used by caller */
 				cFYI(1, ("iocharset set to %s",value));
@@ -1042,11 +1044,13 @@
 			if (value && *value) {
 				vol->linux_uid =
 					simple_strtoul(value, &value, 0);
+				vol->override_uid = 1;
 			}
 		} else if (strnicmp(data, "gid", 3) == 0) {
 			if (value && *value) {
 				vol->linux_gid =
 					simple_strtoul(value, &value, 0);
+				vol->override_gid = 1;
 			}
 		} else if (strnicmp(data, "file_mode", 4) == 0) {
 			if (value && *value) {
@@ -1101,7 +1105,7 @@
 				}
 				/* The string has 16th byte zero still from
 				set at top of the function  */
-				if((i==15) && (value[i] != 0))
+				if ((i==15) && (value[i] != 0))
 					printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
 			}
 		} else if (strnicmp(data, "servern", 7) == 0) {
@@ -1125,7 +1129,7 @@
 				}
 				/* The string has 16th byte zero still from
 				   set at top of the function  */
-				if((i==15) && (value[i] != 0))
+				if ((i==15) && (value[i] != 0))
 					printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
 			}
 		} else if (strnicmp(data, "credentials", 4) == 0) {
@@ -1232,13 +1236,13 @@
 			printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
 	}
 	if (vol->UNC == NULL) {
-		if(devname == NULL) {
+		if (devname == NULL) {
 			printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
 			return 1;
 		}
 		if ((temp_len = strnlen(devname, 300)) < 300) {
 			vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
-			if(vol->UNC == NULL)
+			if (vol->UNC == NULL)
 				return 1;
 			strcpy(vol->UNC,devname);
 			if (strncmp(vol->UNC, "//", 2) == 0) {
@@ -1813,7 +1817,7 @@
 	if (srvTcp) {
 		cFYI(1, ("Existing tcp session with server found"));                
 	} else {	/* create socket */
-		if(volume_info.port)
+		if (volume_info.port)
 			sin_server.sin_port = htons(volume_info.port);
 		else
 			sin_server.sin_port = 0;
@@ -1829,7 +1833,7 @@
 		if (rc < 0) {
 			cERROR(1,
 			       ("Error connecting to IPv4 socket. Aborting operation"));			       
-			if(csocket != NULL)
+			if (csocket != NULL)
 				sock_release(csocket);
 			kfree(volume_info.UNC);
 			kfree(volume_info.password);
@@ -1863,7 +1867,7 @@
 			srvTcp->tcpStatus = CifsNew;
 			init_MUTEX(&srvTcp->tcpSem);
 			srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
-			if( IS_ERR(srvTcp->tsk) ) {
+			if ( IS_ERR(srvTcp->tsk) ) {
 				rc = PTR_ERR(srvTcp->tsk);
 				cERROR(1,("error %d create cifsd thread", rc));
 				srvTcp->tsk = NULL;
@@ -1909,7 +1913,7 @@
 				int len = strlen(volume_info.domainname);
 				pSesInfo->domainName = 
 					kmalloc(len + 1, GFP_KERNEL);
-				if(pSesInfo->domainName)
+				if (pSesInfo->domainName)
 					strcpy(pSesInfo->domainName,
 						volume_info.domainname);
 			}
@@ -1919,7 +1923,7 @@
 			/* BB FIXME need to pass vol->secFlgs BB */
 			rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
 			up(&pSesInfo->sesSem);
-			if(!rc)
+			if (!rc)
 				atomic_inc(&srvTcp->socketUseCount);
 		} else
 			kfree(volume_info.password);
@@ -1927,7 +1931,7 @@
     
 	/* search for existing tcon to this server share */
 	if (!rc) {
-		if(volume_info.rsize > CIFSMaxBufSize) {
+		if (volume_info.rsize > CIFSMaxBufSize) {
 			cERROR(1,("rsize %d too large, using MaxBufSize",
 				volume_info.rsize));
 			cifs_sb->rsize = CIFSMaxBufSize;
@@ -1936,11 +1940,11 @@
 		else /* default */
 			cifs_sb->rsize = CIFSMaxBufSize;
 
-		if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
+		if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
 			cERROR(1,("wsize %d too large using 4096 instead",
 				  volume_info.wsize));
 			cifs_sb->wsize = 4096;
-		} else if(volume_info.wsize)
+		} else if (volume_info.wsize)
 			cifs_sb->wsize = volume_info.wsize;
 		else
 			cifs_sb->wsize = 
@@ -1953,14 +1957,14 @@
 			   conjunction with 52K kvec constraint on arch with 4K
 			   page size  */
 
-		if(cifs_sb->rsize < 2048) {
+		if (cifs_sb->rsize < 2048) {
 			cifs_sb->rsize = 2048; 
 			/* Windows ME may prefer this */
 			cFYI(1,("readsize set to minimum 2048"));
 		}
 		/* calculate prepath */
 		cifs_sb->prepath = volume_info.prepath;
-		if(cifs_sb->prepath) {
+		if (cifs_sb->prepath) {
 			cifs_sb->prepathlen = strlen(cifs_sb->prepath);
 			cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
 			volume_info.prepath = NULL;
@@ -1973,24 +1977,27 @@
 		cFYI(1,("file mode: 0x%x  dir mode: 0x%x",
 			cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
 
-		if(volume_info.noperm)
+		if (volume_info.noperm)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
-		if(volume_info.setuids)
+		if (volume_info.setuids)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
-		if(volume_info.server_ino)
+		if (volume_info.server_ino)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
-		if(volume_info.remap)
+		if (volume_info.remap)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
-		if(volume_info.no_xattr)
+		if (volume_info.no_xattr)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
-		if(volume_info.sfu_emul)
+		if (volume_info.sfu_emul)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
-		if(volume_info.nobrl)
+		if (volume_info.nobrl)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
-		if(volume_info.cifs_acl)
+		if (volume_info.cifs_acl)
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
-
-		if(volume_info.direct_io) {
+		if (volume_info.override_uid)
+			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
+		if (volume_info.override_gid)
+			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
+		if (volume_info.direct_io) {
 			cFYI(1,("mounting share using direct i/o"));
 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
 		}
@@ -2043,7 +2050,7 @@
 			}
 		}
 	}
-	if(pSesInfo) {
+	if (pSesInfo) {
 		if (pSesInfo->capabilities & CAP_LARGE_FILES) {
 			sb->s_maxbytes = (u64) 1 << 63;
 		} else
@@ -2057,11 +2064,11 @@
 	if (rc) {
 		/* if session setup failed, use count is zero but
 		we still need to free cifsd thread */
-		if(atomic_read(&srvTcp->socketUseCount) == 0) {
+		if (atomic_read(&srvTcp->socketUseCount) == 0) {
 			spin_lock(&GlobalMid_Lock);
 			srvTcp->tcpStatus = CifsExiting;
 			spin_unlock(&GlobalMid_Lock);
-			if(srvTcp->tsk) {
+			if (srvTcp->tsk) {
 				send_sig(SIGKILL,srvTcp->tsk,1);
 				kthread_stop(srvTcp->tsk);
 			}
@@ -2076,7 +2083,7 @@
 					int temp_rc;
 					temp_rc = CIFSSMBLogoff(xid, pSesInfo);
 					/* if the socketUseCount is now zero */
-					if((temp_rc == -ESHUTDOWN) &&
+					if ((temp_rc == -ESHUTDOWN) &&
 					   (pSesInfo->server) && (pSesInfo->server->tsk)) {
 						send_sig(SIGKILL,pSesInfo->server->tsk,1);
 						kthread_stop(pSesInfo->server->tsk);
@@ -2140,7 +2147,7 @@
 	__u16 count;
 
 	cFYI(1, ("In sesssetup"));
-	if(ses == NULL)
+	if (ses == NULL)
 		return -EINVAL;
 	user = ses->userName;
 	domain = ses->domainName;
@@ -2195,7 +2202,7 @@
 			*bcc_ptr = 0;
 			bcc_ptr++;
 		}
-		if(user == NULL)
+		if (user == NULL)
 			bytes_returned = 0; /* skip null user */
 	        else
 			bytes_returned =
@@ -2229,7 +2236,7 @@
 		bcc_ptr += 2 * bytes_returned;
 		bcc_ptr += 2;
 	} else {
-		if(user != NULL) {                
+		if (user != NULL) {                
 		    strncpy(bcc_ptr, user, 200);
 		    bcc_ptr += strnlen(user, 200);
 		}