Beispiel #1
0
static enum ndr_err_code ndr_push_xattr_DosInfo(struct ndr_push *ndr, int ndr_flags, const union xattr_DosInfo *r)
{
	if (ndr_flags & NDR_SCALARS) {
		int level = ndr_push_get_switch_value(ndr, r);
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, level));
		switch (level) {
			case 1: {
				NDR_CHECK(ndr_push_xattr_DosInfo1(ndr, NDR_SCALARS, &r->info1));
			break; }

			case 2: {
				NDR_CHECK(ndr_push_xattr_DosInfo2Old(ndr, NDR_SCALARS, &r->oldinfo2));
			break; }

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	if (ndr_flags & NDR_BUFFERS) {
		int level = ndr_push_get_switch_value(ndr, r);
		switch (level) {
			case 1:
			break;

			case 2:
			break;

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #2
0
static enum ndr_err_code ndr_push_echo_Enum3(struct ndr_push *ndr, int ndr_flags, const union echo_Enum3 *r)
{
	if (ndr_flags & NDR_SCALARS) {
		int level = ndr_push_get_switch_value(ndr, r);
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, level));
		switch (level) {
			case ECHO_ENUM1: {
				NDR_CHECK(ndr_push_echo_Enum1(ndr, NDR_SCALARS, r->e1));
			break; }

			case ECHO_ENUM2: {
				NDR_CHECK(ndr_push_echo_Enum2(ndr, NDR_SCALARS, &r->e2));
			break; }

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	if (ndr_flags & NDR_BUFFERS) {
		int level = ndr_push_get_switch_value(ndr, r);
		switch (level) {
			case ECHO_ENUM1:
			break;

			case ECHO_ENUM2:
			break;

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #3
0
static enum ndr_err_code ndr_push_frsapi_IsPathReplicated(struct ndr_push *ndr, int flags, const struct frsapi_IsPathReplicated *r)
{
	if (flags & NDR_IN) {
		NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.path));
		if (r->in.path) {
			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(r->in.path, CH_UTF16)));
			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0));
			NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(r->in.path, CH_UTF16)));
			NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.path, ndr_charset_length(r->in.path, CH_UTF16), sizeof(uint16_t), CH_UTF16));
		}
		NDR_CHECK(ndr_push_frsapi_ReplicaSetType(ndr, NDR_SCALARS, r->in.replica_set_type));
	}
	if (flags & NDR_OUT) {
		if (r->out.replicated == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.replicated));
		if (r->out.primary == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.primary));
		if (r->out.root == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.root));
		if (r->out.replica_set_guid == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, r->out.replica_set_guid));
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #4
0
/*
  expand the available space in the buffer to ndr->offset + extra_size
*/
_PUBLIC_ enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size)
{
	uint32_t size = extra_size + ndr->offset;

	if (size < ndr->offset) {
		/* extra_size overflowed the offset */
		return ndr_push_error(ndr, NDR_ERR_BUFSIZE, "Overflow in push_expand to %u",
				      size);
	}

	if (ndr->alloc_size > size) {
		return NDR_ERR_SUCCESS;
	}

	ndr->alloc_size += NDR_BASE_MARSHALL_SIZE;
	if (size+1 > ndr->alloc_size) {
		ndr->alloc_size = size+1;
	}
	ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->alloc_size);
	if (!ndr->data) {
		return ndr_push_error(ndr, NDR_ERR_ALLOC, "Failed to push_expand to %u",
				      ndr->alloc_size);
	}

	return NDR_ERR_SUCCESS;
}
Beispiel #5
0
static enum ndr_err_code ndr_push_echo_TestCall(struct ndr_push *ndr, int flags, const struct echo_TestCall *r)
{
	if (flags & NDR_IN) {
		if (r->in.s1 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.s1, CH_UTF16)));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.s1, CH_UTF16)));
		NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.s1, ndr_charset_length(r->in.s1, CH_UTF16), sizeof(uint16_t), CH_UTF16));
	}
	if (flags & NDR_OUT) {
		if (r->out.s2 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.s2));
		if (*r->out.s2) {
			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.s2, CH_UTF16)));
			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.s2, CH_UTF16)));
			NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.s2, ndr_charset_length(*r->out.s2, CH_UTF16), sizeof(uint16_t), CH_UTF16));
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #6
0
NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
			  uint32_t length, uint8_t byte_mul, charset_t chset)
{
	ssize_t ret, required;

	if (NDR_BE(ndr) && chset == CH_UTF16) {
		chset = CH_UTF16BE;
	}

	required = byte_mul * length;
	
	NDR_PUSH_NEED_BYTES(ndr, required);
	ret = convert_string(CH_UNIX, chset, 
			     var, strlen(var),
			     ndr->data+ndr->offset, required, False);
	if (ret == -1) {
		return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
				      "Bad character conversion");
	}

	/* Make sure the remaining part of the string is filled with zeroes */
	if (ret < required) {
		memset(ndr->data+ndr->offset+ret, 0, required-ret);
	}

	ndr->offset += required;

	return NT_STATUS_OK;
}
Beispiel #7
0
/*
  push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
*/
enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
{
	uint32_t old_offset;
	uint32_t padding;

	if (!(ndr_flags & NDR_SCALARS)) {
		return NDR_ERR_SUCCESS;
	}

	if (sid->num_auths > 5) {
		return ndr_push_error(ndr, NDR_ERR_RANGE, 
				      "dom_sid28 allows only upto 5 sub auth [%u]", 
				      sid->num_auths);
	}

	old_offset = ndr->offset;
	NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));

	padding = 28 - (ndr->offset - old_offset);

	if (padding > 0) {
		NDR_CHECK(ndr_push_zero(ndr, padding));
	}

	return NDR_ERR_SUCCESS;
}
Beispiel #8
0
static enum ndr_err_code ndr_push_echo_TestSurrounding(struct ndr_push *ndr, int flags, const struct echo_TestSurrounding *r)
{
	if (flags & NDR_IN) {
		if (r->in.data == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Surrounding(ndr, NDR_SCALARS, r->in.data));
	}
	if (flags & NDR_OUT) {
		if (r->out.data == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Surrounding(ndr, NDR_SCALARS, r->out.data));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #9
0
static enum ndr_err_code ndr_push_rot_get_modification_time(struct ndr_push *ndr, int flags, const struct rot_get_modification_time *r)
{
	if (flags & NDR_IN) {
		if (r->in.moniker == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_MInterfacePointer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.moniker));
	}
	if (flags & NDR_OUT) {
		if (r->out.t == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, *r->out.t));
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #10
0
static enum ndr_err_code ndr_push_dssetup_DsRoleInfo(struct ndr_push *ndr, int ndr_flags, const union dssetup_DsRoleInfo *r)
{
	if (ndr_flags & NDR_SCALARS) {
		uint32_t level = ndr_push_get_switch_value(ndr, r);
		NDR_CHECK(ndr_push_union_align(ndr, 5));
		NDR_CHECK(ndr_push_dssetup_DsRoleInfoLevel(ndr, NDR_SCALARS, level));
		NDR_CHECK(ndr_push_union_align(ndr, 5));
		switch (level) {
			case DS_ROLE_BASIC_INFORMATION: {
				NDR_CHECK(ndr_push_dssetup_DsRolePrimaryDomInfoBasic(ndr, NDR_SCALARS, &r->basic));
			break; }

			case DS_ROLE_UPGRADE_STATUS: {
				NDR_CHECK(ndr_push_dssetup_DsRoleUpgradeStatus(ndr, NDR_SCALARS, &r->upgrade));
			break; }

			case DS_ROLE_OP_STATUS: {
				NDR_CHECK(ndr_push_dssetup_DsRoleOpStatus(ndr, NDR_SCALARS, &r->opstatus));
			break; }

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u at %s", level, __location__);
		}
	}
	if (ndr_flags & NDR_BUFFERS) {
		uint32_t level = ndr_push_get_switch_value(ndr, r);
		switch (level) {
			case DS_ROLE_BASIC_INFORMATION:
				NDR_CHECK(ndr_push_dssetup_DsRolePrimaryDomInfoBasic(ndr, NDR_BUFFERS, &r->basic));
			break;

			case DS_ROLE_UPGRADE_STATUS:
			break;

			case DS_ROLE_OP_STATUS:
			break;

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u at %s", level, __location__);
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #11
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)) {
		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;
}
Beispiel #12
0
static enum ndr_err_code ndr_push_frsapi_GetDsPollingIntervalW(struct ndr_push *ndr, int flags, const struct frsapi_GetDsPollingIntervalW *r)
{
	if (flags & NDR_IN) {
	}
	if (flags & NDR_OUT) {
		if (r->out.CurrentInterval == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.CurrentInterval));
		if (r->out.DsPollingLongInterval == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.DsPollingLongInterval));
		if (r->out.DsPollingShortInterval == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.DsPollingShortInterval));
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #13
0
/*
  push a ipv4address
*/
_PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
{
	uint32_t addr;
	if (!is_ipaddress(address)) {
		return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
				      "Invalid IPv4 address: '%s'", 
				      address);
	}
	addr = inet_addr(address);
	NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
	return NDR_ERR_SUCCESS;
}
Beispiel #14
0
static enum ndr_err_code ndr_push_echo_TestEnum(struct ndr_push *ndr, int flags, const struct echo_TestEnum *r)
{
	if (flags & NDR_IN) {
		if (r->in.foo1 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Enum1(ndr, NDR_SCALARS, *r->in.foo1));
		if (r->in.foo2 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Enum2(ndr, NDR_SCALARS, r->in.foo2));
		if (r->in.foo3 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.foo3, *r->in.foo1));
		NDR_CHECK(ndr_push_echo_Enum3(ndr, NDR_SCALARS, r->in.foo3));
	}
	if (flags & NDR_OUT) {
		if (r->out.foo1 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Enum1(ndr, NDR_SCALARS, *r->out.foo1));
		if (r->out.foo2 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_echo_Enum2(ndr, NDR_SCALARS, r->out.foo2));
		if (r->out.foo3 == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.foo3, *r->out.foo1));
		NDR_CHECK(ndr_push_echo_Enum3(ndr, NDR_SCALARS, r->out.foo3));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #15
0
static enum ndr_err_code ndr_push_echo_AddOne(struct ndr_push *ndr, int flags, const struct echo_AddOne *r)
{
	if (flags & NDR_IN) {
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.in_data));
	}
	if (flags & NDR_OUT) {
		if (r->out.out_data == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.out_data));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #16
0
static enum ndr_err_code ndr_push_rot_enum(struct ndr_push *ndr, int flags, const struct rot_enum *r)
{
	if (flags & NDR_IN) {
	}
	if (flags & NDR_OUT) {
		if (r->out.EnumMoniker == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_MInterfacePointer(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.EnumMoniker));
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #17
0
static enum ndr_err_code ndr_push_rot_add(struct ndr_push *ndr, int flags, const struct rot_add *r)
{
	if (flags & NDR_IN) {
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags));
		if (r->in.unk == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_MInterfacePointer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.unk));
		if (r->in.moniker == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_MInterfacePointer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.moniker));
	}
	if (flags & NDR_OUT) {
		if (r->out.rotid == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.rotid));
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #18
0
static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr_flags, const union xattr_NTACL_Info *r)
{
	if (ndr_flags & NDR_SCALARS) {
		int level = ndr_push_get_switch_value(ndr, r);
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, level));
		switch (level) {
			case 1: {
				NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd));
			break; }

			case 2: {
				NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs));
			break; }

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	if (ndr_flags & NDR_BUFFERS) {
		int level = ndr_push_get_switch_value(ndr, r);
		switch (level) {
			case 1:
				if (r->sd) {
					NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd));
				}
			break;

			case 2:
				if (r->sd_hs) {
					NDR_CHECK(ndr_push_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs));
				}
			break;

			default:
				return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #19
