]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Move smbd_do_query_getinfo_quota to smb2_nttrans.c
authorDavid Mulder <dmulder@suse.com>
Fri, 11 Mar 2022 19:16:49 +0000 (12:16 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 7 Apr 2022 17:37:29 +0000 (17:37 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/nttrans.c
source3/smbd/proto.h
source3/smbd/smb2_nttrans.c

index 67751cec7f4ec84a06e9a0a4733d70fb6866c744..fd3cb4848806dfb4877fdedd7968a63b4c58f586 100644 (file)
@@ -1988,273 +1988,6 @@ static void call_nt_transact_ioctl(connection_struct *conn,
 
 
 #ifdef HAVE_SYS_QUOTAS
-static enum ndr_err_code fill_qtlist_from_sids(TALLOC_CTX *mem_ctx,
-                                              struct files_struct *fsp,
-                                              SMB_NTQUOTA_HANDLE *qt_handle,
-                                              struct dom_sid *sids,
-                                              uint32_t elems)
-{
-       uint32_t i;
-       TALLOC_CTX *list_ctx = NULL;
-
-       list_ctx = talloc_init("quota_sid_list");
-
-       if (list_ctx == NULL) {
-               DBG_ERR("failed to allocate\n");
-               return NDR_ERR_ALLOC;
-       }
-
-       if (qt_handle->quota_list!=NULL) {
-               free_ntquota_list(&(qt_handle->quota_list));
-       }
-       for (i = 0; i < elems; i++) {
-               SMB_NTQUOTA_STRUCT qt;
-               SMB_NTQUOTA_LIST *list_item;
-               bool ok;
-
-               if (!NT_STATUS_IS_OK(vfs_get_ntquota(fsp,
-                                                    SMB_USER_QUOTA_TYPE,
-                                                    &sids[i], &qt))) {
-                       /* non fatal error, return empty item in result */
-                       ZERO_STRUCT(qt);
-                       continue;
-               }
-
-
-               list_item = talloc_zero(list_ctx, SMB_NTQUOTA_LIST);
-               if (list_item == NULL) {
-                       DBG_ERR("failed to allocate\n");
-                       return NDR_ERR_ALLOC;
-               }
-
-               ok = sid_to_uid(&sids[i], &list_item->uid);
-               if (!ok) {
-                       struct dom_sid_buf buf;
-                       DBG_WARNING("Could not convert SID %s to uid\n",
-                                   dom_sid_str_buf(&sids[i], &buf));
-                       /* No idea what to return here... */
-                       return NDR_ERR_INVALID_POINTER;
-               }
-
-               list_item->quotas = talloc_zero(list_item, SMB_NTQUOTA_STRUCT);
-               if (list_item->quotas == NULL) {
-                       DBG_ERR("failed to allocate\n");
-                       return NDR_ERR_ALLOC;
-               }
-
-               *list_item->quotas = qt;
-               list_item->mem_ctx = list_ctx;
-               DLIST_ADD(qt_handle->quota_list, list_item);
-       }
-       qt_handle->tmp_list = qt_handle->quota_list;
-       return NDR_ERR_SUCCESS;
-}
-
-static enum ndr_err_code extract_sids_from_buf(TALLOC_CTX *mem_ctx,
-                                 uint32_t sidlistlength,
-                                 DATA_BLOB *sid_buf,
-                                 struct dom_sid **sids,
-                                 uint32_t *num)
-{
-       DATA_BLOB blob;
-       uint32_t i = 0;
-       enum ndr_err_code err;
-
-       struct sid_list_elem {
-               struct sid_list_elem *prev, *next;
-               struct dom_sid sid;
-       };
-
-       struct sid_list_elem *sid_list = NULL;
-       struct sid_list_elem *iter = NULL;
-       TALLOC_CTX *list_ctx = talloc_init("sid_list");
-       if (!list_ctx) {
-               DBG_ERR("OOM\n");
-               err = NDR_ERR_ALLOC;
-               goto done;
-       }
-
-       *num = 0;
-       *sids = NULL;
-
-       if (sidlistlength) {
-               uint32_t offset = 0;
-               struct ndr_pull *ndr_pull = NULL;
-
-               if (sidlistlength > sid_buf->length) {
-                       DBG_ERR("sid_list_length 0x%x exceeds "
-                               "available bytes %zx\n",
-                               sidlistlength,
-                               sid_buf->length);
-                       err = NDR_ERR_OFFSET;
-                       goto done;
-               }
-               while (true) {
-                       struct file_get_quota_info info;
-                       struct sid_list_elem *item = NULL;
-                       uint32_t new_offset = 0;
-                       blob.data = sid_buf->data + offset;
-                       blob.length = sidlistlength - offset;
-                       ndr_pull = ndr_pull_init_blob(&blob, list_ctx);
-                       if (!ndr_pull) {
-                               DBG_ERR("OOM\n");
-                               err = NDR_ERR_ALLOC;
-                               goto done;
-                       }
-                       err = ndr_pull_file_get_quota_info(ndr_pull,
-                                          NDR_SCALARS | NDR_BUFFERS, &info);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
-                               DBG_ERR("Failed to pull file_get_quota_info "
-                                       "from sidlist buffer\n");
-                               goto done;
-                       }
-                       item = talloc_zero(list_ctx, struct sid_list_elem);
-                       if (!item) {
-                               DBG_ERR("OOM\n");
-                               err = NDR_ERR_ALLOC;
-                               goto done;
-                       }
-                       item->sid = info.sid;
-                       DLIST_ADD(sid_list, item);
-                       i++;
-                       if (i == UINT32_MAX) {
-                               DBG_ERR("Integer overflow\n");
-                               err = NDR_ERR_ARRAY_SIZE;
-                               goto done;
-                       }
-                       new_offset = info.next_entry_offset;
-
-                       /* if new_offset == 0 no more sid(s) to read. */
-                       if (new_offset == 0) {
-                               break;
-                       }
-
-                       /* Integer wrap? */
-                       if ((offset + new_offset) < offset) {
-                               DBG_ERR("Integer wrap while adding "
-                                       "new_offset 0x%x to current "
-                                       "buffer offset 0x%x\n",
-                                       new_offset, offset);
-                               err = NDR_ERR_OFFSET;
-                               goto done;
-                       }
-
-                       offset += new_offset;
-
-                       /* check if new offset is outside buffer boundry. */
-                       if (offset >= sidlistlength) {
-                               DBG_ERR("bufsize 0x%x exceeded by "
-                                        "new offset 0x%x)\n",
-                                       sidlistlength,
-                                       offset);
-                               err = NDR_ERR_OFFSET;
-                               goto done;
-                       }
-               }
-               *sids = talloc_zero_array(mem_ctx, struct dom_sid, i);
-               if (*sids == NULL) {
-                       DBG_ERR("OOM\n");
-                       err = NDR_ERR_ALLOC;
-                       goto done;
-               }
-
-               *num = i;
-
-               for (iter = sid_list, i = 0; iter; iter = iter->next, i++) {
-                       struct dom_sid_buf buf;
-                       (*sids)[i] = iter->sid;
-                       DBG_DEBUG("quota SID[%u] %s\n",
-                               (unsigned int)i,
-                               dom_sid_str_buf(&iter->sid, &buf));
-               }
-       }
-       err = NDR_ERR_SUCCESS;
-done:
-       TALLOC_FREE(list_ctx);
-       return err;
-}
-
-NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
-                                    files_struct *fsp,
-                                    bool restart_scan,
-                                    bool return_single,
-                                    uint32_t sid_list_length,
-                                    DATA_BLOB *sid_buf,
-                                    uint32_t max_data_count,
-                                    uint8_t **p_data,
-                                    uint32_t *p_data_size)
-{
-       NTSTATUS status;
-       SMB_NTQUOTA_HANDLE *qt_handle = NULL;
-       SMB_NTQUOTA_LIST *qt_list = NULL;
-       DATA_BLOB blob = data_blob_null;
-       enum ndr_err_code err;
-
-       qt_handle =
-               (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->private_data;
-
-       if (sid_list_length ) {
-               struct dom_sid *sids;
-               uint32_t elems = 0;
-               /*
-                * error check pulled offsets and lengths for wrap and
-                * exceeding available bytes.
-                */
-               if (sid_list_length > sid_buf->length) {
-                       DBG_ERR("sid_list_length 0x%x exceeds "
-                               "available bytes %zx\n",
-                               sid_list_length,
-                               sid_buf->length);
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-
-               err = extract_sids_from_buf(mem_ctx, sid_list_length,
-                                           sid_buf, &sids, &elems);
-               if (!NDR_ERR_CODE_IS_SUCCESS(err) || elems == 0) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-               err = fill_qtlist_from_sids(mem_ctx,
-                                           fsp,
-                                           qt_handle,
-                                           sids,
-                                           elems);
-               if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-       } else if (restart_scan) {
-               if (vfs_get_user_ntquota_list(fsp,
-                                             &(qt_handle->quota_list))!=0) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-       } else {
-               if (qt_handle->quota_list!=NULL &&
-                       qt_handle->tmp_list==NULL) {
-                       free_ntquota_list(&(qt_handle->quota_list));
-               }
-       }
-
-       if (restart_scan !=0 ) {
-               qt_list = qt_handle->quota_list;
-       } else {
-               qt_list = qt_handle->tmp_list;
-       }
-       status = fill_quota_buffer(mem_ctx, qt_list,
-                                  return_single != 0,
-                                  max_data_count,
-                                  &blob,
-                                  &qt_handle->tmp_list);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       if (blob.length > max_data_count) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-
-       *p_data = blob.data;
-       *p_data_size = blob.length;
-       return NT_STATUS_OK;
-}
-
 /****************************************************************************
  Reply to get user quota
 ****************************************************************************/
index 9fb7b707ed2f8a23de0988c4d99506a7e91fe1e8..5cfaef92387ae8f402663d1b57f681b4ba79988a 100644 (file)
@@ -678,20 +678,6 @@ void reply_ntcreate_and_X(struct smb_request *req);
 struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size);
 void reply_ntcancel(struct smb_request *req);
 void reply_ntrename(struct smb_request *req);
-#ifdef HAVE_SYS_QUOTAS
-
-struct smb2_query_quota_info;
-
-NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
-                                    files_struct *fsp,
-                                    bool restart_scan,
-                                    bool return_single,
-                                    uint32_t sid_list_length,
-                                    DATA_BLOB *sidbuffer,
-                                    uint32_t max_data_count,
-                                    uint8_t **p_data,
-                                    uint32_t *p_data_size);
-#endif
 void reply_nttrans(struct smb_request *req);
 void reply_nttranss(struct smb_request *req);
 
@@ -714,6 +700,20 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
                                        uint32_t max_data_count,
                                        uint8_t **ppmarshalled_sd,
                                        size_t *psd_size);
