extern int max_send;
extern enum protocol_types Protocol;
-extern int smb_read_error;
extern uint32 global_client_caps;
extern struct current_user current_user;
Refuse to allow clients to overwrite our private xattrs.
****************************************************************************/
-static BOOL samba_private_attr_name(const char *unix_ea_name)
+static bool samba_private_attr_name(const char *unix_ea_name)
{
static const char *prohibited_ea_names[] = {
SAMBA_POSIX_INHERITANCE_EA_NAME,
Get one EA value. Fill in a struct ea_struct.
****************************************************************************/
-static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
+static bool get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
const char *fname, char *ea_name, struct ea_struct *pea)
{
/* Get the value of this xattr. Max size is 64k. */
return False;
}
- DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name, (unsigned int)sizeret));
+ DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
dump_data(10, (uint8 *)val, sizeret);
pea->flags = 0;
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-void send_trans2_replies(struct smb_request *req,
+void send_trans2_replies(connection_struct *conn,
+ struct smb_request *req,
const char *params,
int paramsize,
const char *pdata,
int params_sent_thistime, data_sent_thistime, total_sent_thistime;
int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
int data_alignment_offset = 0;
- BOOL overflow = False;
+ bool overflow = False;
/* Modify the data_to_send and datasize and set the error if
we're trying to send more than max_data_bytes. We still send
/* Send the packet */
show_msg((char *)req->outbuf);
- if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
- exit_server_cleanly("send_trans2_replies: send_smb failed.");
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(conn)))
+ exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
char *pdata = *ppdata;
int deny_mode;
int32 open_attr;
- BOOL oplock_request;
+ bool oplock_request;
#if 0
- BOOL return_additional_info;
+ bool return_additional_info;
int16 open_sattr;
time_t open_time;
#endif
fname, (unsigned int)deny_mode, (unsigned int)open_attr,
(unsigned int)open_ofun, open_size));
- /* XXXX we need to handle passed times, sattr and flags */
-
- status = unix_convert(ctx, 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);
- return;
- }
-
if (open_ofun == 0) {
reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
return;
return;
}
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- access_mask,
- share_mode,
- create_disposition,
- create_options,
- open_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 */
+ open_attr, /* file_attributes */
+ oplock_request, /* oplock_request */
+ open_size, /* allocation_size */
+ NULL, /* sd */
+ ea_list, /* ea_list */
+ &fsp, /* result */
+ &smb_action, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
return;
}
- /* Save the requested allocation size. */
- /* Allocate space for the file if a size hint is supplied */
- if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
- SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
- if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
- fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
- if (fsp->is_directory) {
- close_file(fsp,ERROR_CLOSE);
- /* Can't set allocation size on a directory. */
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
- }
- if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
- close_file(fsp,ERROR_CLOSE);
- reply_nterror(req, NT_STATUS_DISK_FULL);
- return;
- }
-
- /* Adjust size here to return the right size in the reply.
- Windows does it this way. */
- size = fsp->initial_allocation_size;
- } else {
- fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
- }
- }
-
- if (ea_list && smb_action == FILE_WAS_CREATED) {
- status = set_ea(conn, fsp, fname, ea_list);
- if (!NT_STATUS_IS_OK(status)) {
- close_file(fsp,ERROR_CLOSE);
- reply_nterror(req, status);
- return;
- }
- }
-
/* Realloc the size of parameters and data we will return */
*pparams = (char *)SMB_REALLOC(*pparams, 30);
if(*pparams == NULL ) {
}
/* Send the required number of replies */
- send_trans2_replies(req, params, 30, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
}
/*********************************************************
Case can be significant or not.
**********************************************************/
-static BOOL exact_match(connection_struct *conn,
+static bool exact_match(connection_struct *conn,
const char *str,
const char *mask)
{
Get a level dependent lanman2 dir entry.
****************************************************************************/
-static BOOL get_lanman2_dir_entry(TALLOC_CTX *ctx,
+static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
connection_struct *conn,
uint16 flags2,
const char *path_mask,
uint32 dirtype,
int info_level,
int requires_resume_key,
- BOOL dont_descend,
+ bool dont_descend,
char **ppdata,
char *base_data,
char *end_data,
int space_remaining,
- BOOL *out_of_space,
- BOOL *got_exact_match,
+ bool *out_of_space,
+ bool *got_exact_match,
int *last_entry_off,
struct ea_list *name_list)
{
const char *dname;
- BOOL found = False;
+ bool found = False;
SMB_STRUCT_STAT sbuf;
const char *mask = NULL;
char *pathreal = NULL;
time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
char *nameptr;
char *last_entry_ptr;
- BOOL was_8_3;
+ bool was_8_3;
uint32 nt_extmode; /* Used for NT connections instead of mode */
- BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
- BOOL check_mangled_names = lp_manglednames(conn->params);
+ bool needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+ bool check_mangled_names = lp_manglednames(conn->params);
char mangled_name[13]; /* mangled 8.3 name. */
*out_of_space = False;
}
while (!found) {
- BOOL got_match;
- BOOL ms_dfs_link = False;
+ bool got_match;
+ bool ms_dfs_link = False;
/* Needed if we run out of space */
long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
}
if (got_match) {
- BOOL isdots = (ISDOT(dname) || ISDOTDOT(dname));
+ bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
if (dont_descend && !isdots) {
continue;
SSVAL(p,20,mode);
p += 23;
nameptr = p;
- p += align_string(pdata, p, 0);
+ if (flags2 & FLAGS2_UNICODE_STRINGS) {
+ p += ucs2_align(base_data, p, 0);
+ }
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE);
p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
nameptr = p;
len = srvstr_push(base_data, flags2,
- p + 1, fname, PTR_DIFF(end_data, p),
+ p + 1, fname, PTR_DIFF(end_data, p+1),
STR_TERMINATE | STR_NOALIGN);
if (flags2 & FLAGS2_UNICODE_STRINGS) {
if (len > 2) {
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
len = srvstr_push(base_data, flags2,
- p + 4, fname, PTR_DIFF(end_data, p),
+ p + 4, fname, PTR_DIFF(end_data, p+4),
STR_TERMINATE_ASCII);
SIVAL(p,0,len);
p += 4 + len;
uint32 dirtype;
int maxentries;
uint16 findfirst_flags;
- BOOL close_after_first;
- BOOL close_if_end;
- BOOL requires_resume_key;
+ bool close_after_first;
+ bool close_if_end;
+ bool requires_resume_key;
int info_level;
char *directory = NULL;
const char *mask = NULL;
int dptr_num = -1;
int numentries = 0;
int i;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
+ bool finished = False;
+ bool dont_descend = False;
+ bool out_of_space = False;
int space_remaining;
- BOOL mask_contains_wcard = False;
+ bool mask_contains_wcard = False;
SMB_STRUCT_STAT sbuf;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
out_of_space = False;
for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
- BOOL got_exact_match = False;
+ bool got_exact_match = False;
/* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
if(got_exact_match)
finished = True;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ /* Ensure space_remaining never goes -ve. */
+ if (PTR_DIFF(p,pdata) > max_data_bytes) {
+ space_remaining = 0;
+ out_of_space = true;
+ } else {
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
}
/* Check if we can close the dirptr */
SSVAL(params,6,0); /* Never an EA error */
SSVAL(params,8,last_entry_off);
- send_trans2_replies(req, params, 10, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 10, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
if ((! *directory) && dptr_path(dptr_num)) {
uint16 info_level;
uint32 resume_key;
uint16 findnext_flags;
- BOOL close_after_request;
- BOOL close_if_end;
- BOOL requires_resume_key;
- BOOL continue_bit;
- BOOL mask_contains_wcard = False;
+ bool close_after_request;
+ bool close_if_end;
+ bool requires_resume_key;
+ bool continue_bit;
+ bool mask_contains_wcard = False;
char *resume_name = NULL;
const char *mask = NULL;
const char *directory = NULL;
uint16 dirtype;
int numentries = 0;
int i, last_entry_off=0;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
+ bool finished = False;
+ bool dont_descend = False;
+ bool out_of_space = False;
int space_remaining;
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
} /* end if resume_name && !continue_bit */
for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
- BOOL got_exact_match = False;
+ bool got_exact_match = False;
/* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
SSVAL(params,4,0); /* Never an EA error */
SSVAL(params,6,last_entry_off);
- send_trans2_replies(req, params, 8, pdata, PTR_DIFF(p,pdata),
+ send_trans2_replies(conn, req, params, 8, pdata, PTR_DIFF(p,pdata),
max_data_bytes);
return;
info_level = SVAL(params,0);
+ if (IS_IPC(conn)) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: not an allowed "
+ "info level (0x%x) on IPC$.\n",
+ (unsigned int)info_level));
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ }
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: encryption required "
+ "and info level 0x%x sent.\n",
+ (unsigned int)info_level));
+ exit_server_cleanly("encryption required "
+ "on connection");
+ return;
+ }
+ }
+
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
if(SMB_VFS_STAT(conn,".",&st)!=0) {
*/
case SMB_QUERY_CIFS_UNIX_INFO:
+ {
+ bool large_write = lp_min_receive_file_size() &&
+ !srv_is_signing_active();
+ bool large_read = !srv_is_signing_active();
+ int encrypt_caps = 0;
+
if (!lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
}
+
+ switch (conn->encrypt_level) {
+ case 0:
+ encrypt_caps = 0;
+ break;
+ case 1:
+ case Auto:
+ encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
+ break;
+ case Required:
+ encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
+ CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
+ large_write = false;
+ large_read = false;
+ break;
+ }
+
data_len = 12;
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
- /* We have POSIX ACLs, pathname and locking capability. */
+
+ /* We have POSIX ACLs, pathname, encryption,
+ * large read/write, and locking capability. */
+
SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
CIFS_UNIX_POSIX_ACLS_CAP|
CIFS_UNIX_POSIX_PATHNAMES_CAP|
CIFS_UNIX_FCNTL_LOCKS_CAP|
CIFS_UNIX_EXTATTR_CAP|
CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
- /* Ensure we don't do this on signed or sealed data. */
- (srv_is_signing_active() ? 0 : CIFS_UNIX_LARGE_READ_CAP)
- )));
+ encrypt_caps|
+ (large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
+ (large_write ?
+ CIFS_UNIX_LARGE_WRITE_CAP : 0))));
break;
+ }
case SMB_QUERY_POSIX_FS_INFO:
{
*/
for (i = 0, sid_bytes = 0;
i < current_user.nt_user_token->num_sids; ++i) {
- sid_bytes +=
- sid_size(¤t_user.nt_user_token->user_sids[i]);
+ sid_bytes += ndr_size_dom_sid(
+ ¤t_user.nt_user_token->user_sids[i], 0);
}
/* SID list byte count */
/* SID list */
for (i = 0;
i < current_user.nt_user_token->num_sids; ++i) {
- int sid_len =
- sid_size(¤t_user.nt_user_token->user_sids[i]);
+ int sid_len = ndr_size_dom_sid(
+ ¤t_user.nt_user_token->user_sids[i], 0);
sid_linearize(pdata + data_len, sid_len,
¤t_user.nt_user_token->user_sids[i]);
}
- send_trans2_replies(req, params, 0, pdata, data_len,
+ send_trans2_replies(conn, req, params, 0, pdata, data_len,
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
info_level = SVAL(params,2);
+ if (IS_IPC(conn)) {
+ if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
+ info_level != SMB_SET_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2setfsinfo: not an allowed "
+ "info level (0x%x) on IPC$.\n",
+ (unsigned int)info_level));
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ }
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
+ if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
+ DEBUG(0,("call_trans2setfsinfo: encryption required "
+ "and info level 0x%x sent.\n",
+ (unsigned int)info_level));
+ exit_server_cleanly("encryption required "
+ "on connection");
+ return;
+ }
+ }
+
switch(info_level) {
case SMB_SET_CIFS_UNIX_INFO:
{
}
break;
}
+
case SMB_REQUEST_TRANSPORT_ENCRYPTION:
{
NTSTATUS status;
if (!lp_unix_extensions()) {
reply_nterror(
- req, NT_STATUS_INVALID_LEVEL);
+ req,
+ NT_STATUS_INVALID_LEVEL);
return;
}
- DEBUG( 4,("call_trans2setfsinfo: request transport encrption.\n"));
+ if (lp_smb_encrypt(SNUM(conn)) == false) {
+ reply_nterror(
+ req,
+ NT_STATUS_NOT_SUPPORTED);
+ return;
+ }
+
+ DEBUG( 4,("call_trans2setfsinfo: "
+ "request transport encrption.\n"));
status = srv_request_encryption_setup(conn,
- (unsigned char **)ppdata,
- &data_len,
- (unsigned char **)pparams,
- ¶m_len
- );
-
- if (!NT_STATUS_IS_OK(status)) {
- /*
- * TODO: Check
- * MORE_PROCESSING_REQUIRED, this used
- * to have special handling here.
- */
+ (unsigned char **)ppdata,
+ &data_len,
+ (unsigned char **)pparams,
+ ¶m_len);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
+ !NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
- send_trans2_replies(req,
- *pparams, param_len,
- *ppdata, data_len,
- max_data_bytes);
+ send_trans2_replies(conn, req,
+ *pparams,
+ param_len,
+ *ppdata,
+ data_len,
+ max_data_bytes);
if (NT_STATUS_IS_OK(status)) {
- /* Server-side transport encryption is now *on*. */
+ /* Server-side transport
+ * encryption is now *on*. */
status = srv_encryption_start(conn);
if (!NT_STATUS_IS_OK(status)) {
- exit_server_cleanly("Failure in setting up encrypted transport");
+ exit_server_cleanly(
+ "Failure in setting "
+ "up encrypted transport");
}
}
return;
}
+
case SMB_FS_QUOTA_INFORMATION:
{
files_struct *fsp = NULL;
Utility function to marshall a POSIX acl into wire format.
****************************************************************************/
-static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
+static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
{
int entry_id = SMB_ACL_FIRST_ENTRY;
SMB_ACL_ENTRY_T entry;
*
* XXX: this really should be behind the VFS interface. To do this, we would
* need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
- * Each VFS module could then implement it's own mapping as appropriate for the
+ * Each VFS module could then implement its own mapping as appropriate for the
* platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
*/
static const struct {unsigned stat_fflag; unsigned smb_fflag;}
#endif /* HAVE_STAT_ST_FLAGS */
}
-static BOOL map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
+static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
const uint32 smb_fflags,
const uint32 smb_fmask,
int *stat_fflags)
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
char *base_name;
char *p;
SMB_OFF_T pos = 0;
- BOOL delete_pending = False;
+ bool delete_pending = False;
int len;
time_t create_time, mtime, atime;
struct timespec create_time_ts, mtime_ts, atime_ts;
case SMB_QUERY_FILE_UNIX_LINK:
{
- char *buffer = TALLOC_SIZE(ctx, 1024);
+ char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1);
if (!buffer) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
#endif
len = SMB_VFS_READLINK(conn,fullpathname,
- buffer, 1023);
+ buffer, PATH_MAX);
if (len == -1) {
reply_unixerror(req, ERRDOS,
ERRnoaccess);
return;
}
- send_trans2_replies(req, params, param_size, *ppdata, data_size,
+ send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
max_data_bytes);
return;
files_struct *fsp,
const char *fname,
const SMB_STRUCT_STAT *psbuf,
- struct timespec ts[2])
+ struct timespec ts[2],
+ bool setting_write_time)
{
uint32 action =
FILE_NOTIFY_CHANGE_LAST_ACCESS
|FILE_NOTIFY_CHANGE_LAST_WRITE;
-
if (!VALID_STAT(*psbuf)) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
+ if (!setting_write_time) {
+ /* ts[1] comes from change time, not write time. */
+ action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
+ }
+
DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) ));
DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) ));
if(file_ntimes(conn, fname, ts)!=0) {
return map_nt_error_from_unix(errno);
}
- if (action != 0) {
- notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
- }
+ notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);
+
return NT_STATUS_OK;
}
DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n",
fname, (unsigned int)dosmode ));
- if(file_set_dosmode(conn, fname, dosmode, psbuf, False)) {
+ if(file_set_dosmode(conn, fname, dosmode, psbuf, NULL, false)) {
DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n",
fname, strerror(errno)));
return map_nt_error_from_unix(errno);
SMB_STRUCT_STAT *psbuf)
{
NTSTATUS status = NT_STATUS_OK;
- BOOL delete_on_close;
+ bool delete_on_close;
uint32 dosmode = 0;
if (total_data < 1) {
files_struct *fsp,
const char *fname)
{
- BOOL overwrite;
+ bool overwrite;
uint32 root_fid;
uint32 len;
char *newname = NULL;
char *base_name = NULL;
- BOOL dest_has_wcard = False;
+ bool dest_has_wcard = False;
NTSTATUS status = NT_STATUS_OK;
char *p;
TALLOC_CTX *ctx = talloc_tos();
uint16 posix_acl_version;
uint16 num_file_acls;
uint16 num_def_acls;
- BOOL valid_file_acls = True;
- BOOL valid_def_acls = True;
+ bool valid_file_acls = True;
+ bool valid_def_acls = True;
if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
return NT_STATUS_INVALID_PARAMETER;
****************************************************************************/
static NTSTATUS smb_set_posix_lock(connection_struct *conn,
- const uint8 *inbuf,
- int length,
+ const struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
SMB_BIG_UINT count;
SMB_BIG_UINT offset;
uint32 lock_pid;
- BOOL blocking_lock = False;
+ bool blocking_lock = False;
enum brl_type lock_type;
+
NTSTATUS status = NT_STATUS_OK;
if (fsp == NULL || fsp->fh->fd == -1) {
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- (char *)inbuf, length,
+ req,
fsp,
-1, /* infinite timeout. */
0,
fsp,
fname,
psbuf,
- ts);
+ ts,
+ true);
}
/****************************************************************************
uint32 dosmode = 0;
struct timespec ts[2];
NTSTATUS status = NT_STATUS_OK;
+ bool setting_write_time = true;
if (total_data < 36) {
return NT_STATUS_INVALID_PARAMETER;
/* Prefer a defined time to an undefined one. */
if (null_timespec(ts[1])) {
- ts[1] = null_timespec(write_time) ? changed_time : write_time;
+ if (null_timespec(write_time)) {
+ ts[1] = changed_time;
+ setting_write_time = false;
+ } else {
+ ts[1] = write_time;
+ }
}
DEBUG(10,("smb_set_file_basic_info: file %s\n",
fsp,
fname,
psbuf,
- ts);
+ ts,
+ setting_write_time);
}
/****************************************************************************
* This is equivalent to a write. Ensure it's seen immediately
* if there are no pending writes.
*/
- set_filetime(fsp->conn, fsp->fsp_name, timespec_current());
+ set_filetime(fsp->conn, fsp->fsp_name,
+ timespec_current());
}
return NT_STATUS_OK;
}
uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
NTSTATUS status = NT_STATUS_OK;
- BOOL delete_on_fail = False;
+ bool delete_on_fail = False;
enum perm_type ptype;
if (total_data < 100) {
fsp,
fname,
psbuf,
- ts);
+ ts,
+ true);
}
/****************************************************************************
SMB_STRUCT_STAT *psbuf,
int *pdata_return_size)
{
- BOOL extended_oplock_granted = False;
+ bool extended_oplock_granted = False;
char *pdata = *ppdata;
uint32 flags = 0;
uint32 wire_open_mode = 0;
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2,
+ send_trans2_replies(conn, req, params, 2,
*ppdata, 0,
max_data_bytes);
return;
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
}
- status = smb_set_posix_lock(conn, req->inbuf,
- smb_len(req->inbuf) + 4,
+ status = smb_set_posix_lock(conn, req,
pdata, total_data, fsp);
break;
}
}
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, data_return_size,
+ send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
return;
return;
}
- status = create_directory(conn, directory);
+ status = create_directory(conn, req, directory);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
SSVAL(params,0,0);
- send_trans2_replies(req, params, 2, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
return;
}
if(fnf_handle == 0)
fnf_handle = 257;
- send_trans2_replies(req, params, 6, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
return;
}
SSVAL(params,0,0); /* No changes */
SSVAL(params,2,0); /* No EA errors */
- send_trans2_replies(req, params, 4, *ppdata, 0, max_data_bytes);
+ send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
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);
+ send_trans2_replies(conn, req,0,0,*ppdata,reply_size, max_data_bytes);
return;
}
srvstr_push(pdata, req->flags2, pdata+18,
lp_servicename(SNUM(conn)), 13,
STR_ASCII|STR_TERMINATE); /* Service name */
- send_trans2_replies(req, *pparams, 0, *ppdata, 32,
+ send_trans2_replies(conn, req, *pparams, 0, *ppdata, 32,
max_data_bytes);
return;
}
Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
-void reply_findclose(connection_struct *conn, struct smb_request *req)
+void reply_findclose(struct smb_request *req)
{
int dptr_num;
Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
-void reply_findnclose(connection_struct *conn, struct smb_request *req)
+void reply_findnclose(struct smb_request *req)
{
int dptr_num;
SSVAL(req->inbuf,smb_flg2,req->flags2);
}
+ if (conn->encrypt_level == Required && !req->encrypted) {
+ if (state->call != TRANSACT2_QFSINFO &&
+ state->call != TRANSACT2_SETFSINFO) {
+ DEBUG(0,("handle_trans2: encryption required "
+ "with call 0x%x\n",
+ (unsigned int)state->call));
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
+ }
+ }
+
/* Now we must call the relevant TRANS2 function */
switch(state->call) {
case TRANSACT2_OPEN:
Reply to a SMBtrans2.
****************************************************************************/
-void reply_trans2(connection_struct *conn, struct smb_request *req)
+void reply_trans2(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int dsoff;
unsigned int dscnt;
unsigned int psoff;
return;
}
- if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
- && (tran_call != TRANSACT2_GET_DFS_REFERRAL)
- && (tran_call != TRANSACT2_QFILEINFO)) {
- reply_doserror(req, ERRSRV, ERRaccess);
- END_PROFILE(SMBtrans2);
- return;
+ if (IS_IPC(conn)) {
+ switch (tran_call) {
+ /* List the allowed trans2 calls on IPC$ */
+ case TRANSACT2_OPEN:
+ case TRANSACT2_GET_DFS_REFERRAL:
+ case TRANSACT2_QFILEINFO:
+ case TRANSACT2_QFSINFO:
+ case TRANSACT2_SETFSINFO:
+ break;
+ default:
+ reply_doserror(req, ERRSRV, ERRaccess);
+ END_PROFILE(SMBtrans2);
+ return;
+ }
}
if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
Reply to a SMBtranss2
****************************************************************************/
-void reply_transs2(connection_struct *conn, struct smb_request *req)
+void reply_transs2(struct smb_request *req)
{
+ connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
int size;