extern uint32 global_client_caps;
extern struct current_user current_user;
-extern BOOL global_encrypted_passwords_negotiated;
+extern bool global_encrypted_passwords_negotiated;
/****************************************************************************
Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
#define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
static NTSTATUS check_path_syntax_internal(char *path,
- BOOL posix_path,
- BOOL *p_last_component_contains_wcard)
+ bool posix_path,
+ bool *p_last_component_contains_wcard)
{
char *d = path;
const char *s = path;
NTSTATUS ret = NT_STATUS_OK;
- BOOL start_of_name_component = True;
+ bool start_of_name_component = True;
*p_last_component_contains_wcard = False;
NTSTATUS check_path_syntax(char *path)
{
- BOOL ignore;
+ bool ignore;
return check_path_syntax_internal(path, False, &ignore);
}
a wildcard.
****************************************************************************/
-NTSTATUS check_path_syntax_wcard(char *path, BOOL *p_contains_wcard)
+NTSTATUS check_path_syntax_wcard(char *path, bool *p_contains_wcard)
{
return check_path_syntax_internal(path, False, p_contains_wcard);
}
NTSTATUS check_path_syntax_posix(char *path)
{
- BOOL ignore;
+ bool ignore;
return check_path_syntax_internal(path, True, &ignore);
}
size_t src_len,
int flags,
NTSTATUS *err,
- BOOL *contains_wcard)
+ bool *contains_wcard)
{
size_t ret;
Check if we have a correct fsp pointing to a file. Basic check for open fsp.
****************************************************************************/
-BOOL check_fsp_open(connection_struct *conn, struct smb_request *req,
+bool check_fsp_open(connection_struct *conn, struct smb_request *req,
files_struct *fsp, struct current_user *user)
{
if (!(fsp) || !(conn)) {
CHECK_FSP macro.
****************************************************************************/
-BOOL check_fsp(connection_struct *conn, struct smb_request *req,
+bool check_fsp(connection_struct *conn, struct smb_request *req,
files_struct *fsp, struct current_user *user)
{
if (!check_fsp_open(conn, req, fsp, user)) {
Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
****************************************************************************/
-BOOL fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
+bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
files_struct *fsp, struct current_user *user)
{
if ((fsp) && (conn) && ((conn)==(fsp)->conn)
/*
* We only really use 4 bytes of the outbuf, but for the smb_setlen
- * calculation & friends (send_smb uses that) we need the full smb
+ * calculation & friends (srv_send_smb uses that) we need the full smb
* header.
*/
char outbuf[smb_size];
- static BOOL already_got_session = False;
+ static bool already_got_session = False;
*name1 = *name2 = 0;
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- send_smb(smbd_server_fd(), outbuf);
+ srv_send_smb(smbd_server_fd(), outbuf, false);
return;
}
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tcon(connection_struct *conn, struct smb_request *req)
+void reply_tcon(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
const char *service;
char *service_buf = NULL;
char *password = NULL;
password_blob = data_blob(password, pwlen+1);
conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
+ req->conn = conn;
data_blob_clear_free(&password_blob);
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
+void reply_tcon_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *service = NULL;
DATA_BLOB password;
TALLOC_CTX *ctx = talloc_tos();
/* we might have to close an old one */
if ((tcon_flags & 0x1) && conn) {
close_cnum(conn,req->vuid);
+ req->conn = NULL;
+ conn = NULL;
}
if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
conn = make_connection(service, password, client_devicetype,
req->vuid, &nt_status);
+ req->conn =conn;
data_blob_clear_free(&password);
Reply to an unknown type.
****************************************************************************/
-int reply_unknown(char *inbuf,char *outbuf)
-{
- int type;
- type = CVAL(inbuf,smb_com);
-
- DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
- smb_fn_name(type), type, type));
-
- return(ERROR_DOS(ERRSRV,ERRunknownsmb));
-}
-
void reply_unknown_new(struct smb_request *req, uint8 type)
{
DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_ioctl(connection_struct *conn, struct smb_request *req)
+void reply_ioctl(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
uint16 device;
uint16 function;
uint32 ioctl_code;
Reply to a checkpath.
****************************************************************************/
-void reply_checkpath(connection_struct *conn, struct smb_request *req)
+void reply_checkpath(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
Reply to a getatr.
****************************************************************************/
-void reply_getatr(connection_struct *conn, struct smb_request *req)
+void reply_getatr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
SMB_STRUCT_STAT sbuf;
int mode=0;
Reply to a setatr.
****************************************************************************/
-void reply_setatr(connection_struct *conn, struct smb_request *req)
+void reply_setatr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
int mode;
time_t mtime;
else
mode &= ~aDIR;
- if (file_set_dosmode(conn,fname,mode,&sbuf,False) != 0) {
+ if (file_set_dosmode(conn,fname,mode,&sbuf,NULL,false) != 0) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
END_PROFILE(SMBsetatr);
return;
Reply to a dskattr.
****************************************************************************/
-void reply_dskattr(connection_struct *conn, struct smb_request *req)
+void reply_dskattr(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT dfree,dsize,bsize;
START_PROFILE(SMBdskattr);
total_space = dsize * (double)bsize;
free_space = dfree * (double)bsize;
- dsize = (total_space+63*512) / (64*512);
- dfree = (free_space+63*512) / (64*512);
+ dsize = (SMB_BIG_UINT)((total_space+63*512) / (64*512));
+ dfree = (SMB_BIG_UINT)((free_space+63*512) / (64*512));
if (dsize > 0xFFFF) dsize = 0xFFFF;
if (dfree > 0xFFFF) dfree = 0xFFFF;
Can be called from SMBsearch, SMBffirst or SMBfunique.
****************************************************************************/
-void reply_search(connection_struct *conn, struct smb_request *req)
+void reply_search(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *mask = NULL;
char *directory = NULL;
char *fname = NULL;
uint32 dirtype;
unsigned int numentries = 0;
unsigned int maxentries = 0;
- BOOL finished = False;
+ bool finished = False;
char *p;
int status_len;
char *path = NULL;
char status[21];
int dptr_num= -1;
- BOOL check_descend = False;
- BOOL expect_close = False;
+ bool check_descend = False;
+ bool expect_close = False;
NTSTATUS nt_status;
- BOOL mask_contains_wcard = False;
- BOOL allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
+ bool mask_contains_wcard = False;
+ bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBsearch);
Reply to a fclose (stop directory search).
****************************************************************************/
-void reply_fclose(connection_struct *conn, struct smb_request *req)
+void reply_fclose(struct smb_request *req)
{
int status_len;
char status[21];
char *p;
char *path = NULL;
NTSTATUS err;
- BOOL path_contains_wcard = False;
+ bool path_contains_wcard = False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBfclose);
Reply to an open.
****************************************************************************/
-void reply_open(connection_struct *conn, struct smb_request *req)
+void reply_open(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint32 fattr=0;
SMB_OFF_T size = 0;
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBopen);
- return;
- }
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
- }
-
- if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
- &access_mask, &share_mode, &create_disposition, &create_options)) {
+ if (!map_open_params_to_ntcreate(
+ fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
+ &share_mode, &create_disposition, &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
END_PROFILE(SMBopen);
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- dos_attr,
- oplock_request,
- &info, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ dos_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &info, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
Reply to an open and X.
****************************************************************************/
-void reply_open_and_X(connection_struct *conn, struct smb_request *req)
+void reply_open_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint16 open_flags;
int deny_mode;
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBopenX);
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopenX);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBopenX);
- return;
- }
-
- if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
- &access_mask,
- &share_mode,
- &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(
+ fname, deny_mode, smb_ofun, &access_mask,
+ &share_mode, &create_disposition, &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
END_PROFILE(SMBopenX);
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- smb_attr,
- oplock_request,
- &smb_action, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ smb_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ &smb_action, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
/****************************************************************************
Reply to a SMBulogoffX.
- conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
+void reply_ulogoffX(struct smb_request *req)
{
user_struct *vuser;
Reply to a mknew or a create.
****************************************************************************/
-void reply_mknew(connection_struct *conn, struct smb_request *req)
+void reply_mknew(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
int com;
uint32 fattr = 0;
return;
}
- status = resolve_dfspath(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcreate);
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBcreate);
- return;
- }
-
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBcreate);
- return;
- }
-
if (fattr & aVOLID) {
DEBUG(0,("Attempt to create file (%s) with volid set - "
"please report this\n", fname));
create_disposition = FILE_OVERWRITE_IF;
}
- /* Open file using ntcreate. */
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- fattr,
- oplock_request,
- NULL, &fsp);
+ status = create_file(conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ fname, /* fname */
+ access_mask, /* access_mask */
+ share_mode, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ fattr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
Reply to a create temporary file.
****************************************************************************/
-void reply_ctemp(connection_struct *conn, struct smb_request *req)
+void reply_ctemp(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *fname = NULL;
uint32 fattr;
files_struct *fsp;
****************************************************************************/
NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
- uint32 dirtype, const char *name_in, BOOL has_wild)
+ uint32 dirtype, const char *name_in, bool has_wild)
{
const char *directory = NULL;
char *mask = NULL;
Reply to a unlink
****************************************************************************/
-void reply_unlink(connection_struct *conn, struct smb_request *req)
+void reply_unlink(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
uint32 dirtype;
NTSTATUS status;
- BOOL path_contains_wcard = False;
+ bool path_contains_wcard = False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBunlink);
Reply to a readbraw (core+ protocol).
****************************************************************************/
-void reply_readbraw(connection_struct *conn, struct smb_request *req)
+void reply_readbraw(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
START_PROFILE(SMBreadbraw);
- if (srv_is_signing_active()) {
- exit_server_cleanly("reply_readbraw: SMB signing is active - "
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
+ exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
"raw reads/writes are disallowed.");
}
Reply to a lockread (core+ protocol).
****************************************************************************/
-void reply_lockread(connection_struct *conn, struct smb_request *req)
+void reply_lockread(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t nread = -1;
char *data;
SMB_OFF_T startpos;
return;
}
- set_message((char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
Reply to a read.
****************************************************************************/
-void reply_read(connection_struct *conn, struct smb_request *req)
+void reply_read(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtoread;
ssize_t nread = 0;
char *data;
return;
}
- set_message((char *)req->outbuf, 5, nread+3, False);
+ srv_set_message((char *)req->outbuf, 5, nread+3, False);
SSVAL(req->outbuf,smb_vwv0,nread);
SSVAL(req->outbuf,smb_vwv5,nread+3);
int outsize;
char *data;
- outsize = set_message(outbuf,12,smb_maxcnt,False);
+ outsize = srv_set_message(outbuf,12,smb_maxcnt,False);
data = smb_buf(outbuf);
memset(outbuf+smb_vwv0,'\0',24); /* valgrind init. */
*/
if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
+ !is_encrypted_packet(req->inbuf) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
Reply to a read and X.
****************************************************************************/
-void reply_read_and_X(connection_struct *conn, struct smb_request *req)
+void reply_read_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
SMB_OFF_T startpos;
size_t smb_maxcnt;
- BOOL big_readX = False;
+ bool big_readX = False;
#if 0
size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
#endif
END_PROFILE(SMBreadX);
return;
}
- /* We currently don't do this on signed data. */
- if (srv_is_signing_active()) {
+ /* We currently don't do this on signed or sealed data. */
+ if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
Reply to a writebraw (core+ or LANMAN1.0 protocol).
****************************************************************************/
-void reply_writebraw(connection_struct *conn, struct smb_request *req)
+void reply_writebraw(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int outsize = 0;
char *buf = NULL;
ssize_t nwritten=0;
size_t tcount;
SMB_OFF_T startpos;
char *data=NULL;
- BOOL write_through;
+ bool write_through;
files_struct *fsp;
NTSTATUS status;
}
if (numtowrite>0) {
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
* it to send more bytes */
memcpy(buf, req->inbuf, smb_size);
- outsize = set_message(buf,
+ outsize = srv_set_message(buf,
Protocol>PROTOCOL_COREPLUS?1:0,0,True);
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
- if (!send_smb(smbd_server_fd(),buf)) {
- exit_server_cleanly("reply_writebraw: send_smb "
+ if (!srv_send_smb(smbd_server_fd(),
+ buf,
+ IS_CONN_ENCRYPTED(conn))) {
+ exit_server_cleanly("reply_writebraw: srv_send_smb "
"failed.");
}
/* Now read the raw data into the buffer and write it */
- if (read_smb_length(smbd_server_fd(),buf,SMB_SECONDARY_WAIT) == -1) {
+ if (read_smb_length(smbd_server_fd(),buf,
+ SMB_SECONDARY_WAIT, get_srv_read_error()) == -1) {
exit_server_cleanly("secondary writebraw failed");
}
(int)tcount,(int)nwritten,(int)numtowrite));
}
- if (read_data(smbd_server_fd(), buf+4, numtowrite)
+ if (read_data(smbd_server_fd(), buf+4, numtowrite,get_srv_read_error())
!= numtowrite ) {
DEBUG(0,("reply_writebraw: Oversize secondary write "
"raw read failed (%s). Terminating\n",
exit_server_cleanly("secondary writebraw failed");
}
- nwritten = write_file(fsp,buf+4,startpos+nwritten,numtowrite);
+ nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
if (nwritten == -1) {
TALLOC_FREE(buf);
reply_unixerror(req, ERRHRD, ERRdiskfull);
Reply to a writeunlock (core+).
****************************************************************************/
-void reply_writeunlock(connection_struct *conn, struct smb_request *req)
+void reply_writeunlock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
ssize_t nwritten = -1;
size_t numtowrite;
SMB_OFF_T startpos;
if(numtowrite == 0) {
nwritten = 0;
} else {
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
status = sync_file(conn, fsp, False /* write through */);
return;
}
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
END_PROFILE(SMBwriteunlock);
return;
Reply to a write.
****************************************************************************/
-void reply_write(connection_struct *conn, struct smb_request *req)
+void reply_write(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtowrite;
ssize_t nwritten = -1;
SMB_OFF_T startpos;
return;
}
} else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(req,fsp,data,startpos,numtowrite);
status = sync_file(conn, fsp, False);
if (!NT_STATUS_IS_OK(status)) {
return;
}
+/****************************************************************************
+ Ensure a buffer is a valid writeX for recvfile purposes.
+****************************************************************************/
+
+#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
+ (2*14) + /* word count (including bcc) */ \
+ 1 /* pad byte */)
+
+bool is_valid_writeX_buffer(const uint8_t *inbuf)
+{
+ size_t numtowrite;
+ connection_struct *conn = NULL;
+ unsigned int doff = 0;
+ size_t len = smb_len_large(inbuf);
+
+ if (is_encrypted_packet(inbuf)) {
+ /* Can't do this on encrypted
+ * connections. */
+ return false;
+ }
+
+ if (CVAL(inbuf,smb_com) != SMBwriteX) {
+ return false;
+ }
+
+ if (CVAL(inbuf,smb_vwv0) != 0xFF ||
+ CVAL(inbuf,smb_wct) != 14) {
+ DEBUG(10,("is_valid_writeX_buffer: chained or "
+ "invalid word length.\n"));
+ return false;
+ }
+
+ conn = conn_find(SVAL(inbuf, smb_tid));
+ if (conn == NULL) {
+ DEBUG(10,("is_valid_writeX_buffer: bad tid\n"));
+ return false;
+ }
+ if (IS_IPC(conn)) {
+ DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n"));
+ return false;
+ }
+ doff = SVAL(inbuf,smb_vwv11);
+
+ numtowrite = SVAL(inbuf,smb_vwv10);
+
+ if (len > doff && len - doff > 0xFFFF) {
+ numtowrite |= (((size_t)SVAL(inbuf,smb_vwv9))<<16);
+ }
+
+ if (numtowrite == 0) {
+ DEBUG(10,("is_valid_writeX_buffer: zero write\n"));
+ return false;
+ }
+
+ /* Ensure the sizes match up. */
+ if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) {
+ /* no pad byte...old smbclient :-( */
+ DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n",
+ (unsigned int)doff,
+ (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE));
+ return false;
+ }
+
+ if (len - doff != numtowrite) {
+ DEBUG(10,("is_valid_writeX_buffer: doff mismatch "
+ "len = %u, doff = %u, numtowrite = %u\n",
+ (unsigned int)len,
+ (unsigned int)doff,
+ (unsigned int)numtowrite ));
+ return false;
+ }
+
+ DEBUG(10,("is_valid_writeX_buffer: true "
+ "len = %u, doff = %u, numtowrite = %u\n",
+ (unsigned int)len,
+ (unsigned int)doff,
+ (unsigned int)numtowrite ));
+
+ return true;
+}
+
/****************************************************************************
Reply to a write and X.
****************************************************************************/
-void reply_write_and_X(connection_struct *conn, struct smb_request *req)
+void reply_write_and_X(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
SMB_OFF_T startpos;
size_t numtowrite;
- BOOL write_through;
+ bool write_through;
ssize_t nwritten;
unsigned int smb_doff;
unsigned int smblen;
char *data;
- BOOL large_writeX;
NTSTATUS status;
START_PROFILE(SMBwriteX);
numtowrite = SVAL(req->inbuf,smb_vwv10);
smb_doff = SVAL(req->inbuf,smb_vwv11);
smblen = smb_len(req->inbuf);
- large_writeX = ((req->wct == 14) && (smblen > 0xFFFF));
- /* Deal with possible LARGE_WRITEX */
- if (large_writeX) {
- numtowrite |= ((((size_t)SVAL(req->inbuf,smb_vwv9)) & 1 )<<16);
+ if (req->unread_bytes > 0xFFFF ||
+ (smblen > smb_doff &&
+ smblen - smb_doff > 0xFFFF)) {
+ numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
}
- if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
- reply_doserror(req, ERRDOS, ERRbadmem);
- END_PROFILE(SMBwriteX);
- return;
+ if (req->unread_bytes) {
+ /* Can't do a recvfile write on IPC$ */
+ if (IS_IPC(conn)) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
+ if (numtowrite != req->unread_bytes) {
+ reply_doserror(req, ERRDOS, ERRbadmem);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
+ } else {
+ if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
+ smb_doff + numtowrite > smblen) {
+ reply_doserror(req, ERRDOS, ERRbadmem);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
}
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
+ if (req->unread_bytes) {
+ reply_doserror(req, ERRDOS, ERRbadmem);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
reply_pipe_write_and_X(req);
END_PROFILE(SMBwriteX);
return;
nwritten = 0;
} else {
- if (schedule_aio_write_and_X(conn, req, fsp, data, startpos,
- numtowrite)) {
+ if (req->unread_bytes == 0 &&
+ schedule_aio_write_and_X(conn, req, fsp, data,
+ startpos, numtowrite)) {
END_PROFILE(SMBwriteX);
return;
}
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
-
+
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
END_PROFILE(SMBwriteX);
reply_outbuf(req, 6, 0);
SSVAL(req->outbuf,smb_vwv2,nwritten);
- if (large_writeX)
- SSVAL(req->outbuf,smb_vwv4,(nwritten>>16)&1);
+ SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
if (nwritten < (ssize_t)numtowrite) {
SCVAL(req->outbuf,smb_rcls,ERRHRD);
Reply to a lseek.
****************************************************************************/
-void reply_lseek(connection_struct *conn, struct smb_request *req)
+void reply_lseek(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_OFF_T startpos;
SMB_OFF_T res= -1;
int mode,umode;
}
if (umode == SEEK_END) {
- if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) {
+ if((res = SMB_VFS_LSEEK(fsp,startpos,umode)) == -1) {
if(errno == EINVAL) {
SMB_OFF_T current_pos = startpos;
SMB_STRUCT_STAT sbuf;
current_pos += sbuf.st_size;
if(current_pos < 0)
- res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET);
+ res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
}
}
Reply to a flush.
****************************************************************************/
-void reply_flush(connection_struct *conn, struct smb_request *req)
+void reply_flush(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
uint16 fnum;
files_struct *fsp;
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_exit(connection_struct *conn, struct smb_request *req)
+void reply_exit(struct smb_request *req)
{
START_PROFILE(SMBexit);
Reply to a close - has to deal with closing a directory opened by NT SMB's.
****************************************************************************/
-void reply_close(connection_struct *conn, struct smb_request *req)
+void reply_close(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp = NULL;
START_PROFILE(SMBclose);
Reply to a writeclose (Core+ protocol).
****************************************************************************/
-void reply_writeclose(connection_struct *conn, struct smb_request *req)
+void reply_writeclose(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
size_t numtowrite;
ssize_t nwritten = -1;
NTSTATUS close_status = NT_STATUS_OK;
return;
}
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(req,fsp,data,startpos,numtowrite);
set_filetime(conn, fsp->fsp_name, mtime);
Reply to a lock.
****************************************************************************/
-void reply_lock(connection_struct *conn, struct smb_request *req)
+void reply_lock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp;
Reply to a unlock.
****************************************************************************/
-void reply_unlock(connection_struct *conn, struct smb_request *req)
+void reply_unlock(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp;
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_tdis(connection_struct *conn, struct smb_request *req)
+void reply_tdis(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
START_PROFILE(SMBtdis);
if (!conn) {
conn->used = False;
close_cnum(conn,req->vuid);
+ req->conn = NULL;
reply_outbuf(req, 0, 0);
END_PROFILE(SMBtdis);
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-void reply_echo(connection_struct *conn, struct smb_request *req)
+void reply_echo(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int smb_reverb;
int seq_num;
unsigned int data_len = smb_buflen(req->inbuf);
SSVAL(req->outbuf,smb_vwv0,seq_num);
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("reply_echo: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)||req->encrypted))
+ exit_server_cleanly("reply_echo: srv_send_smb failed.");
}
DEBUG(3,("echo %d times\n", smb_reverb));
Reply to a printopen.
****************************************************************************/
-void reply_printopen(connection_struct *conn, struct smb_request *req)
+void reply_printopen(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
NTSTATUS status;
Reply to a printclose.
****************************************************************************/
-void reply_printclose(connection_struct *conn, struct smb_request *req)
+void reply_printclose(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
NTSTATUS status;
Reply to a printqueue.
****************************************************************************/
-void reply_printqueue(connection_struct *conn, struct smb_request *req)
+void reply_printqueue(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int max_count;
int start_index;
Reply to a printwrite.
****************************************************************************/
-void reply_printwrite(connection_struct *conn, struct smb_request *req)
+void reply_printwrite(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
int numtowrite;
char *data;
files_struct *fsp;
data = smb_buf(req->inbuf) + 3;
- if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
+ if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
END_PROFILE(SMBsplwr);
return;
Reply to a mkdir.
****************************************************************************/
-void reply_mkdir(connection_struct *conn, struct smb_request *req)
+void reply_mkdir(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *directory = NULL;
NTSTATUS status;
SMB_STRUCT_STAT sbuf;
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
tree recursively. Return True on ok, False on fail.
****************************************************************************/
-static BOOL recursive_rmdir(TALLOC_CTX *ctx,
+static bool recursive_rmdir(TALLOC_CTX *ctx,
connection_struct *conn,
char *directory)
{
const char *dname = NULL;
- BOOL ret = True;
+ bool ret = True;
long offset = 0;
struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
Reply to a rmdir.
****************************************************************************/
-void reply_rmdir(connection_struct *conn, struct smb_request *req)
+void reply_rmdir(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *directory = NULL;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
Resolve wildcards in a filename rename.
********************************************************************/
-static BOOL resolve_wildcards(TALLOC_CTX *ctx,
+static bool resolve_wildcards(TALLOC_CTX *ctx,
const char *name1,
const char *name2,
char **pp_newname)
const char *newname)
{
files_struct *fsp;
- BOOL did_rename = False;
+ bool did_rename = False;
for(fsp = file_find_di_first(lck->id); fsp;
fsp = file_find_di_next(fsp)) {
report from <AndyLiebman@aol.com>.
****************************************************************************/
-static BOOL rename_path_prefix_equal(const char *src, const char *dest)
+static bool rename_path_prefix_equal(const char *src, const char *dest)
{
const char *psrc = src;
const char *pdst = dest;
* Do the notify calls from a rename
*/
-static void notify_rename(connection_struct *conn, BOOL is_dir,
+static void notify_rename(connection_struct *conn, bool is_dir,
const char *oldpath, const char *newpath)
{
char *olddir, *newdir;
char *newname,
const char *newname_last_component,
uint32 attrs,
- BOOL replace_if_exists)
+ bool replace_if_exists)
{
TALLOC_CTX *ctx = talloc_tos();
SMB_STRUCT_STAT sbuf, sbuf1;
NTSTATUS status = NT_STATUS_OK;
struct share_mode_lock *lck = NULL;
- BOOL dst_exists;
+ bool dst_exists;
ZERO_STRUCT(sbuf);
const char *name_in,
const char *newname_in,
uint32 attrs,
- BOOL replace_if_exists,
- BOOL src_has_wild,
- BOOL dest_has_wild)
+ bool replace_if_exists,
+ bool src_has_wild,
+ bool dest_has_wild)
{
char *directory = NULL;
char *mask = NULL;
/*
* No wildcards - just process the one file.
*/
- BOOL is_short_name = mangle_is_8_3(name, True, conn->params);
+ bool is_short_name = mangle_is_8_3(name, True, conn->params);
/* Add a terminating '/' to the directory name. */
directory = talloc_asprintf_append(directory,
files_struct *fsp = NULL;
char *fname = NULL;
char *destname = NULL;
- BOOL sysdir_entry = False;
+ bool sysdir_entry = False;
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
Reply to a mv.
****************************************************************************/
-void reply_mv(connection_struct *conn, struct smb_request *req)
+void reply_mv(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
char *p;
uint32 attrs;
NTSTATUS status;
- BOOL src_has_wcard = False;
- BOOL dest_has_wcard = False;
+ bool src_has_wcard = False;
+ bool dest_has_wcard = False;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBmv);
const char *dest1,
int ofun,
int count,
- BOOL target_is_directory)
+ bool target_is_directory)
{
SMB_STRUCT_STAT src_sbuf, sbuf2;
SMB_OFF_T ret=-1;
}
if ((ofun&3) == 1) {
- if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) {
+ if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
/*
* Stop the copy from occurring.
Reply to a file copy.
****************************************************************************/
-void reply_copy(connection_struct *conn, struct smb_request *req)
+void reply_copy(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
char *directory = NULL;
int tid2;
int ofun;
int flags;
- BOOL target_is_directory=False;
- BOOL source_has_wild = False;
- BOOL dest_has_wild = False;
+ bool target_is_directory=False;
+ bool source_has_wild = False;
+ bool dest_has_wild = False;
SMB_STRUCT_STAT sbuf1, sbuf2;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
Get a lock pid, dealing with large count requests.
****************************************************************************/
-uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
+uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
{
if(!large_file_format)
return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
Get a lock count, dealing with large count requests.
****************************************************************************/
-SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format)
+SMB_BIG_UINT get_lock_count( char *data, int data_offset, bool large_file_format)
{
SMB_BIG_UINT count = 0;
Get a lock offset, dealing with large offset requests.
****************************************************************************/
-SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
+SMB_BIG_UINT get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
{
SMB_BIG_UINT offset = 0;
Reply to a lockingX request.
****************************************************************************/
-void reply_lockingX(connection_struct *conn, struct smb_request *req)
+void reply_lockingX(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
files_struct *fsp;
unsigned char locktype;
unsigned char oplocklevel;
int32 lock_timeout;
int i;
char *data;
- BOOL large_file_format;
- BOOL err;
+ bool large_file_format;
+ bool err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
START_PROFILE(SMBlockingX);
*/
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
/* Client can insist on breaking to none. */
- BOOL break_to_none = (oplocklevel == 0);
- BOOL result;
+ bool break_to_none = (oplocklevel == 0);
+ bool result;
DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
"for fnum = %d\n", (unsigned int)oplocklevel,
offset,
WINDOWS_LOCK);
} else {
- BOOL blocking_lock = lock_timeout ? True : False;
- BOOL defer_lock = False;
+ bool blocking_lock = lock_timeout ? True : False;
+ bool defer_lock = False;
struct byte_range_lock *br_lck;
uint32 block_smbpid;
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)req->inbuf,
- smb_len(req->inbuf)+4,
+ req,
fsp,
lock_timeout,
i,
please contact vl@samba.org
****************************************************************************/
-void reply_readbmpx(connection_struct *conn, struct smb_request *req)
+void reply_readbmpx(struct smb_request *req)
{
START_PROFILE(SMBreadBmpx);
reply_doserror(req, ERRSRV, ERRuseSTD);
please contact vl@samba.org
****************************************************************************/
-void reply_readbs(connection_struct *conn, struct smb_request *req)
+void reply_readbs(struct smb_request *req)
{
START_PROFILE(SMBreadBs);
reply_doserror(req, ERRSRV, ERRuseSTD);
Reply to a SMBsetattrE.
****************************************************************************/
-void reply_setattrE(connection_struct *conn, struct smb_request *req)
+void reply_setattrE(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
struct timespec ts[2];
files_struct *fsp;
please contact vl@samba.org
****************************************************************************/
-void reply_writebmpx(connection_struct *conn, struct smb_request *req)
+void reply_writebmpx(struct smb_request *req)
{
START_PROFILE(SMBwriteBmpx);
reply_doserror(req, ERRSRV, ERRuseSTD);
please contact vl@samba.org
****************************************************************************/
-void reply_writebs(connection_struct *conn, struct smb_request *req)
+void reply_writebs(struct smb_request *req)
{
START_PROFILE(SMBwriteBs);
reply_doserror(req, ERRSRV, ERRuseSTD);
Reply to a SMBgetattrE.
****************************************************************************/
-void reply_getattrE(connection_struct *conn, struct smb_request *req)
+void reply_getattrE(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
SMB_STRUCT_STAT sbuf;
int mode;
files_struct *fsp;