示例#1
0
_PUBLIC_ enum ndr_err_code ndr_push_PAC_BUFFER_RAW(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER_RAW *r)
{
	if (ndr_flags & NDR_SCALARS) {
		NDR_CHECK(ndr_push_align(ndr, 4));
		NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ndr_size));
		{
			uint32_t _flags_save_DATA_BLOB_REM = ndr->flags;
			ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
			NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info));
			ndr->flags = _flags_save_DATA_BLOB_REM;
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
	}
	if (ndr_flags & NDR_BUFFERS) {
		{
			uint32_t _flags_save_DATA_BLOB_REM = ndr->flags;
			ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
			if (r->info) {
				NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info));
				{
					struct ndr_push *_ndr_info;
					NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, NDR_ROUND(r->ndr_size, 8)));
					NDR_CHECK(ndr_push_DATA_BLOB_REM(_ndr_info, NDR_SCALARS, r->info));
					NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, NDR_ROUND(r->ndr_size, 8)));
				}
			}
			ndr->flags = _flags_save_DATA_BLOB_REM;
		}
	}
	return NDR_ERR_SUCCESS;
}
示例#2
0
NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor *r)
{
    {
        uint32_t _flags_save_STRUCT = ndr->flags;
        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
        if (ndr_flags & NDR_SCALARS) {
            NDR_CHECK(ndr_push_align(ndr, 4));
            NDR_CHECK(ndr_push_security_descriptor_revision(ndr, NDR_SCALARS, r->revision));
            NDR_CHECK(ndr_push_security_descriptor_type(ndr, NDR_SCALARS, r->type));
            NDR_CHECK(ndr_push_relative_ptr1(ndr, r->owner_sid));
            NDR_CHECK(ndr_push_relative_ptr1(ndr, r->group_sid));
            NDR_CHECK(ndr_push_relative_ptr1(ndr, r->sacl));
            NDR_CHECK(ndr_push_relative_ptr1(ndr, r->dacl));
        }
        if (ndr_flags & NDR_BUFFERS) {
            if (r->owner_sid) {
                NDR_CHECK(ndr_push_relative_ptr2(ndr, r->owner_sid));
                NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->owner_sid));
            }
            if (r->group_sid) {
                NDR_CHECK(ndr_push_relative_ptr2(ndr, r->group_sid));
                NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->group_sid));
            }
            if (r->sacl) {
                NDR_CHECK(ndr_push_relative_ptr2(ndr, r->sacl));
                NDR_CHECK(ndr_push_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->sacl));
            }
            if (r->dacl) {
                NDR_CHECK(ndr_push_relative_ptr2(ndr, r->dacl));
                NDR_CHECK(ndr_push_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->dacl));
            }
        }
        ndr->flags = _flags_save_STRUCT;
    }
    return NT_STATUS_OK;
}
示例#3
0
/*
  push a relative object - stage2 start
  this is called during buffers processing
*/
_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2_start(struct ndr_push *ndr, const void *p)
{
	if (p == NULL) {
		return NDR_ERR_SUCCESS;
	}
	if (!(ndr->flags & LIBNDR_FLAG_RELATIVE_REVERSE)) {
		return ndr_push_relative_ptr2(ndr, p);
	}
	if (ndr->relative_end_offset == -1) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
			      "ndr_push_relative_ptr2_start RELATIVE_REVERSE flag set and relative_end_offset %d",
			      ndr->relative_end_offset);
	}
	NDR_CHECK(ndr_token_store(ndr, &ndr->relative_begin_list, p, ndr->offset));
	return NDR_ERR_SUCCESS;
}
示例#4
0
文件: ndr.c 项目: Arkhont/samba
/*
  push a relative object - stage2 start
  this is called during buffers processing
*/
_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2_start(struct ndr_push *ndr, const void *p)
{
	if (p == NULL) {
		return NDR_ERR_SUCCESS;
	}
	if (!(ndr->flags & LIBNDR_FLAG_RELATIVE_REVERSE)) {
		uint32_t relative_offset;
		size_t pad;
		size_t align = 1;

		if (ndr->offset < ndr->relative_base_offset) {
			return ndr_push_error(ndr, NDR_ERR_BUFSIZE,
				      "ndr_push_relative_ptr2_start ndr->offset(%u) < ndr->relative_base_offset(%u)",
				      ndr->offset, ndr->relative_base_offset);
		}

		relative_offset = ndr->offset - ndr->relative_base_offset;

		if (ndr->flags & LIBNDR_FLAG_NOALIGN) {
			align = 1;
		} else if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
			align = 2;
		} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
			align = 4;
		} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
			align = 8;
		}

		pad = ndr_align_size(relative_offset, align);
		if (pad) {
			NDR_CHECK(ndr_push_zero(ndr, pad));
		}

		return ndr_push_relative_ptr2(ndr, p);
	}
	if (ndr->relative_end_offset == -1) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
			      "ndr_push_relative_ptr2_start RELATIVE_REVERSE flag set and relative_end_offset %d",
			      ndr->relative_end_offset);
	}
	NDR_CHECK(ndr_token_store(ndr, &ndr->relative_begin_list, p, ndr->offset));
	return NDR_ERR_SUCCESS;
}
示例#5
0
_PUBLIC_ NTSTATUS ndr_push_WbemQualifier(struct ndr_push *ndr, int ndr_flags, const struct WbemQualifier *r)
{
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
            	NDR_CHECK(ndr_push_relative_ptr1(ndr, r->name));
                NDR_CHECK(ndr_push_WBEM_FLAVOR_TYPE(ndr, NDR_SCALARS, r->flavors));
                NDR_CHECK(ndr_push_CIMTYPE_ENUMERATION(ndr, NDR_SCALARS, r->cimtype));
                NDR_CHECK(ndr_push_set_switch_value(ndr, &r->value, r->cimtype & CIM_TYPEMASK));
                NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->value));
        }
        if (ndr_flags & NDR_BUFFERS) {
                if (r->name) {
			uint32_t ofs;
			int32_t i;
			for (i = 0; i < arr_sizeof(qualifier_keys); ++i)
				if (qualifier_keys[i] && !strcmp(r->name, qualifier_keys[i])) break;
			if (i == arr_sizeof(qualifier_keys)) {
				if (!strncmp(qn_unknown, r->name, sizeof(qn_unknown) - 1))
                            		i = atoi(r->name + sizeof(qn_unknown) - 1);
				else
					i = -1;
			}
			if (i >= 0) {
				ofs = ndr->offset;
				NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->name, &ndr->offset));
				NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x80000000 | i));
				ndr->offset = ofs;
			} else {
                    		NDR_CHECK(ndr_push_relative_ptr2(ndr, r->name));
                    		NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->name));
			}
                }
                NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->value));
        }
        return NT_STATUS_OK;
}
示例#6
0
/*
  push a relative object - stage2 end
  this is called during buffers processing
*/
_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2_end(struct ndr_push *ndr, const void *p)
{
	uint32_t begin_offset = 0xFFFFFFFF;
	ssize_t len;
	uint32_t correct_offset = 0;
	uint32_t align = 1;
	uint32_t pad = 0;

	if (p == NULL) {
		return NDR_ERR_SUCCESS;
	}

	if (!(ndr->flags & LIBNDR_FLAG_RELATIVE_REVERSE)) {
		return NDR_ERR_SUCCESS;
	}

	if (ndr->flags & LIBNDR_FLAG_NO_NDR_SIZE) {
		/* better say more than calculation a too small buffer */
		NDR_PUSH_ALIGN(ndr, 8);
		return NDR_ERR_SUCCESS;
	}

	if (ndr->relative_end_offset < ndr->offset) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
				      "ndr_push_relative_ptr2_end:"
				      "relative_end_offset %u < offset %u",
				      ndr->relative_end_offset, ndr->offset);
	}

	NDR_CHECK(ndr_token_retrieve(&ndr->relative_begin_list, p, &begin_offset));

	/* we have marshalled a buffer, see how long it was */
	len = ndr->offset - begin_offset;

	if (len < 0) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
				      "ndr_push_relative_ptr2_end:"
				      "offset %u - begin_offset %u < 0",
				      ndr->offset, begin_offset);
	}

	if (ndr->relative_end_offset < len) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
				      "ndr_push_relative_ptr2_end:"
				      "relative_end_offset %u < len %lld",
				      ndr->offset, (long long)len);
	}

	/* the reversed offset is at the end of the main buffer */
	correct_offset = ndr->relative_end_offset - len;

	/* TODO: remove this hack and let the idl use FLAG_ALIGN2 explicit */
	align = 2;

	if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
		align = 2;
	} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
		align = 4;
	} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
		align = 8;
	}

	pad = ndr_align_size(correct_offset, align);
	if (pad) {
		correct_offset += pad;
		correct_offset -= align;
	}

	if (correct_offset < begin_offset) {
		return ndr_push_error(ndr, NDR_ERR_RELATIVE,
				      "ndr_push_relative_ptr2_end: "
				      "correct_offset %u < begin_offset %u",
				      correct_offset, begin_offset);
	}

	if (len > 0) {
		uint32_t clear_size = correct_offset - begin_offset;

		clear_size = MIN(clear_size, len);

		/* now move the marshalled buffer to the end of the main buffer */
		memmove(ndr->data + correct_offset, ndr->data + begin_offset, len);

		if (clear_size) {
			/* and wipe out old buffer within the main buffer */
			memset(ndr->data + begin_offset, '\0', clear_size);
		}
	}

	/* and set the end offset for the next buffer */
	ndr->relative_end_offset = correct_offset;

	/* finally write the offset to the main buffer */
	ndr->offset = correct_offset;
	NDR_CHECK(ndr_push_relative_ptr2(ndr, p));

	/* restore to where we were in the main buffer */
	ndr->offset = begin_offset;

	return NDR_ERR_SUCCESS;
}