[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Apr 26 21:12:48 MDT 2010


The branch, master has been updated
       via  a94a4b7... Plumb in get_nt_acl into SMB2.
      from  be35a40... s4-dns: fixed dc.dc duplication in DNS update list

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a94a4b788c3056068d0c8e42c55e990f418db666
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 26 20:11:59 2010 -0700

    Plumb in get_nt_acl into SMB2.
    
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h     |    7 ++
 source3/smbd/nttrans.c      |  131 ++++++++++++++++++++++++++++++-------------
 source3/smbd/smb2_getinfo.c |   82 +++++++++++++++++++++++++--
 3 files changed, 174 insertions(+), 46 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index a27ef89..ff4a04b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6616,6 +6616,13 @@ void reply_ntcreate_and_X(struct smb_request *req);
 struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size);
 void reply_ntcancel(struct smb_request *req);
 void reply_ntrename(struct smb_request *req);
+NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
+					TALLOC_CTX *mem_ctx,
+					files_struct *fsp,
+					uint32_t security_info_wanted,
+					uint32_t max_data_count,
+					uint8_t **ppmarshalled_sd,
+					size_t *psd_size);
 void reply_nttrans(struct smb_request *req);
 void reply_nttranss(struct smb_request *req);
 
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 2783545..3ce196d 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1770,6 +1770,75 @@ static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
 
 /****************************************************************************
  Reply to query a security descriptor.
+ Callable from SMB2 and SMB2.
+ If it returns NT_STATUS_BUFFER_TOO_SMALL, pdata_size is initialized with
+ the required size.
+****************************************************************************/
+
+NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
+					TALLOC_CTX *mem_ctx,
+					files_struct *fsp,
+					uint32_t security_info_wanted,
+					uint32_t max_data_count,
+					uint8_t **ppmarshalled_sd,
+					size_t *psd_size)
+{
+	NTSTATUS status;
+	SEC_DESC *psd = NULL;
+
+	/*
+	 * Get the permissions to return.
+	 */
+
+	if (!lp_nt_acl_support(SNUM(conn))) {
+		status = get_null_nt_acl(mem_ctx, &psd);
+	} else {
+		status = SMB_VFS_FGET_NT_ACL(
+			fsp, security_info_wanted, &psd);
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* 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;
+
+	*psd_size = ndr_size_security_descriptor(psd, NULL, 0);
+
+	DEBUG(3,("smbd_do_query_security_desc: sd_size = %lu.\n",
+		(unsigned long)*psd_size));
+
+	if (DEBUGLEVEL >= 10) {
+		DEBUG(10,("smbd_do_query_security_desc for file %s\n",
+			  fsp_str_dbg(fsp)));
+		NDR_PRINT_DEBUG(security_descriptor, psd);
+	}
+
+	if (max_data_count < *psd_size) {
+		TALLOC_FREE(psd);
+		return NT_STATUS_BUFFER_TOO_SMALL;
+	}
+
+	status = marshall_sec_desc(mem_ctx, psd,
+				   ppmarshalled_sd, psd_size);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(psd);
+		return status;
+	}
+
+	TALLOC_FREE(psd);
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ SMB1 reply to query a security descriptor.
 ****************************************************************************/
 
 static void call_nt_transact_query_security_desc(connection_struct *conn,
@@ -1784,12 +1853,11 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
 {
 	char *params = *ppparams;
 	char *data = *ppdata;
-	SEC_DESC *psd = NULL;
-	size_t sd_size;
+	size_t sd_size = 0;
 	uint32 security_info_wanted;
 	files_struct *fsp = NULL;
 	NTSTATUS status;
-	DATA_BLOB blob;
+	uint8_t *marshalled_sd = NULL;
 
         if(parameter_count < 8) {
 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -1818,46 +1886,38 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
 	 * Get the permissions to return.
 	 */
 
-	if (!lp_nt_acl_support(SNUM(conn))) {
-		status = get_null_nt_acl(talloc_tos(), &psd);
-	} else {
-		status = SMB_VFS_FGET_NT_ACL(
-			fsp, security_info_wanted, &psd);
-	}
+	status = smbd_do_query_security_desc(conn,
+					talloc_tos(),
+					fsp,
+					security_info_wanted,
+					max_data_count,
+					&marshalled_sd,
+					&sd_size);
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
+		SIVAL(params,0,(uint32_t)sd_size);
+		send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
+			params, 4, NULL, 0);
+		return;
+        }
+
 	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, NULL, 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_str_dbg(fsp)));
-		NDR_PRINT_DEBUG(security_descriptor, psd);
-	}
+	SMB_ASSERT(sd_size > 0);
 
-	SIVAL(params,0,(uint32)sd_size);
+	SIVAL(params,0,(uint32_t)sd_size);
 
 	if (max_data_count < sd_size) {
 		send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
-				params, 4, *ppdata, 0);
+				params, 4, NULL, 0);
 		return;
 	}
 
 	/*
-	 * Allocate the data we will point this at.
+	 * Allocate the data we will return.
 	 */
 
 	data = nttrans_realloc(ppdata, sd_size);
@@ -1866,16 +1926,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
 		return;
 	}
 
