s3:smbd: fix NULL dereference in case of readlink failure
[Samba.git] / source4 / torture / rpc / netlogon_crypto.c
blob85844604ee278185f23eb36ee215ec9f6a4d8091
1 /*
2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 Copyright (C) Tim Potter 2003
9 Copyright (C) Matthias Dieter Wallnöfer 2009-2010
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "includes.h"
26 #include "lib/replace/system/network.h"
27 #include "lib/cmdline/cmdline.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "libcli/auth/libcli_auth.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "param/param.h"
32 #include "lib/param/loadparm.h"
33 #include "libcli/security/security.h"
35 #undef strcasecmp
37 #define TEST_MACHINE_NAME "torturetest"
39 static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
40 struct torture_context *tctx,
41 uint32_t negotiate_flags,
42 struct cli_credentials *machine_credentials,
43 bool force_client_rc4)
45 struct netr_ServerReqChallenge r;
46 struct netr_ServerAuthenticate3 a;
47 struct netr_Credential netr_creds1 = {
48 .data = {0},
50 struct netr_Credential netr_creds2 = {
51 .data = {0},
53 struct netr_Credential netr_creds3 = {
54 .data = {0},
56 struct netlogon_creds_CredentialState *creds_state = NULL;
57 struct samr_Password machine_password = {
58 .hash = {0},
60 const char *machine_name = NULL;
61 const char *plain_pass = NULL;
62 struct dcerpc_binding_handle *b = NULL;
63 uint32_t rid = 0;
64 NTSTATUS status;
65 bool weak_crypto_allowed =
66 (lpcfg_weak_crypto(tctx->lp_ctx) ==
67 SAMBA_WEAK_CRYPTO_ALLOWED);
69 if (p == NULL) {
70 return false;
72 b = p->binding_handle;
74 ZERO_STRUCT(r);
75 ZERO_STRUCT(a);
77 torture_comment(tctx, "client negotiate_flags=0x%08x\n", negotiate_flags);
79 machine_name = cli_credentials_get_workstation(machine_credentials);
80 torture_assert_not_null(tctx, machine_name, "machine name is not set");
82 plain_pass = cli_credentials_get_password(machine_credentials);
83 torture_assert_not_null(tctx, plain_pass, "plain_pass is not set");
86 torture_comment(tctx, "Testing ServerReqChallenge\n");
88 r.in.server_name = NULL;
89 r.in.computer_name = machine_name;
90 r.in.credentials = &netr_creds1;
91 r.out.return_credentials = &netr_creds2;
93 netlogon_creds_random_challenge(&netr_creds1);
95 status = dcerpc_netr_ServerReqChallenge_r(b, tctx, &r);
96 torture_assert_ntstatus_ok(tctx,
97 status,
98 "ServerReqChallenge failed");
99 torture_assert_ntstatus_ok(tctx,
100 r.out.result,
101 "ServerReqChallenge failed");
103 E_md4hash(plain_pass, machine_password.hash);
105 a.in.server_name = NULL;
106 a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
107 a.in.secure_channel_type =
108 cli_credentials_get_secure_channel_type(machine_credentials);
109 a.in.computer_name = machine_name;
110 a.in.negotiate_flags = &negotiate_flags;
111 a.in.credentials = &netr_creds3;
112 a.out.return_credentials = &netr_creds3;
113 a.out.negotiate_flags = &negotiate_flags;
114 a.out.rid = &rid;
116 if (force_client_rc4) {
117 GNUTLS_FIPS140_SET_LAX_MODE();
119 creds_state = netlogon_creds_client_init(tctx,
120 a.in.account_name,
121 a.in.computer_name,
122 a.in.secure_channel_type,
123 &netr_creds1,
124 &netr_creds2,
125 &machine_password,
126 &netr_creds3,
127 negotiate_flags);
128 GNUTLS_FIPS140_SET_STRICT_MODE();
129 /* Test that we fail to encrypt with RC4 */
130 if (creds_state == NULL &&
131 !weak_crypto_allowed && !force_client_rc4 &&
132 (negotiate_flags & NETLOGON_NEG_ARCFOUR)) {
133 return false;
135 torture_assert_not_null(tctx,
136 creds_state,
137 "Failed init netlogon client creds");
140 torture_comment(tctx, "Testing ServerAuthenticate3\n");
142 status = dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a);
143 torture_assert_ntstatus_ok(tctx,
144 status,
145 "ServerAuthenticate3 failed");
147 /* Check that the server denies RC4 */
148 if (!NT_STATUS_IS_OK(a.out.result) &&
149 !weak_crypto_allowed &&
150 force_client_rc4) {
151 torture_assert_ntstatus_equal(tctx,
152 a.out.result,
153 NT_STATUS_DOWNGRADE_DETECTED,
154 "Unexpected status code");
155 return false;
157 torture_assert_ntstatus_ok(tctx,
158 a.out.result,
159 "ServerAuthenticate3 failed");
160 torture_assert(tctx,
161 netlogon_creds_client_check(creds_state, &netr_creds3),
162 "Credential chaining failed");
164 torture_comment(tctx,
165 "server negotiate_flags=0x%08x\n",
166 negotiate_flags);
168 if (!weak_crypto_allowed) {
169 torture_assert(tctx,
170 (negotiate_flags & NETLOGON_NEG_ARCFOUR) == 0,
171 "Server should not announce RC4 support");
174 /* Prove that requesting a challenge again won't break it */
175 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
176 "ServerReqChallenge failed");
177 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
179 return true;
183 /* Test that we can successfully authenticate using AES. */
184 static bool test_AES_Crypto(struct torture_context *tctx,
185 struct dcerpc_pipe *p,
186 struct cli_credentials *machine_credentials)
188 uint32_t negotiate_flags =
189 NETLOGON_NEG_AUTH2_ADS_FLAGS|
190 NETLOGON_NEG_SUPPORTS_AES;
191 bool ok;
193 ok = test_ServerAuth3Crypto(p,
194 tctx,
195 negotiate_flags,
196 machine_credentials,
197 false);
198 if (!ok) {
199 return false;
202 return true;
205 /* If we try to use RC4, the client code should fail to encrypt. */
206 static bool test_RC4_Crypto_Fail(struct torture_context *tctx,
207 struct dcerpc_pipe *p,
208 struct cli_credentials *machine_credentials)
210 uint32_t negotiate_flags =
211 NETLOGON_NEG_AUTH2_ADS_FLAGS|
212 NETLOGON_NEG_ARCFOUR;
213 bool ok;
215 ok = test_ServerAuth3Crypto(p,
216 tctx,
217 negotiate_flags,
218 machine_credentials,
219 false);
220 if (!ok) {
221 return true;
224 return false;
228 * Enforce the use of RC4 and try to authenticate. The server should fail
229 * in this case as it doesn't allow RC4
231 static bool test_RC4_Crypto_Force(struct torture_context *tctx,
232 struct dcerpc_pipe *p,
233 struct cli_credentials *machine_credentials)
235 uint32_t negotiate_flags =
236 NETLOGON_NEG_AUTH2_ADS_FLAGS|
237 NETLOGON_NEG_ARCFOUR;
238 bool ok;
240 ok = test_ServerAuth3Crypto(p,
241 tctx,
242 negotiate_flags,
243 machine_credentials,
244 true);
245 if (!ok) {
246 return true;
249 return false;
252 struct torture_suite *torture_rpc_netlogon_crypto_fips(TALLOC_CTX *mem_ctx)
254 struct torture_suite *suite = torture_suite_create(mem_ctx,
255 "fips.netlogon.crypto");
256 struct torture_rpc_tcase *tcase = NULL;
258 tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite,
259 "netlogon",
260 &ndr_table_netlogon,
261 TEST_MACHINE_NAME);
263 torture_rpc_tcase_add_test_creds(tcase,
264 "test_AES_Crytpo",
265 test_AES_Crypto);
266 torture_rpc_tcase_add_test_creds(tcase,
267 "test_RC4_Crytpo_Fail",
268 test_RC4_Crypto_Fail);
269 torture_rpc_tcase_add_test_creds(tcase,
270 "test_RC4_Crytpo_Force",
271 test_RC4_Crypto_Force);
273 return suite;