r6717: - torture test of async useradd function and monitor messages.
[samba.git] / source / torture / libnet / userman.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Test suite for libnet calls.
4
5    Copyright (C) Rafal Szczesniak 2005
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/ndr_samr.h"
24 #include "libnet/composite.h"
25 #include "libcli/composite/monitor.h"
26
27 #define TEST_USERNAME  "libnetusermantest"
28
29
30 static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
31                             struct policy_handle *handle, struct samr_String *domname)
32 {
33         NTSTATUS status;
34         struct policy_handle h, domain_handle;
35         struct samr_Connect r1;
36         struct samr_LookupDomain r2;
37         struct samr_OpenDomain r3;
38         
39         printf("connecting\n");
40         
41         r1.in.system_name = 0;
42         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
43         r1.out.connect_handle = &h;
44         
45         status = dcerpc_samr_Connect(p, mem_ctx, &r1);
46         if (!NT_STATUS_IS_OK(status)) {
47                 printf("Connect failed - %s\n", nt_errstr(status));
48                 return False;
49         }
50         
51         r2.in.connect_handle = &h;
52         r2.in.domain_name = domname;
53
54         printf("domain lookup on %s\n", domname->string);
55
56         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
57         if (!NT_STATUS_IS_OK(status)) {
58                 printf("LookupDomain failed - %s\n", nt_errstr(status));
59                 return False;
60         }
61
62         r3.in.connect_handle = &h;
63         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
64         r3.in.sid = r2.out.sid;
65         r3.out.domain_handle = &domain_handle;
66
67         printf("opening domain\n");
68
69         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
70         if (!NT_STATUS_IS_OK(status)) {
71                 printf("OpenDomain failed - %s\n", nt_errstr(status));
72                 return False;
73         } else {
74                 *handle = domain_handle;
75         }
76
77         return True;
78 }
79
80
81 static BOOL test_useradd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
82                          struct policy_handle *domain_handle,
83                          const char *name)
84 {
85         NTSTATUS status;
86         BOOL ret = True;
87         struct rpc_composite_useradd user;
88         
89         user.in.domain_handle = *domain_handle;
90         user.in.username      = name;
91
92         printf("Testing rpc_composite_useradd\n");
93
94         status = rpc_composite_useradd(p, mem_ctx, &user);
95         if (!NT_STATUS_IS_OK(status)) {
96                 printf("Failed to call sync rpc_composite_userinfo - %s\n", nt_errstr(status));
97                 return False;
98         }
99         
100         return ret;
101 }
102
103
104 static void msg_handler(struct monitor_msg *m)
105 {
106         switch (m->type) {
107         case rpc_create_user:
108                 printf("monitor_msg: user created (rid=%d)\n", m->data.rpc_create_user.rid);
109                 break;
110         }
111 }
112
113
114 static BOOL test_useradd_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
115                                struct policy_handle *handle, const char* username)
116 {
117         NTSTATUS status;
118         BOOL ret = True;
119         struct composite_context *c;
120         struct rpc_composite_useradd user;
121
122         user.in.domain_handle = *handle;
123         user.in.username      = username;
124         
125         printf("Testing async rpc_composite_useradd\n");
126         
127         c = rpc_composite_useradd_send(p, &user, msg_handler);
128         if (!c) {
129                 printf("Failed to call async rpc_composite_useradd\n");
130                 return False;
131         }
132
133         status = rpc_composite_useradd_recv(c, mem_ctx, &user);
134         if (!NT_STATUS_IS_OK(status)) {
135                 printf("Calling async rpc_composite_useradd failed - %s\n", nt_errstr(status));
136                 return False;
137         }
138
139         return True;
140
141 }
142
143
144 static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
145                          struct policy_handle *domain_handle, const char *username)
146 {
147         NTSTATUS status;
148         struct samr_LookupNames r1;
149         struct samr_OpenUser r2;
150         struct samr_DeleteUser r3;
151         struct samr_String names[2];
152         uint32_t rid;
153         struct policy_handle user_handle;
154
155         names[0].string = username;
156
157         r1.in.domain_handle  = domain_handle;
158         r1.in.num_names      = 1;
159         r1.in.names          = names;
160         
161         printf("user account lookup '%s'\n", username);
162
163         status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
164         if (!NT_STATUS_IS_OK(status)) {
165                 printf("LookupNames failed - %s\n", nt_errstr(status));
166                 return False;
167         }
168
169         rid = r1.out.rids.ids[0];
170         
171         r2.in.domain_handle  = domain_handle;
172         r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
173         r2.in.rid            = rid;
174         r2.out.user_handle   = &user_handle;
175
176         printf("opening user account\n");
177
178         status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
179         if (!NT_STATUS_IS_OK(status)) {
180                 printf("OpenUser failed - %s\n", nt_errstr(status));
181                 return False;
182         }
183
184         r3.in.user_handle  = &user_handle;
185         r3.out.user_handle = &user_handle;
186
187         printf("deleting user account\n");
188         
189         status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
190         if (!NT_STATUS_IS_OK(status)) {
191                 printf("DeleteUser failed - %s\n", nt_errstr(status));
192                 return False;
193         }
194         
195         return True;
196 }
197
198
199 static BOOL test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
200                             struct policy_handle *handle, const char* user)
201 {
202         NTSTATUS status;
203         struct policy_handle user_handle;
204         struct samr_String username;
205         struct samr_CreateUser r1;
206         struct samr_Close r2;
207         uint32_t user_rid;
208
209         username.string = user;
210         
211         r1.in.domain_handle = handle;
212         r1.in.account_name = &username;
213         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214         r1.out.user_handle = &user_handle;
215         r1.out.rid = &user_rid;
216
217         printf("creating user '%s'\n", username.string);
218         
219         status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
220         if (!NT_STATUS_IS_OK(status)) {
221                 printf("CreateUser failed - %s\n", nt_errstr(status));
222
223                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
224                         printf("User (%s) already exists - attempting to delete and recreate account again\n", user);
225                         if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
226                                 return False;
227                         }
228
229                         printf("creating user account\n");
230                         
231                         status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
232                         if (!NT_STATUS_IS_OK(status)) {
233                                 printf("CreateUser failed - %s\n", nt_errstr(status));
234                                 return False;
235                         }
236                         return True;
237                 }               
238                 return False;
239         }
240
241         r2.in.handle = &user_handle;
242         r2.out.handle = &user_handle;
243         
244         printf("closing user '%s'\n", username.string);
245
246         status = dcerpc_samr_Close(p, mem_ctx, &r2);
247         if (!NT_STATUS_IS_OK(status)) {
248                 printf("Close failed - %s\n", nt_errstr(status));
249                 return False;
250         }
251
252         return True;
253 }
254
255
256 static BOOL test_userdel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
257                          struct policy_handle *handle, const char *username)
258 {
259         NTSTATUS status;
260         struct rpc_composite_userdel user;
261         
262         user.in.domain_handle = *handle;
263         user.in.username = username;
264         
265         status = rpc_composite_userdel(p, mem_ctx, &user);
266         if (!NT_STATUS_IS_OK(status)) {
267                 printf("Failed to call sync rpc_composite_userdel - %s\n", nt_errstr(status));
268                 return False;
269         }
270
271         return True;
272 }
273
274
275 BOOL torture_useradd(void)
276 {
277         NTSTATUS status;
278         const char *binding;
279         struct dcerpc_pipe *p;
280         struct policy_handle h;
281         struct samr_String domain_name;
282         char* name = TEST_USERNAME;
283         TALLOC_CTX *mem_ctx;
284         BOOL ret = True;
285
286         mem_ctx = talloc_init("test_useradd");
287         binding = lp_parm_string(-1, "torture", "binding");
288
289         status = torture_rpc_connection(mem_ctx, 
290                                         &p,
291                                         DCERPC_SAMR_NAME,
292                                         DCERPC_SAMR_UUID,
293                                         DCERPC_SAMR_VERSION);
294         
295         if (!NT_STATUS_IS_OK(status)) {
296                 return False;
297         }
298
299         domain_name.string = lp_workgroup();
300         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
301                 ret = False;
302                 goto done;
303         }
304
305         if (!test_useradd(p, mem_ctx, &h, name)) {
306                 ret = False;
307                 goto done;
308         }
309
310         if (!test_cleanup(p, mem_ctx, &h, name)) {
311                 ret = False;
312                 goto done;
313         }
314
315         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
316                 ret = False;
317                 goto done;
318         }
319
320         if (!test_useradd_async(p, mem_ctx, &h, name)) {
321                 ret = False;
322                 goto done;
323         }
324
325         if (!test_cleanup(p, mem_ctx, &h, name)) {
326                 ret = False;
327                 goto done;
328         }
329
330 done:
331         talloc_free(mem_ctx);
332         return ret;
333 }
334
335
336 BOOL torture_userdel(void)
337 {
338         NTSTATUS status;
339         const char *binding;
340         struct dcerpc_pipe *p;
341         struct policy_handle h;
342         struct samr_String domain_name;
343         char* name = TEST_USERNAME;
344         TALLOC_CTX *mem_ctx;
345         BOOL ret = True;
346
347         mem_ctx = talloc_init("test_userdel");
348         binding = lp_parm_string(-1, "torture", "binding");
349
350         status = torture_rpc_connection(mem_ctx, 
351                                         &p,
352                                         DCERPC_SAMR_NAME,
353                                         DCERPC_SAMR_UUID,
354                                         DCERPC_SAMR_VERSION);
355         
356         if (!NT_STATUS_IS_OK(status)) {
357                 return False;
358         }
359
360         domain_name.string = lp_workgroup();
361         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
362                 ret = False;
363                 goto done;
364         }
365
366         if (!test_createuser(p, mem_ctx, &h, name)) {
367                 ret = False;
368                 goto done;
369         }
370         
371         if (!test_userdel(p, mem_ctx, &h, name)) {
372                 ret = False;
373                 goto done;
374         }
375         
376 done:
377         talloc_free(mem_ctx);
378         return ret;
379 }