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

📄 ndr.c

📁 samba服务器!
💻 C
📖 第 1 页 / 共 2 页
字号:
			NDR_CHECK(ndr_push_zero(subndr, padding_len));		} else 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);		}	}	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 NT_STATUS_OK;}/*  store a token in the ndr context, for later retrieval*/NTSTATUS 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);	if (tok == NULL) {		return NT_STATUS_NO_MEMORY;	}	tok->key = key;	tok->value = value;	DLIST_ADD((*list), tok);	return NT_STATUS_OK;}/*  retrieve a token from a ndr context, using cmp_fn to match the tokens*/NTSTATUS 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_map_error(NDR_ERR_TOKEN);found:	*v = tok->value;	if (_remove_tok) {		DLIST_REMOVE((*list), tok);		talloc_free(tok);	}	return NT_STATUS_OK;		}/*  retrieve a token from a ndr context*/NTSTATUS 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*/uint32_t ndr_token_peek(struct ndr_token_list **list, const void *key){	NTSTATUS status;	uint32_t v;	status = ndr_token_retrieve_cmp_fn(list, key, &v, NULL, False);	if (NT_STATUS_IS_OK(status)) return v;	return 0;}/*  pull an array size field and add it to the array_size_list token list*/NTSTATUS 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*/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*/NTSTATUS 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 NT_STATUS_OK;}/*  pull an array length field and add it to the array_length_list token list*/NTSTATUS 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*/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*/NTSTATUS 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 NT_STATUS_OK;}/*  store a switch value */NTSTATUS 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);}NTSTATUS 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);}NTSTATUS 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 */uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p){	return ndr_token_peek(&ndr->switch_list, p);}uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p){	return ndr_token_peek(&ndr->switch_list, p);}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*/NTSTATUS ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,			      ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	ndr = ndr_pull_init_blob(blob, mem_ctx);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	return fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);}/*  pull a struct from a blob using NDR - failing if all bytes are not consumed*/NTSTATUS ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,				  ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	NTSTATUS status;	ndr = ndr_pull_init_blob(blob, mem_ctx);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) return status;	if (ndr->offset != ndr->data_size) {		return NT_STATUS_BUFFER_TOO_SMALL;	}	return status;}/*  pull a union from a blob using NDR, given the union discriminator*/NTSTATUS ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,			     uint32_t level, ndr_pull_flags_fn_t fn){	struct ndr_pull *ndr;	NTSTATUS status;	ndr = ndr_pull_init_blob(blob, mem_ctx);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	ndr_pull_set_switch_value(ndr, p, level);	status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) return status;	if (ndr->offset != ndr->data_size) {		return NT_STATUS_BUFFER_TOO_SMALL;	}	return status;}/*  push a struct to a blob using NDR*/NTSTATUS ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p,			      ndr_push_flags_fn_t fn){	NTSTATUS status;	struct ndr_push *ndr;	ndr = ndr_push_init_ctx(mem_ctx);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	*blob = ndr_push_blob(ndr);	return NT_STATUS_OK;}/*  push a union to a blob using NDR*/NTSTATUS ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,			     uint32_t level, ndr_push_flags_fn_t fn){	NTSTATUS status;	struct ndr_push *ndr;	ndr = ndr_push_init_ctx(mem_ctx);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	ndr_push_set_switch_value(ndr, p, level);	status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	*blob = ndr_push_blob(ndr);	return NT_STATUS_OK;}/*  generic ndr_size_*() handler for structures*/size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push){	struct ndr_push *ndr;	NTSTATUS status;	size_t ret;	/* avoid recursion */	if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0;	ndr = ndr_push_init_ctx(NULL);	if (!ndr) return 0;	ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE;	status = push(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) {		return 0;	}	ret = ndr->offset;	talloc_free(ndr);	return ret;}/*  generic ndr_size_*() handler for unions*/size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_flags_fn_t push){	struct ndr_push *ndr;	NTSTATUS status;	size_t ret;	/* avoid recursion */	if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0;	ndr = ndr_push_init_ctx(NULL);	if (!ndr) return 0;	ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE;	ndr_push_set_switch_value(ndr, p, level);	status = push(ndr, NDR_SCALARS|NDR_BUFFERS, p);	if (!NT_STATUS_IS_OK(status)) {		return 0;	}	ret = ndr->offset;	talloc_free(ndr);	return ret;}/*  get the current base for relative pointers for the push*/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*/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*/NTSTATUS 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*/NTSTATUS 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*/NTSTATUS ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p){	if (p == NULL) {		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));		return NT_STATUS_OK;	}	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*/NTSTATUS ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p){	struct ndr_push_save save;	uint32_t ptr_offset = 0xFFFFFFFF;	if (p == NULL) {		return NT_STATUS_OK;	}	ndr_push_save(ndr, &save);	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_push_restore(ndr, &save);	return NT_STATUS_OK;}/*  get the current base for relative pointers for the pull*/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*/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*/NTSTATUS 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*/NTSTATUS 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*/NTSTATUS 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*/NTSTATUS 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 + -