libnet_domain.c

来自「samba最新软件」· C语言 代码 · 共 1,253 行 · 第 1/3 页

C
1,253
字号
/*    Unix SMB/CIFS implementation.   Copyright (C) Rafal Szczesniak 2005      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/>.*//*  a composite function for domain handling on samr and lsa pipes*/#include "includes.h"#include "libcli/composite/composite.h"#include "libnet/libnet.h"#include "librpc/gen_ndr/ndr_samr_c.h"#include "librpc/gen_ndr/ndr_lsa_c.h"struct domain_open_samr_state {	struct libnet_context     *ctx;	struct dcerpc_pipe        *pipe;	struct libnet_RpcConnect  rpcconn;	struct samr_Connect       connect;	struct samr_LookupDomain  lookup;	struct samr_OpenDomain    open;	struct samr_Close         close;	struct lsa_String         domain_name;	uint32_t                  access_mask;	struct policy_handle      connect_handle;	struct policy_handle      domain_handle;	/* information about the progress */	void (*monitor_fn)(struct monitor_msg*);};static void continue_domain_open_close(struct rpc_request *req);static void continue_domain_open_connect(struct rpc_request *req);static void continue_domain_open_lookup(struct rpc_request *req);static void continue_domain_open_open(struct rpc_request *req);/** * Stage 0.5 (optional): Connect to samr rpc pipe */static void continue_domain_open_rpc_connect(struct composite_context *ctx){	struct composite_context *c;	struct domain_open_samr_state *s;	struct rpc_request *conn_req;	c = talloc_get_type(ctx->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct domain_open_samr_state);	c->status = libnet_RpcConnect_recv(ctx, s->ctx, c, &s->rpcconn);	if (!composite_is_ok(c)) return;	s->pipe = s->rpcconn.out.dcerpc_pipe;	/* preparing parameters for samr_Connect rpc call */	s->connect.in.system_name      = 0;	s->connect.in.access_mask      = s->access_mask;	s->connect.out.connect_handle  = &s->connect_handle;	/* send request */	conn_req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);	if (composite_nomem(conn_req, c)) return;	/* callback handler */	composite_continue_rpc(c, conn_req, continue_domain_open_connect, c);}/** * Stage 0.5 (optional): Close existing (in libnet context) domain * handle */static void continue_domain_open_close(struct rpc_request *req){	struct composite_context *c;	struct domain_open_samr_state *s;	struct rpc_request *conn_req;	c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct domain_open_samr_state);	/* receive samr_Close reply */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	if (s->monitor_fn) {		struct monitor_msg msg;				msg.type = mon_SamrClose;		msg.data = NULL;		msg.data_size = 0;		s->monitor_fn(&msg);	}	/* reset domain handle and associated data in libnet_context */	s->ctx->samr.name        = NULL;	s->ctx->samr.access_mask = 0;	ZERO_STRUCT(s->ctx->samr.handle);	/* preparing parameters for samr_Connect rpc call */	s->connect.in.system_name      = 0;	s->connect.in.access_mask      = s->access_mask;	s->connect.out.connect_handle  = &s->connect_handle;		/* send request */	conn_req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);	if (composite_nomem(conn_req, c)) return;	/* callback handler */	composite_continue_rpc(c, conn_req, continue_domain_open_connect, c);}/** * Stage 1: Connect to SAM server. */static void continue_domain_open_connect(struct rpc_request *req){	struct composite_context *c;	struct domain_open_samr_state *s;	struct rpc_request *lookup_req;	struct samr_LookupDomain *r;		c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct domain_open_samr_state);	/* receive samr_Connect reply */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	if (s->monitor_fn) {		struct monitor_msg msg;		msg.type = mon_SamrConnect;		msg.data = NULL;		msg.data_size = 0;		s->monitor_fn(&msg);	}	r = &s->lookup;	/* prepare for samr_LookupDomain call */	r->in.connect_handle = &s->connect_handle;	r->in.domain_name    = &s->domain_name;	lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);	if (composite_nomem(lookup_req, c)) return;	composite_continue_rpc(c, lookup_req, continue_domain_open_lookup, c);}/** * Stage 2: Lookup domain by name. */static void continue_domain_open_lookup(struct rpc_request *req){	struct composite_context *c;	struct domain_open_samr_state *s;	struct rpc_request *opendom_req;	struct samr_OpenDomain *r;	c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct domain_open_samr_state);		/* receive samr_LookupDomain reply */	c->status = dcerpc_ndr_request_recv(req);	if (s->monitor_fn) {		struct monitor_msg msg;		struct msg_rpc_lookup_domain data;		data.domain_name = s->domain_name.string;		msg.type = mon_SamrLookupDomain;		msg.data = (void*)&data;		msg.data_size = sizeof(data);		s->monitor_fn(&msg);	}	r = &s->open;	/* check the rpc layer status */	if (!composite_is_ok(c));	/* check the rpc call itself status */	if (!NT_STATUS_IS_OK(s->lookup.out.result)) {		composite_error(c, s->lookup.out.result);		return;	}	/* prepare for samr_OpenDomain call */	r->in.connect_handle = &s->connect_handle;	r->in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;	r->in.sid            = s->lookup.out.sid;	r->out.domain_handle = &s->domain_handle;	opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);	if (composite_nomem(opendom_req, c)) return;	composite_continue_rpc(c, opendom_req, continue_domain_open_open, c);}/* * Stage 3: Open domain. */static void continue_domain_open_open(struct rpc_request *req){	struct composite_context *c;	struct domain_open_samr_state *s;	c = talloc_get_type(req->async.private_data, struct composite_context);	s = talloc_get_type(c->private_data, struct domain_open_samr_state);	/* receive samr_OpenDomain reply */	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	if (s->monitor_fn) {		struct monitor_msg msg;				msg.type = mon_SamrOpenDomain;		msg.data = NULL;		msg.data_size = 0;		s->monitor_fn(&msg);	}	composite_done(c);}/** * Sends asynchronous DomainOpenSamr request * * @param ctx initialised libnet context * @param io arguments and results of the call * @param monitor pointer to monitor function that is passed monitor message */struct composite_context *libnet_DomainOpenSamr_send(struct libnet_context *ctx,						     struct libnet_DomainOpen *io,						     void (*monitor)(struct monitor_msg*)){	struct composite_context *c;	struct domain_open_samr_state *s;	struct composite_context *rpcconn_req;	struct rpc_request *close_req, *conn_req;	c = composite_create(ctx, ctx->event_ctx);	if (c == NULL) return NULL;	s = talloc_zero(c, struct domain_open_samr_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;	s->monitor_fn   = monitor;	s->ctx                 = ctx;	s->pipe                = ctx->samr.pipe;	s->access_mask         = io->in.access_mask;	s->domain_name.string  = talloc_strdup(c, io->in.domain_name);	/* check, if there's samr pipe opened already, before opening a domain */	if (ctx->samr.pipe == NULL) {		/* attempting to connect a domain controller */		s->rpcconn.level           = LIBNET_RPC_CONNECT_DC;		s->rpcconn.in.name         = io->in.domain_name;		s->rpcconn.in.dcerpc_iface = &ndr_table_samr;				/* send rpc pipe connect request */		rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn, s->monitor_fn);		if (composite_nomem(rpcconn_req, c)) return c;		composite_continue(c, rpcconn_req, continue_domain_open_rpc_connect, c);		return c;	}	/* libnet context's domain handle is not empty, so check out what	   was opened first, before doing anything */	if (!policy_handle_empty(&ctx->samr.handle)) {		if (strequal(ctx->samr.name, io->in.domain_name) &&		    ctx->samr.access_mask == io->in.access_mask) {			/* this domain is already opened */			composite_done(c);			return c;		} else {			/* another domain or access rights have been			   requested - close the existing handle first */			s->close.in.handle = &ctx->samr.handle;			/* send request to close domain handle */			close_req = dcerpc_samr_Close_send(s->pipe, c, &s->close);			if (composite_nomem(close_req, c)) return c;			/* callback handler */			composite_continue_rpc(c, close_req, continue_domain_open_close, c);			return c;		}	}	/* preparing parameters for samr_Connect rpc call */	s->connect.in.system_name      = 0;	s->connect.in.access_mask      = s->access_mask;	s->connect.out.connect_handle  = &s->connect_handle;		/* send request */	conn_req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);	if (composite_nomem(conn_req, c)) return c;	/* callback handler */	composite_continue_rpc(c, conn_req, continue_domain_open_connect, c);	return c;}/** * Waits for and receives result of asynchronous DomainOpenSamr call *  * @param c composite context returned by asynchronous DomainOpen call * @param ctx initialised libnet context * @param mem_ctx memory context of the call * @param io pointer to results (and arguments) of the call * @return nt status code of execution */NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_context *ctx,				    TALLOC_CTX *mem_ctx, struct libnet_DomainOpen *io){	NTSTATUS status;	struct domain_open_samr_state *s;	/* wait for results of sending request */	status = composite_wait(c);		if (NT_STATUS_IS_OK(status) && io) {		s = talloc_get_type(c->private_data, struct domain_open_samr_state);		io->out.domain_handle = s->domain_handle;		/* store the resulting handle and related data for use by other		   libnet functions */		ctx->samr.connect_handle = s->connect_handle;		ctx->samr.handle      = s->domain_handle;		ctx->samr.sid         = talloc_steal(ctx, s->lookup.out.sid);		ctx->samr.name        = talloc_steal(ctx, s->domain_name.string);		ctx->samr.access_mask = s->access_mask;	}	talloc_free(c);	return status;}struct domain_open_lsa_state {	const char *name;	uint32_t access_mask;	struct libnet_context *ctx;	struct libnet_RpcConnect rpcconn;	struct lsa_OpenPolicy2   openpol;	struct policy_handle handle;	struct dcerpc_pipe *pipe;	/* information about the progress */	void (*monitor_fn)(struct monitor_msg*);};static void continue_rpc_connect_lsa(struct composite_context *ctx);static void continue_lsa_policy_open(struct rpc_request *req);/** * Sends asynchronous DomainOpenLsa request * * @param ctx initialised libnet context * @param io arguments and results of the call * @param monitor pointer to monitor function that is passed monitor message */struct composite_context* libnet_DomainOpenLsa_send(struct libnet_context *ctx,						    struct libnet_DomainOpen *io,						    void (*monitor)(struct monitor_msg*)){	struct composite_context *c;	struct domain_open_lsa_state *s;	struct composite_context *rpcconn_req;	struct rpc_request *openpol_req;	struct lsa_QosInfo *qos;	/* create composite context and state */	c = composite_create(ctx, ctx->event_ctx);	if (c == NULL) return c;	s = talloc_zero(c, struct domain_open_lsa_state);	if (composite_nomem(s, c)) return c;	c->private_data = s;

⌨️ 快捷键说明

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