⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndr.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	}	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_uint32(ndr, NDR_SCALARS, subndr->offset));		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;}/*  store a token in the ndr context, for later retrieval*/_PUBLIC_ enum ndr_err_code ndr_token_store(TALLOC_CTX *mem_ctx,			 struct ndr_token_list **list, 			 const void *key, 			 uint32_t value){	struct ndr_token_list *tok;	tok = talloc(mem_ctx, struct ndr_token_list);	NDR_ERR_HAVE_NO_MEMORY(tok);	tok->key = key;	tok->value = value;	DLIST_ADD((*list), tok);	return NDR_ERR_SUCCESS;}/*  retrieve a token from a ndr context, using cmp_fn to match the tokens*/_PUBLIC_ enum ndr_err_code ndr_token_retrieve_cmp_fn(struct ndr_token_list **list, const void *key, uint32_t *v,				   comparison_fn_t _cmp_fn, bool _remove_tok){	struct ndr_token_list *tok;	for (tok=*list;tok;tok=tok->next) {		if (_cmp_fn && _cmp_fn(tok->key,key)==0) goto found;		else if (!_cmp_fn && tok->key == key) goto found;	}	return NDR_ERR_TOKEN;found:	*v = tok->value;	if (_remove_tok) {		DLIST_REMOVE((*list), tok);		talloc_free(tok);	}	return NDR_ERR_SUCCESS;}/*  retrieve a token from a ndr context*/_PUBLIC_ enum ndr_err_code ndr_token_retrieve(struct ndr_token_list **list, const void *key, uint32_t *v){	return ndr_token_retrieve_cmp_fn(list, key, v, NULL, true);}/*  peek at but don't removed a token from a ndr context*/_PUBLIC_ uint32_t ndr_token_peek(struct ndr_token_list **list, const void *key){	enum ndr_err_code status;	uint32_t v;	status = ndr_token_retrieve_cmp_fn(list, key, &v, NULL, false);	if (!NDR_ERR_CODE_IS_SUCCESS(status)) {		return 0;	}	return v;}/*  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_uint32(ndr, NDR_SCALARS, &size));	return ndr_token_store(ndr, &ndr->array_size_list, p, size);}/*  get the stored array size field*/_PUBLIC_ uint32_t ndr_get_array_size(struct ndr_pull *ndr, const void *p){	return ndr_token_peek(&ndr->array_size_list, p);}/*  check the stored array size field*/_PUBLIC_ enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, uint32_t size){	uint32_t stored;	stored = ndr_token_peek(&ndr->array_size_list, p);	if (stored != size) {		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 				      "Bad array size - got %u expected %u\n",				      stored, size);	}	return NDR_ERR_SUCCESS;}/*  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_uint32(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_uint32(ndr, NDR_SCALARS, &length));	return ndr_token_store(ndr, &ndr->array_length_list, p, length);}/*  get the stored array length field*/_PUBLIC_ uint32_t ndr_get_array_length(struct ndr_pull *ndr, const void *p){	return ndr_token_peek(&ndr->array_length_list, p);}/*  check the stored array length field*/_PUBLIC_ enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, void *p, uint32_t length){	uint32_t stored;	stored = ndr_token_peek(&ndr->array_length_list, p);	if (stored != length) {		return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 				      "Bad array length - got %u expected %u\n",				      stored, length);	}	return NDR_ERR_SUCCESS;}/*  store a switch value */_PUBLIC_ enum ndr_err_code ndr_push_set_switch_value(struct ndr_push *ndr, const void *p, uint32_t val){	return ndr_token_store(ndr, &ndr->switch_list, p, val);}_PUBLIC_ enum ndr_err_code ndr_pull_set_switch_value(struct ndr_pull *ndr, const void *p, uint32_t val){	return ndr_token_store(ndr, &ndr->switch_list, p, val);}_PUBLIC_ enum ndr_err_code ndr_print_set_switch_value(struct ndr_print *ndr, const void *p, uint32_t val){	return ndr_token_store(ndr, &ndr->switch_list, p, val);}/*  retrieve a switch value */_PUBLIC_ uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p){	return ndr_token_peek(&ndr->switch_list, p);}_PUBLIC_ uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p){	return ndr_token_peek(&ndr->switch_list, p);}_PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p){	return ndr_token_peek(&ndr->switch_list, p);}/*  pull a struct from a blob using NDR*/_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p,			      ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	return NDR_ERR_SUCCESS;}/*  pull a struct from a blob using NDR - failing if all bytes are not consumed*/_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 						    struct smb_iconv_convenience *iconv_convenience,						    void *p, ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	if (ndr->offset < ndr->data_size) {		return ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,				      "not all bytes consumed ofs[%u] size[%u]",				      ndr->offset, ndr->data_size);	}	return NDR_ERR_SUCCESS;}/*  pull a union from a blob using NDR, given the union discriminator*/_PUBLIC_ enum ndr_err_code ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 					       struct smb_iconv_convenience *iconv_convenience, void *p,			     uint32_t level, ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(ndr_pull_set_switch_value(ndr, p, level));	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	return NDR_ERR_SUCCESS;}/*  pull a union from a blob using NDR, given the union discriminator,  failing if all bytes are not consumed*/_PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 						   struct smb_iconv_convenience *iconv_convenience, void *p,			     uint32_t level, ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(ndr_pull_set_switch_value(ndr, p, level));	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	if (ndr->offset < ndr->data_size) {		return ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,				      "not all bytes consumed ofs[%u] size[%u]",				      ndr->offset, ndr->data_size);	}	return NDR_ERR_SUCCESS;}/*  push a struct to a blob using NDR*/_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const void *p, ndr_push_flags_fn_t fn){	struct ndr_push *ndr;	ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	*blob = ndr_push_blob(ndr);	talloc_steal(mem_ctx, blob->data);	talloc_free(ndr);	return NDR_ERR_SUCCESS;}/*  push a union to a blob using NDR*/_PUBLIC_ enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p,			     uint32_t level, ndr_push_flags_fn_t fn){	struct ndr_push *ndr;	ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience);	NDR_ERR_HAVE_NO_MEMORY(ndr);	NDR_CHECK(ndr_push_set_switch_value(ndr, p, level));	NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));	*blob = ndr_push_blob(ndr);	talloc_steal(mem_ctx, blob->data);	talloc_free(ndr);	return NDR_ERR_SUCCESS;}/*  generic ndr_size_*() handler for structures*/_PUBLIC_ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push){	struct ndr_push *ndr;	enum ndr_err_code status;	size_t ret;	/* avoid recursion */	if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0;	ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm));	if (!ndr) return 0;	ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE;	status = push(ndr, NDR_SCALARS|NDR_BUFFERS, discard_const(p));	if (!NDR_ERR_CODE_IS_SUCCESS(status)) {		talloc_free(ndr);		return 0;	}	ret = ndr->offset;	talloc_free(ndr);	return ret;}/*  generic ndr_size_*() handler for unions*/_PUBLIC_ size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_flags_fn_t push){	struct ndr_push *ndr;	enum ndr_err_code status;	size_t ret;	/* avoid recursion */	if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0;	ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm));	if (!ndr) return 0;	ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE;	status = ndr_push_set_switch_value(ndr, p, level);	if (!NDR_ERR_CODE_IS_SUCCESS(status)) {		talloc_free(ndr);		return 0;	}	status = push(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NDR_ERR_CODE_IS_SUCCESS(status)) {		talloc_free(ndr);		return 0;	}	ret = ndr->offset;	talloc_free(ndr);	return ret;}/*  get the current base for relative pointers for the push*/_PUBLIC_ uint32_t ndr_push_get_relative_base_offset(struct ndr_push *ndr){	return ndr->relative_base_offset;}/*  restore the old base for relative pointers for the push*/_PUBLIC_ void ndr_push_restore_relative_base_offset(struct ndr_push *ndr, uint32_t offset){	ndr->relative_base_offset = offset;}/*  setup the current base for relative pointers for the push  called in the NDR_SCALAR stage*/_PUBLIC_ enum ndr_err_code ndr_push_setup_relative_base_offset1(struct ndr_push *ndr, const void *p, uint32_t offset){	ndr->relative_base_offset = offset;	return ndr_token_store(ndr, &ndr->relative_base_list, p, offset);}/*  setup the current base for relative pointers for the push  called in the NDR_BUFFERS stage*/_PUBLIC_ enum ndr_err_code ndr_push_setup_relative_base_offset2(struct ndr_push *ndr, const void *p){	return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset);}/*  push a relative object - stage1  this is called during SCALARS processing*/_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p){	if (p == NULL) {		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));		return NDR_ERR_SUCCESS;	}	NDR_CHECK(ndr_push_align(ndr, 4));	NDR_CHECK(ndr_token_store(ndr, &ndr->relative_list, p, ndr->offset));	return ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF);}/*  push a relative object - stage2  this is called during buffers processing*/_PUBLIC_ 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;}/*  get the current base for relative pointers for the pull*/_PUBLIC_ uint32_t ndr_pull_get_relative_base_offset(struct ndr_pull *ndr){	return ndr->relative_base_offset;}/*  restore the old base for relative pointers for the pull*/_PUBLIC_ void ndr_pull_restore_relative_base_offset(struct ndr_pull *ndr, uint32_t offset){	ndr->relative_base_offset = offset;}/*  setup the current base for relative pointers for the pull  called in the NDR_SCALAR stage*/_PUBLIC_ enum ndr_err_code ndr_pull_setup_relative_base_offset1(struct ndr_pull *ndr, const void *p, uint32_t offset){	ndr->relative_base_offset = offset;	return ndr_token_store(ndr, &ndr->relative_base_list, p, offset);}/*  setup the current base for relative pointers for the pull  called in the NDR_BUFFERS stage*/_PUBLIC_ enum ndr_err_code ndr_pull_setup_relative_base_offset2(struct ndr_pull *ndr, const void *p){	return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset);}/*  pull a relative object - stage1  called during SCALARS processing*/_PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr1(struct ndr_pull *ndr, const void *p, uint32_t rel_offset){	rel_offset += ndr->relative_base_offset;	if (rel_offset > ndr->data_size) {		return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, 				      "ndr_pull_relative_ptr1 rel_offset(%u) > ndr->data_size(%u)",				      rel_offset, ndr->data_size);	}	return ndr_token_store(ndr, &ndr->relative_list, p, rel_offset);}/*  pull a relative object - stage2  called during BUFFERS processing*/_PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p){	uint32_t rel_offset;	NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &rel_offset));	return ndr_pull_set_offset(ndr, rel_offset);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -