Exemple #1
0
/*
  pull an array length field and add it to the array_length_list token list
*/
_PUBLIC_ enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const void *p)
{
	uint32_t length, offset;
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &offset));
	if (offset != 0) {
		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
				      "non-zero array offset %u\n", offset);
	}
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
	return ndr_token_store(ndr, &ndr->array_length_list, p, length);
}
Exemple #2
0
/*
  parse a ref pointer referent identifier
*/
_PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
{
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
	/* ref pointers always point to data */
	*v = 1;
	return NDR_ERR_SUCCESS;
}
Exemple #3
0
/*
 * Pull a DATA_BLOB from the wire.
 * 1) when called with LIBNDR_FLAG_ALIGN* alignment flags set, pull padding
 *    bytes _only_. The length is determined by the alignment required and the
 *    current ndr offset.
 * 2) When called with the LIBNDR_FLAG_REMAINING flag, pull all remaining bytes
 *    from the ndr buffer.
 * 3) Otherwise, pull a uint3264 length _and_ a corresponding byte array from the
 *    ndr buffer.
 */
_PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
{
	uint32_t length = 0;

	if (ndr->flags & LIBNDR_FLAG_REMAINING) {
		length = ndr->data_size - ndr->offset;
	} else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
		if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
			length = NDR_ALIGN(ndr, 2);
		} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
			length = NDR_ALIGN(ndr, 4);
		} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
			length = NDR_ALIGN(ndr, 8);
		}
		if (ndr->data_size - ndr->offset < length) {
			length = ndr->data_size - ndr->offset;
		}
	} else {
		NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length));
	}
	NDR_PULL_NEED_BYTES(ndr, length);
	*blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
	ndr->offset += length;
	return NDR_ERR_SUCCESS;
}
Exemple #4
0
/*
  parse a pointer referent identifier
*/
_PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
{
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v));
	if (*v != 0) {
		ndr->ptr_count++;
	}
	return NDR_ERR_SUCCESS;
}
Exemple #5
0
/*
  parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
*/
enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
{
	uint32_t num_auths;
	if (!(ndr_flags & NDR_SCALARS)) {
		return NDR_ERR_SUCCESS;
	}
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &num_auths));
	NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
	if (sid->num_auths != num_auths) {
		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
				      "Bad array size %u should exceed %u", 
				      num_auths, sid->num_auths);
	}
	return NDR_ERR_SUCCESS;
}
Exemple #6
0
/*
  pull an array size field and add it to the array_size_list token list
*/
_PUBLIC_ enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void *p)
{
	uint32_t size;
	NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &size));
	return ndr_token_store(ndr, &ndr->array_size_list, p, size);
}
Exemple #7
0
/*
  handle subcontext buffers, which in midl land are user-marshalled, but
  we use magic in pidl to make them easier to cope with
*/
_PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
				   struct ndr_pull **_subndr,
				   size_t header_size,
				   ssize_t size_is)
{
	struct ndr_pull *subndr;
	uint32_t r_content_size;
	bool force_le = false;
	bool force_be = false;

	switch (header_size) {
	case 0: {
		uint32_t content_size = ndr->data_size - ndr->offset;
		if (size_is >= 0) {
			content_size = size_is;
		}
		r_content_size = content_size;
		break;
	}

	case 2: {
		uint16_t content_size;
		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &content_size));
		if (size_is >= 0 && size_is != content_size) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", 
						(int)size_is, (int)content_size);
		}
		r_content_size = content_size;
		break;
	}

	case 4: {
		uint32_t content_size;
		NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &content_size));
		if (size_is >= 0 && size_is != content_size) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", 
						(int)size_is, (int)content_size);
		}
		r_content_size = content_size;
		break;
	}
	case 0xFFFFFC01: {
		/*
		 * Common Type Header for the Serialization Stream
		 * See [MS-RPCE] 2.2.6 Type Serialization Version 1
		 */
		uint8_t version;
		uint8_t drep;
		uint16_t hdrlen;
		uint32_t filler;
		uint32_t content_size;
		uint32_t reserved;

		/* version */
		NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &version));

		if (version != 1) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
					      "Bad subcontext (PULL) Common Type Header version %d != 1",
					      (int)version);
		}

		/*
		 * 0x10 little endian
		 * 0x00 big endian
		 */
		NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &drep));
		if (drep == 0x10) {
			force_le = true;
		} else if (drep == 0x00) {
			force_be = true;
		} else {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
					      "Bad subcontext (PULL) Common Type Header invalid drep 0x%02X",
					      (unsigned int)drep);
		}

		/* length of the "Private Header for Constructed Type" */
		NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &hdrlen));
		if (hdrlen != 8) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
					      "Bad subcontext (PULL) Common Type Header length %d != 8",
					      (int)hdrlen);
		}

		/* filler should be ignored */
		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &filler));

		/*
		 * Private Header for Constructed Type
		 */
		/* length - will be updated latter */
		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size));
		if (size_is >= 0 && size_is != content_size) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d",
					      (int)size_is, (int)content_size);
		}
		/* the content size must be a multiple of 8 */
		if ((content_size % 8) != 0) {
			return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
					      "Bad subcontext (PULL) size_is(%d) not padded to 8 content_size %d",
					      (int)size_is, (int)content_size);
		}
		r_content_size = content_size;

		/* reserved */
		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &reserved));
		break;
	}
	default:
		return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d", 
				      (int)header_size);
	}

	NDR_PULL_NEED_BYTES(ndr, r_content_size);

	subndr = talloc_zero(ndr, struct ndr_pull);
	NDR_ERR_HAVE_NO_MEMORY(subndr);
	subndr->flags		= ndr->flags & ~LIBNDR_FLAG_NDR64;
	subndr->current_mem_ctx	= ndr->current_mem_ctx;

	subndr->data = ndr->data + ndr->offset;
	subndr->offset = 0;
	subndr->data_size = r_content_size;
	subndr->iconv_convenience = talloc_reference(subndr, ndr->iconv_convenience);

	if (force_le) {
		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
	} else if (force_be) {
		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
	}

	*_subndr = subndr;
	return NDR_ERR_SUCCESS;
}