r7588: Fix lacking space in the comment.
[Samba/ekacnet.git] / source4 / libnet / userinfo.c
blobb7e739df3d3b9bd46c7f2b33e4b269baa34f95df
1 /*
2 Unix SMB/CIFS implementation.
4 Copyright (C) Rafal Szczesniak 2005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 a composite function for getting user information via samr pipe
25 #include "includes.h"
26 #include "libcli/raw/libcliraw.h"
27 #include "libcli/composite/composite.h"
28 #include "libcli/composite/monitor.h"
29 #include "librpc/gen_ndr/ndr_samr.h"
30 #include "libnet/composite.h"
32 static void userinfo_handler(struct rpc_request *req);
34 enum userinfo_stage { USERINFO_OPENUSER, USERINFO_GETUSER, USERINFO_CLOSEUSER };
36 struct userinfo_state {
37 enum userinfo_stage stage;
38 struct dcerpc_pipe *pipe;
39 struct rpc_request *req;
40 struct policy_handle user_handle;
41 uint16_t level;
42 struct samr_OpenUser openuser;
43 struct samr_QueryUserInfo queryuserinfo;
44 struct samr_Close samrclose;
45 union samr_UserInfo *info;
49 /**
50 * Stage 1: Open user policy handle in SAM server.
52 static NTSTATUS userinfo_openuser(struct composite_context *c,
53 struct userinfo_state *s)
55 /* receive samr_OpenUser reply */
56 c->status = dcerpc_ndr_request_recv(s->req);
57 NT_STATUS_NOT_OK_RETURN(c->status);
59 /* prepare parameters for QueryUserInfo call */
60 s->queryuserinfo.in.user_handle = &s->user_handle;
61 s->queryuserinfo.in.level = s->level;
63 /* queue rpc call, set event handling and new state */
64 s->req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo);
65 if (s->req == NULL) goto failure;
67 s->req->async.callback = userinfo_handler;
68 s->req->async.private = c;
69 s->stage = USERINFO_GETUSER;
71 return NT_STATUS_OK;
73 failure:
74 return NT_STATUS_UNSUCCESSFUL;
78 /**
79 * Stage 2: Get requested user information.
81 static NTSTATUS userinfo_getuser(struct composite_context *c,
82 struct userinfo_state *s)
84 /* receive samr_QueryUserInfo reply */
85 c->status = dcerpc_ndr_request_recv(s->req);
86 NT_STATUS_NOT_OK_RETURN(c->status);
88 s->info = talloc_steal(s, s->queryuserinfo.out.info);
90 /* prepare arguments for Close call */
91 s->samrclose.in.handle = &s->user_handle;
92 s->samrclose.out.handle = &s->user_handle;
94 /* queue rpc call, set event handling and new state */
95 s->req = dcerpc_samr_Close_send(s->pipe, c, &s->samrclose);
97 s->req->async.callback = userinfo_handler;
98 s->req->async.private = c;
99 s->stage = USERINFO_CLOSEUSER;
101 return NT_STATUS_OK;
106 * Stage 3: Close policy handle associated with opened user.
108 static NTSTATUS userinfo_closeuser(struct composite_context *c,
109 struct userinfo_state *s)
111 /* receive samr_Close reply */
112 c->status = dcerpc_ndr_request_recv(s->req);
113 NT_STATUS_NOT_OK_RETURN(c->status);
115 c->state = SMBCLI_REQUEST_DONE;
117 return NT_STATUS_OK;
122 * Event handler for asynchronous request. Handles transition through
123 * intermediate stages of the call.
125 * @param req rpc call context
127 static void userinfo_handler(struct rpc_request *req)
129 struct composite_context *c = req->async.private;
130 struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
131 struct monitor_msg msg;
133 /* Stages of the call */
134 switch (s->stage) {
135 case USERINFO_OPENUSER:
136 c->status = userinfo_openuser(c, s);
137 msg.type = rpc_open_user;
138 msg.data.rpc_open_user.rid = s->openuser.in.rid;
139 msg.data.rpc_open_user.access_mask = s->openuser.in.access_mask;
140 break;
142 case USERINFO_GETUSER:
143 c->status = userinfo_getuser(c, s);
144 msg.type = rpc_query_user;
145 msg.data.rpc_query_user.level = s->queryuserinfo.in.level;
146 break;
148 case USERINFO_CLOSEUSER:
149 c->status = userinfo_closeuser(c, s);
150 msg.type = rpc_close_user;
151 msg.data.rpc_close_user.rid = s->openuser.in.rid;
152 break;
155 if (!NT_STATUS_IS_OK(c->status)) {
156 c->state = SMBCLI_REQUEST_ERROR;
159 if (c->monitor_fn) {
160 c->monitor_fn(&msg);
163 if (c->state >= SMBCLI_REQUEST_DONE &&
164 c->async.fn) {
165 c->async.fn(c);
171 * Sends asynchronous userinfo request
173 * @param p dce/rpc call pipe
174 * @param io arguments and results of the call
176 struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p,
177 struct libnet_rpc_userinfo *io,
178 void (*monitor)(struct monitor_msg*))
180 struct composite_context *c;
181 struct userinfo_state *s;
182 struct dom_sid *sid;
184 c = talloc_zero(p, struct composite_context);
185 if (c == NULL) goto failure;
187 s = talloc_zero(c, struct userinfo_state);
188 if (s == NULL) goto failure;
190 s->level = io->in.level;
191 s->pipe = p;
193 sid = dom_sid_parse_talloc(s, io->in.sid);
194 if (sid == NULL) goto failure;
195 c->state = SMBCLI_REQUEST_SEND;
196 c->private = s;
197 c->event_ctx = dcerpc_event_context(p);
198 c->monitor_fn = monitor;
200 /* preparing parameters to send rpc request */
201 s->openuser.in.domain_handle = &io->in.domain_handle;
202 s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
203 s->openuser.in.rid = sid->sub_auths[sid->num_auths - 1];
204 s->openuser.out.user_handle = &s->user_handle;
206 /* send request */
207 s->req = dcerpc_samr_OpenUser_send(p, c, &s->openuser);
209 /* callback handler */
210 s->req->async.callback = userinfo_handler;
211 s->req->async.private = c;
212 s->stage = USERINFO_OPENUSER;
214 return c;
216 failure:
217 talloc_free(c);
218 return NULL;
223 * Waits for and receives result of asynchronous userinfo call
225 * @param c composite context returned by asynchronous userinfo call
226 * @param mem_ctx memory context of the call
227 * @param io pointer to results (and arguments) of the call
228 * @return nt status code of execution
231 NTSTATUS libnet_rpc_userinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
232 struct libnet_rpc_userinfo *io)
234 NTSTATUS status;
235 struct userinfo_state *s;
237 /* wait for results of sending request */
238 status = composite_wait(c);
240 if (NT_STATUS_IS_OK(status) && io) {
241 s = talloc_get_type(c->private, struct userinfo_state);
242 talloc_steal(mem_ctx, s->info);
243 io->out.info = *s->info;
246 /* memory context associated to composite context is no longer needed */
247 talloc_free(c);
248 return status;
253 * Synchronous version of userinfo call
255 * @param pipe dce/rpc call pipe
256 * @param mem_ctx memory context for the call
257 * @param io arguments and results of the call
258 * @return nt status code of execution
261 NTSTATUS libnet_rpc_userinfo(struct dcerpc_pipe *pipe,
262 TALLOC_CTX *mem_ctx,
263 struct libnet_rpc_userinfo *io)
265 struct composite_context *c = libnet_rpc_userinfo_send(pipe, io, NULL);
266 return libnet_rpc_userinfo_recv(c, mem_ctx, io);