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
26 #include "libcli/raw/libcliraw.h"
27 #include "libcli/composite/composite.h"
28 #include "librpc/gen_ndr/ndr_samr.h"
29 #include "libnet/composite.h"
31 static void userinfo_handler(struct rpc_request *req);
34 static NTSTATUS userinfo_openuser(struct composite_context *c,
35 struct rpc_composite_userinfo *io)
37 struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
38 struct rpc_request *req = s->req;
39 struct samr_OpenUser *rep;
40 struct samr_QueryUserInfo r;
42 /* receive samr_OpenUser reply */
43 c->status = dcerpc_ndr_request_recv(req);
44 NT_STATUS_NOT_OK_RETURN(c->status);
45 rep = (struct samr_OpenUser*)req->ndr.struct_ptr;
47 /* prepare parameters for QueryUserInfo call */
48 r.in.user_handle = rep->out.user_handle;
49 r.in.level = io->in.level;
51 /* queue rpc call, set event handling and new state */
52 s->req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &r);
53 if (s->req == NULL) goto failure;
55 s->req->async.callback = userinfo_handler;
56 s->req->async.private = c;
57 s->stage = USERINFO_GETUSER;
59 return rep->out.result;
62 return NT_STATUS_UNSUCCESSFUL;
66 static NTSTATUS userinfo_getuser(struct composite_context *c,
67 struct rpc_composite_userinfo *io)
69 struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
70 struct rpc_request *req = s->pipe->conn->pending;
71 struct samr_QueryUserInfo *rep;
74 /* receive samr_QueryUserInfo reply */
75 c->status = dcerpc_ndr_request_recv(req);
76 NT_STATUS_NOT_OK_RETURN(c->status);
77 rep = (struct samr_QueryUserInfo*)req->ndr.struct_ptr;
79 /* prepare arguments for Close call */
80 r.in.handle = rep->in.user_handle;
82 /* queue rpc call, set event handling and new state */
83 s->req = dcerpc_samr_Close_send(s->pipe, c, &r);
85 s->req->async.callback = userinfo_handler;
86 s->req->async.private = c;
87 s->stage = USERINFO_CLOSEUSER;
89 /* copying result of composite call */
90 io->out.info = *rep->out.info;
92 return rep->out.result;
96 static NTSTATUS userinfo_closeuser(struct composite_context *c,
97 struct rpc_composite_userinfo *io)
99 struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
100 struct rpc_request *req = s->pipe->conn->pending;
101 struct samr_Close *rep;
103 /* receive samr_Close reply */
104 c->status = dcerpc_ndr_request_recv(req);
105 NT_STATUS_NOT_OK_RETURN(c->status);
106 rep = (struct samr_Close*)req->ndr.struct_ptr;
109 return rep->out.result;
113 static void userinfo_handler(struct rpc_request *req)
115 struct composite_context *c = req->async.private;
116 struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
119 case USERINFO_OPENUSER:
120 c->status = userinfo_openuser(c, &s->io);
123 case USERINFO_GETUSER:
124 c->status = userinfo_getuser(c, &s->io);
127 case USERINFO_CLOSEUSER:
128 c->status = userinfo_closeuser(c, &s->io);
132 if (!NT_STATUS_IS_OK(c->status)) {
133 c->state = SMBCLI_REQUEST_ERROR;
136 if (c->state >= SMBCLI_REQUEST_DONE &&
143 struct composite_context* rpc_composite_userinfo_send(struct dcerpc_pipe *p,
144 struct rpc_composite_userinfo *io)
147 struct composite_context *c;
148 struct userinfo_state *s;
149 struct samr_OpenUser *r;
152 c = talloc_zero(p, struct composite_context);
153 if (c == NULL) goto failure;
155 s = talloc_zero(c, struct userinfo_state);
156 if (s == NULL) goto failure;
158 /* copying input parameters */
159 s->io.in.domain_handle = io->in.domain_handle;
160 s->io.in.sid = talloc_strdup(p, io->in.sid);
161 s->io.in.level = io->in.level;
162 sid = dom_sid_parse_talloc(c, s->io.in.sid);
163 if (sid == NULL) goto failure;
166 c->event_ctx = dcerpc_event_context(p);
168 /* preparing parameters to send rpc request */
169 r = talloc_zero(p, struct samr_OpenUser);
170 r->in.domain_handle = &s->io.in.domain_handle;
171 r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
172 r->in.rid = sid->sub_auths[sid->num_auths - 1];
175 s->req = dcerpc_samr_OpenUser_send(p, c, r);
177 /* callback handler */
178 s->req->async.callback = userinfo_handler;
179 s->req->async.private = c;
180 s->stage = USERINFO_OPENUSER;
189 NTSTATUS rpc_composite_userinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
190 struct rpc_composite_userinfo *io)
193 struct userinfo_state *s;
195 status = composite_wait(c);
197 if (NT_STATUS_IS_OK(status) && io) {
198 s = talloc_get_type(c->private, struct userinfo_state);
199 talloc_steal(mem_ctx, &s->io.out.info);
200 io->out.info = s->io.out.info;
208 NTSTATUS rpc_composite_userinfo(struct dcerpc_pipe *pipe,
210 struct rpc_composite_userinfo *io)
212 struct composite_context *c = rpc_composite_userinfo_send(pipe, io);
213 return rpc_composite_userinfo_recv(c, mem_ctx, io);