r5769: Fix unused variable warning.
[samba.git] / source4 / libnet / userinfo.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Rafal Szczesniak 2005
5    
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.
10    
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.
15    
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.
19 */
20
21 /*
22   a composite function for getting user information via samr pipe
23 */
24
25 #include "includes.h"
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"
30
31 static void userinfo_handler(struct rpc_request *req);
32
33
34 static NTSTATUS userinfo_openuser(struct composite_context *c,
35                                   struct rpc_composite_userinfo *io)
36 {
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;
41
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;
46
47         /* prepare parameters for QueryUserInfo call */
48         r.in.user_handle = rep->out.user_handle;
49         r.in.level       = io->in.level;
50         
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;
54         
55         s->req->async.callback = userinfo_handler;
56         s->req->async.private  = c;
57         s->stage = USERINFO_GETUSER;
58         
59         return rep->out.result;
60
61 failure:
62         return NT_STATUS_UNSUCCESSFUL;
63 }
64
65
66 static NTSTATUS userinfo_getuser(struct composite_context *c,
67                                  struct rpc_composite_userinfo *io)
68 {
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;
72         struct samr_Close r;
73         
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;
78         
79         /* prepare arguments for Close call */
80         r.in.handle = rep->in.user_handle;
81         
82         /* queue rpc call, set event handling and new state */
83         s->req = dcerpc_samr_Close_send(s->pipe, c, &r);
84         
85         s->req->async.callback = userinfo_handler;
86         s->req->async.private  = c;
87         s->stage = USERINFO_CLOSEUSER;
88
89         /* copying result of composite call */
90         io->out.info = *rep->out.info;
91
92         return rep->out.result;
93 }
94
95
96 static NTSTATUS userinfo_closeuser(struct composite_context *c,
97                                    struct rpc_composite_userinfo *io)
98 {
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;
102         
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;
107
108         /* return result */
109         return rep->out.result;
110 }
111
112
113 static void userinfo_handler(struct rpc_request *req)
114 {
115         struct composite_context *c = req->async.private;
116         struct userinfo_state *s = talloc_get_type(c->private, struct userinfo_state);
117
118         switch (s->stage) {
119         case USERINFO_OPENUSER:
120                 c->status = userinfo_openuser(c, &s->io);
121                 break;
122
123         case USERINFO_GETUSER:
124                 c->status = userinfo_getuser(c, &s->io);
125                 break;
126                 
127         case USERINFO_CLOSEUSER:
128                 c->status = userinfo_closeuser(c, &s->io);
129                 break;
130         }
131
132         if (!NT_STATUS_IS_OK(c->status)) {
133                 c->state = SMBCLI_REQUEST_ERROR;
134         }
135
136         if (c->state >= SMBCLI_REQUEST_DONE &&
137             c->async.fn) {
138                 c->async.fn(c);
139         }
140 }
141
142
143 struct composite_context* rpc_composite_userinfo_send(struct dcerpc_pipe *p,
144                                                       struct rpc_composite_userinfo *io)
145 {       
146
147         struct composite_context *c;
148         struct userinfo_state *s;
149         struct samr_OpenUser *r;
150         struct dom_sid *sid;
151         
152         c = talloc_zero(p, struct composite_context);
153         if (c == NULL) goto failure;
154         
155         s = talloc_zero(c, struct userinfo_state);
156         if (s == NULL) goto failure;
157         
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;
164         
165         c->private = s;
166         c->event_ctx = dcerpc_event_context(p);
167
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];
173
174         /* send request */
175         s->req = dcerpc_samr_OpenUser_send(p, c, r);
176
177         /* callback handler */
178         s->req->async.callback = userinfo_handler;
179         s->req->async.private  = c;
180         s->stage = USERINFO_OPENUSER;
181
182         return c;
183         
184 failure:
185         talloc_free(c);
186 }
187
188
189 NTSTATUS rpc_composite_userinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
190                                      struct rpc_composite_userinfo *io)
191 {
192         NTSTATUS status;
193         struct userinfo_state *s;
194         
195         status = composite_wait(c);
196         
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;
201         }
202
203         talloc_free(c);
204         return status;
205 }
206
207
208 NTSTATUS rpc_composite_userinfo(struct dcerpc_pipe *pipe,
209                                 TALLOC_CTX *mem_ctx,
210                                 struct rpc_composite_userinfo *io)
211 {
212         struct composite_context *c = rpc_composite_userinfo_send(pipe, io);
213         return rpc_composite_userinfo_recv(c, mem_ctx, io);
214 }