s3-libsmb: support getting user's quota in SMB2
authorUri Simchoni <uri@samba.org>
Mon, 12 Sep 2016 19:38:15 +0000 (22:38 +0300)
committerJeremy Allison <jra@samba.org>
Tue, 4 Oct 2016 00:00:23 +0000 (02:00 +0200)
Signed-off-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/libsmb/cli_smb2_fnum.c
source3/libsmb/cli_smb2_fnum.h
source3/libsmb/cliquota.c

index a998d6fedecac53f8e02d507ab46efd7b60c220f..a841f4cd7c30652f90e6c28da8cb08fd816b0bf3 100644 (file)
@@ -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;
index 2df54a30b407a5dedcb7ecf89b5fa41e9c0e8a67..93d7529b8469165433f8175ce5ddab56466ec459 100644 (file)
@@ -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,
index 3091efbd22f769472c8511d220ca68dc77ad9192..1f89176adb5cfc6385a6a9b60c9f927d56e6c3cc 100644 (file)
@@ -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);