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,
