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 + -
显示快捷键?