From: Uri Simchoni Date: Mon, 12 Sep 2016 19:38:15 +0000 (+0300) Subject: s3-libsmb: support getting user's quota in SMB2 X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=b6375ce54934ea61eda0af03e354f08b6ec9494e s3-libsmb: support getting user's quota in SMB2 Signed-off-by: Uri Simchoni Reviewed-by: Jeremy Allison --- diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index a998d6fedeca..a841f4cd7c30 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -37,6 +37,7 @@ #include "libsmb/proto.h" #include "lib/util/tevent_ntstatus.h" #include "../libcli/security/security.h" +#include "../librpc/gen_ndr/ndr_security.h" #include "lib/util_ea.h" #include "librpc/gen_ndr/ndr_ioctl.h" #include "ntioctl.h" @@ -2347,6 +2348,91 @@ NTSTATUS cli_smb2_get_ea_list_path(struct cli_state *cli, return status; } +/*************************************************************** + Wrapper that allows SMB2 to get user quota. + Synchronous only. +***************************************************************/ + +NTSTATUS cli_smb2_get_user_quota(struct cli_state *cli, + int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt) +{ + NTSTATUS status; + DATA_BLOB inbuf = data_blob_null; + DATA_BLOB outbuf = data_blob_null; + struct smb2_hnd *ph = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + unsigned sid_len; + unsigned int offset; + 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 fail; + } + + if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + status = map_fnum_to_smb2_handle(cli, quota_fnum, &ph); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + sid_len = ndr_size_dom_sid(&pqt->sid, 0); + + inbuf = data_blob_talloc_zero(frame, 24 + sid_len); + if (inbuf.data == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + buf = inbuf.data; + + SCVAL(buf, 0, 1); /* ReturnSingle */ + SCVAL(buf, 1, 0); /* RestartScan */ + SSVAL(buf, 2, 0); /* Reserved */ + if (8 + sid_len < 8) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + SIVAL(buf, 4, 8 + sid_len); /* SidListLength */ + SIVAL(buf, 8, 0); /* StartSidLength */ + SIVAL(buf, 12, 0); /* StartSidOffset */ + SIVAL(buf, 16, 0); /* NextEntryOffset */ + SIVAL(buf, 20, sid_len); /* SidLength */ + sid_linearize(buf + 24, sid_len, &pqt->sid); + + 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 fail; + } + + if (!parse_user_quota_record(outbuf.data, outbuf.length, &offset, + pqt)) { + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + DEBUG(0, ("Got invalid FILE_QUOTA_INFORMATION in reply.\n")); + } + +fail: + 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 2df54a30b407..93d7529b8469 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -149,6 +149,9 @@ NTSTATUS cli_smb2_set_ea_path(struct cli_state *cli, const char *ea_name, const char *ea_val, size_t ea_len); +NTSTATUS cli_smb2_get_user_quota(struct cli_state *cli, + int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt); 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 3091efbd22f7..1f89176adb5c 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -23,6 +23,7 @@ #include "fake_file.h" #include "../libcli/security/security.h" #include "trans2.h" +#include "../libcli/smb/smbXcli_base.h" NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum) { @@ -118,6 +119,10 @@ NTSTATUS cli_get_user_quota(struct cli_state *cli, int quota_fnum, smb_panic("cli_get_user_quota() called with NULL Pointer!"); } + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + return cli_smb2_get_user_quota(cli, quota_fnum, pqt); + } + SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA); SSVAL(params, 0,quota_fnum);