diff options
-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 dd03a56233..4e3b7cba62 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 b21e6501d6..7a6815b680 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 5871fd143f..27f17f9628 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 d687974ff3..5cbe8c68ac 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 114050ae16..7886ee86ce 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 672c683309..7ac6c4699f 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 2ba0781e62..8e03094aef 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; |