summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/trans2.c246
1 files changed, 161 insertions, 85 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 9bae8a416e..b95c017b83 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -3338,10 +3338,12 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
Reply to a TRANSACT2_QFILEINFO on a PIPE !
****************************************************************************/
-static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- unsigned int tran_call,
- char **pparams, int total_params, char **ppdata, int total_data,
- unsigned int max_data_bytes)
+static void call_trans2qpipeinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
char *pdata = *ppdata;
@@ -3351,30 +3353,35 @@ static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outb
smb_np_struct *p_pipe = NULL;
if (!params) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
if (total_params < 4) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
p_pipe = get_rpc_pipe_p(SVAL(params,0));
if (p_pipe == NULL) {
- return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return;
}
info_level = SVAL(params,2);
*pparams = (char *)SMB_REALLOC(*pparams,2);
if (*pparams == NULL) {
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
params = *pparams;
SSVAL(params,0,0);
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL ) {
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
pdata = *ppdata;
@@ -3388,12 +3395,14 @@ static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outb
break;
default:
- return ERROR_NT(NT_STATUS_INVALID_LEVEL);
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
}
- send_trans2_replies(inbuf, outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
+ send_trans2_replies_new(req, params, param_size, *ppdata, data_size,
+ max_data_bytes);
- return(-1);
+ return;
}
/****************************************************************************
@@ -3401,15 +3410,16 @@ static int call_trans2qpipeinfo(connection_struct *conn, char *inbuf, char *outb
file name or file id).
****************************************************************************/
-static int call_trans2qfilepathinfo(connection_struct *conn,
- struct smb_request *req,
- char *inbuf, char *outbuf, int length, int bufsize,
- unsigned int tran_call,
- char **pparams, int total_params, char **ppdata, int total_data,
- unsigned int max_data_bytes)
+static void call_trans2qfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
char *pdata = *ppdata;
+ char *dstart, *dend;
uint16 info_level;
int mode=0;
int nlink;
@@ -3434,22 +3444,21 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
char *lock_data = NULL;
- if (!params)
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ if (!params) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
ZERO_STRUCT(sbuf);
if (tran_call == TRANSACT2_QFILEINFO) {
if (total_params < 4) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
if (IS_IPC(conn)) {
- return call_trans2qpipeinfo(conn,
- inbuf,
- outbuf,
- length,
- bufsize,
+ return call_trans2qpipeinfo(conn, req,
tran_call,
pparams,
total_params,
@@ -3464,7 +3473,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- return ERROR_NT(NT_STATUS_INVALID_LEVEL);
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
}
if(fsp && (fsp->fake_file_handle)) {
@@ -3488,11 +3498,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/* Always do lstat for UNIX calls. */
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
- return UNIXERROR(ERRDOS,ERRbadpath);
+ reply_unixerror(req,ERRDOS,ERRbadpath);
+ return;
}
} else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
- return UNIXERROR(ERRDOS,ERRbadpath);
+ reply_unixerror(req, ERRDOS, ERRbadpath);
+ return;
}
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
@@ -3501,12 +3513,15 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/*
* Original code - this is an open file.
*/
- CHECK_FSP(fsp,conn);
+ if (!check_fsp(conn, req, fsp, &current_user)) {
+ return;
+ }
pstrcpy(fname, fsp->fsp_name);
if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRbadfid));
+ reply_unixerror(req, ERRDOS, ERRbadfid);
+ return;
}
pos = fsp->fh->position_information;
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
@@ -3518,7 +3533,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/* qpathinfo */
if (total_params < 7) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
info_level = SVAL(params,0);
@@ -3526,14 +3542,16 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- return ERROR_NT(NT_STATUS_INVALID_LEVEL);
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
}
srvstr_get_path(params, req->flags2, fname, &params[6],
sizeof(fname), total_params - 6,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
status = resolve_dfspath(conn,
@@ -3541,36 +3559,44 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
}
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
- return UNIXERROR(ERRDOS,ERRbadpath);
+ reply_unixerror(req, ERRDOS, ERRbadpath);
+ return;
}
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
- return UNIXERROR(ERRDOS,ERRbadpath);
+ reply_unixerror(req, ERRDOS, ERRbadpath);
+ return;
}
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
delete_pending = get_delete_on_close_flag(fileid);
if (delete_pending) {
- return ERROR_NT(NT_STATUS_DELETE_PENDING);
+ reply_nterror(req, NT_STATUS_DELETE_PENDING);
+ return;
}
}
@@ -3586,7 +3612,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- return ERROR_NT(NT_STATUS_INVALID_LEVEL);
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
}
DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
@@ -3614,29 +3641,38 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint32 ea_size;
if (total_data < 4) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
ea_size = IVAL(pdata,0);
if (total_data > 0 && ea_size != total_data) {
DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
if (!lp_ea_support(SNUM(conn))) {
- return ERROR_DOS(ERRDOS,ERReasnotsupported);
+ reply_doserror(req, ERRDOS,
+ ERReasnotsupported);
+ return;
}
if ((data_ctx = talloc_init("ea_list")) == NULL) {
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
/* Pull out the list of names. */
ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
talloc_destroy(data_ctx);
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
break;
}
@@ -3644,15 +3680,19 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_POSIX_LOCK:
{
if (fsp == NULL || fsp->fh->fd == -1) {
- return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return;
}
if (total_data != POSIX_LOCK_DATA_SIZE) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
if ((data_ctx = talloc_init("lock_request")) == NULL) {
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
/* Copy the lock range data. */
@@ -3660,7 +3700,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
data_ctx, pdata, total_data);
if (!lock_data) {
talloc_destroy(data_ctx);
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
}
default:
@@ -3670,7 +3711,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*pparams = (char *)SMB_REALLOC(*pparams,2);
if (*pparams == NULL) {
talloc_destroy(data_ctx);
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
params = *pparams;
SSVAL(params,0,0);
@@ -3678,9 +3720,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL ) {
talloc_destroy(data_ctx);
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
pdata = *ppdata;
+ dstart = pdata;
+ dend = dstart + data_size - 1;
create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
mtime_ts = get_mtimespec(&sbuf);
@@ -3757,7 +3802,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
if (tran_call == TRANSACT2_QFILEINFO) {
/* os/2 needs this ? really ?*/
- return ERROR_DOS(ERRDOS,ERRbadfunc);
+ reply_doserror(req, ERRDOS, ERRbadfunc);
+ return;
}
data_size = 0;
param_size = 0;
@@ -3794,7 +3840,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
data_ctx = talloc_init("ea_ctx");
if (!data_ctx) {
- return ERROR_NT(NT_STATUS_NO_MEMORY);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len);
@@ -3870,8 +3917,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if(!mangle_is_8_3(short_name, True, conn->params)) {
mangle_map(short_name,True,True,conn->params);
}
- len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2),
- pdata+4, short_name, -1,
+ len = srvstr_push(dstart, req->flags2,
+ pdata+4, short_name,
+ PTR_DIFF(dend, pdata+4),
STR_UNICODE);
data_size = 4 + len;
SIVAL(pdata,0,len);
@@ -3882,8 +3930,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/*
this must be *exactly* right for ACLs on mapped drives to work
*/
- len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2),
- pdata+4, dos_fname, -1, STR_UNICODE);
+ len = srvstr_push(dstart, req->flags2,
+ pdata+4, dos_fname,
+ PTR_DIFF(dend, pdata+4),
+ STR_UNICODE);
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
data_size = 4 + len;
SIVAL(pdata,0,len);
@@ -3924,8 +3974,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
pdata += 24;
SIVAL(pdata,0,ea_size);
pdata += 4; /* EA info */
- len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2),
- pdata+4, dos_fname, -1, STR_UNICODE);
+ len = srvstr_push(dstart, req->flags2,
+ pdata+4, dos_fname,
+ PTR_DIFF(dend, pdata+4),
+ STR_UNICODE);
SIVAL(pdata,0,len);
pdata += 4 + len;
data_size = PTR_DIFF(pdata,(*ppdata));
@@ -4078,18 +4130,25 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_mode))
- return(UNIXERROR(ERRSRV,ERRbadlink));
+ if(!S_ISLNK(sbuf.st_mode)) {
+ reply_unixerror(req, ERRSRV,
+ ERRbadlink);
+ return;
+ }
#else
- return(UNIXERROR(ERRDOS,ERRbadlink));
+ reply_unixerror(req, ERRDOS, ERRbadlink);
+ return;
#endif
len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */
- if (len == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if (len == -1) {
+ reply_unixerror(req, ERRDOS,
+ ERRnoaccess);
+ return;
+ }
buffer[len] = 0;
- len = srvstr_push(outbuf,
- SVAL(outbuf, smb_flg2),
- pdata, buffer, -1,
+ len = srvstr_push(dstart, req->flags2,
+ pdata, buffer,
+ PTR_DIFF(dend, pdata),
STR_TERMINATE);
pdata += len;
data_size = PTR_DIFF(pdata,(*ppdata));
@@ -4114,7 +4173,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (file_acl == NULL && no_acl_syscall_error(errno)) {
DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
fname ));
- return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
+ reply_nterror(
+ req,
+ NT_STATUS_NOT_IMPLEMENTED);
+ return;
}
if (S_ISDIR(sbuf.st_mode)) {
@@ -4140,7 +4202,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
+ reply_nterror(
+ req,
+ NT_STATUS_BUFFER_TOO_SMALL);
+ return;
}
SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
@@ -4153,7 +4218,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ reply_nterror(
+ req, NT_STATUS_INTERNAL_ERROR);
+ return;
}
if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
if (file_acl) {
@@ -4162,7 +4229,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ reply_nterror(
+ req,
+ NT_STATUS_INTERNAL_ERROR);
+ return;
}
if (file_acl) {
@@ -4186,7 +4256,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
enum brl_type lock_type;
if (total_data != POSIX_LOCK_DATA_SIZE) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
}
switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
@@ -4200,7 +4272,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
default:
/* There's no point in asking for an unlock... */
talloc_destroy(data_ctx);
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(
+ req,
+ NT_STATUS_INVALID_PARAMETER);
+ return;
}
lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
@@ -4245,18 +4320,21 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
} else {
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
break;
}
default:
- return ERROR_NT(NT_STATUS_INVALID_LEVEL);
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
}
- send_trans2_replies(inbuf, outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
+ send_trans2_replies_new(req, params, param_size, *ppdata, data_size,
+ max_data_bytes);
- return(-1);
+ return;
}
/****************************************************************************
@@ -6770,12 +6848,10 @@ static int handle_trans2(connection_struct *conn, struct smb_request *req,
case TRANSACT2_QFILEINFO:
{
START_PROFILE(Trans2_qpathinfo);
- outsize = call_trans2qfilepathinfo(
- conn, req,
- inbuf, outbuf, size, bufsize, state->call,
- &state->param, state->total_param,
- &state->data, state->total_data,
- state->max_data_return);
+ call_trans2qfilepathinfo(conn, req, state->call,
+ &state->param, state->total_param,
+ &state->data, state->total_data,
+ state->max_data_return);
END_PROFILE(Trans2_qpathinfo);
break;
}