summaryrefslogtreecommitdiff
path: root/source3/smbd/trans2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/trans2.c')
-rw-r--r--source3/smbd/trans2.c329
1 files changed, 173 insertions, 156 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 8e03094aef..63dcb06f5d 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
SMB transaction2 handling
Copyright (C) Jeremy Allison 1994-2007
@@ -13,12 +13,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -211,7 +211,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str
if (strnequal(p, "system.", 7) || samba_private_attr_name(p))
continue;
-
+
listp = TALLOC_P(mem_ctx, struct ea_list);
if (!listp)
return NULL;
@@ -1008,7 +1008,9 @@ static void call_trans2open(connection_struct *conn,
Case can be significant or not.
**********************************************************/
-static BOOL exact_match(connection_struct *conn, char *str, char *mask)
+static BOOL exact_match(connection_struct *conn,
+ const char *str,
+ const char *mask)
{
if (mask[0] == '.' && mask[1] == 0)
return False;
@@ -1134,21 +1136,29 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
Get a level dependent lanman2 dir entry.
****************************************************************************/
-static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
- char *path_mask,uint32 dirtype,int info_level,
- int requires_resume_key,
- BOOL dont_descend,char **ppdata,
- char *base_data, char *end_data,
- int space_remaining,
- BOOL *out_of_space, BOOL *got_exact_match,
- int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
+static BOOL get_lanman2_dir_entry(TALLOC_CTX *ctx,
+ connection_struct *conn,
+ uint16 flags2,
+ const char *path_mask,
+ uint32 dirtype,
+ int info_level,
+ int requires_resume_key,
+ BOOL dont_descend,
+ char **ppdata,
+ char *base_data,
+ char *end_data,
+ int space_remaining,
+ BOOL *out_of_space,
+ BOOL *got_exact_match,
+ int *last_entry_off,
+ struct ea_list *name_list)
{
const char *dname;
BOOL found = False;
SMB_STRUCT_STAT sbuf;
- pstring mask;
- pstring pathreal;
- pstring fname;
+ const char *mask = NULL;
+ char *pathreal = NULL;
+ const char *fname = NULL;
char *p, *q, *pdata = *ppdata;
uint32 reskey=0;
long prev_dirpos=0;
@@ -1166,7 +1176,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
BOOL check_mangled_names = lp_manglednames(conn->params);
char mangled_name[13]; /* mangled 8.3 name. */
- *fname = 0;
*out_of_space = False;
*got_exact_match = False;
@@ -1174,18 +1183,20 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
ZERO_STRUCT(adate_ts);
ZERO_STRUCT(create_date_ts);
- if (!conn->dirptr)
+ if (!conn->dirptr) {
return(False);
+ }
p = strrchr_m(path_mask,'/');
if(p != NULL) {
- if(p[1] == '\0')
- pstrcpy(mask,"*.*");
- else
- pstrcpy(mask, p+1);
- } else
- pstrcpy(mask, path_mask);
-
+ if(p[1] == '\0') {
+ mask = talloc_strdup(ctx,"*.*");
+ } else {
+ mask = p+1;
+ }
+ } else {
+ mask = path_mask;
+ }
while (!found) {
BOOL got_match;
@@ -1193,7 +1204,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
/* Needed if we run out of space */
long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
- dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
+ dname = dptr_ReadDirName(ctx,conn->dirptr,&curr_dirpos,&sbuf);
/*
* Due to bugs in NT client redirectors we are not using
@@ -1206,7 +1217,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n",
(long)conn->dirptr,curr_dirpos));
-
+
if (!dname) {
return(False);
}
@@ -1217,14 +1228,15 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
* pathreal which is composed from dname.
*/
- pstrcpy(fname,dname);
+ pathreal = NULL;
+ fname = dname;
/* Mangle fname if it's an illegal name. */
- if (mangle_must_mangle(fname,conn->params)) {
- if (!name_to_8_3(fname,mangled_name,True,conn->params)) {
+ if (mangle_must_mangle(dname,conn->params)) {
+ if (!name_to_8_3(dname,mangled_name,True,conn->params)) {
continue; /* Error - couldn't mangle. */
}
- pstrcpy(fname,mangled_name);
+ fname = mangled_name;
}
if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) {
@@ -1250,21 +1262,34 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
}
if (got_match) {
- BOOL isdots = (strequal(dname,"..") || strequal(dname,"."));
+ BOOL isdots = (ISDOT(dname) || ISDOTDOT(dname));
+
if (dont_descend && !isdots) {
continue;
}
-
- pstrcpy(pathreal,conn->dirpath);
- if(needslash) {
- pstrcat(pathreal,"/");
+
+ if (needslash) {
+ pathreal = NULL;
+ pathreal = talloc_asprintf(ctx,
+ "%s/%s",
+ conn->dirpath,
+ dname);
+ } else {
+ pathreal = talloc_asprintf(ctx,
+ "%s%s",
+ conn->dirpath,
+ dname);
+ }
+
+ if (!pathreal) {
+ return False;
}
- pstrcat(pathreal,dname);
if (INFO_LEVEL_IS_UNIX(info_level)) {
if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
+ TALLOC_FREE(pathreal);
continue;
}
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
@@ -1283,6 +1308,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
pathreal,strerror(errno)));
+ TALLOC_FREE(pathreal);
continue;
}
}
@@ -1295,6 +1321,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
if (!dir_check_ftype(conn,mode,dirtype)) {
DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype));
+ TALLOC_FREE(pathreal);
continue;
}
@@ -1316,9 +1343,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
create_date = convert_timespec_to_time_t(create_date_ts);
mdate = convert_timespec_to_time_t(mdate_ts);
adate = convert_timespec_to_time_t(adate_ts);
-
+
DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",pathreal,fname));
-
+
found = True;
dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos);
@@ -1425,7 +1452,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
SSVAL(p,20,mode);
p += 22; /* p now points to the EA area. */
- file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
+ file_list = get_ea_list_from_file(ctx, conn, NULL, pathreal, &ea_len);
name_list = ea_list_union(name_list, file_list, &ea_len);
/* We need to determine if this entry will fit in the space available. */
@@ -1439,7 +1466,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
}
/* Push the ea_data followed by the name. */
- p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
+ p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
nameptr = p;
len = srvstr_push(base_data, flags2,
p + 1, fname, PTR_DIFF(end_data, p),
@@ -1537,7 +1564,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
SIVAL(pdata,0,len);
p = pdata + len;
break;
-
+
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
p += 4;
@@ -1713,7 +1740,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2,
break;
- default:
+ default:
return(False);
}
@@ -1760,7 +1787,7 @@ static void call_trans2findfirst(connection_struct *conn,
BOOL requires_resume_key;
int info_level;
char *directory = NULL;
- pstring mask;
+ const char *mask = NULL;
char *p;
int last_entry_off=0;
int dptr_num = -1;
@@ -1772,7 +1799,6 @@ static void call_trans2findfirst(connection_struct *conn,
int space_remaining;
BOOL mask_contains_wcard = False;
SMB_STRUCT_STAT sbuf;
- TALLOC_CTX *ea_ctx = NULL;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
@@ -1790,8 +1816,6 @@ static void call_trans2findfirst(connection_struct *conn,
requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
info_level = SVAL(params,6);
- *mask = 0;
-
DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
(unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
@@ -1864,10 +1888,10 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
if(p == NULL) {
/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
if((directory[0] == '.') && (directory[1] == '\0')) {
- pstrcpy(mask,"*");
+ mask = "*";
mask_contains_wcard = True;
} else {
- pstrcpy(mask,directory);
+ mask = directory;
}
directory = talloc_strdup(talloc_tos(), "./");
if (!directory) {
@@ -1875,7 +1899,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return;
}
} else {
- pstrcpy(mask,p+1);
+ mask = p+1;
*p = 0;
}
@@ -1901,16 +1925,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
reply_doserror(req, ERRDOS, ERReasnotsupported);
return;
}
-
- if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
/* Pull out the list of names. */
- ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -1919,7 +1937,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL ) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1929,7 +1946,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* Realloc the params space */
*pparams = (char *)SMB_REALLOC(*pparams, 10);
if (*pparams == NULL) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1949,7 +1965,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
&conn->dirptr);
if (!NT_STATUS_IS_OK(ntstatus)) {
- talloc_destroy(ea_ctx);
reply_nterror(req, ntstatus);
return;
}
@@ -1957,13 +1972,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
dptr_num = dptr_dnum(conn->dirptr);
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
- /* We don't need to check for VOL here as this is returned by
+ /* We don't need to check for VOL here as this is returned by
a different TRANS2 call. */
-
+
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
dont_descend = True;
-
+
p = pdata;
space_remaining = max_data_bytes;
out_of_space = False;
@@ -1977,14 +1992,19 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
out_of_space = True;
finished = False;
} else {
- finished = !get_lanman2_dir_entry(conn,
+ TALLOC_CTX *sub_ctx = talloc_stackframe();
+
+ finished = !get_lanman2_dir_entry(sub_ctx,
+ conn,
req->flags2,
mask,dirtype,info_level,
requires_resume_key,dont_descend,
&p,pdata,data_end,
space_remaining, &out_of_space,
&got_exact_match,
- &last_entry_off, ea_list, ea_ctx);
+ &last_entry_off, ea_list);
+
+ TALLOC_FREE(sub_ctx);
}
if (finished && out_of_space)
@@ -2005,8 +2025,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
}
-
- talloc_destroy(ea_ctx);
/* Check if we can close the dirptr */
if(close_after_first || (finished && close_if_end)) {
@@ -2014,8 +2032,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
dptr_close(&dptr_num);
}
- /*
- * If there are no matching entries we must return ERRDOS/ERRbadfile -
+ /*
+ * If there are no matching entries we must return ERRDOS/ERRbadfile -
* from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
* the protocol level is less than NT1. Tested with smbclient. JRA.
* This should fix the OS/2 client bug #2335.
@@ -2101,9 +2119,9 @@ static void call_trans2findnext(connection_struct *conn,
BOOL continue_bit;
BOOL mask_contains_wcard = False;
char *resume_name = NULL;
- pstring mask;
- pstring directory;
- char *p;
+ const char *mask = NULL;
+ const char *directory = NULL;
+ char *p = NULL;
uint16 dirtype;
int numentries = 0;
int i, last_entry_off=0;
@@ -2111,7 +2129,6 @@ static void call_trans2findnext(connection_struct *conn,
BOOL dont_descend = False;
BOOL out_of_space = False;
int space_remaining;
- TALLOC_CTX *ea_ctx = NULL;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
@@ -2131,8 +2148,6 @@ static void call_trans2findnext(connection_struct *conn,
requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
- *mask = *directory = 0;
-
srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
params+12,
total_params - 12, STR_TERMINATE, &ntstatus,
@@ -2202,21 +2217,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
-
+
if (!lp_ea_support(SNUM(conn))) {
reply_doserror(req, ERRDOS, ERReasnotsupported);
return;
}
-
- if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
/* Pull out the list of names. */
- ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -2225,7 +2234,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -2236,7 +2244,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* Realloc the params space */
*pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
if(*pparams == NULL ) {
- talloc_destroy(ea_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -2245,7 +2252,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* Check that the dptr is valid */
if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
- talloc_destroy(ea_ctx);
reply_doserror(req, ERRDOS, ERRnofiles);
return;
}
@@ -2255,34 +2261,33 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* Get the wildcard mask from the dptr */
if((p = dptr_wcard(dptr_num))== NULL) {
DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
- talloc_destroy(ea_ctx);
reply_doserror(req, ERRDOS, ERRnofiles);
return;
}
- pstrcpy(mask, p);
- pstrcpy(directory,conn->dirpath);
+ mask = p;
+ directory = conn->dirpath;
/* Get the attr mask from the dptr */
dirtype = dptr_attr(dptr_num);
DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n",
- dptr_num, mask, dirtype,
+ dptr_num, mask, dirtype,
(long)conn->dirptr,
dptr_TellDir(conn->dirptr)));
- /* We don't need to check for VOL here as this is returned by
+ /* We don't need to check for VOL here as this is returned by
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive))
dont_descend = True;
-
+
p = pdata;
space_remaining = max_data_bytes;
out_of_space = False;
- /*
+ /*
* Seek to the correct position. We no longer use the resume key but
* depend on the last file name instead.
*/
@@ -2299,12 +2304,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (mangle_is_mangled(resume_name, conn->params)) {
char *new_resume_name = NULL;
- mangle_lookup_name_from_8_3(talloc_tos(),
+ mangle_lookup_name_from_8_3(ctx,
resume_name,
&new_resume_name,
conn->params);
if (new_resume_name) {
- pstrcpy(resume_name, new_resume_name);
+ resume_name = new_resume_name;
}
}
@@ -2329,14 +2334,19 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
out_of_space = True;
finished = False;
} else {
- finished = !get_lanman2_dir_entry(conn,
+ TALLOC_CTX *sub_ctx = talloc_stackframe();
+
+ finished = !get_lanman2_dir_entry(sub_ctx,
+ conn,
req->flags2,
mask,dirtype,info_level,
requires_resume_key,dont_descend,
&p,pdata,data_end,
space_remaining, &out_of_space,
&got_exact_match,
- &last_entry_off, ea_list, ea_ctx);
+ &last_entry_off, ea_list);
+
+ TALLOC_FREE(sub_ctx);
}
if (finished && out_of_space)
@@ -2357,8 +2367,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
}
-
- talloc_destroy(ea_ctx);
+
+ DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
+ smb_fn_name(CVAL(req->inbuf,smb_com)),
+ mask, directory, dirtype, numentries ) );
/* Check if we can close the dirptr */
if(close_after_request || (finished && close_if_end)) {
@@ -2375,13 +2387,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
send_trans2_replies(req, params, 8, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
- if ((! *directory) && dptr_path(dptr_num))
- slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
-
- DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)),
- mask, directory, dirtype, numentries ) );
-
return;
}
@@ -3511,7 +3516,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
unsigned int data_size = 0;
unsigned int param_size = 2;
SMB_STRUCT_STAT sbuf;
- pstring dos_fname;
+ char *dos_fname = NULL;
char *fname = NULL;
char *fullpathname;
char *base_name;
@@ -3523,7 +3528,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
struct timespec create_time_ts, mtime_ts, atime_ts;
files_struct *fsp = NULL;
struct file_id fileid;
- TALLOC_CTX *data_ctx = NULL;
struct ea_list *ea_list = NULL;
uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
char *lock_data = NULL;
@@ -3712,7 +3716,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
- p = strrchr_m(fname,'/');
+ p = strrchr_m(fname,'/');
if (!p)
base_name = fname;
else
@@ -3754,15 +3758,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- if ((data_ctx = talloc_init("ea_list")) == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
/* Pull out the list of names. */
- ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
+ ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
- talloc_destroy(data_ctx);
reply_nterror(
req, NT_STATUS_INVALID_PARAMETER);
return;
@@ -3783,16 +3781,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- if ((data_ctx = talloc_init("lock_request")) == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
/* Copy the lock range data. */
lock_data = (char *)TALLOC_MEMDUP(
- data_ctx, pdata, total_data);
+ ctx, pdata, total_data);
if (!lock_data) {
- talloc_destroy(data_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -3803,7 +3795,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*pparams = (char *)SMB_REALLOC(*pparams,2);
if (*pparams == NULL) {
- talloc_destroy(data_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -3812,7 +3803,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL ) {
- talloc_destroy(data_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -3857,10 +3847,20 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* NT expects the name to be in an exact form of the *full*
filename. See the trans2 torture test */
- if (strequal(base_name,".")) {
- pstrcpy(dos_fname, "\\");
+ if (ISDOT(base_name)) {
+ dos_fname = talloc_strdup(ctx, "\\");
+ if (!dos_fname) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
} else {
- pstr_sprintf(dos_fname, "\\%s", fname);
+ dos_fname = talloc_asprintf(ctx,
+ "\\%s",
+ fname);
+ if (!dos_fname) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
string_replace(dos_fname, '/', '\\');
}
@@ -3894,14 +3894,14 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_INFO_IS_NAME_VALID:
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
if (tran_call == TRANSACT2_QFILEINFO) {
- /* os/2 needs this ? really ?*/
+ /* os/2 needs this ? really ?*/
reply_doserror(req, ERRDOS, ERRbadfunc);
return;
}
data_size = 0;
param_size = 0;
break;
-
+
case SMB_INFO_QUERY_EAS_FROM_LIST:
{
size_t total_ea_len = 0;
@@ -3909,18 +3909,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
+ ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
- talloc_destroy(data_ctx);
data_size = 4;
SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
break;
}
- data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
- talloc_destroy(data_ctx);
+ data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
break;
}
@@ -3931,22 +3929,14 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
- data_ctx = talloc_init("ea_ctx");
- if (!data_ctx) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
- ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
+ ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
- talloc_destroy(data_ctx);
data_size = 4;
SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
break;
}
- data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list);
- talloc_destroy(data_ctx);
+ data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
break;
}
@@ -4219,7 +4209,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_UNIX_LINK:
{
- pstring buffer;
+ char *buffer = TALLOC_SIZE(ctx, 1024);
+
+ if (!buffer) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
@@ -4232,7 +4227,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
reply_unixerror(req, ERRDOS, ERRbadlink);
return;
#endif
- len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
+ len = SMB_VFS_READLINK(conn,fullpathname,
+ buffer, 1023);
if (len == -1) {
reply_unixerror(req, ERRDOS,
ERRnoaccess);
@@ -4364,7 +4360,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case POSIX_LOCK_TYPE_UNLOCK:
default:
/* There's no point in asking for an unlock... */
- talloc_destroy(data_ctx);
reply_nterror(
req,
NT_STATUS_INVALID_PARAMETER);
@@ -4860,21 +4855,32 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
/* !widelinks forces the target path to be within the share. */
/* This means we can interpret the target as a pathname. */
if (!lp_widelinks(SNUM(conn))) {
- pstring rel_name;
+ char *rel_name = NULL;
char *last_dirp = NULL;
if (*link_target == '/') {
/* No absolute paths allowed. */
return NT_STATUS_ACCESS_DENIED;
}
- pstrcpy(rel_name, newname);
+ rel_name = talloc_strdup(ctx,newname);
+ if (!rel_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
last_dirp = strrchr_m(rel_name, '/');
if (last_dirp) {
last_dirp[1] = '\0';
} else {
- pstrcpy(rel_name, "./");
+ rel_name = talloc_strdup(ctx,"./");
+ if (!rel_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ rel_name = talloc_asprintf_append(ctx,
+ "%s",
+ link_target);
+ if (!rel_name) {
+ return NT_STATUS_NO_MEMORY;
}
- pstrcat(rel_name, link_target);
status = check_name(conn, rel_name);
if (!NT_STATUS_IS_OK(status)) {
@@ -4945,7 +4951,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
uint32 root_fid;
uint32 len;
char *newname = NULL;
- pstring base_name;
+ char *base_name = NULL;
BOOL dest_has_wcard = False;
NTSTATUS status = NT_STATUS_OK;
char *p;
@@ -4988,15 +4994,26 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
}
/* Create the base directory. */
- pstrcpy(base_name, fname);
+ base_name = talloc_strdup(ctx, fname);
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
p = strrchr_m(base_name, '/');
if (p) {
p[1] = '\0';
} else {
- pstrcpy(base_name, "./");
+ base_name = talloc_strdup(ctx, "./");
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
/* Append the new name. */
- pstrcat(base_name, newname);
+ base_name = talloc_asprintf_append(base_name,
+ "%s",
+ newname);
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
if (fsp) {
SMB_STRUCT_STAT sbuf;
@@ -5026,7 +5043,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
} else {
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
fname, base_name ));
- status = rename_internals(conn, req, fname, base_name, 0,
+ status = rename_internals(ctx, conn, req, fname, base_name, 0,
overwrite, False, dest_has_wcard);
}