svn commit: samba r25309 - in branches: SAMBA_3_0_MAINT/source/smbd SAMBA_3_2/source/smbd SAMBA_3_2_0/source/smbd

jra at samba.org jra at samba.org
Mon Sep 24 19:11:43 GMT 2007


Author: jra
Date: 2007-09-24 19:11:42 +0000 (Mon, 24 Sep 2007)
New Revision: 25309

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=25309

Log:
Volker's fix for bug #4984 - samba4 torture test
to follow. Ensure we don't prepend "./" as a root
directory - this is an invalid pathname for unix_convert().
Jeremy.

Modified:
   branches/SAMBA_3_0_MAINT/source/smbd/nttrans.c
   branches/SAMBA_3_2/source/smbd/nttrans.c
   branches/SAMBA_3_2_0/source/smbd/nttrans.c


Changeset:
Modified: branches/SAMBA_3_0_MAINT/source/smbd/nttrans.c
===================================================================
--- branches/SAMBA_3_0_MAINT/source/smbd/nttrans.c	2007-09-24 18:47:50 UTC (rev 25308)
+++ branches/SAMBA_3_0_MAINT/source/smbd/nttrans.c	2007-09-24 19:11:42 UTC (rev 25309)
@@ -543,7 +543,6 @@
 		 */
 		pstring rel_fname;
 		files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			END_PROFILE(SMBntcreateX);
@@ -583,15 +582,18 @@
 		 */
 
 		pstrcpy( fname, dir_fsp->fsp_name );
-		dir_name_len = strlen(fname);
 
-		/*
-		 * Ensure it ends in a '\'.
-		 */
+		if (ISDOT(fname)) {
+			fname[0] = '\0';
+		} else {
+			size_t dir_name_len = strlen(fname);
+			/*
+			 * Ensure it ends in a '\'.
+			 */
 
-		if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			pstrcat(fname, "/");
-			dir_name_len++;
+			if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
+				pstrcat(fname, "/");
+			}
 		}
 
 		srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
@@ -1244,7 +1246,6 @@
 		 * This filename is relative to a directory fid.
 		 */
 		files_struct *dir_fsp = file_fsp(params,4);
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			return ERROR_DOS(ERRDOS,ERRbadfid);
@@ -1272,15 +1273,18 @@
 		 */
 
 		pstrcpy( fname, dir_fsp->fsp_name );
-		dir_name_len = strlen(fname);
 
-		/*
-		 * Ensure it ends in a '\'.
-		 */
+                if (ISDOT(fname)) {
+			fname[0] = '\0';
+		} else {
+			size_t dir_name_len = strlen(fname);
+			/*
+			 * Ensure it ends in a '\'.
+			 */
 
-		if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			pstrcat(fname, "/");
-			dir_name_len++;
+			if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
+				pstrcat(fname, "/");
+			}
 		}
 
 		{

Modified: branches/SAMBA_3_2/source/smbd/nttrans.c
===================================================================
--- branches/SAMBA_3_2/source/smbd/nttrans.c	2007-09-24 18:47:50 UTC (rev 25308)
+++ branches/SAMBA_3_2/source/smbd/nttrans.c	2007-09-24 19:11:42 UTC (rev 25309)
@@ -586,7 +586,6 @@
 		char *rel_fname = NULL;
 		files_struct *dir_fsp = file_fsp(
 			SVAL(req->inbuf, smb_ntcreate_RootDirectoryFid));
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			reply_doserror(req, ERRDOS, ERRbadfid);
@@ -629,29 +628,46 @@
 			return;
 		}
 
