diff options
author | Jeremy Allison <jra@samba.org> | 2007-09-11 23:57:59 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:30:41 -0500 |
commit | 3a9d3821649c9ea88a6cd424f0838a453165a00a (patch) | |
tree | 4b4f61570a20e0a252436ebd88b1d0dee58c704e /source3 | |
parent | 1ef2464451ee64023173637fa03e703405dc8c85 (diff) | |
download | samba-3a9d3821649c9ea88a6cd424f0838a453165a00a.tar.gz samba-3a9d3821649c9ea88a6cd424f0838a453165a00a.tar.xz samba-3a9d3821649c9ea88a6cd424f0838a453165a00a.zip |
r25111: Move to talloced pathnames on most code paths.
There are now ony 17 pstrings left in reply.c,
and these will be easy to remove (and I'll be
doing that shortly). Had to fix an interesting
bug in pull_ucs2_base_talloc() when a source
string is not null terminated :-).
Jeremy.
(This used to be commit 0c9a8c4dff10974dbffd2a302ae982896122fcc0)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/charcnv.c | 16 | ||||
-rw-r--r-- | source3/smbd/dir.c | 13 | ||||
-rw-r--r-- | source3/smbd/filename.c | 3 | ||||
-rw-r--r-- | source3/smbd/msdfs.c | 16 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 376 | ||||
-rw-r--r-- | source3/smbd/reply.c | 249 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 106 |
7 files changed, 438 insertions, 341 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index dd03a562330..4e3b7cba62f 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1460,7 +1460,21 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx, if (dest_len) { /* Did we already process the terminating zero ? */ if (dest[dest_len-1] != 0) { - dest[dest_len-1] = 0; + size_t size = talloc_get_size(dest); + /* Have we got space to append the '\0' ? */ + if (size <= dest_len) { + /* No, realloc. */ + dest = TALLOC_REALLOC(ctx, dest, + dest_len+1); + if (!dest) { + /* talloc fail. */ + dest_len = (size_t)-1; + return 0; + } + } + /* Yay - space ! */ + dest[dest_len] = '\0'; + dest_len++; } } else if (dest) { dest[0] = 0; diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b21e6501d66..7a6815b6806 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -752,8 +752,9 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) return True; } -static BOOL mangle_mask_match(connection_struct *conn, const char *filename, - char *mask) +static BOOL mangle_mask_match(connection_struct *conn, + const char *filename, + const char *mask) { char mname[13]; @@ -791,11 +792,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); - - if (dname == NULL) + + if (dname == NULL) return(False); - - pstrcpy(filename,dname); + + pstrcpy(filename,dname); /* notice the special *.* handling. This appears to be the only difference between the wildcard handling in this routine and in the trans2 routines. diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 5871fd143f7..27f17f96283 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -553,8 +553,7 @@ NTSTATUS unix_convert(connection_struct *conn, tmp = talloc_asprintf(ctx, "%s/%s", dirpath, found_name); - } - else { + } else { tmp = talloc_strdup(ctx, found_name); } diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index d687974ff3f..5cbe8c68aca 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -817,9 +817,9 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx, } if (pdp->reqpath[0] != '\0') { - ref->alternate_path = talloc_asprintf(ctx, - "%s%s", + ref->alternate_path = talloc_asprintf_append( ref->alternate_path, + "%s", pdp->reqpath); if (!ref->alternate_path) { TALLOC_FREE(pdp); @@ -1298,7 +1298,6 @@ BOOL create_msdfs_link(const struct junction_map *jucn, goto out; } for(i=0; i<jucn->referral_count; i++) { - char *old_msdfs_link = msdfs_link; char *refpath = jucn->referral_list[i].alternate_path; /* Alternate paths always use Windows separators. */ @@ -1310,21 +1309,18 @@ BOOL create_msdfs_link(const struct junction_map *jucn, continue; } if (i > 0 && insert_comma) { - msdfs_link = talloc_asprintf(conn->mem_ctx, - "%s,%s", - old_msdfs_link, + msdfs_link = talloc_asprintf_append(msdfs_link, + ",%s", refpath); } else { - msdfs_link = talloc_asprintf(conn->mem_ctx, - "%s%s", - old_msdfs_link, + msdfs_link = talloc_asprintf_append(msdfs_link, + "%s", refpath); } if (!msdfs_link) { goto out; } - TALLOC_FREE(old_msdfs_link); if (!insert_comma) { insert_comma = True; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 114050ae162..7886ee86ce9 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB NT transaction handling - Copyright (C) Jeremy Allison 1994-1998 + Copyright (C) Jeremy Allison 1994-2007 Copyright (C) Stefan (metze) Metzmacher 2003 This program is free software; you can redistribute it and/or modify @@ -51,7 +51,7 @@ static char *nttrans_realloc(char **ptr, size_t size) if (ptr==NULL) { smb_panic("nttrans_realloc() called with NULL ptr"); } - + *ptr = (char *)SMB_REALLOC(*ptr, size); if(*ptr == NULL) { return NULL; @@ -80,7 +80,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, int alignment_offset = 3; int data_alignment_offset = 0; - /* + /* * If there genuinely are no parameters or data to send just send * the empty packet. */ @@ -101,10 +101,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, data_alignment_offset = 4 - (params_to_send % 4); } - /* + /* * Space is bufsize minus Netbios over TCP header minus SMB header. * The alignment_offset is to align the param bytes on a four byte - * boundary (2 bytes for data len, one byte pad). + * boundary (2 bytes for data len, one byte pad). * NT needs this to work correctly. */ @@ -131,7 +131,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset; - /* + /* * We can never send more than useable_space. */ @@ -146,7 +146,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize); SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize); - /* + /* * Calculate how many parameters and data we can fit into * this packet. Parameters get precedence. */ @@ -172,7 +172,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, SIVAL(req->outbuf,smb_ntr_ParameterOffset, ((smb_buf(req->outbuf)+alignment_offset) - smb_base(req->outbuf))); - /* + /* * Absolute displacement of param bytes sent in this packet. */ @@ -202,7 +202,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata); } - /* + /* * Copy the param bytes into the packet. */ @@ -229,7 +229,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, +params_sent_thistime+data_alignment_offset, pd,data_sent_thistime); } - + DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n", params_sent_thistime, data_sent_thistime, useable_space)); DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n", @@ -240,7 +240,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, 0, 0, nt_error, __LINE__,__FILE__); } - + /* Send the packet */ show_msg((char *)req->outbuf); if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) { @@ -248,10 +248,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, } TALLOC_FREE(req->outbuf); - + pp += params_sent_thistime; pd += data_sent_thistime; - + params_to_send -= params_sent_thistime; data_to_send -= data_sent_thistime; @@ -264,7 +264,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, params_to_send, data_to_send)); return; } - } + } } /**************************************************************************** @@ -385,14 +385,20 @@ static void nt_open_pipe(char *fname, connection_struct *conn, static void do_ntcreate_pipe_open(connection_struct *conn, struct smb_request *req) { - pstring fname; + char *fname = NULL; int pnum = -1; char *p = NULL; uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags); + TALLOC_CTX *ctx = talloc_tos(); - srvstr_pull_buf((char *)req->inbuf, req->flags2, fname, - smb_buf(req->inbuf), sizeof(fname), STR_TERMINATE); + srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf), STR_TERMINATE); + if (!fname) { + reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, + ERRDOS, ERRbadpipe); + return; + } nt_open_pipe(fname, conn, req, &pnum); if (req->outbuf) { @@ -402,7 +408,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn, /* * Deal with pipe return. - */ + */ if (flags & EXTENDED_RESPONSE_REQUIRED) { /* This is very strange. We @@ -434,7 +440,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn, if (flags & EXTENDED_RESPONSE_REQUIRED) { p += 25; SIVAL(p,0,FILE_GENERIC_ALL); - /* + /* * For pipes W2K3 seems to return * 0x12019B next. * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA) @@ -470,9 +476,9 @@ static void reply_ntcreate_and_X_quota(connection_struct *conn, } reply_outbuf(req, 34, 0); - + p = (char *)req->outbuf + smb_vwv2; - + /* SCVAL(p,0,NO_OPLOCK_RETURN); */ p++; SSVAL(p,0,fsp->fnum); @@ -488,8 +494,7 @@ static void reply_ntcreate_and_X_quota(connection_struct *conn, void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req) -{ - pstring fname_in; +{ char *fname = NULL; uint32 flags; uint32 access_mask; @@ -578,7 +583,7 @@ void reply_ntcreate_and_X(connection_struct *conn, /* * This filename is relative to a directory fid. */ - pstring rel_fname; + char *rel_fname = NULL; files_struct *dir_fsp = file_fsp( SVAL(req->inbuf, smb_ntcreate_RootDirectoryFid)); size_t dir_name_len; @@ -591,8 +596,9 @@ void reply_ntcreate_and_X(connection_struct *conn, if(!dir_fsp->is_directory) { - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf), sizeof(fname_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, + req->flags2, &fname, + smb_buf(req->inbuf), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -604,7 +610,7 @@ void reply_ntcreate_and_X(connection_struct *conn, * Check to see if this is a mac fork of some kind. */ - if( is_ntfs_stream_name(fname_in)) { + if( is_ntfs_stream_name(fname)) { reply_nterror( req, NT_STATUS_OBJECT_PATH_NOT_FOUND); END_PROFILE(SMBntcreateX); @@ -627,30 +633,47 @@ void reply_ntcreate_and_X(connection_struct *conn, * Copy in the base directory name. */ - pstrcpy( fname_in, dir_fsp->fsp_name ); - dir_name_len = strlen(fname_in); + dir_name_len = strlen(dir_fsp->fsp_name); + fname = TALLOC_SIZE(ctx, 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 '\'. + * Ensure it ends in a '/'. + * We used TALLOC_SIZE +2 to add space for the '/'. */ - if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) { - pstrcat(fname_in, "/"); + 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++; } - srvstr_get_path((char *)req->inbuf, req->flags2, rel_fname, - smb_buf(req->inbuf), sizeof(rel_fname), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &rel_fname, + smb_buf(req->inbuf), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBntcreateX); return; } - pstrcat(fname_in, rel_fname); + fname = talloc_asprintf(ctx, "%s%s", + fname, + rel_fname); + if (!fname) { + reply_nterror( + req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBntcreateX); + return; + } } else { - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf), sizeof(fname_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -662,8 +685,8 @@ void reply_ntcreate_and_X(connection_struct *conn, * Check to see if this is a mac fork of some kind. */ - if( is_ntfs_stream_name(fname_in)) { - enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname_in); + if( is_ntfs_stream_name(fname)) { + enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname); if (fake_file_type!=FAKE_FILE_TYPE_NONE) { /* * Here we go! support for changing the disk quotas --metze @@ -675,7 +698,7 @@ void reply_ntcreate_and_X(connection_struct *conn, * xp also tries a QUERY_FILE_INFO on the file and then close it */ reply_ntcreate_and_X_quota(conn, req, - fake_file_type, fname_in); + fake_file_type, fname); } else { reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); } @@ -690,7 +713,7 @@ void reply_ntcreate_and_X(connection_struct *conn, */ status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -890,8 +913,8 @@ void reply_ntcreate_and_X(connection_struct *conn, reply_doserror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBntcreateX); return; - } - + } + /* Save the requested allocation size. */ if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) { @@ -914,7 +937,7 @@ void reply_ntcreate_and_X(connection_struct *conn, } } - /* + /* * If the caller set the extended oplock request bit * and we granted one (by whatever means) - set the * correct bit for extended oplock reply. @@ -941,7 +964,7 @@ void reply_ntcreate_and_X(connection_struct *conn, } p = (char *)req->outbuf + smb_vwv2; - + /* * Currently as we don't support level II oplocks we just report * exclusive & batch here. @@ -958,7 +981,7 @@ void reply_ntcreate_and_X(connection_struct *conn, } else { SCVAL(p,0,NO_OPLOCK_RETURN); } - + p++; SSVAL(p,0,fsp->fnum); p += 2; @@ -1028,13 +1051,14 @@ static void do_nt_transact_create_pipe(connection_struct *conn, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count) { - pstring fname; + char *fname = NULL; char *params = *ppparams; int pnum = -1; char *p = NULL; NTSTATUS status; size_t param_len; uint32 flags; + TALLOC_CTX *ctx = talloc_tos(); /* * Ensure minimum number of parameters sent. @@ -1048,8 +1072,8 @@ static void do_nt_transact_create_pipe(connection_struct *conn, flags = IVAL(params,0); - srvstr_get_path(params, req->flags2, fname, params+53, - sizeof(fname), parameter_count-53, STR_TERMINATE, + srvstr_get_path(ctx, params, req->flags2, &fname, params+53, + parameter_count-53, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1062,7 +1086,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn, /* Error return */ return; } - + /* Realloc the size of parameters and data we will return */ if (flags & EXTENDED_RESPONSE_REQUIRED) { /* Extended response is 32 more byyes. */ @@ -1075,16 +1099,16 @@ static void do_nt_transact_create_pipe(connection_struct *conn, reply_doserror(req, ERRDOS, ERRnomem); return; } - + p = params; SCVAL(p,0,NO_OPLOCK_RETURN); - + p += 2; SSVAL(p,0,pnum); p += 2; SIVAL(p,0,FILE_WAS_OPENED); p += 8; - + p += 32; SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */ p += 20; @@ -1093,11 +1117,11 @@ static void do_nt_transact_create_pipe(connection_struct *conn, /* Device state. */ SSVAL(p,2, 0x5FF); /* ? */ p += 4; - + if (flags & EXTENDED_RESPONSE_REQUIRED) { p += 25; SIVAL(p,0,FILE_GENERIC_ALL); - /* + /* * For pipes W2K3 seems to return * 0x12019B next. * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA) @@ -1106,10 +1130,10 @@ static void do_nt_transact_create_pipe(connection_struct *conn, } DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname)); - + /* Send the required number of replies */ send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0); - + return; } @@ -1123,7 +1147,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu SEC_DESC *psd = NULL; TALLOC_CTX *mem_ctx; NTSTATUS status; - + if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) { return NT_STATUS_OK; } @@ -1143,7 +1167,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu * Setup the prs_struct to point at the memory we just * allocated. */ - + prs_give_memory( &pd, data, sd_len, False); /* @@ -1154,11 +1178,11 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n")); /* * Return access denied for want of a better error message.. - */ + */ talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } - + if (psd->owner_sid==0) { security_info_sent &= ~OWNER_SECURITY_INFORMATION; } @@ -1171,9 +1195,9 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu if (psd->dacl==0) { security_info_sent &= ~DACL_SECURITY_INFORMATION; } - + status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); - + talloc_destroy(mem_ctx); return status; } @@ -1181,7 +1205,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu /**************************************************************************** Read a list of EA names and data from an incoming data buffer. Create an ea_list with them. ****************************************************************************/ - + static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size) { struct ea_list *ea_list_head = NULL; @@ -1220,7 +1244,6 @@ static void call_nt_transact_create(connection_struct *conn, char **ppdata, uint32 data_count, uint32 max_data_count) { - pstring fname_in; char *fname = NULL; char *params = *ppparams; char *data = *ppdata; @@ -1331,6 +1354,7 @@ static void call_nt_transact_create(connection_struct *conn, /* * This filename is relative to a directory fid. */ + char *tmpname = NULL; files_struct *dir_fsp = file_fsp(SVAL(params,4)); size_t dir_name_len; @@ -1340,8 +1364,8 @@ static void call_nt_transact_create(connection_struct *conn, } if(!dir_fsp->is_directory) { - srvstr_get_path(params, req->flags2, fname_in, - params+53, sizeof(fname_in), + srvstr_get_path(ctx, params, req->flags2, &fname, + params+53, parameter_count-53, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { @@ -1353,7 +1377,7 @@ static void call_nt_transact_create(connection_struct *conn, * Check to see if this is a mac fork of some kind. */ - if( is_ntfs_stream_name(fname_in)) { + if( is_ntfs_stream_name(fname)) { reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); return; @@ -1367,33 +1391,46 @@ static void call_nt_transact_create(connection_struct *conn, * Copy in the base directory name. */ - pstrcpy( fname_in, dir_fsp->fsp_name ); - dir_name_len = strlen(fname_in); + dir_name_len = strlen(dir_fsp->fsp_name); + fname = TALLOC_SIZE(ctx, 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 '\'. + * Ensure it ends in a '/'. + * We used TALLOC_SIZE +2 to add space for the '/'. */ - if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) { - pstrcat(fname_in, "/"); + 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++; } - { - pstring tmpname; - srvstr_get_path(params, req->flags2, tmpname, - params+53, sizeof(tmpname), - parameter_count-53, STR_TERMINATE, - &status); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - return; - } - pstrcat(fname_in, tmpname); + srvstr_get_path(ctx, params, req->flags2, &tmpname, + params+53, + parameter_count-53, STR_TERMINATE, + &status); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + return; + } + fname = talloc_asprintf(ctx, "%s%s", + fname, + tmpname); + if (!fname) { + reply_nterror( + req, NT_STATUS_NO_MEMORY); + return; } } else { - srvstr_get_path(params, req->flags2, fname_in, params+53, - sizeof(fname_in), parameter_count-53, + srvstr_get_path(ctx, params, req->flags2, &fname, params+53, + parameter_count-53, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1404,7 +1441,7 @@ static void call_nt_transact_create(connection_struct *conn, * Check to see if this is a mac fork of some kind. */ - if( is_ntfs_stream_name(fname_in)) { + if( is_ntfs_stream_name(fname)) { reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); return; } @@ -1430,7 +1467,7 @@ static void call_nt_transact_create(connection_struct *conn, status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(case_state); @@ -1584,7 +1621,7 @@ static void call_nt_transact_create(connection_struct *conn, * According to the MS documentation, the only time the security * descriptor is applied to the opened file is iff we *created* the * file; an existing file stays the same. - * + * * Also, it seems (from observation) that you can open the file with * any access mask but you can still write the sd. We need to override * the granted access before we call set_sd @@ -1607,7 +1644,7 @@ static void call_nt_transact_create(connection_struct *conn, } fsp->access_mask = saved_access_mask; } - + if (ea_len && (info == FILE_WAS_CREATED)) { status = set_ea(conn, fsp, fname, ea_list); if (!NT_STATUS_IS_OK(status)) { @@ -1629,8 +1666,8 @@ static void call_nt_transact_create(connection_struct *conn, close_file(fsp,ERROR_CLOSE); reply_doserror(req, ERRDOS, ERRnoaccess); return; - } - + } + /* Save the requested allocation size. */ if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12); @@ -1655,7 +1692,7 @@ static void call_nt_transact_create(connection_struct *conn, } } - /* + /* * If the caller set the extended oplock request bit * and we granted one (by whatever means) - set the * correct bit for extended oplock reply. @@ -1694,7 +1731,7 @@ static void call_nt_transact_create(connection_struct *conn, } else { SCVAL(p,0,NO_OPLOCK_RETURN); } - + p += 2; SSVAL(p,0,fsp->fnum); p += 2; @@ -1765,12 +1802,12 @@ void reply_ntcancel(connection_struct *conn, struct smb_request *req) /* * Go through and cancel any pending change notifies. */ - + START_PROFILE(SMBntcancel); remove_pending_change_notify_requests_by_mid(req->mid); remove_pending_lock_requests_by_mid(req->mid); srv_cancel_sign_response(req->mid); - + DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid)); END_PROFILE(SMBntcancel); @@ -1923,8 +1960,6 @@ static NTSTATUS copy_internals(connection_struct *conn, void reply_ntrename(connection_struct *conn, struct smb_request *req) { - pstring oldname_in; - pstring newname_in; char *oldname = NULL; char *newname = NULL; char *p; @@ -1947,8 +1982,8 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req) rename_type = SVAL(req->inbuf,smb_vwv1); p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, oldname_in, p, - sizeof(oldname_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p, + 0, STR_TERMINATE, &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1956,22 +1991,22 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req) return; } - if( is_ntfs_stream_name(oldname_in)) { + if( is_ntfs_stream_name(oldname)) { /* Can't rename a stream. */ reply_nterror(req, NT_STATUS_ACCESS_DENIED); END_PROFILE(SMBntrename); return; } - if (ms_has_wild(oldname_in)) { + if (ms_has_wild(oldname)) { reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); END_PROFILE(SMBntrename); return; } p++; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p, - sizeof(newname_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, + 0, STR_TERMINATE, &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1981,7 +2016,7 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - oldname_in, + oldname, &oldname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1997,7 +2032,7 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - newname_in, + newname, &newname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2057,13 +2092,13 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req) } reply_outbuf(req, 0, 0); - + END_PROFILE(SMBntrename); return; } /**************************************************************************** - Reply to a notify change - queue the request and + Reply to a notify change - queue the request and don't allow a directory to be opened. ****************************************************************************/ @@ -2175,11 +2210,12 @@ static void call_nt_transact_rename(connection_struct *conn, uint32 max_data_count) { char *params = *ppparams; - pstring new_name; + char *new_name = NULL; files_struct *fsp = NULL; BOOL replace_if_exists = False; BOOL dest_has_wcard = False; NTSTATUS status; + TALLOC_CTX *ctx = talloc_tos(); if(parameter_count < 5) { reply_doserror(req, ERRDOS, ERRbadfunc); @@ -2191,8 +2227,8 @@ static void call_nt_transact_rename(connection_struct *conn, if (!check_fsp(conn, req, fsp, ¤t_user)) { return; } - srvstr_get_path_wcard(params, req->flags2, new_name, params+4, - sizeof(new_name), parameter_count - 4, + srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4, + parameter_count - 4, STR_TERMINATE, &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -2215,10 +2251,10 @@ static void call_nt_transact_rename(connection_struct *conn, * Rename was successful. */ send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); - + DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", fsp->fsp_name, new_name)); - + return; } @@ -2351,7 +2387,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn, security descriptor.\n")); /* * Return access denied for want of a better error message.. - */ + */ talloc_destroy(mem_ctx); reply_unixerror(req, ERRDOS, ERRnoaccess); return; @@ -2421,7 +2457,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn, send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); return; } - + /**************************************************************************** Reply to NT IOCTL ****************************************************************************/ @@ -2469,7 +2505,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum)); send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); return; - + case FSCTL_CREATE_OR_GET_OBJECT_ID: { unsigned char objid[16]; @@ -2515,7 +2551,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT); return; - + case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/ { /* @@ -2564,9 +2600,9 @@ static void call_nt_transact_ioctl(connection_struct *conn, reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - + shadow_data->mem_ctx = shadow_mem_ctx; - + /* * Call the VFS routine to actually do the work. */ @@ -2606,7 +2642,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, talloc_destroy(shadow_data->mem_ctx); reply_nterror(req, NT_STATUS_NO_MEMORY); return; - } + } cur_pdata = pdata; @@ -2643,11 +2679,11 @@ static void call_nt_transact_ioctl(connection_struct *conn, return; } - + case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */ { - /* pretend this succeeded - - * + /* pretend this succeeded - + * * we have to send back a list with all files owned by this SID * * but I have to check that --metze @@ -2655,7 +2691,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, DOM_SID sid; uid_t uid; size_t sid_len = MIN(data_count-4,SID_MAX_SIZE); - + DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum)); if (!fsp_belongs_conn(conn, req, fsp, ¤t_user)) { @@ -2664,7 +2700,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, /* unknown 4 bytes: this is not the length of the sid :-( */ /*unknown = IVAL(pdata,0);*/ - + sid_parse(pdata+4,sid_len,&sid); DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid))); @@ -2673,7 +2709,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, sid_string_static(&sid),(unsigned long)sid_len)); uid = (-1); } - + /* we can take a look at the find source :-) * * find ./ -uid $uid -name '*' is what we need here @@ -2686,16 +2722,16 @@ static void call_nt_transact_ioctl(connection_struct *conn, * (maybe we can hang the result anywhere in the fsp struct) * * we don't send all files at once - * and at the next we should *not* start from the beginning, - * so we have to cache the result + * and at the next we should *not* start from the beginning, + * so we have to cache the result * * --metze */ - + /* this works for now... */ send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); return; - } + } default: if (!logged_message) { logged_message = True; /* Only print this once... */ @@ -2710,7 +2746,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, #ifdef HAVE_SYS_QUOTAS /**************************************************************************** - Reply to get user quota + Reply to get user quota ****************************************************************************/ static void call_nt_transact_get_user_quota(connection_struct *conn, @@ -2758,7 +2794,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, reply_doserror(req, ERRDOS, ERRinvalidparam); return; } - + /* maybe we can check the quota_fnum */ fsp = file_fsp(SVAL(params,0)); if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { @@ -2773,16 +2809,16 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd; level = SVAL(params,2); - - /* unknown 12 bytes leading in params */ - + + /* unknown 12 bytes leading in params */ + switch (level) { case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE: /* seems that we should continue with the enum here --metze */ - if (qt_handle->quota_list!=NULL && + if (qt_handle->quota_list!=NULL && qt_handle->tmp_list==NULL) { - + /* free the list */ free_ntquota_list(&(qt_handle->quota_list)); @@ -2824,7 +2860,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* we should not trust the value in max_data_count*/ max_data_count = MIN(max_data_count,2048); - + pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ if(pdata == NULL) { reply_doserror(req, ERRDOS, ERRnomem); @@ -2835,7 +2871,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* set params Size of returned Quota Data 4 bytes*/ /* but set it later when we know it */ - + /* for each entry push the data */ if (start_enum) { @@ -2852,28 +2888,28 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* nextoffset entry 4 bytes */ SIVAL(entry,0,entry_len); - + /* then the len of the SID 4 bytes */ SIVAL(entry,4,sid_len); - + /* unknown data 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/ - + /* the used disk space 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,16,tmp_list->quotas->usedspace); - + /* the soft quotas 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,24,tmp_list->quotas->softlim); - + /* the hard quotas 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,32,tmp_list->quotas->hardlim); - + /* and now the SID */ sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid); } - + qt_handle->tmp_list = tmp_list; - + /* overwrite the offset of the last entry */ SIVAL(entry-entry_len,0,0); @@ -2884,9 +2920,9 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, break; case TRANSACT_GET_USER_QUOTA_FOR_SID: - - /* unknown 4 bytes IVAL(pdata,0) */ - + + /* unknown 4 bytes IVAL(pdata,0) */ + if (data_count < 8) { DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8)); reply_doserror(req, ERRDOS, ERRunknownlevel); @@ -2919,11 +2955,11 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, } sid_parse(pdata+8,sid_len,&sid); - + if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { ZERO_STRUCT(qt); - /* - * we have to return zero's in all fields + /* + * we have to return zero's in all fields * instead of returning an error here * --metze */ @@ -2947,25 +2983,25 @@ static void call_nt_transact_get_user_quota(connection_struct *conn, /* set params Size of returned Quota Data 4 bytes*/ SIVAL(params,0,data_len); - + /* nextoffset entry 4 bytes */ SIVAL(entry,0,0); - + /* then the len of the SID 4 bytes */ SIVAL(entry,4,sid_len); - + /* unknown data 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/ - + /* the used disk space 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,16,qt.usedspace); - + /* the soft quotas 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,24,qt.softlim); - + /* the hard quotas 8 bytes SMB_BIG_UINT */ SBIG_UINT(entry,32,qt.hardlim); - + /* and now the SID */ sid_linearize(entry+40, sid_len, &sid); @@ -3023,7 +3059,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, reply_doserror(req, ERRDOS, ERRinvalidparam); return; } - + /* maybe we can check the quota_fnum */ fsp = file_fsp(SVAL(params,0)); if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { @@ -3052,7 +3088,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, return; } - /* unknown 8 bytes in pdata + /* unknown 8 bytes in pdata * maybe its the change time in NTTIME */ @@ -3097,7 +3133,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn, return; } #endif /* LARGE_SMB_OFF_T */ - + sid_parse(pdata+40,sid_len,&sid); DEBUGADD(8,("SID: %s\n",sid_string_static(&sid))); @@ -3227,7 +3263,7 @@ static void handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE(NT_transact_set_user_quota); - break; + break; } #endif /* HAVE_SYS_QUOTAS */ @@ -3307,7 +3343,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req) state->setup = NULL; state->call = function_code; - /* + /* * All nttrans messages we handle have smb_wct == 19 + * state->setup_count. Ensure this is so as a sanity check. */ @@ -3339,7 +3375,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req) reply_doserror(req, ERRDOS, ERRnomem); END_PROFILE(SMBnttrans); return; - } + } if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) goto bad_param; if ((smb_base(req->inbuf)+dsoff+dscnt @@ -3361,7 +3397,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req) reply_doserror(req, ERRDOS, ERRnomem); END_PROFILE(SMBnttrans); return; - } + } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) goto bad_param; if ((smb_base(req->inbuf)+psoff+pscnt @@ -3431,7 +3467,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req) END_PROFILE(SMBnttrans); return; } - + /**************************************************************************** Reply to a SMBnttranss ****************************************************************************/ @@ -3489,7 +3525,7 @@ void reply_nttranss(connection_struct *conn, struct smb_request *req) state->received_param += pcnt; state->received_data += dcnt; - + if ((state->received_data > state->total_data) || (state->received_param > state->total_param)) goto bad_param; @@ -3529,7 +3565,7 @@ void reply_nttranss(connection_struct *conn, struct smb_request *req) goto bad_param; memcpy(state->data+ddisp, smb_base(req->inbuf)+doff, - dcnt); + dcnt); } if ((state->received_param < state->total_param) || diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 672c6833093..7ac6c4699fb 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Main SMB reply routines Copyright (C) Andrew Tridgell 1992-1998 @@ -10,12 +10,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/>. */ @@ -208,27 +208,46 @@ NTSTATUS check_path_syntax_posix(char *path) Pull a string and check the path allowing a wilcard - provide for error return. ****************************************************************************/ -size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest, - const char *src, size_t dest_len, size_t src_len, - int flags, NTSTATUS *err, BOOL *contains_wcard) +size_t srvstr_get_path_wcard(TALLOC_CTX *ctx, + const char *inbuf, + uint16 smb_flags2, + char **pp_dest, + const char *src, + size_t src_len, + int flags, + NTSTATUS *err, + BOOL *contains_wcard) { size_t ret; -#ifdef DEVELOPER - SMB_ASSERT(dest_len == sizeof(pstring)); -#endif + + *pp_dest = NULL; if (src_len == 0) { - ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src, - dest_len, flags); + ret = srvstr_pull_buf_talloc(ctx, + inbuf, + smb_flags2, + pp_dest, + src, + flags); } else { - ret = srvstr_pull(inbuf, smb_flags2, dest, src, - dest_len, src_len, flags); + ret = srvstr_pull_talloc(ctx, + inbuf, + smb_flags2, + pp_dest, + src, + src_len, + flags); + } + + if (!*pp_dest) { + *err = NT_STATUS_INVALID_PARAMETER; + return ret; } *contains_wcard = False; if (smb_flags2 & FLAGS2_DFS_PATHNAMES) { - /* + /* * For a DFS path the function parse_dfs_path() * will do the path processing, just make a copy. */ @@ -237,9 +256,9 @@ size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest, } if (lp_posix_pathnames()) { - *err = check_path_syntax_posix(dest); + *err = check_path_syntax_posix(*pp_dest); } else { - *err = check_path_syntax_wcard(dest, contains_wcard); + *err = check_path_syntax_wcard(*pp_dest, contains_wcard); } return ret; @@ -249,25 +268,43 @@ size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest, Pull a string and check the path - provide for error return. ****************************************************************************/ -size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest, - const char *src, size_t dest_len, size_t src_len, - int flags, NTSTATUS *err) +size_t srvstr_get_path(TALLOC_CTX *ctx, + const char *inbuf, + uint16 smb_flags2, + char **pp_dest, + const char *src, + size_t src_len, + int flags, + NTSTATUS *err) { size_t ret; -#ifdef DEVELOPER - SMB_ASSERT(dest_len == sizeof(pstring)); -#endif + + *pp_dest = NULL; if (src_len == 0) { - ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src, - dest_len, flags); + ret = srvstr_pull_buf_talloc(ctx, + inbuf, + smb_flags2, + pp_dest, + src, + flags); } else { - ret = srvstr_pull(inbuf, smb_flags2, dest, src, - dest_len, src_len, flags); + ret = srvstr_pull_talloc(ctx, + inbuf, + smb_flags2, + pp_dest, + src, + src_len, + flags); + } + + if (!*pp_dest) { + *err = NT_STATUS_INVALID_PARAMETER; + return ret; } if (smb_flags2 & FLAGS2_DFS_PATHNAMES) { - /* + /* * For a DFS path the function parse_dfs_path() * will do the path processing, just make a copy. */ @@ -276,9 +313,9 @@ size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest, } if (lp_posix_pathnames()) { - *err = check_path_syntax_posix(dest); + *err = check_path_syntax_posix(*pp_dest); } else { - *err = check_path_syntax(dest); + *err = check_path_syntax(*pp_dest); } return ret; @@ -802,14 +839,13 @@ static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status) } return status; } - + /**************************************************************************** Reply to a checkpath. ****************************************************************************/ void reply_checkpath(connection_struct *conn, struct smb_request *req) { - pstring name_in; char *name = NULL; SMB_STRUCT_STAT sbuf; NTSTATUS status; @@ -817,8 +853,8 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req) START_PROFILE(SMBcheckpath); - srvstr_get_path((char *)req->inbuf, req->flags2, name_in, - smb_buf(req->inbuf) + 1, sizeof(name_in), 0, + srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name, + smb_buf(req->inbuf) + 1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { status = map_checkpath_error((char *)req->inbuf, status); @@ -829,7 +865,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - name_in, + name, &name); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -841,7 +877,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req) goto path_err; } - DEBUG(3,("reply_checkpath %s mode=%d\n", name_in, (int)SVAL(req->inbuf,smb_vwv0))); + DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0))); status = unix_convert(conn, name, False, &name, NULL, &sbuf); if (!NT_STATUS_IS_OK(status)) { @@ -904,7 +940,6 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req) void reply_getatr(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; SMB_STRUCT_STAT sbuf; int mode=0; @@ -917,8 +952,8 @@ void reply_getatr(connection_struct *conn, struct smb_request *req) START_PROFILE(SMBgetatr); p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, p, - sizeof(fname_in), 0, STR_TERMINATE, &status); + p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p, + 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBgetatr); @@ -927,7 +962,7 @@ void reply_getatr(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -995,7 +1030,7 @@ void reply_getatr(connection_struct *conn, struct smb_request *req) } DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) ); - + END_PROFILE(SMBgetatr); return; } @@ -1006,7 +1041,6 @@ void reply_getatr(connection_struct *conn, struct smb_request *req) void reply_setatr(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; int mode; time_t mtime; @@ -1023,8 +1057,8 @@ void reply_setatr(connection_struct *conn, struct smb_request *req) } p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, p, - sizeof(fname_in), 0, STR_TERMINATE, &status); + p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p, + 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBsetatr); @@ -1033,7 +1067,7 @@ void reply_setatr(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1046,7 +1080,7 @@ void reply_setatr(connection_struct *conn, struct smb_request *req) END_PROFILE(SMBsetatr); return; } - + status = unix_convert(conn, fname, False, &fname, NULL, &sbuf); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1171,7 +1205,6 @@ void reply_search(connection_struct *conn, struct smb_request *req) BOOL finished = False; char *p; int status_len; - pstring path_in; char *path = NULL; char status[21]; int dptr_num= -1; @@ -1207,9 +1240,15 @@ void reply_search(connection_struct *conn, struct smb_request *req) maxentries = SVAL(req->inbuf,smb_vwv0); dirtype = SVAL(req->inbuf,smb_vwv1); p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path_in, p, - sizeof(path_in), 0, STR_TERMINATE, &nt_status, - &mask_contains_wcard); + p += srvstr_get_path_wcard(ctx, + (char *)req->inbuf, + req->flags2, + &path, + p, + 0, + STR_TERMINATE, + &nt_status, + &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); END_PROFILE(SMBsearch); @@ -1218,7 +1257,7 @@ void reply_search(connection_struct *conn, struct smb_request *req) nt_status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - path_in, + path, &path, &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1440,12 +1479,13 @@ void reply_search(connection_struct *conn, struct smb_request *req) void reply_fclose(connection_struct *conn, struct smb_request *req) { int status_len; - pstring path; char status[21]; int dptr_num= -2; char *p; + char *path = NULL; NTSTATUS err; BOOL path_contains_wcard = False; + TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBfclose); @@ -1456,9 +1496,15 @@ void reply_fclose(connection_struct *conn, struct smb_request *req) } p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path, p, - sizeof(path), 0, STR_TERMINATE, &err, - &path_contains_wcard); + p += srvstr_get_path_wcard(ctx, + (char *)req->inbuf, + req->flags2, + &path, + p, + 0, + STR_TERMINATE, + &err, + &path_contains_wcard); if (!NT_STATUS_IS_OK(err)) { reply_nterror(req, err); END_PROFILE(SMBfclose); @@ -1496,7 +1542,6 @@ void reply_fclose(connection_struct *conn, struct smb_request *req) void reply_open(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; uint32 fattr=0; SMB_OFF_T size = 0; @@ -1526,8 +1571,8 @@ void reply_open(connection_struct *conn, struct smb_request *req) deny_mode = SVAL(req->inbuf,smb_vwv0); dos_attr = SVAL(req->inbuf,smb_vwv1); - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf)+1, sizeof(fname_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf)+1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1537,7 +1582,7 @@ void reply_open(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -1634,7 +1679,6 @@ void reply_open(connection_struct *conn, struct smb_request *req) void reply_open_and_X(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; uint16 open_flags; int deny_mode; @@ -1692,8 +1736,8 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req) } /* XXXX we need to handle passed times, sattr and flags */ - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf), sizeof(fname_in), 0, STR_TERMINATE, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf), 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1703,7 +1747,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBopenX); @@ -1882,7 +1926,6 @@ void reply_ulogoffX(connection_struct *conn, struct smb_request *req) void reply_mknew(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; int com; uint32 fattr = 0; @@ -1913,8 +1956,8 @@ void reply_mknew(connection_struct *conn, struct smb_request *req) srv_make_unix_date3(req->inbuf + smb_vwv1)); /* mtime. */ - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf) + 1, sizeof(fname_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf) + 1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1924,7 +1967,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); @@ -2014,7 +2057,6 @@ void reply_mknew(connection_struct *conn, struct smb_request *req) void reply_ctemp(connection_struct *conn, struct smb_request *req) { - pstring fname_in; char *fname = NULL; uint32 fattr; files_struct *fsp; @@ -2036,23 +2078,31 @@ void reply_ctemp(connection_struct *conn, struct smb_request *req) fattr = SVAL(req->inbuf,smb_vwv0); oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, - smb_buf(req->inbuf)+1, sizeof(fname_in), 0, STR_TERMINATE, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, + smb_buf(req->inbuf)+1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBctemp); return; } - if (*fname_in) { - pstrcat(fname_in,"/TMXXXXXX"); + if (*fname) { + fname = talloc_asprintf(ctx, + "%s/TMXXXXXX", + fname); } else { - pstrcat(fname_in,"TMXXXXXX"); + fname = talloc_strdup(ctx, "TMXXXXXX"); + } + + if (!fname) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBctemp); + return; } status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -2458,7 +2508,6 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, void reply_unlink(connection_struct *conn, struct smb_request *req) { - pstring name_in; char *name = NULL; uint32 dirtype; NTSTATUS status; @@ -2475,8 +2524,8 @@ void reply_unlink(connection_struct *conn, struct smb_request *req) dirtype = SVAL(req->inbuf,smb_vwv0); - srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in, - smb_buf(req->inbuf) + 1, sizeof(name_in), 0, + srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, + smb_buf(req->inbuf) + 1, 0, STR_TERMINATE, &status, &path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -2486,7 +2535,7 @@ void reply_unlink(connection_struct *conn, struct smb_request *req) status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - name_in, + name, &name, &path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { @@ -4660,7 +4709,6 @@ void reply_printwrite(connection_struct *conn, struct smb_request *req) void reply_mkdir(connection_struct *conn, struct smb_request *req) { - pstring directory_in; char *directory = NULL; NTSTATUS status; SMB_STRUCT_STAT sbuf; @@ -4668,8 +4716,8 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req) START_PROFILE(SMBmkdir); - srvstr_get_path((char *)req->inbuf, req->flags2, directory_in, - smb_buf(req->inbuf) + 1, sizeof(directory_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory, + smb_buf(req->inbuf) + 1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -4679,7 +4727,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - directory_in, + directory, &directory); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -4916,7 +4964,6 @@ NTSTATUS rmdir_internals(connection_struct *conn, const char *directory) void reply_rmdir(connection_struct *conn, struct smb_request *req) { - pstring directory_in; char *directory = NULL; SMB_STRUCT_STAT sbuf; NTSTATUS status; @@ -4924,8 +4971,8 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req) START_PROFILE(SMBrmdir); - srvstr_get_path((char *)req->inbuf, req->flags2, directory_in, - smb_buf(req->inbuf) + 1, sizeof(directory_in), 0, + srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory, + smb_buf(req->inbuf) + 1, 0, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -4935,7 +4982,7 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req) status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - directory_in, + directory, &directory); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -5683,8 +5730,6 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req, void reply_mv(connection_struct *conn, struct smb_request *req) { - pstring name_in; - pstring newname_in; char *name = NULL; char *newname = NULL; char *p; @@ -5705,8 +5750,8 @@ void reply_mv(connection_struct *conn, struct smb_request *req) attrs = SVAL(req->inbuf,smb_vwv0); p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in, p, - sizeof(name_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p, + 0, STR_TERMINATE, &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -5714,8 +5759,8 @@ void reply_mv(connection_struct *conn, struct smb_request *req) return; } p++; - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p, - sizeof(newname_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, + 0, STR_TERMINATE, &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -5725,7 +5770,7 @@ void reply_mv(connection_struct *conn, struct smb_request *req) status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - name_in, + name, &name, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { @@ -5742,7 +5787,7 @@ void reply_mv(connection_struct *conn, struct smb_request *req) status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - newname_in, + newname, &newname, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { @@ -5903,9 +5948,7 @@ NTSTATUS copy_file(connection_struct *conn, void reply_copy(connection_struct *conn, struct smb_request *req) { - pstring name_in; char *name = NULL; - pstring newname_in; char *newname = NULL; pstring directory; pstring mask; @@ -5938,16 +5981,16 @@ void reply_copy(connection_struct *conn, struct smb_request *req) *directory = *mask = 0; p = smb_buf(req->inbuf); - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in, p, - sizeof(name_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p, + 0, STR_TERMINATE, &status, &source_has_wild); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBcopy); return; } - p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p, - sizeof(newname_in), 0, STR_TERMINATE, &status, + p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, + 0, STR_TERMINATE, &status, &dest_has_wild); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -5955,7 +5998,7 @@ void reply_copy(connection_struct *conn, struct smb_request *req) return; } - DEBUG(3,("reply_copy : %s -> %s\n",name_in,newname_in)); + DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); if (tid2 != conn->cnum) { /* can't currently handle inter share copies XXXX */ @@ -5967,7 +6010,7 @@ void reply_copy(connection_struct *conn, struct smb_request *req) status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - name_in, + name, &name, &source_has_wild); if (!NT_STATUS_IS_OK(status)) { @@ -5984,7 +6027,7 @@ void reply_copy(connection_struct *conn, struct smb_request *req) status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - newname_in, + newname, &newname, &dest_has_wild); if (!NT_STATUS_IS_OK(status)) { @@ -6085,7 +6128,7 @@ void reply_copy(connection_struct *conn, struct smb_request *req) END_PROFILE(SMBcopy); return; } - + status = check_name(conn, newname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2ba0781e620..8e03094aef5 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -783,7 +783,6 @@ static void call_trans2open(connection_struct *conn, int open_ofun; uint32 open_size; char *pname; - pstring fname_in; char *fname = NULL; SMB_OFF_T size=0; int fattr=0,mtime=0; @@ -798,6 +797,7 @@ static void call_trans2open(connection_struct *conn, uint32 share_mode; uint32 create_disposition; uint32 create_options = 0; + TALLOC_CTX *ctx = talloc_tos(); /* * Ensure we have enough parameters to perform the operation. @@ -830,8 +830,8 @@ static void call_trans2open(connection_struct *conn, return; } - srvstr_get_path(params, req->flags2, fname_in, pname, - sizeof(fname_in), total_params - 28, STR_TERMINATE, + srvstr_get_path(ctx, params, req->flags2, &fname, pname, + total_params - 28, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -844,12 +844,12 @@ static void call_trans2open(connection_struct *conn, /* XXXX we need to handle passed times, sattr and flags */ - status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf); + status = unix_convert(conn, fname, False, &fname, NULL, &sbuf); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; } - + status = check_name(conn, fname); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -1759,7 +1759,6 @@ static void call_trans2findfirst(connection_struct *conn, BOOL close_if_end; BOOL requires_resume_key; int info_level; - pstring directory_in; char *directory = NULL; pstring mask; char *p; @@ -1791,7 +1790,7 @@ static void call_trans2findfirst(connection_struct *conn, requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); info_level = SVAL(params,6); - *directory_in = *mask = 0; + *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", @@ -1826,8 +1825,8 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", return; } - srvstr_get_path_wcard(params, req->flags2, directory_in, - params+12, sizeof(directory_in), total_params - 12, + srvstr_get_path_wcard(ctx, params, req->flags2, &directory, + params+12, total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { reply_nterror(req, ntstatus); @@ -1836,7 +1835,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", ntstatus = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - directory_in, + directory, &directory, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { @@ -2101,7 +2100,7 @@ static void call_trans2findnext(connection_struct *conn, BOOL requires_resume_key; BOOL continue_bit; BOOL mask_contains_wcard = False; - pstring resume_name; + char *resume_name = NULL; pstring mask; pstring directory; char *p; @@ -2115,6 +2114,7 @@ static void call_trans2findnext(connection_struct *conn, TALLOC_CTX *ea_ctx = NULL; struct ea_list *ea_list = NULL; NTSTATUS ntstatus = NT_STATUS_OK; + TALLOC_CTX *ctx = talloc_tos(); if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -2131,10 +2131,10 @@ 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 = *resume_name = 0; + *mask = *directory = 0; - srvstr_get_path_wcard(params, req->flags2, resume_name, - params+12, sizeof(resume_name), + srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name, + params+12, total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard); if (!NT_STATUS_IS_OK(ntstatus)) { @@ -2142,12 +2142,12 @@ static void call_trans2findnext(connection_struct *conn, complain (it thinks we're asking for the directory above the shared path or an invalid name). Catch this as the resume name is only compared, never used in a file access. JRA. */ - srvstr_pull(params, req->flags2, - resume_name, params+12, - sizeof(resume_name), total_params - 12, + srvstr_pull_talloc(ctx, params, req->flags2, + &resume_name, params+12, + total_params - 12, STR_TERMINATE); - if (!(ISDOT(resume_name) || ISDOTDOT(resume_name))) { + if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) { reply_nterror(req, ntstatus); return; } @@ -3527,7 +3527,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, struct ea_list *ea_list = NULL; uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ char *lock_data = NULL; - TALLOC_CTX *ctx = NULL; + TALLOC_CTX *ctx = talloc_tos(); if (!params) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -3620,7 +3620,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, } } else { - pstring fname_in; NTSTATUS status = NT_STATUS_OK; /* qpathinfo */ @@ -3638,8 +3637,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn, return; } - srvstr_get_path(params, req->flags2, fname_in, ¶ms[6], - sizeof(fname_in), total_params - 6, + srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], + total_params - 6, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -3649,7 +3648,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -4835,9 +4834,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, int total_data, const char *fname) { - pstring link_target; + char *link_target = NULL; const char *newname = fname; NTSTATUS status = NT_STATUS_OK; + TALLOC_CTX *ctx = talloc_tos(); /* Set a symbolic link. */ /* Don't allow this if follow links is false. */ @@ -4850,8 +4850,12 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, return NT_STATUS_ACCESS_DENIED; } - srvstr_pull(pdata, req->flags2, link_target, pdata, - sizeof(link_target), total_data, STR_TERMINATE); + srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata, + total_data, STR_TERMINATE); + + if (!link_target) { + return NT_STATUS_INVALID_PARAMETER; + } /* !widelinks forces the target path to be within the share. */ /* This means we can interpret the target as a pathname. */ @@ -4897,7 +4901,6 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, const char *pdata, int total_data, const char *fname) { - pstring oldname_in; char *oldname = NULL; TALLOC_CTX *ctx = talloc_tos(); NTSTATUS status = NT_STATUS_OK; @@ -4907,15 +4910,15 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn, return NT_STATUS_INVALID_PARAMETER; } - srvstr_get_path(pdata, req->flags2, oldname_in, pdata, - sizeof(oldname_in), total_data, STR_TERMINATE, &status); + srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata, + total_data, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return status; } status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - oldname_in, + oldname, &oldname); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4941,7 +4944,6 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, BOOL overwrite; uint32 root_fid; uint32 len; - pstring newname_in; char *newname = NULL; pstring base_name; BOOL dest_has_wcard = False; @@ -4961,16 +4963,19 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn, return NT_STATUS_INVALID_PARAMETER; } - srvstr_get_path_wcard(pdata, req->flags2, newname_in, &pdata[12], - sizeof(newname_in), len, 0, &status, + srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12], + len, 0, &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { return status; } + DEBUG(10,("smb_file_rename_information: got name |%s|\n", + newname)); + status = resolve_dfspath_wcard(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - newname_in, + newname, &newname, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { @@ -6265,8 +6270,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } } else { - pstring fname_in; - /* set path info */ if (total_params < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -6274,8 +6277,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } info_level = SVAL(params,0); - srvstr_get_path(params, req->flags2, fname_in, ¶ms[6], - sizeof(fname_in), total_params - 6, STR_TERMINATE, + srvstr_get_path(ctx, params, req->flags2, &fname, ¶ms[6], + total_params - 6, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -6284,7 +6287,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, status = resolve_dfspath(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, - fname_in, + fname, &fname); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { @@ -6619,11 +6622,11 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, { char *params = *pparams; char *pdata = *ppdata; - pstring directory_in; char *directory = NULL; SMB_STRUCT_STAT sbuf; NTSTATUS status = NT_STATUS_OK; struct ea_list *ea_list = NULL; + TALLOC_CTX *ctx = talloc_tos(); if (!CAN_WRITE(conn)) { reply_doserror(req, ERRSRV, ERRaccess); @@ -6635,17 +6638,17 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, return; } - srvstr_get_path(params, req->flags2, directory_in, ¶ms[4], - sizeof(directory_in), total_params - 4, STR_TERMINATE, + srvstr_get_path(ctx, params, req->flags2, &directory, ¶ms[4], + total_params - 4, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; } - DEBUG(3,("call_trans2mkdir : name = %s\n", directory_in)); + DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); - status = unix_convert(conn, directory_in, False, &directory, NULL, &sbuf); + status = unix_convert(conn, directory, False, &directory, NULL, &sbuf); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); return; @@ -6821,10 +6824,11 @@ static void call_trans2getdfsreferral(connection_struct *conn, unsigned int max_data_bytes) { char *params = *pparams; - pstring pathname; + char *pathname = NULL; int reply_size = 0; int max_referral_level; NTSTATUS status = NT_STATUS_OK; + TALLOC_CTX *ctx = talloc_tos(); DEBUG(10,("call_trans2getdfsreferral\n")); @@ -6840,14 +6844,18 @@ static void call_trans2getdfsreferral(connection_struct *conn, return; } - srvstr_pull(params, req->flags2, pathname, ¶ms[2], - sizeof(pathname), total_params - 2, STR_TERMINATE); + srvstr_pull_talloc(ctx, params, req->flags2, &pathname, ¶ms[2], + total_params - 2, STR_TERMINATE); + if (!pathname) { + reply_nterror(req, NT_STATUS_NOT_FOUND); + return; + } if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level, ppdata,&status)) < 0) { reply_nterror(req, status); return; } - + SSVAL(req->inbuf, smb_flg2, SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); send_trans2_replies(req,0,0,*ppdata,reply_size, max_data_bytes); @@ -6872,7 +6880,7 @@ static void call_trans2ioctl(connection_struct *conn, files_struct *fsp = file_fsp(SVAL(req->inbuf,smb_vwv15)); /* check for an invalid fid before proceeding */ - + if (!fsp) { reply_doserror(req, ERRDOS, ERRbadfid); return; |