#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
****************************************************************************/
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);
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 */
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 */