-		/*
-		 * Copy in the base directory name.
-		 */
+		if (ISDOT(dir_fsp->fsp_name)) {
+			/*
+			 * We're at the toplevel dir, the final file name
+			 * must not contain ./, as this is filtered out
+			 * normally by srvstr_get_path and unix_convert
+			 * explicitly rejects paths containing ./.
+			 */
+			fname = talloc_strdup(ctx,"");
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				END_PROFILE(SMBntcreateX);
+				return;
+			}
+		} else {
+			size_t dir_name_len = strlen(dir_fsp->fsp_name);
 
-		dir_name_len = strlen(dir_fsp->fsp_name);
-		fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
-		if (!fname) {
-			reply_nterror(
-				req, NT_STATUS_NO_MEMORY);
-			END_PROFILE(SMBntcreateX);
-			return;
-		}
-		memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
+			/*
+			 * Copy in the base directory name.
+			 */
 
-		/*
-		 * Ensure it ends in a '/'.
-		 * We used TALLOC_SIZE +2 to add space for the '/'.
-		 */
+			fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
+			if (!fname) {
+				reply_nterror(
+					req, NT_STATUS_NO_MEMORY);
+				END_PROFILE(SMBntcreateX);
+				return;
+			}
+			memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
 
-		if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			fname[dir_name_len] = '/';
-			fname[dir_name_len+1] = '\0';
-			dir_name_len++;
+			/*
+			 * Ensure it ends in a '/'.
+			 * We used TALLOC_SIZE +2 to add space for the '/'.
+			 */
+
+			if(dir_name_len &&
+					(fname[dir_name_len-1] != '\\') &&
+					(fname[dir_name_len-1] != '/')) {
+				fname[dir_name_len] = '/';
+				fname[dir_name_len+1] = '\0';
+			}
 		}
 
 		srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &rel_fname,
@@ -1356,7 +1372,6 @@
 		 */
 		char *tmpname = NULL;
 		files_struct *dir_fsp = file_fsp(SVAL(params,4));
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			reply_doserror(req, ERRDOS, ERRbadfid);
@@ -1387,28 +1402,43 @@
 			return;
 		}
 
-		/*
-		 * Copy in the base directory name.
-		 */
+		if (ISDOT(dir_fsp->fsp_name)) {
+			/*
+			 * We're at the toplevel dir, the final file name
+			 * must not contain ./, as this is filtered out
+			 * normally by srvstr_get_path and unix_convert
+			 * explicitly rejects paths containing ./.
+			 */
+			fname = talloc_strdup(ctx,"");
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+		} else {
+			size_t dir_name_len = strlen(dir_fsp->fsp_name);
 
-		dir_name_len = strlen(dir_fsp->fsp_name);
-		fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
-		if (!fname) {
-			reply_nterror(
-				req, NT_STATUS_NO_MEMORY);
-			return;
-		}
-		memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
+			/*
+			 * Copy in the base directory name.
+			 */
 
-		/*
-		 * Ensure it ends in a '/'.
-		 * We used TALLOC_SIZE +2 to add space for the '/'.
-		 */
+			fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+			memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
 
-		if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			fname[dir_name_len] = '/';
-			fname[dir_name_len+1] = '\0';
-			dir_name_len++;
+			/*
+			 * Ensure it ends in a '/'.
+			 * We used TALLOC_SIZE +2 to add space for the '/'.
+			 */
+
+			if(dir_name_len &&
+					(fname[dir_name_len-1] != '\\') &&
+					(fname[dir_name_len-1] != '/')) {
+				fname[dir_name_len] = '/';
+				fname[dir_name_len+1] = '\0';
+			}
 		}
 
 		srvstr_get_path(ctx, params, req->flags2, &tmpname,

Modified: branches/SAMBA_3_2_0/source/smbd/nttrans.c
===================================================================
--- branches/SAMBA_3_2_0/source/smbd/nttrans.c	2007-09-24 18:47:50 UTC (rev 25308)
+++ branches/SAMBA_3_2_0/source/smbd/nttrans.c	2007-09-24 19:11:42 UTC (rev 25309)
@@ -586,7 +586,6 @@
 		char *rel_fname = NULL;
 		files_struct *dir_fsp = file_fsp(
 			SVAL(req->inbuf, smb_ntcreate_RootDirectoryFid));
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			reply_doserror(req, ERRDOS, ERRbadfid);
@@ -629,29 +628,46 @@
 			return;
 		}
 
