r25309: Volker's fix for bug #4984 - samba4 torture test
authorJeremy Allison <jra@samba.org>
Mon, 24 Sep 2007 19:11:42 +0000 (19:11 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:58 +0000 (12:30 -0500)
to follow. Ensure we don't prepend "./" as a root
directory - this is an invalid pathname for unix_convert().
Jeremy.
(This used to be commit f70ac2e25847e41ecf54ae9d66e3247e1996b152)

source3/smbd/nttrans.c

index dce0d6188d91f669c3e8752a24937d1b20911d4c..e69fd86995dbb10c1b22cfbfc5cf098d6aa762c1 100644 (file)
@@ -586,7 +586,6 @@ void reply_ntcreate_and_X(connection_struct *conn,
                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 @@ void reply_ntcreate_and_X(connection_struct *conn,
                        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);
+
+                       /*
+                        * 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';
-                       dir_name_len++;
+                       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 @@ static void call_nt_transact_create(connection_struct *conn,
                 */
                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 @@ static void call_nt_transact_create(connection_struct *conn,
                        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);
+
+                       /*
+                        * 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';
-                       dir_name_len++;
+                       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,