From a94a4b788c3056068d0c8e42c55e990f418db666 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 26 Apr 2010 20:11:59 -0700 Subject: Plumb in get_nt_acl into SMB2. Jeremy. --- source3/smbd/smb2_getinfo.c | 82 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 6 deletions(-) (limited to 'source3/smbd/smb2_getinfo.c') diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 3a8c07757e..d59339fa59 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; -- cgit