r12542: Move some more prototypes out to seperate headers
[abartlet/samba.git/.git] / source4 / 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 "libnet/userman.h"
26 #include "libnet/libnet.h"
27
28 #define TEST_USERNAME  "libnetusermantest"
29
30
31 static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
32                             struct policy_handle *handle, struct lsa_String *domname)
33 {
34         NTSTATUS status;
35         struct policy_handle h, domain_handle;
36         struct samr_Connect r1;
37         struct samr_LookupDomain r2;
38         struct samr_OpenDomain r3;
39         
40         printf("connecting\n");
41         
42         r1.in.system_name = 0;
43         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
44         r1.out.connect_handle = &h;
45         
46         status = dcerpc_samr_Connect(p, mem_ctx, &r1);
47         if (!NT_STATUS_IS_OK(status)) {
48                 printf("Connect failed - %s\n", nt_errstr(status));
49                 return False;
50         }
51         
52         r2.in.connect_handle = &h;
53         r2.in.domain_name = domname;
54
55         printf("domain lookup on %s\n", domname->string);
56
57         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
58         if (!NT_STATUS_IS_OK(status)) {
59                 printf("LookupDomain failed - %s\n", nt_errstr(status));
60                 return False;
61         }
62
63         r3.in.connect_handle = &h;
64         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
65         r3.in.sid = r2.out.sid;
66         r3.out.domain_handle = &domain_handle;
67
68         printf("opening domain\n");
69
70         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
71         if (!NT_STATUS_IS_OK(status)) {
72                 printf("OpenDomain failed - %s\n", nt_errstr(status));
73                 return False;
74         } else {
75                 *handle = domain_handle;
76         }
77
78         return True;
79 }
80
81
82 static BOOL test_useradd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
83                          struct policy_handle *domain_handle,
84                          const char *name)
85 {
86         NTSTATUS status;
87         BOOL ret = True;
88         struct libnet_rpc_useradd user;
89         
90         user.in.domain_handle = *domain_handle;
91         user.in.username      = name;
92
93         printf("Testing libnet_rpc_useradd\n");
94
95         status = libnet_rpc_useradd(p, mem_ctx, &user);
96         if (!NT_STATUS_IS_OK(status)) {
97                 printf("Failed to call sync rpc_composite_userinfo - %s\n", nt_errstr(status));
98                 return False;
99         }
100         
101         return ret;
102 }
103
104
105 static void msg_handler(struct monitor_msg *m)
106 {
107         struct msg_rpc_create_user *msg_create;
108
109         switch (m->type) {
110         case rpc_create_user:
111                 msg_create = (struct msg_rpc_create_user*)m->data;
112                 printf("monitor_msg: user created (rid=%d)\n", msg_create->rid);
113                 break;
114         }
115 }
116
117
118 static BOOL test_useradd_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
119                                struct policy_handle *handle, const char* username)
120 {
121         NTSTATUS status;
122         struct composite_context *c;
123         struct libnet_rpc_useradd user;
124
125         user.in.domain_handle = *handle;
126         user.in.username      = username;
127         
128         printf("Testing async libnet_rpc_useradd\n");
129         
130         c = libnet_rpc_useradd_send(p, &user, msg_handler);
131         if (!c) {
132                 printf("Failed to call async libnet_rpc_useradd\n");
133                 return False;
134         }
135
136         status = libnet_rpc_useradd_recv(c, mem_ctx, &user);
137         if (!NT_STATUS_IS_OK(status)) {
138                 printf("Calling async libnet_rpc_useradd failed - %s\n", nt_errstr(status));
139                 return False;
140         }
141
142         return True;
143
144 }
145
146
147 static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
148                          struct policy_handle *domain_handle, const char *username)
149 {
150         NTSTATUS status;
151         struct samr_LookupNames r1;
152         struct samr_OpenUser r2;
153         struct samr_DeleteUser r3;
154         struct lsa_String names[2];
155         uint32_t rid;
156         struct policy_handle user_handle;
157
158         names[0].string = username;
159
160         r1.in.domain_handle  = domain_handle;
161         r1.in.num_names      = 1;
162         r1.in.names          = names;
163         
164         printf("user account lookup '%s'\n", username);
165
166         status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
167         if (!NT_STATUS_IS_OK(status)) {
168                 printf("LookupNames failed - %s\n", nt_errstr(status));
169                 return False;
170         }
171
172         rid = r1.out.rids.ids[0];
173         
174         r2.in.domain_handle  = domain_handle;
175         r2.in.access_mask    = SEC_FLAG_MAXIMUM_ALLOWED;
176         r2.in.rid            = rid;
177         r2.out.user_handle   = &user_handle;
178
179         printf("opening user account\n");
180
181         status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
182         if (!NT_STATUS_IS_OK(status)) {
183                 printf("OpenUser failed - %s\n", nt_errstr(status));
184                 return False;
185         }
186
187         r3.in.user_handle  = &user_handle;
188         r3.out.user_handle = &user_handle;
189
190         printf("deleting user account\n");
191         
192         status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
193         if (!NT_STATUS_IS_OK(status)) {
194                 printf("DeleteUser failed - %s\n", nt_errstr(status));
195                 return False;
196         }
197         
198         return True;
199 }
200
201
202 static BOOL test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
203                             struct policy_handle *handle, const char* user)
204 {
205         NTSTATUS status;
206         struct policy_handle user_handle;
207         struct lsa_String username;
208         struct samr_CreateUser r1;
209         struct samr_Close r2;
210         uint32_t user_rid;
211
212         username.string = user;
213         
214         r1.in.domain_handle = handle;
215         r1.in.account_name = &username;
216         r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
217         r1.out.user_handle = &user_handle;
218         r1.out.rid = &user_rid;
219
220         printf("creating user '%s'\n", username.string);
221         
222         status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
223         if (!NT_STATUS_IS_OK(status)) {
224                 printf("CreateUser failed - %s\n", nt_errstr(status));
225
226                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
227                         printf("User (%s) already exists - attempting to delete and recreate account again\n", user);
228                         if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
229                                 return False;
230                         }
231
232                         printf("creating user account\n");
233                         
234                         status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
235                         if (!NT_STATUS_IS_OK(status)) {
236                                 printf("CreateUser failed - %s\n", nt_errstr(status));
237                                 return False;
238                         }
239                         return True;
240                 }               
241                 return False;
242         }
243
244         r2.in.handle = &user_handle;
245         r2.out.handle = &user_handle;
246         
247         printf("closing user '%s'\n", username.string);
248
249         status = dcerpc_samr_Close(p, mem_ctx, &r2);
250         if (!NT_STATUS_IS_OK(status)) {
251                 printf("Close failed - %s\n", nt_errstr(status));
252                 return False;
253         }
254
255         return True;
256 }
257
258
259 static BOOL test_userdel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
260                          struct policy_handle *handle, const char *username)
261 {
262         NTSTATUS status;
263         struct libnet_rpc_userdel user;
264         
265         user.in.domain_handle = *handle;
266         user.in.username = username;
267         
268         status = libnet_rpc_userdel(p, mem_ctx, &user);
269         if (!NT_STATUS_IS_OK(status)) {
270                 printf("Failed to call sync libnet_rpc_userdel - %s\n", nt_errstr(status));
271                 return False;
272         }
273
274         return True;
275 }
276
277
278 static BOOL test_usermod(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
279                          struct policy_handle *handle, const char *username,
280                          struct usermod_change *change)
281 {
282         NTSTATUS status;
283         struct libnet_rpc_usermod user;
284         
285         user.in.domain_handle = *handle;
286         user.in.username = username;
287         user.in.change = *change;
288
289         printf("modifying user\n");
290
291         status = libnet_rpc_usermod(p, mem_ctx, &user);
292         if (!NT_STATUS_IS_OK(status)) {
293                 printf("Failed to call sync libnet_rpc_usermod - %s\n", nt_errstr(status));
294                 return False;
295         }
296
297         return True;
298 }
299
300
301 BOOL torture_useradd(void)
302 {
303         NTSTATUS status;
304         const char *binding;
305         struct dcerpc_pipe *p;
306         struct policy_handle h;
307         struct lsa_String domain_name;
308         const char *name = TEST_USERNAME;
309         TALLOC_CTX *mem_ctx;
310         BOOL ret = True;
311
312         mem_ctx = talloc_init("test_useradd");
313         binding = lp_parm_string(-1, "torture", "binding");
314
315         status = torture_rpc_connection(mem_ctx, 
316                                         &p,
317                                         &dcerpc_table_samr);
318         
319         if (!NT_STATUS_IS_OK(status)) {
320                 return False;
321         }
322
323         domain_name.string = lp_workgroup();
324         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
325                 ret = False;
326                 goto done;
327         }
328
329         if (!test_useradd(p, mem_ctx, &h, name)) {
330                 ret = False;
331                 goto done;
332         }
333
334         if (!test_cleanup(p, mem_ctx, &h, name)) {
335                 ret = False;
336                 goto done;
337         }
338
339         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
340                 ret = False;
341                 goto done;
342         }
343
344         if (!test_useradd_async(p, mem_ctx, &h, name)) {
345                 ret = False;
346                 goto done;
347         }
348
349         if (!test_cleanup(p, mem_ctx, &h, name)) {
350                 ret = False;
351                 goto done;
352         }
353
354 done:
355         talloc_free(mem_ctx);
356         return ret;
357 }
358
359
360 BOOL torture_userdel(void)
361 {
362         NTSTATUS status;
363         const char *binding;
364         struct dcerpc_pipe *p;
365         struct policy_handle h;
366         struct lsa_String domain_name;
367         const char *name = TEST_USERNAME;
368         TALLOC_CTX *mem_ctx;
369         BOOL ret = True;
370
371         mem_ctx = talloc_init("test_userdel");
372         binding = lp_parm_string(-1, "torture", "binding");
373
374         status = torture_rpc_connection(mem_ctx, 
375                                         &p,
376                                         &dcerpc_table_samr);
377         
378         if (!NT_STATUS_IS_OK(status)) {
379                 return False;
380         }
381
382         domain_name.string = lp_workgroup();
383         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
384                 ret = False;
385                 goto done;
386         }
387
388         if (!test_createuser(p, mem_ctx, &h, name)) {
389                 ret = False;
390                 goto done;
391         }
392         
393         if (!test_userdel(p, mem_ctx, &h, name)) {
394                 ret = False;
395                 goto done;
396         }
397         
398 done:
399         talloc_free(mem_ctx);
400         return ret;
401 }
402
403
404 BOOL torture_usermod(void)
405 {
406         NTSTATUS status;
407         const char *binding;
408         struct dcerpc_pipe *p;
409         struct policy_handle h;
410         struct lsa_String domain_name;
411         const char *name = TEST_USERNAME;
412         TALLOC_CTX *mem_ctx;
413         BOOL ret = True;
414         int i;
415
416         struct timeval expiry = { 12345, 67890 };
417         struct timeval allow  = { 67890, 12345 };
418         struct timeval force  = { 33333, 55444 };
419
420         struct usermod_change changes[] = {
421                 { USERMOD_FIELD_ACCOUNT_NAME,   "changed", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
422                 { USERMOD_FIELD_FULL_NAME,      NULL, "Testing full account name", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
423                 { USERMOD_FIELD_DESCRIPTION,    NULL, NULL, "Description of tested account", NULL, NULL, NULL, NULL, NULL, NULL, 0 },
424                 { USERMOD_FIELD_COMMENT,        NULL, NULL, NULL, "Comment for the tested account", NULL, NULL, NULL, NULL, NULL, 0 },
425                 { USERMOD_FIELD_LOGON_SCRIPT,   NULL, NULL, NULL, NULL, "test_logon.cmd", NULL, NULL, NULL, NULL, 0 },
426                 { USERMOD_FIELD_PROFILE_PATH,   NULL, NULL, NULL, NULL, NULL, "\\\\TESTSRV\\profiles\\test", NULL, NULL, NULL, 0 },
427                 { USERMOD_FIELD_ACCT_EXPIRY,    NULL, NULL, NULL, NULL, NULL, NULL, &expiry, NULL, NULL, 0 },
428                 { USERMOD_FIELD_ALLOW_PASS_CHG, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &allow, NULL, 0 },
429                 { USERMOD_FIELD_FORCE_PASS_CHG, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &force, ACB_NORMAL }
430         };
431         
432         mem_ctx = talloc_init("test_userdel");
433         binding = lp_parm_string(-1, "torture", "binding");
434
435         status = torture_rpc_connection(mem_ctx, 
436                                         &p,
437                                         &dcerpc_table_samr);
438         
439         if (!NT_STATUS_IS_OK(status)) {
440                 return False;
441         }
442
443         domain_name.string = lp_workgroup();
444
445         if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
446                 ret = False;
447                 goto done;
448         }
449
450         if (!test_createuser(p, mem_ctx, &h, name)) {
451                 ret = False;
452                 goto done;
453         }
454
455         for (i = 0; i < (sizeof(changes)/sizeof(struct usermod_change)); i++) {
456                 if (!test_usermod(p, mem_ctx, &h, name, &changes[i])) {
457                         ret = False;
458                         goto done;
459                 }
460
461                 if (changes[i].fields & USERMOD_FIELD_ACCOUNT_NAME) {
462                         name = talloc_strdup(mem_ctx, changes[i].account_name);
463                 }
464         }
465
466         if (!test_cleanup(p, mem_ctx, &h, name)) {
467                 ret = False;
468                 goto done;
469         }
470
471 done:
472         talloc_free(mem_ctx);
473         return ret;
474 }