diff options
-rw-r--r-- | source3/smbd/process.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 122 |
2 files changed, 85 insertions, 39 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 9604439230..ad6ddba737 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -731,7 +731,7 @@ static const struct smb_message_struct { /* 0x26 */ { "SMBtranss",NULL,reply_transs,AS_USER | CAN_IPC}, /* 0x27 */ { "SMBioctl",NULL,reply_ioctl,0}, /* 0x28 */ { "SMBioctls",NULL, NULL,AS_USER}, -/* 0x29 */ { "SMBcopy",reply_copy,NULL,AS_USER | NEED_WRITE }, +/* 0x29 */ { "SMBcopy",NULL,reply_copy,AS_USER | NEED_WRITE }, /* 0x2a */ { "SMBmove",NULL, NULL,AS_USER | NEED_WRITE }, /* 0x2b */ { "SMBecho",NULL,reply_echo,0}, /* 0x2c */ { "SMBwriteclose",NULL,reply_writeclose,AS_USER}, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index f079ef4b21..831c376e08 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -5640,9 +5640,8 @@ NTSTATUS copy_file(connection_struct *conn, Reply to a file copy. ****************************************************************************/ -int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +void reply_copy(connection_struct *conn, struct smb_request *req) { - int outsize = 0; pstring name; pstring directory; pstring mask,newname; @@ -5650,32 +5649,45 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int count=0; int error = ERRnoaccess; int err = 0; - int tid2 = SVAL(inbuf,smb_vwv0); - int ofun = SVAL(inbuf,smb_vwv1); - int flags = SVAL(inbuf,smb_vwv2); + int tid2; + int ofun; + int flags; BOOL target_is_directory=False; BOOL source_has_wild = False; BOOL dest_has_wild = False; SMB_STRUCT_STAT sbuf1, sbuf2; NTSTATUS status; + START_PROFILE(SMBcopy); + if (req->wct < 3) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + END_PROFILE(SMBcopy); + return; + } + + tid2 = SVAL(req->inbuf,smb_vwv0); + ofun = SVAL(req->inbuf,smb_vwv1); + flags = SVAL(req->inbuf,smb_vwv2); + *directory = *mask = 0; - p = smb_buf(inbuf); - p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p, + p = smb_buf(req->inbuf); + p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name, p, sizeof(name), 0, STR_TERMINATE, &status, &source_has_wild); if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); END_PROFILE(SMBcopy); - return ERROR_NT(status); + return; } - p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), newname, p, + p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wild); if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); END_PROFILE(SMBcopy); - return ERROR_NT(status); + return; } DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); @@ -5683,57 +5695,75 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if (tid2 != conn->cnum) { /* can't currently handle inter share copies XXXX */ DEBUG(3,("Rejecting inter-share copy\n")); + reply_doserror(req, ERRSRV, ERRinvdevice); END_PROFILE(SMBcopy); - return ERROR_DOS(ERRSRV,ERRinvdevice); + return; } - status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &source_has_wild); + status = resolve_dfspath_wcard(conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + name, &source_has_wild); if (!NT_STATUS_IS_OK(status)) { - END_PROFILE(SMBcopy); 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); + END_PROFILE(SMBcopy); + return; } - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } - status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wild); + status = resolve_dfspath_wcard(conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + newname, &dest_has_wild); if (!NT_STATUS_IS_OK(status)) { - END_PROFILE(SMBcopy); 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); + END_PROFILE(SMBcopy); + return; } - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1); if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); END_PROFILE(SMBcopy); - return ERROR_NT(status); + return; } status = unix_convert(conn, newname, dest_has_wild, NULL, &sbuf2); if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); END_PROFILE(SMBcopy); - return ERROR_NT(status); + return; } target_is_directory = VALID_STAT_OF_DIR(sbuf2); if ((flags&1) && target_is_directory) { + reply_doserror(req, ERRDOS, ERRbadfile); END_PROFILE(SMBcopy); - return ERROR_DOS(ERRDOS,ERRbadfile); + return; } if ((flags&2) && !target_is_directory) { + reply_doserror(req, ERRDOS, ERRbadpath); END_PROFILE(SMBcopy); - return ERROR_DOS(ERRDOS,ERRbadpath); + return; } if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) { /* wants a tree copy! XXXX */ DEBUG(3,("Rejecting tree copy\n")); + reply_doserror(req, ERRSRV, ERRerror); END_PROFILE(SMBcopy); - return ERROR_DOS(ERRSRV,ERRerror); + return; } p = strrchr_m(name,'/'); @@ -5764,27 +5794,33 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, pstrcat(directory,mask); if (dest_has_wild) { if (!resolve_wildcards(directory,newname)) { + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBcopy); - return ERROR_NT(NT_STATUS_NO_MEMORY); + return; } } status = check_name(conn, directory); if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } status = check_name(conn, newname); if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } status = copy_file(conn,directory,newname,ofun, count,target_is_directory); if(!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); END_PROFILE(SMBcopy); - return ERROR_NT(status); + return; } else { count++; } @@ -5799,13 +5835,17 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, status = check_name(conn, directory); if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } dir_hnd = OpenDir(conn, directory, mask, 0); if (dir_hnd == NULL) { status = map_nt_error_from_unix(errno); - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } error = ERRbadfile; @@ -5831,12 +5871,16 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, status = check_name(conn, fname); if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } status = check_name(conn, destname); if (!NT_STATUS_IS_OK(status)) { - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBcopy); + return; } DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname)); @@ -5854,19 +5898,21 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, if(err) { /* Error on close... */ errno = err; + reply_unixerror(req, ERRHRD, ERRgeneral); END_PROFILE(SMBcopy); - return(UNIXERROR(ERRHRD,ERRgeneral)); + return; } + reply_doserror(req, ERRDOS, error); END_PROFILE(SMBcopy); - return ERROR_DOS(ERRDOS,error); + return; } - - outsize = set_message(inbuf,outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,count); + + reply_outbuf(req, 1, 0); + SSVAL(req->outbuf,smb_vwv0,count); END_PROFILE(SMBcopy); - return(outsize); + return; } #undef DBGC_CLASS |