/* Strip \\ off the name. */
fname++;
- status = np_open(req, conn, fname, &fsp);
+ status = np_open(req, fname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
? BATCH_OPLOCK : 0;
}
- status = create_file(conn, req, root_dir_fid, fname,
- access_mask, share_access, create_disposition,
- create_options, file_attributes, oplock_request,
- allocation_size, NULL, NULL, &fsp, &info, &sbuf);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ root_dir_fid, /* root_dir_fid */
+ fname, /* fname */
+ CFF_DOS_PATH, /* create_file_flags */
+ access_mask, /* access_mask */
+ share_access, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ file_attributes, /* file_attributes */
+ oplock_request, /* oplock_request */
+ allocation_size, /* 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)) {
return status;
}
- if (psd->owner_sid==0) {
+ if (psd->owner_sid == NULL) {
security_info_sent &= ~OWNER_SECURITY_INFORMATION;
}
- if (psd->group_sid==0) {
+ if (psd->group_sid == NULL) {
security_info_sent &= ~GROUP_SECURITY_INFORMATION;
}
- if (psd->sacl==0) {
- security_info_sent &= ~SACL_SECURITY_INFORMATION;
- }
- if (security_info_sent & DACL_SECURITY_INFORMATION) {
- psd->type |= SEC_DESC_DACL_PRESENT;
- }
- if (psd->dacl==0) {
- security_info_sent &= ~DACL_SECURITY_INFORMATION;
- }
/* Convert all the generic bits. */
security_acl_map_generic(psd->dacl, &file_generic_mapping);
security_acl_map_generic(psd->sacl, &file_generic_mapping);
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("set_sd for file %s\n", fsp->fsp_name ));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd);
TALLOC_FREE(psd);
? BATCH_OPLOCK : 0;
}
- status = create_file(conn, req, root_dir_fid, fname,
- access_mask, share_access, create_disposition,
- create_options, file_attributes, oplock_request,
- allocation_size, sd, ea_list, &fsp, &info, &sbuf);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ root_dir_fid, /* root_dir_fid */
+ fname, /* fname */
+ CFF_DOS_PATH, /* create_file_flags */
+ access_mask, /* access_mask */
+ share_access, /* share_access */
+ create_disposition, /* create_disposition*/
+ create_options, /* create_options */
+ file_attributes, /* file_attributes */
+ oplock_request, /* oplock_request */
+ allocation_size, /* allocation_size */
+ sd, /* sd */
+ ea_list, /* ea_list */
+ &fsp, /* result */
+ &info, /* pinfo */
+ &sbuf); /* psbuf */
if(!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
DEBUG(10,("copy_internals: doing file copy %s to %s\n",
oldname, newname));
- status = open_file_ntcreate(conn, req, oldname, &sbuf1,
- FILE_READ_DATA, /* Read-only. */
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_OPEN,
- 0, /* No create options. */
- FILE_ATTRIBUTE_NORMAL,
- NO_OPLOCK,
- &info, &fsp1);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ oldname, /* fname */
+ 0, /* create_file_flags */
+ FILE_READ_DATA, /* access_mask */
+ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
+ FILE_SHARE_DELETE),
+ FILE_OPEN, /* create_disposition*/
+ 0, /* create_options */
+ FILE_ATTRIBUTE_NORMAL, /* file_attributes */
+ NO_OPLOCK, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp1, /* result */
+ &info, /* pinfo */
+ &sbuf1); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = open_file_ntcreate(conn, req, newname, &sbuf2,
- FILE_WRITE_DATA, /* Read-only. */
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- FILE_CREATE,
- 0, /* No create options. */
- fattr,
- NO_OPLOCK,
- &info, &fsp2);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ req, /* req */
+ 0, /* root_dir_fid */
+ newname, /* fname */
+ 0, /* create_file_flags */
+ FILE_WRITE_DATA, /* access_mask */
+ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
+ FILE_SHARE_DELETE),
+ FILE_CREATE, /* create_disposition*/
+ 0, /* create_options */
+ fattr, /* file_attributes */
+ NO_OPLOCK, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp2, /* result */
+ &info, /* pinfo */
+ &sbuf2); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
close_file(NULL, fsp1, ERROR_CLOSE);
status = SMB_VFS_FGET_NT_ACL(
fsp, security_info_wanted, &psd);
}
-
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
+ /* If the SACL/DACL is NULL, but was requested, we mark that it is
+ * present in the reply to match Windows behavior */
+ if (psd->sacl == NULL &&
+ security_info_wanted & SACL_SECURITY_INFORMATION)
+ psd->type |= SEC_DESC_SACL_PRESENT;
+ if (psd->dacl == NULL &&
+ security_info_wanted & DACL_SECURITY_INFORMATION)
+ psd->type |= SEC_DESC_DACL_PRESENT;
+
sd_size = ndr_size_security_descriptor(psd, 0);
DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
SIVAL(params,0,(uint32)sd_size);
if (max_data_count < sd_size) {
uint16 function_code;
NTSTATUS result;
struct trans_state *state;
- uint32_t size;
- uint32_t av_size;
START_PROFILE(SMBnttrans);
return;
}
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
pscnt = IVAL(req->vwv+9, 1);
psoff = IVAL(req->vwv+11, 1);
dscnt = IVAL(req->vwv+13, 1);
goto bad_param;
if (state->total_data) {
+
+ if (trans_oob(state->total_data, 0, dscnt)
+ || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
return;
}
- if (dscnt > state->total_data ||
- dsoff+dscnt < dsoff) {
- goto bad_param;
- }
-
- if (dsoff > av_size ||
- dscnt > av_size ||
- dsoff+dscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
}
if (state->total_param) {
+
+ if (trans_oob(state->total_param, 0, pscnt)
+ || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
return;
}
- if (pscnt > state->total_param ||
- psoff+pscnt < psoff) {
- goto bad_param;
- }
-
- if (psoff > av_size ||
- pscnt > av_size ||
- psoff+pscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
}
if(state->setup_count > 0) {
DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
state->setup_count));
+
+ /*
+ * No overflow possible here, state->setup_count is an
+ * unsigned int, being filled by a single byte from
+ * CVAL(req->vwv+13, 0) above. The cast in the comparison
+ * below is not necessary, it's here to clarify things. The
+ * validity of req->vwv and req->wct has been checked in
+ * init_smb_request already.
+ */
+ if ((state->setup_count/2) + 19 > (unsigned int)req->wct) {
+ goto bad_param;
+ }
+
state->setup = (uint16 *)TALLOC(state, state->setup_count);
if (state->setup == NULL) {
DEBUG(0,("reply_nttrans : Out of memory\n"));
return;
}
- if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
- (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
- goto bad_param;
- }
- if (smb_nt_SetupStart + state->setup_count > size) {
- goto bad_param;
- }
-
memcpy(state->setup, req->vwv+19, state->setup_count);
dump_data(10, (uint8 *)state->setup, state->setup_count);
}
connection_struct *conn = req->conn;
uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
- uint32_t av_size;
- uint32_t size;
START_PROFILE(SMBnttranss);
state->total_data = IVAL(req->vwv+3, 1);
}
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
-
pcnt = IVAL(req->vwv+5, 1);
poff = IVAL(req->vwv+7, 1);
pdisp = IVAL(req->vwv+9, 1);
goto bad_param;
if (pcnt) {
- if (pdisp > state->total_param ||
- pcnt > state->total_param ||
- pdisp+pcnt > state->total_param ||
- pdisp+pcnt < pdisp) {
- goto bad_param;
- }
-
- if (poff > av_size ||
- pcnt > av_size ||
- poff+pcnt > av_size ||
- poff+pcnt < poff) {
+ if (trans_oob(state->total_param, pdisp, pcnt)
+ || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
goto bad_param;
}
-
- memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,
- pcnt);
+ memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
}
if (dcnt) {
- if (ddisp > state->total_data ||
- dcnt > state->total_data ||
- ddisp+dcnt > state->total_data ||
- ddisp+dcnt < ddisp) {
- goto bad_param;
- }
-
- if (ddisp > av_size ||
- dcnt > av_size ||
- ddisp+dcnt > av_size ||
- ddisp+dcnt < ddisp) {
+ if (trans_oob(state->total_data, ddisp, dcnt)
+ || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
goto bad_param;
}
-
- memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
- dcnt);
+ memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
}
if ((state->received_param < state->total_param) ||