From e0e500258a2e9c92fa371f018e97c452c9bf8c83 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Mon, 19 Sep 2016 22:17:10 +0300 Subject: [PATCH] cliquota: implement quota listing in SMB2 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison --- source3/libsmb/cli_smb2_fnum.c | 73 ++++++++++++++++++++++++++++++++++ source3/libsmb/cli_smb2_fnum.h | 5 +++ source3/libsmb/cliquota.c | 5 +++ 3 files changed, 83 insertions(+) diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index a841f4cd7c30..3f5629c130e8 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -2433,6 +2433,79 @@ fail: return status; } +/*************************************************************** + Wrapper that allows SMB2 to list user quota. + Synchronous only. +***************************************************************/ + +NTSTATUS cli_smb2_list_user_quota_step(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int quota_fnum, + SMB_NTQUOTA_LIST **pqt_list, + bool first) +{ + NTSTATUS status; + DATA_BLOB inbuf = data_blob_null; + DATA_BLOB outbuf = data_blob_null; + struct smb2_hnd *ph = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + uint8_t *buf; + + if (smbXcli_conn_has_async_calls(cli->conn)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto cleanup; + } + + if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { + status = NT_STATUS_INVALID_PARAMETER; + goto cleanup; + } + + status = map_fnum_to_smb2_handle(cli, quota_fnum, &ph); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup; + } + + inbuf = data_blob_talloc_zero(frame, 16); + if (inbuf.data == NULL) { + status = NT_STATUS_NO_MEMORY; + goto cleanup; + } + + buf = inbuf.data; + + SCVAL(buf, 0, 0); /* ReturnSingle */ + SCVAL(buf, 1, first ? 1 : 0); /* RestartScan */ + SSVAL(buf, 2, 0); /* Reserved */ + SIVAL(buf, 4, 0); /* SidListLength */ + SIVAL(buf, 8, 0); /* StartSidLength */ + SIVAL(buf, 12, 0); /* StartSidOffset */ + + status = smb2cli_query_info(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, 4, /* in_info_type */ + 0, /* in_file_info_class */ + 0xFFFF, /* in_max_output_length */ + &inbuf, /* in_input_buffer */ + 0, /* in_additional_info */ + 0, /* in_flags */ + ph->fid_persistent, ph->fid_volatile, frame, + &outbuf); + + if (!NT_STATUS_IS_OK(status)) { + goto cleanup; + } + + status = parse_user_quota_list(outbuf.data, outbuf.length, mem_ctx, + pqt_list); + +cleanup: + TALLOC_FREE(frame); + return status; +} + struct cli_smb2_read_state { struct tevent_context *ev; struct cli_state *cli; diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index 93d7529b8469..b39bfed3a74d 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -152,6 +152,11 @@ NTSTATUS cli_smb2_set_ea_path(struct cli_state *cli, NTSTATUS cli_smb2_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt); +NTSTATUS cli_smb2_list_user_quota_step(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + int quota_fnum, + SMB_NTQUOTA_LIST **pqt_list, + bool first); struct tevent_req *cli_smb2_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 19c2e7ea2cad..ff7e6e6c89ac 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -290,6 +290,11 @@ static NTSTATUS cli_list_user_quota_step(struct cli_state *cli, uint16_t op = first ? TRANSACT_GET_USER_QUOTA_LIST_START : TRANSACT_GET_USER_QUOTA_LIST_CONTINUE; + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + return cli_smb2_list_user_quota_step(cli, mem_ctx, quota_fnum, + pqt_list, first); + } + SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA); SSVAL(params, 0,quota_fnum); -- 2.34.1