-	status = marshall_sec_desc(talloc_tos(), psd,
-				   &blob.data, &blob.length);
-
-	if (!NT_STATUS_IS_OK(status)) {
-		reply_nterror(req, status);
-		return;
-	}
-
-	SMB_ASSERT(sd_size == blob.length);
-	memcpy(data, blob.data, sd_size);
+	memcpy(data, marshalled_sd, sd_size);
 
 	send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
 
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 3a8c077..d59339f 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -34,7 +34,8 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 						 uint64_t in_file_id_volatile);
 static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
 				       TALLOC_CTX *mem_ctx,
-				       DATA_BLOB *out_output_buffer);
+				       DATA_BLOB *out_output_buffer,
+				       NTSTATUS *p_call_status);
 
 static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq);
 NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
@@ -128,11 +129,13 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
 	uint16_t out_output_buffer_offset;
 	DATA_BLOB out_output_buffer = data_blob_null;
 	NTSTATUS status;
+	NTSTATUS call_status;
 	NTSTATUS error; /* transport error */
 
 	status = smbd_smb2_getinfo_recv(subreq,
 					req,
-					&out_output_buffer);
+					&out_output_buffer,
+					&call_status);
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
 		error = smbd_smb2_request_error(req, status);
@@ -144,6 +147,20 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
 		return;
 	}
 
+	if (!NT_STATUS_IS_OK(call_status)) {
+		/* Return a specific error with data. */
+		error = smbd_smb2_request_error_ex(req,
+						call_status,
+						&out_output_buffer,
+						__location__);
+		if (!NT_STATUS_IS_OK(error)) {
+			smbd_server_connection_terminate(req->sconn,
+							 nt_errstr(error));
+			return;
+		}
+		return;
+	}
+
 	out_output_buffer_offset = SMB2_HDR_BODY + 0x08;
 
 	outhdr = (uint8_t *)req->out.vector[i].iov_base;
@@ -197,6 +214,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 	struct smb_request *smbreq;
 	connection_struct *conn = smb2req->tcon->compat_conn;
 	files_struct *fsp;
+	NTSTATUS status;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbd_smb2_getinfo_state);
@@ -204,7 +222,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 	state->smb2req = smb2req;
-	state->status = NT_STATUS_INTERNAL_ERROR;
+	state->status = NT_STATUS_OK;
 	state->out_output_buffer = data_blob_null;
 
 	DEBUG(10,("smbd_smb2_getinfo_send: file_id[0x%016llX]\n",
@@ -246,7 +264,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 		struct ea_list *ea_list = NULL;
 		int lock_data_count = 0;
 		char *lock_data = NULL;
-		NTSTATUS status;
 
 		ZERO_STRUCT(write_time_ts);
 
@@ -360,7 +377,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 		uint16_t file_info_level;
 		char *data = NULL;
 		int data_size = 0;
-		NTSTATUS status;
 
 		/* the levels directly map to the passthru levels */
 		file_info_level = in_file_info_class + 1000;
@@ -392,7 +408,59 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 		break;
 	}
 
+	case 0x03:/* SMB2_GETINFO_SEC */
+	{
+		uint8_t *p_marshalled_sd = NULL;
+		size_t sd_size = 0;
+
+		status = smbd_do_query_security_desc(conn,
+				state,
+				fsp,
+				/* Security info wanted. */
+				in_additional_information,
+				in_output_buffer_length,
+				&p_marshalled_sd,
+				&sd_size);
+
+		if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
+			/* Return needed size. */
+			state->out_output_buffer = data_blob_talloc(state,
+								    NULL,
+								    4);
+			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+				return tevent_req_post(req, ev);
+			}
+			SIVAL(state->out_output_buffer.data,0,(uint32_t)sd_size);
+			state->status = NT_STATUS_BUFFER_TOO_SMALL;
+			break;
+		}
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(10,("smbd_smb2_getinfo_send: "
+				 "smbd_do_query_security_desc of %s failed "
+				 "(%s)\n", fsp_str_dbg(fsp),
+				 nt_errstr(status)));
+			tevent_req_nterror(req, status);
+			return tevent_req_post(req, ev);
+		}
+
+		if (sd_size > 0) {
+			state->out_output_buffer = data_blob_talloc(state,
+								    p_marshalled_sd,
+								    sd_size);
+			if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+				return tevent_req_post(req, ev);
+			}
+		}
+		break;
+	}
+
 	default:
+		DEBUG(10,("smbd_smb2_getinfo_send: "
+			"unknown in_info_type of %u "
+			" for file %s\n",
+			(unsigned int)in_info_type,
+			fsp_str_dbg(fsp) ));
+
 		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
 		return tevent_req_post(req, ev);
 	}
@@ -403,7 +471,8 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
 
 static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
 				       TALLOC_CTX *mem_ctx,
-				       DATA_BLOB *out_output_buffer)
+				       DATA_BLOB *out_output_buffer,
+				       NTSTATUS *pstatus)
 {
 	NTSTATUS status;
 	struct smbd_smb2_getinfo_state *state = tevent_req_data(req,
@@ -416,6 +485,7 @@ static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
 
 	*out_output_buffer = state->out_output_buffer;
 	talloc_steal(mem_ctx, out_output_buffer->data);
+	*pstatus = state->status;
 
 	tevent_req_received(req);
 	return NT_STATUS_OK;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list