added netr_DatabaseSync(). It doesn't work as I haven't done schannel
[sfrench/samba-autobuild/.git] / source4 / torture / rpc / netlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon rpc operations
5
6    Copyright (C) Andrew Tridgell 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25
26 static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
27 {
28         NTSTATUS status;
29         struct netr_LogonUasLogon r;
30
31         r.in.server_name = NULL;
32         r.in.username = lp_parm_string(-1, "torture", "username");
33         r.in.workstation = lp_netbios_name();
34
35         printf("Testing LogonUasLogon\n");
36
37         status = dcerpc_netr_LogonUasLogon(p, mem_ctx, &r);
38         if (!NT_STATUS_IS_OK(status)) {
39                 printf("LogonUasLogon - %s\n", nt_errstr(status));
40                 return False;
41         }
42
43         return True;
44         
45 }
46
47 static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
48 {
49         NTSTATUS status;
50         struct netr_LogonUasLogoff r;
51
52         r.in.server_name = NULL;
53         r.in.username = lp_parm_string(-1, "torture", "username");
54         r.in.workstation = lp_netbios_name();
55
56         printf("Testing LogonUasLogoff\n");
57
58         status = dcerpc_netr_LogonUasLogoff(p, mem_ctx, &r);
59         if (!NT_STATUS_IS_OK(status)) {
60                 printf("LogonUasLogoff - %s\n", nt_errstr(status));
61                 return False;
62         }
63
64         return True;
65         
66 }
67
68 static BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
69                                   struct netr_CredentialState *creds)
70 {
71         NTSTATUS status;
72         struct netr_ServerReqChallenge r;
73         struct netr_ServerAuthenticate a;
74         const char *plain_pass;
75         uint8 mach_pwd[16];
76
77         printf("Testing ServerReqChallenge\n");
78
79         r.in.server_name = NULL;
80         r.in.computer_name = lp_netbios_name();
81         generate_random_buffer(r.in.credentials.data, sizeof(r.in.credentials.data), False);
82
83         status = dcerpc_netr_ServerReqChallenge(p, mem_ctx, &r);
84         if (!NT_STATUS_IS_OK(status)) {
85                 printf("ServerReqChallenge - %s\n", nt_errstr(status));
86                 return False;
87         }
88
89         plain_pass = secrets_fetch_machine_password();
90         if (!plain_pass) {
91                 printf("Unable to fetch machine password!\n");
92                 return False;
93         }
94
95         E_md4hash(plain_pass, mach_pwd);
96
97         creds_client_init(creds, &r.in.credentials, &r.out.credentials, mach_pwd,
98                           &a.in.credentials);
99
100         a.in.server_name = NULL;
101         a.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
102         a.in.secure_challenge_type = 2;
103         a.in.computer_name = lp_netbios_name();
104
105         printf("Testing ServerAuthenticate\n");
106
107         status = dcerpc_netr_ServerAuthenticate(p, mem_ctx, &a);
108         if (!NT_STATUS_IS_OK(status)) {
109                 printf("ServerAuthenticate - %s\n", nt_errstr(status));
110                 return False;
111         }
112
113         if (!creds_client_check(creds, &a.out.credentials)) {
114                 printf("Credential chaining failed\n");
115                 return False;
116         }
117
118         return True;
119 }
120
121 /*
122   try a netlogon SamLogon
123 */
124 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
125 {
126         NTSTATUS status;
127         struct netr_LogonSamLogon r;
128         struct netr_Authenticator auth, auth2;
129         struct netr_NetworkInfo ninfo;
130         const char *username = lp_parm_string(-1, "torture", "username");
131         const char *password = lp_parm_string(-1, "torture", "password");
132         struct netr_CredentialState creds;
133
134         if (!test_SetupCredentials(p, mem_ctx, &creds)) {
135                 return False;
136         }
137
138         ninfo.logon_info.domain_name.string = lp_workgroup();
139         ninfo.logon_info.parameter_control = 0;
140         ninfo.logon_info.logon_id_low = 0;
141         ninfo.logon_info.logon_id_high = 0;
142         ninfo.logon_info.username.string = username;
143         ninfo.logon_info.workstation.string = lp_netbios_name();
144         generate_random_buffer(ninfo.challenge, 
145                                sizeof(ninfo.challenge), False);
146         ninfo.nt.length = 24;
147         ninfo.nt.data = talloc(mem_ctx, 24);
148         SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
149         ninfo.lm.length = 24;
150         ninfo.lm.data = talloc(mem_ctx, 24);
151         SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
152
153         ZERO_STRUCT(auth2);
154
155         creds_client_authenticator(&creds, &auth);
156
157         r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
158         r.in.workstation = lp_netbios_name();
159         r.in.credential = &auth;
160         r.in.authenticator = &auth2;
161         r.in.logon_level = 2;
162         r.in.logon.network = &ninfo;
163         r.in.validation_level = 2;
164
165         printf("Testing SamLogon\n");
166
167         status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
168         if (!NT_STATUS_IS_OK(status)) {
169                 printf("LogonSamLogon - %s\n", nt_errstr(status));
170                 return False;
171         }
172
173         if (!creds_client_check(&creds, &r.out.authenticator->cred)) {
174                 printf("Credential chaining failed\n");
175         }
176
177         return True;
178 }
179
180
181 /*
182   try a change password for our machine account
183 */
184 static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
185 {
186         NTSTATUS status;
187         struct netr_ServerPasswordSet r;
188         const char *password;
189         struct netr_CredentialState creds;
190
191         if (!test_SetupCredentials(p, mem_ctx, &creds)) {
192                 return False;
193         }
194
195         r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
196         r.in.username = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
197         r.in.secure_challenge_type = 2;
198         r.in.computer_name = lp_netbios_name();
199
200         password = generate_random_str(8);
201         E_md4hash(password, r.in.new_password.data);
202
203         creds_client_encrypt(&creds, &r.in.new_password);
204
205         printf("Testing ServerPasswordSet on machine account\n");
206
207         creds_client_authenticator(&creds, &r.in.credential);
208
209         status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
210         if (!NT_STATUS_IS_OK(status)) {
211                 printf("ServerPasswordSet - %s\n", nt_errstr(status));
212                 return False;
213         }
214
215         if (!secrets_store_machine_password(password)) {
216                 printf("Failed to save machine password\n");
217         }
218
219         if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
220                 printf("Credential chaining failed\n");
221         }
222
223         /* by changing the machine password twice we test the credentials
224            chaining fully */
225         printf("Testing a second ServerPasswordSet on machine account\n");
226
227         creds_client_authenticator(&creds, &r.in.credential);
228
229         status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
230         if (!NT_STATUS_IS_OK(status)) {
231                 printf("ServerPasswordSet - %s\n", nt_errstr(status));
232                 return False;
233         }
234
235         if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
236                 printf("Credential chaining failed\n");
237         }
238
239         return True;
240 }
241
242
243 /*
244   try a netlogon DatabaseSync
245 */
246 static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
247 {
248         NTSTATUS status;
249         struct netr_DatabaseSync r;
250         struct netr_CredentialState creds;
251
252         if (!test_SetupCredentials(p, mem_ctx, &creds)) {
253                 return False;
254         }
255
256         creds_client_authenticator(&creds, &r.in.credential);
257         ZERO_STRUCT(r.in.return_authenticator);
258
259         r.in.logonserver = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
260         r.in.computername = lp_netbios_name();
261         r.in.database_id = 1;
262         r.in.sync_context = 1;
263         r.in.preferredmaximumlength = (uint32)-1;
264
265         printf("Testing DatabaseSync\n");
266
267         status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
268         if (!NT_STATUS_IS_OK(status)) {
269                 printf("DatabaseSync - %s\n", nt_errstr(status));
270                 return False;
271         }
272
273         if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
274                 printf("Credential chaining failed\n");
275         }
276
277         return True;
278 }
279
280
281 BOOL torture_rpc_netlogon(int dummy)
282 {
283         NTSTATUS status;
284         struct dcerpc_pipe *p;
285         TALLOC_CTX *mem_ctx;
286         BOOL ret = True;
287
288         mem_ctx = talloc_init("torture_rpc_netlogon");
289
290         status = torture_rpc_connection(&p, 
291                                         DCERPC_NETLOGON_NAME,
292                                         DCERPC_NETLOGON_UUID,
293                                         DCERPC_NETLOGON_VERSION);
294         if (!NT_STATUS_IS_OK(status)) {
295                 return False;
296         }
297         
298         p->flags |= DCERPC_DEBUG_PRINT_BOTH;
299
300         if (!test_LogonUasLogon(p, mem_ctx)) {
301                 ret = False;
302         }
303
304         if (!test_LogonUasLogoff(p, mem_ctx)) {
305                 ret = False;
306         }
307
308         if (!test_SetPassword(p, mem_ctx)) {
309                 ret = False;
310         }
311
312         if (!test_SamLogon(p, mem_ctx)) {
313                 ret = False;
314         }
315
316         if (!test_DatabaseSync(p, mem_ctx)) {
317                 ret = False;
318         }
319
320         torture_rpc_close(p);
321
322         return ret;
323 }