userman.c
来自「samba最新软件」· C语言 代码 · 共 884 行 · 第 1/2 页
C
884 行
/* 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 functions for user management operations (add/del/chg)*/#include "includes.h"#include "libcli/composite/composite.h"#include "libnet/composite.h"#include "libnet/userman.h"#include "libnet/userinfo.h"#include "librpc/gen_ndr/ndr_samr_c.h"/* * Composite USER ADD functionality */struct useradd_state { struct dcerpc_pipe *pipe; struct rpc_request *req; struct policy_handle domain_handle; struct samr_CreateUser createuser; struct policy_handle user_handle; uint32_t user_rid; /* information about the progress */ void (*monitor_fn)(struct monitor_msg *);};static void continue_useradd_create(struct rpc_request *req);/** * Stage 1 (and the only one for now): Create user account. */static void continue_useradd_create(struct rpc_request *req){ struct composite_context *c; struct useradd_state *s; c = talloc_get_type(req->async.private_data, struct composite_context); s = talloc_get_type(c->private_data, struct useradd_state); /* check rpc layer status code */ c->status = dcerpc_ndr_request_recv(s->req); if (!composite_is_ok(c)) return; /* check create user call status code */ c->status = s->createuser.out.result; /* get created user account data */ s->user_handle = *s->createuser.out.user_handle; s->user_rid = *s->createuser.out.rid; /* issue a monitor message */ if (s->monitor_fn) { struct monitor_msg msg; struct msg_rpc_create_user rpc_create; rpc_create.rid = *s->createuser.out.rid; msg.type = mon_SamrCreateUser; msg.data = (void*)&rpc_create; msg.data_size = sizeof(rpc_create); s->monitor_fn(&msg); } composite_done(c);}/** * Sends asynchronous useradd request * * @param p dce/rpc call pipe * @param io arguments and results of the call * @param monitor monitor function for providing information about the progress */struct composite_context *libnet_rpc_useradd_send(struct dcerpc_pipe *p, struct libnet_rpc_useradd *io, void (*monitor)(struct monitor_msg*)){ struct composite_context *c; struct useradd_state *s; if (!p || !io) return NULL; /* composite allocation and setup */ c = composite_create(p, dcerpc_event_context(p)); if (c == NULL) return NULL; s = talloc_zero(c, struct useradd_state); if (composite_nomem(s, c)) return c; c->private_data = s; /* put passed arguments to the state structure */ s->domain_handle = io->in.domain_handle; s->pipe = p; s->monitor_fn = monitor; /* preparing parameters to send rpc request */ s->createuser.in.domain_handle = &io->in.domain_handle; s->createuser.in.account_name = talloc_zero(c, struct lsa_String); if (composite_nomem(s->createuser.in.account_name, c)) return c; s->createuser.in.account_name->string = talloc_strdup(c, io->in.username); if (composite_nomem(s->createuser.in.account_name->string, c)) return c; s->createuser.out.user_handle = &s->user_handle; s->createuser.out.rid = &s->user_rid; /* send the request */ s->req = dcerpc_samr_CreateUser_send(p, c, &s->createuser); if (composite_nomem(s->req, c)) return c; composite_continue_rpc(c, s->req, continue_useradd_create, c); return c;}/** * Waits for and receives result of asynchronous useradd call * * @param c composite context returned by asynchronous useradd call * @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_rpc_useradd_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct libnet_rpc_useradd *io){ NTSTATUS status; struct useradd_state *s; status = composite_wait(c); if (NT_STATUS_IS_OK(status) && io) { /* get and return result of the call */ s = talloc_get_type(c->private_data, struct useradd_state); io->out.user_handle = s->user_handle; } talloc_free(c); return status;}/** * Synchronous version of useradd call * * @param pipe dce/rpc call pipe * @param mem_ctx memory context for the call * @param io arguments and results of the call * @return nt status code of execution */NTSTATUS libnet_rpc_useradd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct libnet_rpc_useradd *io){ struct composite_context *c = libnet_rpc_useradd_send(p, io, NULL); return libnet_rpc_useradd_recv(c, mem_ctx, io);}/* * Composite USER DELETE functionality */struct userdel_state { struct dcerpc_pipe *pipe; struct policy_handle domain_handle; struct policy_handle user_handle; struct samr_LookupNames lookupname; struct samr_OpenUser openuser; struct samr_DeleteUser deleteuser; /* information about the progress */ void (*monitor_fn)(struct monitor_msg *);};static void continue_userdel_name_found(struct rpc_request *req);static void continue_userdel_user_opened(struct rpc_request* req);static void continue_userdel_deleted(struct rpc_request *req);/** * Stage 1: Lookup the user name and resolve it to rid */static void continue_userdel_name_found(struct rpc_request *req){ struct composite_context *c; struct userdel_state *s; struct rpc_request *openuser_req; struct monitor_msg msg; c = talloc_get_type(req->async.private_data, struct composite_context); s = talloc_get_type(c->private_data, struct userdel_state); /* receive samr_LookupNames result */ c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; c->status = s->lookupname.out.result; if (!NT_STATUS_IS_OK(c->status)) { composite_error(c, c->status); return; } /* what to do when there's no user account to delete and what if there's more than one rid resolved */ if (!s->lookupname.out.rids.count) { c->status = NT_STATUS_NO_SUCH_USER; composite_error(c, c->status); return; } else if (!s->lookupname.out.rids.count > 1) { c->status = NT_STATUS_INVALID_ACCOUNT_NAME; composite_error(c, c->status); return; } /* issue a monitor message */ if (s->monitor_fn) { struct msg_rpc_lookup_name msg_lookup; msg_lookup.rid = s->lookupname.out.rids.ids; msg_lookup.count = s->lookupname.out.rids.count; msg.type = mon_SamrLookupName; msg.data = (void*)&msg_lookup; msg.data_size = sizeof(msg_lookup); s->monitor_fn(&msg); } /* prepare the arguments for rpc call */ s->openuser.in.domain_handle = &s->domain_handle; s->openuser.in.rid = s->lookupname.out.rids.ids[0]; s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; s->openuser.out.user_handle = &s->user_handle; /* send rpc request */ openuser_req = dcerpc_samr_OpenUser_send(s->pipe, c, &s->openuser); if (composite_nomem(openuser_req, c)) return; composite_continue_rpc(c, openuser_req, continue_userdel_user_opened, c);}/** * Stage 2: Open user account. */static void continue_userdel_user_opened(struct rpc_request* req){ struct composite_context *c; struct userdel_state *s; struct rpc_request *deluser_req; struct monitor_msg msg; c = talloc_get_type(req->async.private_data, struct composite_context); s = talloc_get_type(c->private_data, struct userdel_state); /* receive samr_OpenUser result */ c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; c->status = s->openuser.out.result; if (!NT_STATUS_IS_OK(c->status)) { composite_error(c, c->status); return; } /* issue a monitor message */ if (s->monitor_fn) { struct msg_rpc_open_user msg_open; msg_open.rid = s->openuser.in.rid; msg_open.access_mask = s->openuser.in.access_mask; msg.type = mon_SamrOpenUser; msg.data = (void*)&msg_open; msg.data_size = sizeof(msg_open); s->monitor_fn(&msg); } /* prepare the final rpc call arguments */ s->deleteuser.in.user_handle = &s->user_handle; s->deleteuser.out.user_handle = &s->user_handle; /* send rpc request */ deluser_req = dcerpc_samr_DeleteUser_send(s->pipe, c, &s->deleteuser); if (composite_nomem(deluser_req, c)) return; /* callback handler setup */ composite_continue_rpc(c, deluser_req, continue_userdel_deleted, c);}/** * Stage 3: Delete user account */static void continue_userdel_deleted(struct rpc_request *req){ struct composite_context *c; struct userdel_state *s; struct monitor_msg msg; c = talloc_get_type(req->async.private_data, struct composite_context); s = talloc_get_type(c->private_data, struct userdel_state); /* receive samr_DeleteUser result */ c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; /* return the actual function call status */ c->status = s->deleteuser.out.result; if (!NT_STATUS_IS_OK(c->status)) { composite_error(c, c->status); return; } /* issue a monitor message */ if (s->monitor_fn) { msg.type = mon_SamrDeleteUser; msg.data = NULL; msg.data_size = 0; s->monitor_fn(&msg); } composite_done(c);}/** * Sends asynchronous userdel request * * @param p dce/rpc call pipe * @param io arguments and results of the call * @param monitor monitor function for providing information about the progress */struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p, struct libnet_rpc_userdel *io, void (*monitor)(struct monitor_msg*)){ struct composite_context *c; struct userdel_state *s; struct rpc_request *lookup_req; /* composite context allocation and setup */ c = composite_create(p, dcerpc_event_context(p)); if (c == NULL) return NULL; s = talloc_zero(c, struct userdel_state); if (composite_nomem(s, c)) return c; c->private_data = s; /* store function parameters in the state structure */ s->pipe = p; s->domain_handle = io->in.domain_handle; s->monitor_fn = monitor; /* preparing parameters to send rpc request */ s->lookupname.in.domain_handle = &io->in.domain_handle; s->lookupname.in.num_names = 1; s->lookupname.in.names = talloc_zero(s, struct lsa_String); s->lookupname.in.names->string = io->in.username; /* send the request */ lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname); if (composite_nomem(lookup_req, c)) return c; /* set the next stage */ composite_continue_rpc(c, lookup_req, continue_userdel_name_found, c); return c;}/** * Waits for and receives results of asynchronous userdel call * * @param c composite context returned by asynchronous userdel call * @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_rpc_userdel_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct libnet_rpc_userdel *io){ NTSTATUS status; struct userdel_state *s; status = composite_wait(c); if (NT_STATUS_IS_OK(status) && io) { s = talloc_get_type(c->private_data, struct userdel_state); io->out.user_handle = s->user_handle; } talloc_free(c); return status;}/** * Synchronous version of userdel call * * @param pipe dce/rpc call pipe * @param mem_ctx memory context for the call * @param io arguments and results of the call * @return nt status code of execution */NTSTATUS libnet_rpc_userdel(struct dcerpc_pipe *p,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?