summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/nttrans.c139
1 files changed, 93 insertions, 46 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 3aaaa9aebb..19f5859abb 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1058,6 +1058,77 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
}
/****************************************************************************
+ Internal fn to set security descriptors.
+****************************************************************************/
+
+static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint security_info_sent, int *pdef_class,uint32 *pdef_code)
+{
+ prs_struct pd;
+ SEC_DESC *psd = NULL;
+ TALLOC_CTX *mem_ctx;
+ BOOL ret;
+
+ if (sd_len == 0) {
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRbadaccess;
+ return False;
+ }
+
+ /*
+ * Init the parse struct we will unmarshall from.
+ */
+
+ if ((mem_ctx = talloc_init()) == NULL) {
+ DEBUG(0,("set_sd: talloc_init failed.\n"));
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnomem;
+ return False;
+ }
+
+ prs_init(&pd, 0, 4, mem_ctx, UNMARSHALL);
+
+ /*
+ * Setup the prs_struct to point at the memory we just
+ * allocated.
+ */
+
+ prs_give_memory( &pd, data, sd_len, False);
+
+ /*
+ * Finally, unmarshall from the data buffer.
+ */
+
+ if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
+ free_sec_desc(&psd);
+ DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
+ /*
+ * Return access denied for want of a better error message..
+ */
+ talloc_destroy(mem_ctx);
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnomem;
+ return False;
+ }
+
+ ret = set_nt_acl( fsp, security_info_sent, psd);
+
+ if (!ret) {
+ free_sec_desc(&psd);
+ talloc_destroy(mem_ctx);
+ *pdef_class = ERRDOS;
+ *pdef_code = ERRnoaccess;
+ return False;
+ }
+
+ free_sec_desc(&psd);
+ talloc_destroy(mem_ctx);
+
+ *pdef_class = 0;
+ *pdef_code = 0;
+ return True;
+}
+
+/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
@@ -1068,6 +1139,7 @@ static int call_nt_transact_create(connection_struct *conn,
{
pstring fname;
char *params = *ppparams;
+ char *data = *ppdata;
int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
/* Breakout the oplock request bits so we can set the
reply bits separately. */
@@ -1088,10 +1160,13 @@ static int call_nt_transact_create(connection_struct *conn,
uint32 create_disposition;
uint32 create_options;
uint32 fname_len;
+ uint32 sd_len;
uint16 root_dir_fid;
int smb_ofun;
int smb_open_mode;
int smb_attr;
+ int error_class;
+ uint32 error_code;
DEBUG(5,("call_nt_transact_create\n"));
@@ -1122,6 +1197,7 @@ static int call_nt_transact_create(connection_struct *conn,
share_access = IVAL(params,24);
create_disposition = IVAL(params,28);
create_options = IVAL(params,32);
+ sd_len = IVAL(params,36);
fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
root_dir_fid = (uint16)IVAL(params,4);
smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
@@ -1336,6 +1412,16 @@ static int call_nt_transact_create(connection_struct *conn,
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
+ /*
+ * Now try and apply the desired SD.
+ */
+
+ if (!set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION, &error_class, &error_code)) {
+ close_file(fsp,False);
+ restore_case_semantics(file_attributes);
+ return(ERROR(error_class, error_code));
+ }
+
restore_case_semantics(file_attributes);
/* Realloc the size of parameters and data we will return */
@@ -1621,13 +1707,11 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
char *params= *ppparams;
char *data = *ppdata;
- prs_struct pd;
- SEC_DESC *psd = NULL;
uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
files_struct *fsp = NULL;
uint32 security_info_sent = 0;
- TALLOC_CTX *mem_ctx;
- BOOL ret;
+ int error_class;
+ uint32 error_code;
if(!lp_nt_acl_support())
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -1643,49 +1727,9 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
(unsigned int)security_info_sent ));
- /*
- * Init the parse struct we will unmarshall from.
- */
-
- if ((mem_ctx = talloc_init()) == NULL) {
- DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
- return(ERROR(ERRDOS,ERRnomem));
- }
-
- prs_init(&pd, 0, 4, mem_ctx, UNMARSHALL);
-
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
-
- prs_give_memory( &pd, data, total_data_count, False);
-
- /*
- * Finally, unmarshall from the data buffer.
- */
-
- if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
- free_sec_desc(&psd);
- DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
-security descriptor.\n"));
- /*
- * Return access denied for want of a better error message..
- */
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- ret = set_nt_acl( fsp, security_info_sent, psd);
+ if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code))
+ return (ERROR(error_class, error_code));
- if (!ret) {
- free_sec_desc(&psd);
- talloc_destroy(mem_ctx);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- free_sec_desc(&psd);
- talloc_destroy(mem_ctx);
send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
return -1;
}
@@ -1774,6 +1818,9 @@ due to being in oplock break state.\n" ));
if ((total_parameter_count && !params) || (total_data_count && !data) ||
(setup_count && !setup)) {
+ safe_free(setup);
+ safe_free(params);
+ safe_free(data);
DEBUG(0,("reply_nttrans : Out of memory\n"));
END_PROFILE(SMBnttrans);
return(ERROR(ERRDOS,ERRnomem));