0
static enum ndr_err_code ndr_push_rot_set_modification_time(struct ndr_push *ndr, int flags, const struct rot_set_modification_time *r)
{
	if (flags & NDR_IN) {
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.rotid));
		if (r->in.t == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, *r->in.t));
	}
	if (flags & NDR_OUT) {
		NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #20
0
/*
  push a relative object - stage2
  this is called during buffers processing
*/
static enum ndr_err_code ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p)
{
	uint32_t save_offset;
	uint32_t ptr_offset = 0xFFFFFFFF;
	if (p == NULL) {
		return NDR_ERR_SUCCESS;
	}
	save_offset = ndr->offset;
	NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ptr_offset));
	if (ptr_offset > ndr->offset) {
		return ndr_push_error(ndr, NDR_ERR_BUFSIZE, 
				      "ndr_push_relative_ptr2 ptr_offset(%u) > ndr->offset(%u)",
				      ptr_offset, ndr->offset);
	}
	ndr->offset = ptr_offset;
	if (save_offset < ndr->relative_base_offset) {
		return ndr_push_error(ndr, NDR_ERR_BUFSIZE, 
				      "ndr_push_relative_ptr2 save_offset(%u) < ndr->relative_base_offset(%u)",
				      save_offset, ndr->relative_base_offset);
	}	
	NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, save_offset - ndr->relative_base_offset));
	ndr->offset = save_offset;
	return NDR_ERR_SUCCESS;
}
Beispiel #21
0
static enum ndr_err_code ndr_push_echo_TestCall2(struct ndr_push *ndr, int flags, const struct echo_TestCall2 *r)
{
	if (flags & NDR_IN) {
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level));
	}
	if (flags & NDR_OUT) {
		if (r->out.info == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.info, r->in.level));
		NDR_CHECK(ndr_push_echo_Info(ndr, NDR_SCALARS, r->out.info));
		NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #22
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;
}
Beispiel #23
0
_PUBLIC_ enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
{
	uint32_t cntr_sub_auths_0;
	if (ndr_flags & NDR_SCALARS) {
		NDR_CHECK(ndr_push_align(ndr, 4));
		NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->sid_rev_num));
		NDR_CHECK(ndr_push_int8(ndr, NDR_SCALARS, r->num_auths));
		NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6));
		if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) {
			return ndr_push_error(ndr, NDR_ERR_RANGE, "value out of range");
		}
		for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) {
			NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sub_auths[cntr_sub_auths_0]));
		}
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #24
0
/*
  expand the available space in the buffer to 'size'
*/
_PUBLIC_ NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32_t size)
{
	if (ndr->alloc_size > size) {
		return NT_STATUS_OK;
	}

	ndr->alloc_size += NDR_BASE_MARSHALL_SIZE;
	if (size+1 > ndr->alloc_size) {
		ndr->alloc_size = size+1;
	}
	ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->alloc_size);
	if (!ndr->data) {
		return ndr_push_error(ndr, NDR_ERR_ALLOC, "Failed to push_expand to %u",
				      ndr->alloc_size);
	}

	return NT_STATUS_OK;
}
Beispiel #25
0
static enum ndr_err_code ndr_push_echo_TestDoublePointer(struct ndr_push *ndr, int flags, const struct echo_TestDoublePointer *r)
{
	if (flags & NDR_IN) {
		if (r->in.data == NULL) {
			return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
		}
		NDR_CHECK(ndr_push_unique_ptr(ndr, *r->in.data));
		if (*r->in.data) {
			NDR_CHECK(ndr_push_unique_ptr(ndr, **r->in.data));
			if (**r->in.data) {
				NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, ***r->in.data));
			}
		}
	}
	if (flags & NDR_OUT) {
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.result));
	}
	return NDR_ERR_SUCCESS;
}
Beispiel #26
0
/*
  push a ipv6address
*/
_PUBLIC_ enum ndr_err_code ndr_push_ipv6address(struct ndr_push *ndr, int ndr_flags, const char *address)
{
#ifdef AF_INET6
	uint8_t addr[IPV6_BYTES];
	int ret;

	if (!is_ipaddress(address)) {
		return ndr_push_error(ndr, NDR_ERR_IPV6ADDRESS,
				      "Invalid IPv6 address: '%s'",
				      address);
	}
	ret = inet_pton(AF_INET6, address, addr);
	if (ret <= 0) {
		return NDR_ERR_IPV6ADDRESS;
	}

	NDR_CHECK(ndr_push_array_uint8(ndr, ndr_flags, addr, IPV6_BYTES));

	return NDR_ERR_SUCCESS;
#else
	return NDR_ERR_IPV6ADDRESS;
#endif
}
Beispiel #27
0
/*
  this is a paranoid NDR input validator. For every packet we pull
  from the wire we push it back again then pull and push it
  again. Then we compare the raw NDR data for that to the NDR we
  initially generated. If they don't match then we know we must have a
  bug in either the pull or push side of our code
*/
static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
					struct ndr_pull *pull_in,
					void *struct_ptr,
					size_t struct_size,
					ndr_push_flags_fn_t ndr_push,
					ndr_pull_flags_fn_t ndr_pull,
					ndr_print_function_t ndr_print)
{
	void *st;
	struct ndr_pull *pull;
	struct ndr_push *push;
	DATA_BLOB blob, blob2;
	TALLOC_CTX *mem_ctx = pull_in;
	char *s1, *s2;
	enum ndr_err_code ndr_err;

	st = talloc_size(mem_ctx, struct_size);
	if (!st) {
		return NT_STATUS_NO_MEMORY;
	}
	memcpy(st, struct_ptr, struct_size);

	push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
	if (!push) {
		return NT_STATUS_NO_MEMORY;
	}	

	ndr_err = ndr_push(push, NDR_OUT, struct_ptr);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation push - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	blob = ndr_push_blob(push);

	pull = ndr_pull_init_flags(c, &blob, mem_ctx);
	if (!pull) {
		return NT_STATUS_NO_MEMORY;
	}

	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	ndr_err = ndr_pull(pull, NDR_OUT, st);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_pull_error(pull, NDR_ERR_VALIDATE,
					 "failed output validation pull - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	push = ndr_push_init_ctx(mem_ctx, c->iconv_convenience);
	if (!push) {
		return NT_STATUS_NO_MEMORY;
	}	

	ndr_err = ndr_push(push, NDR_OUT, st);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation push2 - %s",
					 nt_errstr(status));
		return ndr_map_error2ntstatus(ndr_err);
	}

	blob2 = ndr_push_blob(push);

	if (data_blob_cmp(&blob, &blob2) != 0) {
		DEBUG(3,("original:\n"));
		dump_data(3, blob.data, blob.length);
		DEBUG(3,("secondary:\n"));
		dump_data(3, blob2.data, blob2.length);
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation blobs doesn't match");
		return ndr_map_error2ntstatus(ndr_err);
	}

	/* this checks the printed forms of the two structures, which effectively
	   tests all of the value() attributes */
	s1 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", 
				       NDR_OUT, struct_ptr);
	s2 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", 
				       NDR_OUT, st);
	if (strcmp(s1, s2) != 0) {
#if 1
		DEBUG(3,("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2));
#else
		/* this is sometimes useful */
		printf("VALIDATE ERROR\n");
		file_save("wire.dat", s1, strlen(s1));
		file_save("gen.dat", s2, strlen(s2));
		system("diff -u wire.dat gen.dat");
#endif
		ndr_err = ndr_push_error(push, NDR_ERR_VALIDATE,
					 "failed output validation strings doesn't match");
		return ndr_map_error2ntstatus(ndr_err);
	}

	return NT_STATUS_OK;
}
Beispiel #28
0
/*
  push a subcontext header 
*/
_PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr,
				 struct ndr_push *subndr,
				 size_t header_size,
				 ssize_t size_is)
{
	ssize_t padding_len;

	if (size_is >= 0) {
		padding_len = size_is - subndr->offset;
		if (padding_len < 0) {
			return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PUSH) content_size %d is larger than size_is(%d)",
					      (int)subndr->offset, (int)size_is);
		}
		subndr->offset = size_is;
	}

	switch (header_size) {
	case 0: 
		break;

	case 2: 
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, subndr->offset));
		break;

	case 4: 
		NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, subndr->offset));
		break;

	case 0xFFFFFC01:
		/*
		 * Common Type Header for the Serialization Stream
		 * See [MS-RPCE] 2.2.6 Type Serialization Version 1
		 */
		padding_len = NDR_ROUND(subndr->offset, 8) - subndr->offset;
		if (padding_len > 0) {
			NDR_CHECK(ndr_push_zero(subndr, padding_len));
		}

		/* version */
		NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 1));

		/*
		 * 0x10 little endian
		 * 0x00 big endian
		 */
		NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, NDR_BE(ndr)?0x00:0x10));

		/* length of the "Private Header for Constructed Type" */
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 8));

		/* filler */
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xCCCCCCCC));

		/*
		 * Private Header for Constructed Type
		 */
		/* length - will be updated latter */
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset));

		/* reserved */
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
		break;

	default:
		return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext header size %d", 
				      (int)header_size);
	}

	NDR_CHECK(ndr_push_bytes(ndr, subndr->data, subndr->offset));
	return NDR_ERR_SUCCESS;
}
Beispiel #29
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;
}
Beispiel #30
0
/**
  push a general string onto the wire
*/
NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
{
	ssize_t s_len, c_len, d_len;
	charset_t chset = CH_UTF16LE;
	unsigned flags = ndr->flags;
	unsigned byte_mul = 2;
	uint8_t *dest = NULL;

	if (!(ndr_flags & NDR_SCALARS)) {
		return NT_STATUS_OK;
	}

	if (NDR_BE(ndr)) {
		chset = CH_UTF16BE;
	}
	
	s_len = s?strlen(s):0;

	if (flags & LIBNDR_FLAG_STR_ASCII) {
		chset = CH_DOS;
		byte_mul = 1;
		flags &= ~LIBNDR_FLAG_STR_ASCII;
	}

	if (flags & LIBNDR_FLAG_STR_UTF8) {
		chset = CH_UTF8;
		byte_mul = 1;
		flags &= ~LIBNDR_FLAG_STR_UTF8;
	}

	flags &= ~LIBNDR_FLAG_STR_CONFORMANT;

	if (!(flags & 
	      (LIBNDR_FLAG_STR_NOTERM |
	       LIBNDR_FLAG_STR_FIXLEN15 |
	       LIBNDR_FLAG_STR_FIXLEN32))) {
		s_len++;
	}
	d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, &dest,
				      False);
	if (d_len == -1) {
		return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
				      "Bad character conversion");
	}

	if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
		c_len = d_len;
		flags &= ~LIBNDR_FLAG_STR_BYTESIZE;
	} else if (flags & LIBNDR_FLAG_STR_CHARLEN) {
		c_len = (d_len / byte_mul)-1;
		flags &= ~LIBNDR_FLAG_STR_CHARLEN;
	} else {
		c_len = d_len / byte_mul;
	}

	switch ((flags & LIBNDR_STRING_FLAGS) & ~LIBNDR_FLAG_STR_NOTERM) {
	case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		break;

	case LIBNDR_FLAG_STR_LEN4:
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		break;

	case LIBNDR_FLAG_STR_SIZE4:
		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		break;

	case LIBNDR_FLAG_STR_SIZE2:
		NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, c_len));
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		break;

	case LIBNDR_FLAG_STR_NULLTERM:
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		break;

	case LIBNDR_FLAG_STR_FIXLEN15:
	case LIBNDR_FLAG_STR_FIXLEN32: {
		ssize_t fix_len = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
		uint32_t pad_len = fix_len - d_len;
		if (d_len > fix_len) {
			return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
					      "Bad character conversion");
		}
		NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
		if (pad_len != 0) {
			NDR_CHECK(ndr_push_zero(ndr, pad_len));
		}
		break;
	}

	default:
		return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
				      ndr->flags & LIBNDR_STRING_FLAGS);
	}

	talloc_free(dest);

	return NT_STATUS_OK;
}