s3/smbd: smb2 server implementation for query get/set info.
authorNoel Power <noel.power@suse.com>
Fri, 26 May 2017 15:02:33 +0000 (16:02 +0100)
committerNoel Power <npower@samba.org>
Tue, 31 Jul 2018 14:56:25 +0000 (16:56 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13553

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_setinfo.c
source3/wscript_build

index da82bf5237871a137e8be7742358f4e3e851841d..05c57db902d1b63669cd35badcaa8b999f87b116 100644 (file)
@@ -25,6 +25,8 @@
 #include "../libcli/smb/smb_common.h"
 #include "trans2.h"
 #include "../lib/util/tevent_ntstatus.h"
+#include "librpc/gen_ndr/ndr_quota.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_SMB2
@@ -520,9 +522,87 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
                break;
        }
 
-       case SMB2_GETINFO_QUOTA:
-               tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
-               return tevent_req_post(req, ev);
+       case SMB2_GETINFO_QUOTA: {
+               struct smb2_query_quota_info info;
+               enum ndr_err_code err;
+               uint8_t *data = NULL;
+               uint32_t data_size = 0;
+               struct ndr_pull *ndr_pull = NULL;
+               DATA_BLOB sid_buf = data_blob_null;
+               TALLOC_CTX *tmp_ctx = talloc_init("geninfo_quota");
+
+               if (!tmp_ctx) {
+                       tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+                       return tevent_req_post(req, ev);
+               }
+
+               ndr_pull = ndr_pull_init_blob(&in_input_buffer, tmp_ctx);
+               if (!ndr_pull) {
+                       TALLOC_FREE(tmp_ctx);
+                       tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+                       return tevent_req_post(req, ev);
+               }
+
+               err = ndr_pull_smb2_query_quota_info(ndr_pull,
+                                                    NDR_SCALARS | NDR_BUFFERS,
+                                                    &info);
+
+               if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+                       DBG_DEBUG("failed to pull smb2_query_quota_info\n");
+                       TALLOC_FREE(tmp_ctx);
+                       tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+                       return tevent_req_post(req, ev);
+               }
+
+               DBG_DEBUG("quota list returnsingle %u, restartscan %u, "
+                         "sid_list_length %u, start_sid_length %u, "
+                         "startsidoffset %u\n",
+                         (unsigned int)info.return_single,
+                         (unsigned int)info.restart_scan,
+                         (unsigned int)info.sid_list_length,
+                         (unsigned int)info.start_sid_length,
+                         (unsigned int)info.start_sid_offset);
+
+               /* Currently we do not support the single start sid format */
+               if (info.start_sid_length != 0 || info.start_sid_offset != 0 ) {
+                       DBG_INFO("illegal single sid query\n");
+                       TALLOC_FREE(tmp_ctx);
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               if (in_input_buffer.length < ndr_pull->offset) {
+                       DBG_INFO("Invalid buffer length\n");
+                       TALLOC_FREE(tmp_ctx);
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               sid_buf.data = in_input_buffer.data + ndr_pull->offset;
+               sid_buf.length = in_input_buffer.length - ndr_pull->offset;
+
+               status = smbd_do_query_getinfo_quota(tmp_ctx,
+                                 fsp,
+                                 info.restart_scan,
+                                 info.return_single,
+                                 info.sid_list_length,
+                                 &sid_buf,
+                                 in_output_buffer_length,
+                                 &data,
+                                 &data_size);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(tmp_ctx);
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+
+               state->out_output_buffer =
+                       data_blob_talloc(state, data, data_size);
+               status  = NT_STATUS_OK;
+               TALLOC_FREE(tmp_ctx);
+               break;
+       }
 
        default:
                DEBUG(10,("smbd_smb2_getinfo_send: "
index 1f07b7e11900c5e4fcd7be9d0b7af2efc104ca46..7ed24231a83d93fbd5968e84fc51c07cab50f8f7 100644 (file)
@@ -28,6 +28,7 @@
 #include "../librpc/gen_ndr/open_files.h"
 #include "source3/lib/dbwrap/dbwrap_watch.h"
 #include "messages.h"
+#include "librpc/gen_ndr/ndr_quota.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_SMB2
@@ -553,6 +554,41 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
                break;
        }
 
+       case 0x04:/* SMB2_SETINFO_QUOTA */
+       {
+               struct file_quota_information info = {0};
+               SMB_NTQUOTA_STRUCT qt = {0};
+               enum ndr_err_code err;
+               int ret;
+
+               if (!fsp->fake_file_handle) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+               err = ndr_pull_struct_blob(
+                       &in_input_buffer, state, &info,
+                       (ndr_pull_flags_fn_t)ndr_pull_file_quota_information);
+               if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+                       tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
+                       return tevent_req_post(req, ev);
+               }
+
+               qt.usedspace = info.quota_used;
+
+               qt.softlim = info.quota_threshold;
+
+               qt.hardlim = info.quota_limit;
+
+               qt.sid = info.sid;
+               ret = vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &qt.sid, &qt);
+               if (ret !=0 ) {
+                       status = map_nt_error_from_unix(errno);
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+               status = NT_STATUS_OK;
+               break;
+       }
        default:
                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
                return tevent_req_post(req, ev);
index 7e38b79c3e2a7b1d0d5ce3d8bb15ba43c5012ead..6e34bfaecf0691d2337ccbd23c2ca34159cc2498 100644 (file)
@@ -740,6 +740,7 @@ bld.SAMBA3_LIBRARY('smbd_base',
                         NDR_IOCTL
                         notifyd
                         vfs_acl_common
+                        NDR_QUOTA
                    ''' +
                    bld.env['dmapi_lib'] +
                    bld.env['legacy_quota_libs'] +