-		/*
-		 * Copy in the base directory name.
-		 */
+		if (ISDOT(dir_fsp->fsp_name)) {
+			/*
+			 * We're at the toplevel dir, the final file name
+			 * must not contain ./, as this is filtered out
+			 * normally by srvstr_get_path and unix_convert
+			 * explicitly rejects paths containing ./.
+			 */
+			fname = talloc_strdup(ctx,"");
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				END_PROFILE(SMBntcreateX);
+				return;
+			}
+		} else {
+			size_t dir_name_len = strlen(dir_fsp->fsp_name);
 
-		dir_name_len = strlen(dir_fsp->fsp_name);
-		fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
-		if (!fname) {
-			reply_nterror(
-				req, NT_STATUS_NO_MEMORY);
-			END_PROFILE(SMBntcreateX);
-			return;
-		}
-		memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
+			/*
+			 * Copy in the base directory name.
+			 */
 
-		/*
-		 * Ensure it ends in a '/'.
-		 * We used TALLOC_SIZE +2 to add space for the '/'.
-		 */
+			fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
+			if (!fname) {
+				reply_nterror(
+					req, NT_STATUS_NO_MEMORY);
+				END_PROFILE(SMBntcreateX);
+				return;
+			}
+			memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
 
-		if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			fname[dir_name_len] = '/';
-			fname[dir_name_len+1] = '\0';
-			dir_name_len++;
+			/*
+			 * Ensure it ends in a '/'.
+			 * We used TALLOC_SIZE +2 to add space for the '/'.
+			 */
+
+			if(dir_name_len &&
+					(fname[dir_name_len-1] != '\\') &&
+					(fname[dir_name_len-1] != '/')) {
+				fname[dir_name_len] = '/';
+				fname[dir_name_len+1] = '\0';
+			}
 		}
 
 		srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &rel_fname,
@@ -1356,7 +1372,6 @@
 		 */
 		char *tmpname = NULL;
 		files_struct *dir_fsp = file_fsp(SVAL(params,4));
-		size_t dir_name_len;
 
 		if(!dir_fsp) {
 			reply_doserror(req, ERRDOS, ERRbadfid);
@@ -1387,28 +1402,43 @@
 			return;
 		}
 
-		/*
-		 * Copy in the base directory name.
-		 */
+		if (ISDOT(dir_fsp->fsp_name)) {
+			/*
+			 * We're at the toplevel dir, the final file name
+			 * must not contain ./, as this is filtered out
+			 * normally by srvstr_get_path and unix_convert
+			 * explicitly rejects paths containing ./.
+			 */
+			fname = talloc_strdup(ctx,"");
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+		} else {
+			size_t dir_name_len = strlen(dir_fsp->fsp_name);
 
-		dir_name_len = strlen(dir_fsp->fsp_name);
-		fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
-		if (!fname) {
-			reply_nterror(
-				req, NT_STATUS_NO_MEMORY);
-			return;
-		}
-		memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
+			/*
+			 * Copy in the base directory name.
+			 */
 
-		/*
-		 * Ensure it ends in a '/'.
-		 * We used TALLOC_SIZE +2 to add space for the '/'.
-		 */
+			fname = TALLOC_ARRAY(ctx, char, dir_name_len+2);
+			if (!fname) {
+				reply_nterror(req, NT_STATUS_NO_MEMORY);
+				return;
+			}
+			memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
 
-		if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-			fname[dir_name_len] = '/';
-			fname[dir_name_len+1] = '\0';
-			dir_name_len++;
+			/*
+			 * Ensure it ends in a '/'.
+			 * We used TALLOC_SIZE +2 to add space for the '/'.
+			 */
+
+			if(dir_name_len &&
+					(fname[dir_name_len-1] != '\\') &&
+					(fname[dir_name_len-1] != '/')) {
+				fname[dir_name_len] = '/';
+				fname[dir_name_len+1] = '\0';
+			}
 		}
 
 		srvstr_get_path(ctx, params, req->flags2, &tmpname,



More information about the samba-cvs mailing list