+#ifdef HAVE_SYS_QUOTAS
+
+struct smb2_query_quota_info;
+
+NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
+                                    files_struct *fsp,
+                                    bool restart_scan,
+                                    bool return_single,
+                                    uint32_t sid_list_length,
+                                    DATA_BLOB *sidbuffer,
+                                    uint32_t max_data_count,
+                                    uint8_t **p_data,
+                                    uint32_t *p_data_size);
+#endif
 
 /* The following definitions come from smbd/open.c  */
 
index ce669d6961ade0b9e2661a4e6da438ea30369bce..b8cb6424ca5f49a8b71b4a467b184bfd73144eca 100644 (file)
@@ -560,3 +560,272 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
        TALLOC_FREE(psd);
        return status;
 }
+
+#ifdef HAVE_SYS_QUOTAS
+static enum ndr_err_code fill_qtlist_from_sids(TALLOC_CTX *mem_ctx,
+                                              struct files_struct *fsp,
+                                              SMB_NTQUOTA_HANDLE *qt_handle,
+                                              struct dom_sid *sids,
+                                              uint32_t elems)
+{
+       uint32_t i;
+       TALLOC_CTX *list_ctx = NULL;
+
+       list_ctx = talloc_init("quota_sid_list");
+
+       if (list_ctx == NULL) {
+               DBG_ERR("failed to allocate\n");
+               return NDR_ERR_ALLOC;
+       }
+
+       if (qt_handle->quota_list!=NULL) {
+               free_ntquota_list(&(qt_handle->quota_list));
+       }
+       for (i = 0; i < elems; i++) {
+               SMB_NTQUOTA_STRUCT qt;
+               SMB_NTQUOTA_LIST *list_item;
+               bool ok;
+
+               if (!NT_STATUS_IS_OK(vfs_get_ntquota(fsp,
+                                                    SMB_USER_QUOTA_TYPE,
+                                                    &sids[i], &qt))) {
+                       /* non fatal error, return empty item in result */
+                       ZERO_STRUCT(qt);
+                       continue;
+               }
+
+
+               list_item = talloc_zero(list_ctx, SMB_NTQUOTA_LIST);
+               if (list_item == NULL) {
+                       DBG_ERR("failed to allocate\n");
+                       return NDR_ERR_ALLOC;
+               }
+
+               ok = sid_to_uid(&sids[i], &list_item->uid);
+               if (!ok) {
+                       struct dom_sid_buf buf;
+                       DBG_WARNING("Could not convert SID %s to uid\n",
+                                   dom_sid_str_buf(&sids[i], &buf));
+                       /* No idea what to return here... */
+                       return NDR_ERR_INVALID_POINTER;
+               }
+
+               list_item->quotas = talloc_zero(list_item, SMB_NTQUOTA_STRUCT);
+               if (list_item->quotas == NULL) {
+                       DBG_ERR("failed to allocate\n");
+                       return NDR_ERR_ALLOC;
+               }
+
+               *list_item->quotas = qt;
+               list_item->mem_ctx = list_ctx;
+               DLIST_ADD(qt_handle->quota_list, list_item);
+       }
+       qt_handle->tmp_list = qt_handle->quota_list;
+       return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code extract_sids_from_buf(TALLOC_CTX *mem_ctx,
+                                 uint32_t sidlistlength,
+                                 DATA_BLOB *sid_buf,
+                                 struct dom_sid **sids,
+                                 uint32_t *num)
+{
+       DATA_BLOB blob;
+       uint32_t i = 0;
+       enum ndr_err_code err;
+
+       struct sid_list_elem {
+               struct sid_list_elem *prev, *next;
+               struct dom_sid sid;
+       };
+
+       struct sid_list_elem *sid_list = NULL;
+       struct sid_list_elem *iter = NULL;
+       TALLOC_CTX *list_ctx = talloc_init("sid_list");
+       if (!list_ctx) {
+               DBG_ERR("OOM\n");
+               err = NDR_ERR_ALLOC;
+               goto done;
+       }
+
+       *num = 0;
+       *sids = NULL;
+
+       if (sidlistlength) {
+               uint32_t offset = 0;
+               struct ndr_pull *ndr_pull = NULL;
+
+               if (sidlistlength > sid_buf->length) {
+                       DBG_ERR("sid_list_length 0x%x exceeds "
+                               "available bytes %zx\n",
+                               sidlistlength,
+                               sid_buf->length);
+                       err = NDR_ERR_OFFSET;
+                       goto done;
+               }
+               while (true) {
+                       struct file_get_quota_info info;
+                       struct sid_list_elem *item = NULL;
+                       uint32_t new_offset = 0;
+                       blob.data = sid_buf->data + offset;
+                       blob.length = sidlistlength - offset;
+                       ndr_pull = ndr_pull_init_blob(&blob, list_ctx);
+                       if (!ndr_pull) {
+                               DBG_ERR("OOM\n");
+                               err = NDR_ERR_ALLOC;
+                               goto done;
+                       }
+                       err = ndr_pull_file_get_quota_info(ndr_pull,
+                                          NDR_SCALARS | NDR_BUFFERS, &info);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+                               DBG_ERR("Failed to pull file_get_quota_info "
+                                       "from sidlist buffer\n");
+                               goto done;
+                       }
+                       item = talloc_zero(list_ctx, struct sid_list_elem);
+                       if (!item) {
+                               DBG_ERR("OOM\n");
+                               err = NDR_ERR_ALLOC;
+                               goto done;
+                       }
+                       item->sid = info.sid;
+                       DLIST_ADD(sid_list, item);
+                       i++;
+                       if (i == UINT32_MAX) {
+                               DBG_ERR("Integer overflow\n");
+                               err = NDR_ERR_ARRAY_SIZE;
+                               goto done;
+                       }
+                       new_offset = info.next_entry_offset;
+
+                       /* if new_offset == 0 no more sid(s) to read. */
+                       if (new_offset == 0) {
+                               break;
+                       }
+
+                       /* Integer wrap? */
+                       if ((offset + new_offset) < offset) {
+                               DBG_ERR("Integer wrap while adding "
+                                       "new_offset 0x%x to current "
+                                       "buffer offset 0x%x\n",
+                                       new_offset, offset);
+                               err = NDR_ERR_OFFSET;
+                               goto done;
+                       }
+
+                       offset += new_offset;
+
+                       /* check if new offset is outside buffer boundry. */
+                       if (offset >= sidlistlength) {
+                               DBG_ERR("bufsize 0x%x exceeded by "
+                                        "new offset 0x%x)\n",
+                                       sidlistlength,
+                                       offset);
+                               err = NDR_ERR_OFFSET;
+                               goto done;
+                       }
+               }
+               *sids = talloc_zero_array(mem_ctx, struct dom_sid, i);
+               if (*sids == NULL) {
+                       DBG_ERR("OOM\n");
+                       err = NDR_ERR_ALLOC;
+                       goto done;
+               }
+
+               *num = i;
+
+               for (iter = sid_list, i = 0; iter; iter = iter->next, i++) {
+                       struct dom_sid_buf buf;
+                       (*sids)[i] = iter->sid;
+                       DBG_DEBUG("quota SID[%u] %s\n",
+                               (unsigned int)i,
+                               dom_sid_str_buf(&iter->sid, &buf));
+               }
+       }
+       err = NDR_ERR_SUCCESS;
+done:
+       TALLOC_FREE(list_ctx);
+       return err;
+}
+
+NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
+                                    files_struct *fsp,
+                                    bool restart_scan,
+                                    bool return_single,
+                                    uint32_t sid_list_length,
+                                    DATA_BLOB *sid_buf,
+                                    uint32_t max_data_count,
+                                    uint8_t **p_data,
+                                    uint32_t *p_data_size)
+{
+       NTSTATUS status;
+       SMB_NTQUOTA_HANDLE *qt_handle = NULL;
+       SMB_NTQUOTA_LIST *qt_list = NULL;
+       DATA_BLOB blob = data_blob_null;
+       enum ndr_err_code err;
+
+       qt_handle =
+               (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->private_data;
+
+       if (sid_list_length ) {
+               struct dom_sid *sids;
+               uint32_t elems = 0;
+               /*
+                * error check pulled offsets and lengths for wrap and
+                * exceeding available bytes.
+                */
+               if (sid_list_length > sid_buf->length) {
+                       DBG_ERR("sid_list_length 0x%x exceeds "
+                               "available bytes %zx\n",
+                               sid_list_length,
+                               sid_buf->length);
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               err = extract_sids_from_buf(mem_ctx, sid_list_length,
+                                           sid_buf, &sids, &elems);
+               if (!NDR_ERR_CODE_IS_SUCCESS(err) || elems == 0) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               err = fill_qtlist_from_sids(mem_ctx,
+                                           fsp,
+                                           qt_handle,
+                                           sids,
+                                           elems);
+               if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+       } else if (restart_scan) {
+               if (vfs_get_user_ntquota_list(fsp,
+                                             &(qt_handle->quota_list))!=0) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+       } else {
+               if (qt_handle->quota_list!=NULL &&
+                       qt_handle->tmp_list==NULL) {
+                       free_ntquota_list(&(qt_handle->quota_list));
+               }
+       }
+
+       if (restart_scan !=0 ) {
+               qt_list = qt_handle->quota_list;
+       } else {
+               qt_list = qt_handle->tmp_list;
+       }
+       status = fill_quota_buffer(mem_ctx, qt_list,
+                                  return_single != 0,
+                                  max_data_count,
+                                  &blob,
+                                  &qt_handle->tmp_list);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       if (blob.length > max_data_count) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+
+       *p_data = blob.data;
+       *p_data_size = blob.length;
+       return NT_STATUS_OK;
+}
+#endif /* HAVE_SYS_QUOTAS */