summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_getinfo.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-04-26 20:11:59 -0700
committerJeremy Allison <jra@samba.org>2010-04-26 20:11:59 -0700
commita94a4b788c3056068d0c8e42c55e990f418db666 (patch)
treecf600a4ace7347d87a3edab345f3ff747313b871 /source3/smbd/smb2_getinfo.c
parentbe35a40e037202af4b30cc76e6e986499771e2e2 (diff)
downloadsamba-a94a4b788c3056068d0c8e42c55e990f418db666.tar.gz
samba-a94a4b788c3056068d0c8e42c55e990f418db666.tar.bz2
samba-a94a4b788c3056068d0c8e42c55e990f418db666.zip
Plumb in get_nt_acl into SMB2.
Jeremy.
Diffstat (limited to 'source3/smbd/smb2_getinfo.c')
-rw-r--r--source3/smbd/smb2_getinfo.c82
1 files changed, 76 insertions, 6 deletions
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;