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

📄 dcerpc_util.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   dcerpc utility functions   Copyright (C) Andrew Tridgell 2003   Copyright (C) Jelmer Vernooij 2004   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005   Copyright (C) Rafal Szczesniak 2006      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "lib/events/events.h"#include "libcli/composite/composite.h"#include "librpc/gen_ndr/ndr_epmapper_c.h"#include "librpc/gen_ndr/ndr_dcerpc.h"#include "librpc/gen_ndr/ndr_misc.h"#include "librpc/rpc/dcerpc_proto.h"#include "auth/credentials/credentials.h"#include "param/param.h"/*  find a dcerpc call on an interface by name*/const struct ndr_interface_call *dcerpc_iface_find_call(const struct ndr_interface_table *iface,							const char *name){	int i;	for (i=0;i<iface->num_calls;i++) {		if (strcmp(iface->calls[i].name, name) == 0) {			return &iface->calls[i];		}	}	return NULL;}/*    push a ncacn_packet into a blob, potentially with auth info*/NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, 			 struct smb_iconv_convenience *iconv_convenience,			  struct ncacn_packet *pkt,			  struct dcerpc_auth *auth_info){	struct ndr_push *ndr;	enum ndr_err_code ndr_err;	ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience);	if (!ndr) {		return NT_STATUS_NO_MEMORY;	}	if (!(pkt->drep[0] & DCERPC_DREP_LE)) {		ndr->flags |= LIBNDR_FLAG_BIGENDIAN;	}	if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {		ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;	}	if (auth_info) {		pkt->auth_length = auth_info->credentials.length;	} else {		pkt->auth_length = 0;	}	ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {		return ndr_map_error2ntstatus(ndr_err);	}	if (auth_info) {		ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info);		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {			return ndr_map_error2ntstatus(ndr_err);		}	}	*blob = ndr_push_blob(ndr);	/* fill in the frag length */	dcerpc_set_frag_length(blob, blob->length);	return NT_STATUS_OK;}struct epm_map_binding_state {	struct dcerpc_binding *binding;	const struct ndr_interface_table *table;	struct dcerpc_pipe *pipe;	struct policy_handle handle;	struct GUID guid;	struct epm_twr_t twr;	struct epm_twr_t *twr_r;	struct epm_Map r;};static void continue_epm_recv_binding(struct composite_context *ctx);static void continue_epm_map(struct rpc_request *req);/*  Stage 2 of epm_map_binding: Receive connected rpc pipe and send endpoint  mapping rpc request*/static void continue_epm_recv_binding(struct composite_context *ctx){	struct rpc_request *map_req;	struct composite_context *c = talloc_get_type(ctx->async.private_data,						      struct composite_context);	struct epm_map_binding_state *s = talloc_get_type(c->private_data,							  struct epm_map_binding_state);	/* receive result of rpc pipe connect request */	c->status = dcerpc_pipe_connect_b_recv(ctx, c, &s->pipe);	if (!composite_is_ok(c)) return;	s->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;	/* prepare requested binding parameters */	s->binding->object         = s->table->syntax_id;	c->status = dcerpc_binding_build_tower(s->pipe, s->binding, &s->twr.tower);	if (!composite_is_ok(c)) return;		/* with some nice pretty paper around it of course */	s->r.in.object        = &s->guid;	s->r.in.map_tower     = &s->twr;	s->r.in.entry_handle  = &s->handle;	s->r.in.max_towers    = 1;	s->r.out.entry_handle = &s->handle;	/* send request for an endpoint mapping - a rpc request on connected pipe */	map_req = dcerpc_epm_Map_send(s->pipe, c, &s->r);	if (composite_nomem(map_req, c)) return;		composite_continue_rpc(c, map_req, continue_epm_map, c);}/*  Stage 3 of epm_map_binding: Receive endpoint mapping and provide binding details*/static void continue_epm_map(struct rpc_request *req){	struct composite_context *c = talloc_get_type(req->async.private_data,						      struct composite_context);	struct epm_map_binding_state *s = talloc_get_type(c->private_data,							  struct epm_map_binding_state);	/* receive result of a rpc request */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	/* check the details */	if (s->r.out.result != 0 || *s->r.out.num_towers != 1) {		composite_error(c, NT_STATUS_PORT_UNREACHABLE);		return;	}		s->twr_r = s->r.out.towers[0].twr;	if (s->twr_r == NULL) {		composite_error(c, NT_STATUS_PORT_UNREACHABLE);		return;	}	if (s->twr_r->tower.num_floors != s->twr.tower.num_floors ||	    s->twr_r->tower.floors[3].lhs.protocol != s->twr.tower.floors[3].lhs.protocol) {		composite_error(c, NT_STATUS_PORT_UNREACHABLE);		return;	}	/* get received endpoint */	s->binding->endpoint = talloc_reference(s->binding,						dcerpc_floor_get_rhs_data(c, &s->twr_r->tower.floors[3]));	if (composite_nomem(s->binding->endpoint, c)) return;	composite_done(c);}/*  Request for endpoint mapping of dcerpc binding - try to request for endpoint  unless there is default one.*/struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx,						      struct dcerpc_binding *binding,						      const struct ndr_interface_table *table,						      struct event_context *ev,						      struct loadparm_context *lp_ctx){	struct composite_context *c;	struct epm_map_binding_state *s;	struct composite_context *pipe_connect_req;	struct cli_credentials *anon_creds;	NTSTATUS status;	struct dcerpc_binding *epmapper_binding;	int i;	if (ev == NULL) {		return NULL;	}	/* composite context allocation and setup */	c = composite_create(mem_ctx, ev);	if (c == NULL) {		return NULL;	}	s = talloc_zero(c, struct epm_map_binding_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;	s->binding = binding;	s->table   = table;	/* anonymous credentials for rpc connection used to get endpoint mapping */	anon_creds = cli_credentials_init(mem_ctx);	cli_credentials_set_anonymous(anon_creds);	/*	  First, check if there is a default endpoint specified in the IDL	*/	if (table != NULL) {		struct dcerpc_binding *default_binding;		/* Find one of the default pipes for this interface */		for (i = 0; i < table->endpoints->count; i++) {			status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding);			if (NT_STATUS_IS_OK(status)) {				if (binding->transport == NCA_UNKNOWN) 					binding->transport = default_binding->transport;				if (default_binding->transport == binding->transport && 					default_binding->endpoint) {					binding->endpoint = talloc_reference(binding, default_binding->endpoint);					talloc_free(default_binding);					composite_done(c);					return c;				} else {					talloc_free(default_binding);				}			}		}	}	epmapper_binding = talloc_zero(c, struct dcerpc_binding);	if (composite_nomem(epmapper_binding, c)) return c;	/* basic endpoint mapping data */	epmapper_binding->transport		= binding->transport;	epmapper_binding->host			= talloc_reference(epmapper_binding, binding->host);	epmapper_binding->target_hostname       = epmapper_binding->host;	epmapper_binding->options		= NULL;	epmapper_binding->flags			= 0;	epmapper_binding->assoc_group_id	= 0;	epmapper_binding->endpoint		= NULL;	/* initiate rpc pipe connection */	pipe_connect_req = dcerpc_pipe_connect_b_send(c, epmapper_binding, 						      &ndr_table_epmapper,						      anon_creds, c->event_ctx,						      lp_ctx);	if (composite_nomem(pipe_connect_req, c)) return c;		composite_continue(c, pipe_connect_req, continue_epm_recv_binding, c);	return c;}/*  Receive result of endpoint mapping request */NTSTATUS dcerpc_epm_map_binding_recv(struct composite_context *c){	NTSTATUS status = composite_wait(c);		talloc_free(c);	return status;}/*  Get endpoint mapping for rpc connection*/_PUBLIC_ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding,				const struct ndr_interface_table *table, struct event_context *ev,				struct loadparm_context *lp_ctx){	struct composite_context *c;	c = dcerpc_epm_map_binding_send(mem_ctx, binding, table, ev, lp_ctx);	return dcerpc_epm_map_binding_recv(c);}struct pipe_auth_state {	struct dcerpc_pipe *pipe;	struct dcerpc_binding *binding;	const struct ndr_interface_table *table;	struct loadparm_context *lp_ctx;	struct cli_credentials *credentials;};static void continue_auth_schannel(struct composite_context *ctx);static void continue_auth(struct composite_context *ctx);static void continue_auth_none(struct composite_context *ctx);static void continue_ntlmssp_connection(struct composite_context *ctx);static void continue_spnego_after_wrong_pass(struct composite_context *ctx);/*  Stage 2 of pipe_auth: Receive result of schannel bind request*/static void continue_auth_schannel(struct composite_context *ctx){	struct composite_context *c = talloc_get_type(ctx->async.private_data,						      struct composite_context);	c->status = dcerpc_bind_auth_schannel_recv(ctx);	if (!composite_is_ok(c)) return;	composite_done(c);}/*  Stage 2 of pipe_auth: Receive result of authenticated bind request*/static void continue_auth(struct composite_context *ctx){	struct composite_context *c = talloc_get_type(ctx->async.private_data,						      struct composite_context);	c->status = dcerpc_bind_auth_recv(ctx);	if (!composite_is_ok(c)) return;		composite_done(c);}/*  Stage 2 of pipe_auth: Receive result of authenticated bind request, but handle fallbacks:  SPNEGO -> NTLMSSP*/static void continue_auth_auto(struct composite_context *ctx){	struct composite_context *c = talloc_get_type(ctx->async.private_data,

⌨️ 快捷键说明

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