Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : NT Domain Authentication SMB / MSRPC client
4 : Copyright (C) Andrew Tridgell 1992-2000
5 : Copyright (C) Jeremy Allison 1998.
6 : Largely re-written by Jeremy Allison (C) 2005.
7 : Copyright (C) Guenther Deschner 2008.
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "system/filesys.h"
25 : #include "libsmb/libsmb.h"
26 : #include "rpc_client/rpc_client.h"
27 : #include "rpc_client/cli_pipe.h"
28 : #include "../libcli/auth/libcli_auth.h"
29 : #include "../libcli/auth/netlogon_creds_cli.h"
30 : #include "../librpc/gen_ndr/ndr_netlogon_c.h"
31 : #include "../librpc/gen_ndr/schannel.h"
32 : #include "rpc_client/cli_netlogon.h"
33 : #include "rpc_client/util_netlogon.h"
34 : #include "../libcli/security/security.h"
35 : #include "lib/param/param.h"
36 : #include "libcli/smb/smbXcli_base.h"
37 : #include "dbwrap/dbwrap.h"
38 : #include "dbwrap/dbwrap_open.h"
39 : #include "util_tdb.h"
40 : #include "lib/crypto/gnutls_helpers.h"
41 :
42 :
43 177 : NTSTATUS rpccli_pre_open_netlogon_creds(void)
44 : {
45 0 : static bool already_open = false;
46 0 : TALLOC_CTX *frame;
47 0 : struct loadparm_context *lp_ctx;
48 0 : char *fname;
49 0 : struct db_context *global_db;
50 0 : NTSTATUS status;
51 :
52 177 : if (already_open) {
53 9 : return NT_STATUS_OK;
54 : }
55 :
56 168 : frame = talloc_stackframe();
57 :
58 168 : lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
59 168 : if (lp_ctx == NULL) {
60 0 : TALLOC_FREE(frame);
61 0 : return NT_STATUS_NO_MEMORY;
62 : }
63 :
64 168 : fname = lpcfg_private_db_path(frame, lp_ctx, "netlogon_creds_cli");
65 168 : if (fname == NULL) {
66 0 : TALLOC_FREE(frame);
67 0 : return NT_STATUS_NO_MEMORY;
68 : }
69 :
70 168 : global_db = db_open(frame, fname,
71 : 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
72 : O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
73 : DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS);
74 168 : if (global_db == NULL) {
75 0 : TALLOC_FREE(frame);
76 0 : return NT_STATUS_NO_MEMORY;
77 : }
78 :
79 168 : status = netlogon_creds_cli_set_global_db(lp_ctx, &global_db);
80 168 : TALLOC_FREE(frame);
81 168 : if (!NT_STATUS_IS_OK(status)) {
82 0 : return status;
83 : }
84 :
85 168 : already_open = true;
86 168 : return NT_STATUS_OK;
87 : }
88 :
89 132 : static NTSTATUS rpccli_create_netlogon_creds(
90 : const char *server_computer,
91 : const char *server_netbios_domain,
92 : const char *server_dns_domain,
93 : const char *client_account,
94 : enum netr_SchannelType sec_chan_type,
95 : struct messaging_context *msg_ctx,
96 : TALLOC_CTX *mem_ctx,
97 : struct netlogon_creds_cli_context **netlogon_creds)
98 : {
99 132 : TALLOC_CTX *frame = talloc_stackframe();
100 0 : struct loadparm_context *lp_ctx;
101 0 : NTSTATUS status;
102 :
103 132 : status = rpccli_pre_open_netlogon_creds();
104 132 : if (!NT_STATUS_IS_OK(status)) {
105 0 : TALLOC_FREE(frame);
106 0 : return status;
107 : }
108 :
109 132 : lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
110 132 : if (lp_ctx == NULL) {
111 0 : TALLOC_FREE(frame);
112 0 : return NT_STATUS_NO_MEMORY;
113 : }
114 132 : status = netlogon_creds_cli_context_global(lp_ctx,
115 : msg_ctx,
116 : client_account,
117 : sec_chan_type,
118 : server_computer,
119 : server_netbios_domain,
120 : server_dns_domain,
121 : mem_ctx, netlogon_creds);
122 132 : TALLOC_FREE(frame);
123 132 : if (!NT_STATUS_IS_OK(status)) {
124 0 : return status;
125 : }
126 :
127 132 : return NT_STATUS_OK;
128 : }
129 :
130 132 : NTSTATUS rpccli_create_netlogon_creds_ctx(
131 : struct cli_credentials *creds,
132 : const char *server_computer,
133 : struct messaging_context *msg_ctx,
134 : TALLOC_CTX *mem_ctx,
135 : struct netlogon_creds_cli_context **creds_ctx)
136 : {
137 0 : enum netr_SchannelType sec_chan_type;
138 0 : const char *server_netbios_domain;
139 0 : const char *server_dns_domain;
140 0 : const char *client_account;
141 :
142 132 : sec_chan_type = cli_credentials_get_secure_channel_type(creds);
143 132 : client_account = cli_credentials_get_username(creds);
144 132 : server_netbios_domain = cli_credentials_get_domain(creds);
145 132 : server_dns_domain = cli_credentials_get_realm(creds);
146 :
147 132 : return rpccli_create_netlogon_creds(server_computer,
148 : server_netbios_domain,
149 : server_dns_domain,
150 : client_account,
151 : sec_chan_type,
152 : msg_ctx, mem_ctx,
153 : creds_ctx);
154 : }
155 :
156 132 : NTSTATUS rpccli_setup_netlogon_creds_locked(
157 : struct cli_state *cli,
158 : enum dcerpc_transport_t transport,
159 : struct netlogon_creds_cli_context *creds_ctx,
160 : bool force_reauth,
161 : struct cli_credentials *cli_creds,
162 : uint32_t *negotiate_flags)
163 : {
164 132 : TALLOC_CTX *frame = talloc_stackframe();
165 132 : struct rpc_pipe_client *netlogon_pipe = NULL;
166 132 : struct netlogon_creds_CredentialState *creds = NULL;
167 132 : uint8_t num_nt_hashes = 0;
168 132 : const struct samr_Password *nt_hashes[2] = { NULL, NULL };
169 132 : uint8_t idx_nt_hashes = 0;
170 0 : NTSTATUS status;
171 132 : const char *remote_name = NULL;
172 132 : const struct sockaddr_storage *remote_sockaddr = NULL;
173 :
174 132 : status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
175 132 : if (NT_STATUS_IS_OK(status)) {
176 49 : const char *action = "using";
177 :
178 49 : if (force_reauth) {
179 16 : action = "overwrite";
180 : }
181 :
182 49 : if (cli != NULL) {
183 47 : remote_name = smbXcli_conn_remote_name(cli->conn);
184 : } else {
185 2 : remote_name = "<UNKNOWN>";
186 : }
187 :
188 49 : DEBUG(5,("%s: %s cached netlogon_creds cli[%s/%s] to %s\n",
189 : __FUNCTION__, action,
190 : creds->account_name, creds->computer_name,
191 : remote_name));
192 49 : if (!force_reauth) {
193 33 : goto done;
194 : }
195 16 : TALLOC_FREE(creds);
196 : }
197 :
198 99 : nt_hashes[0] = cli_credentials_get_nt_hash(cli_creds, talloc_tos());
199 99 : if (nt_hashes[0] == NULL) {
200 0 : TALLOC_FREE(frame);
201 0 : return NT_STATUS_NO_MEMORY;
202 : }
203 99 : num_nt_hashes = 1;
204 :
205 99 : nt_hashes[1] = cli_credentials_get_old_nt_hash(cli_creds,
206 : talloc_tos());
207 99 : if (nt_hashes[1] != NULL) {
208 0 : num_nt_hashes = 2;
209 : }
210 :
211 99 : remote_name = smbXcli_conn_remote_name(cli->conn);
212 99 : remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
213 :
214 99 : status = cli_rpc_pipe_open_noauth_transport(cli,
215 : transport,
216 : &ndr_table_netlogon,
217 : remote_name,
218 : remote_sockaddr,
219 : &netlogon_pipe);
220 99 : if (!NT_STATUS_IS_OK(status)) {
221 0 : DEBUG(5,("%s: failed to open noauth netlogon connection to %s - %s\n",
222 : __FUNCTION__,
223 : remote_name,
224 : nt_errstr(status)));
225 0 : TALLOC_FREE(frame);
226 0 : return status;
227 : }
228 99 : talloc_steal(frame, netlogon_pipe);
229 :
230 99 : status = netlogon_creds_cli_auth(creds_ctx,
231 99 : netlogon_pipe->binding_handle,
232 : num_nt_hashes,
233 : nt_hashes,
234 : &idx_nt_hashes);
235 99 : if (!NT_STATUS_IS_OK(status)) {
236 7 : TALLOC_FREE(frame);
237 7 : return status;
238 : }
239 :
240 92 : status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
241 92 : if (!NT_STATUS_IS_OK(status)) {
242 0 : TALLOC_FREE(frame);
243 0 : return NT_STATUS_INTERNAL_ERROR;
244 : }
245 :
246 92 : DEBUG(5,("%s: using new netlogon_creds cli[%s/%s] to %s\n",
247 : __FUNCTION__,
248 : creds->account_name, creds->computer_name,
249 : remote_name));
250 :
251 125 : done:
252 125 : if (negotiate_flags != NULL) {
253 0 : *negotiate_flags = creds->negotiate_flags;
254 : }
255 :
256 125 : TALLOC_FREE(frame);
257 125 : return NT_STATUS_OK;
258 : }
259 :
260 132 : NTSTATUS rpccli_setup_netlogon_creds(
261 : struct cli_state *cli,
262 : enum dcerpc_transport_t transport,
263 : struct netlogon_creds_cli_context *creds_ctx,
264 : bool force_reauth,
265 : struct cli_credentials *cli_creds)
266 : {
267 132 : TALLOC_CTX *frame = talloc_stackframe();
268 0 : struct netlogon_creds_cli_lck *lck;
269 0 : NTSTATUS status;
270 :
271 132 : status = netlogon_creds_cli_lck(
272 : creds_ctx, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
273 : frame, &lck);
274 132 : if (!NT_STATUS_IS_OK(status)) {
275 0 : DBG_WARNING("netlogon_creds_cli_lck failed: %s\n",
276 : nt_errstr(status));
277 0 : TALLOC_FREE(frame);
278 0 : return status;
279 : }
280 :
281 132 : status = rpccli_setup_netlogon_creds_locked(
282 : cli, transport, creds_ctx, force_reauth, cli_creds, NULL);
283 :
284 132 : TALLOC_FREE(frame);
285 :
286 132 : return status;
287 : }
288 :
289 0 : NTSTATUS rpccli_connect_netlogon(
290 : struct cli_state *cli,
291 : enum dcerpc_transport_t transport,
292 : struct netlogon_creds_cli_context *creds_ctx,
293 : bool force_reauth,
294 : struct cli_credentials *trust_creds,
295 : struct rpc_pipe_client **_rpccli)
296 : {
297 0 : TALLOC_CTX *frame = talloc_stackframe();
298 0 : struct netlogon_creds_CredentialState *creds = NULL;
299 0 : enum netlogon_creds_cli_lck_type lck_type;
300 0 : enum netr_SchannelType sec_chan_type;
301 0 : struct netlogon_creds_cli_lck *lck = NULL;
302 0 : uint32_t negotiate_flags;
303 0 : uint8_t found_session_key[16] = {0};
304 0 : bool found_existing_creds = false;
305 0 : bool do_serverauth;
306 0 : struct rpc_pipe_client *rpccli;
307 0 : NTSTATUS status;
308 0 : bool retry = false;
309 0 : const char *remote_name = NULL;
310 0 : const struct sockaddr_storage *remote_sockaddr = NULL;
311 :
312 0 : sec_chan_type = cli_credentials_get_secure_channel_type(trust_creds);
313 0 : if (sec_chan_type == SEC_CHAN_NULL) {
314 0 : DBG_ERR("secure_channel_type gave SEC_CHAN_NULL\n");
315 0 : status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
316 0 : goto fail;
317 : }
318 :
319 0 : again:
320 :
321 : /*
322 : * See whether we can use existing netlogon_creds or
323 : * whether we have to serverauthenticate.
324 : */
325 0 : status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
326 :
327 0 : if (NT_STATUS_IS_OK(status)) {
328 0 : bool cmp = mem_equal_const_time(found_session_key,
329 0 : creds->session_key,
330 : sizeof(found_session_key));
331 0 : found_existing_creds = !cmp;
332 :
333 0 : memcpy(found_session_key,
334 0 : creds->session_key,
335 : sizeof(found_session_key));
336 :
337 0 : TALLOC_FREE(creds);
338 : }
339 :
340 0 : lck_type = (force_reauth || !found_existing_creds) ?
341 0 : NETLOGON_CREDS_CLI_LCK_EXCLUSIVE :
342 : NETLOGON_CREDS_CLI_LCK_SHARED;
343 :
344 0 : status = netlogon_creds_cli_lck(creds_ctx, lck_type, frame, &lck);
345 0 : if (!NT_STATUS_IS_OK(status)) {
346 0 : DBG_DEBUG("netlogon_creds_cli_lck failed: %s\n",
347 : nt_errstr(status));
348 0 : goto fail;
349 : }
350 :
351 0 : if (!found_existing_creds) {
352 : /*
353 : * Try to find creds under the lock again. Someone
354 : * else might have done it for us.
355 : */
356 0 : status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
357 :
358 0 : if (NT_STATUS_IS_OK(status)) {
359 0 : bool cmp = mem_equal_const_time(found_session_key,
360 0 : creds->session_key,
361 : sizeof(found_session_key));
362 0 : found_existing_creds = !cmp;
363 :
364 0 : memcpy(found_session_key, creds->session_key,
365 : sizeof(found_session_key));
366 :
367 0 : TALLOC_FREE(creds);
368 : }
369 : }
370 :
371 0 : remote_name = smbXcli_conn_remote_name(cli->conn);
372 0 : remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
373 :
374 0 : do_serverauth = force_reauth || !found_existing_creds;
375 :
376 0 : if (!do_serverauth) {
377 : /*
378 : * Do the quick schannel bind without a reauth
379 : */
380 0 : status = cli_rpc_pipe_open_bind_schannel(cli,
381 : &ndr_table_netlogon,
382 : transport,
383 : creds_ctx,
384 : remote_name,
385 : remote_sockaddr,
386 : &rpccli);
387 0 : if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
388 0 : DBG_DEBUG("Retrying with serverauthenticate\n");
389 0 : TALLOC_FREE(lck);
390 0 : retry = true;
391 0 : goto again;
392 : }
393 0 : if (!NT_STATUS_IS_OK(status)) {
394 0 : DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
395 : "failed: %s\n", nt_errstr(status));
396 0 : goto fail;
397 : }
398 0 : goto done;
399 : }
400 :
401 0 : if (cli_credentials_is_anonymous(trust_creds)) {
402 0 : DBG_WARNING("get_trust_credential for %s only gave anonymous,"
403 : "unable to negotiate NETLOGON credentials\n",
404 : netlogon_creds_cli_debug_string(
405 : creds_ctx, frame));
406 0 : status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
407 0 : goto fail;
408 : }
409 :
410 0 : status = rpccli_setup_netlogon_creds_locked(
411 : cli, transport, creds_ctx, true, trust_creds,
412 : &negotiate_flags);
413 0 : if (!NT_STATUS_IS_OK(status)) {
414 0 : DBG_DEBUG("rpccli_setup_netlogon_creds failed for %s, "
415 : "unable to setup NETLOGON credentials: %s\n",
416 : netlogon_creds_cli_debug_string(
417 : creds_ctx, frame),
418 : nt_errstr(status));
419 0 : goto fail;
420 : }
421 :
422 0 : if (!(negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
423 0 : if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
424 0 : status = NT_STATUS_DOWNGRADE_DETECTED;
425 0 : DBG_WARNING("Unwilling to make connection to %s"
426 : "without connection level security, "
427 : "must set 'winbind sealed pipes = false'"
428 : " and 'require strong key = false' "
429 : "to proceed: %s\n",
430 : netlogon_creds_cli_debug_string(
431 : creds_ctx, frame),
432 : nt_errstr(status));
433 0 : goto fail;
434 : }
435 :
436 0 : status = cli_rpc_pipe_open_noauth_transport(cli,
437 : transport,
438 : &ndr_table_netlogon,
439 : remote_name,
440 : remote_sockaddr,
441 : &rpccli);
442 0 : if (!NT_STATUS_IS_OK(status)) {
443 0 : DBG_DEBUG("cli_rpc_pipe_open_noauth_transport "
444 : "failed: %s\n", nt_errstr(status));
445 0 : goto fail;
446 : }
447 0 : goto done;
448 : }
449 :
450 0 : status = cli_rpc_pipe_open_bind_schannel(cli,
451 : &ndr_table_netlogon,
452 : transport,
453 : creds_ctx,
454 : remote_name,
455 : remote_sockaddr,
456 : &rpccli);
457 0 : if (!NT_STATUS_IS_OK(status)) {
458 0 : DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
459 : "failed: %s\n", nt_errstr(status));
460 0 : goto fail;
461 : }
462 :
463 0 : status = netlogon_creds_cli_check(creds_ctx, rpccli->binding_handle,
464 : NULL);
465 0 : if (!NT_STATUS_IS_OK(status)) {
466 0 : DBG_WARNING("netlogon_creds_cli_check failed: %s\n",
467 : nt_errstr(status));
468 0 : goto fail;
469 : }
470 :
471 0 : done:
472 0 : *_rpccli = rpccli;
473 0 : status = NT_STATUS_OK;
474 0 : fail:
475 0 : ZERO_STRUCT(found_session_key);
476 0 : TALLOC_FREE(lck);
477 0 : TALLOC_FREE(frame);
478 0 : return status;
479 : }
480 :
481 : /* Logon domain user */
482 :
483 42 : NTSTATUS rpccli_netlogon_password_logon(
484 : struct netlogon_creds_cli_context *creds_ctx,
485 : struct dcerpc_binding_handle *binding_handle,
486 : TALLOC_CTX *mem_ctx,
487 : uint32_t logon_parameters,
488 : const char *domain,
489 : const char *username,
490 : const char *password,
491 : const char *workstation,
492 : const uint64_t logon_id,
493 : enum netr_LogonInfoClass logon_type,
494 : uint8_t *authoritative,
495 : uint32_t *flags,
496 : uint16_t *_validation_level,
497 : union netr_Validation **_validation)
498 : {
499 42 : TALLOC_CTX *frame = talloc_stackframe();
500 0 : NTSTATUS status;
501 0 : union netr_LogonLevel *logon;
502 42 : uint16_t validation_level = 0;
503 42 : union netr_Validation *validation = NULL;
504 42 : char *workstation_slash = NULL;
505 :
506 0 : unsigned char local_nt_response[24];
507 0 : unsigned char local_lm_response[24];
508 42 : struct samr_Password lmpassword = {.hash = {0}};
509 42 : struct samr_Password ntpassword = {.hash = {0}};
510 42 : struct netr_ChallengeResponse lm = {0};
511 42 : struct netr_ChallengeResponse nt = {0};
512 :
513 42 : logon = talloc_zero(frame, union netr_LogonLevel);
514 42 : if (logon == NULL) {
515 0 : TALLOC_FREE(frame);
516 0 : return NT_STATUS_NO_MEMORY;
517 : }
518 :
519 42 : if (workstation == NULL) {
520 20 : workstation = lp_netbios_name();
521 : }
522 :
523 42 : workstation_slash = talloc_asprintf(frame, "\\\\%s", workstation);
524 42 : if (workstation_slash == NULL) {
525 0 : TALLOC_FREE(frame);
526 0 : return NT_STATUS_NO_MEMORY;
527 : }
528 :
529 : /* Initialise input parameters */
530 :
531 42 : switch (logon_type) {
532 6 : case NetlogonInteractiveInformation:
533 : case NetlogonInteractiveTransitiveInformation: {
534 :
535 0 : struct netr_PasswordInfo *password_info;
536 :
537 :
538 6 : password_info = talloc_zero(frame, struct netr_PasswordInfo);
539 6 : if (password_info == NULL) {
540 0 : TALLOC_FREE(frame);
541 0 : return NT_STATUS_NO_MEMORY;
542 : }
543 :
544 6 : nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash);
545 :
546 6 : password_info->identity_info.domain_name.string = domain;
547 6 : password_info->identity_info.parameter_control = logon_parameters;
548 6 : password_info->identity_info.logon_id = logon_id;
549 6 : password_info->identity_info.account_name.string = username;
550 6 : password_info->identity_info.workstation.string = workstation_slash;
551 :
552 6 : password_info->lmpassword = lmpassword;
553 6 : password_info->ntpassword = ntpassword;
554 :
555 6 : logon->password = password_info;
556 :
557 6 : break;
558 : }
559 36 : case NetlogonNetworkInformation:
560 : case NetlogonNetworkTransitiveInformation: {
561 0 : struct netr_NetworkInfo *network_info;
562 0 : uint8_t chal[8];
563 0 : int rc;
564 :
565 36 : ZERO_STRUCT(lm);
566 36 : ZERO_STRUCT(nt);
567 :
568 36 : network_info = talloc_zero(frame, struct netr_NetworkInfo);
569 36 : if (network_info == NULL) {
570 0 : TALLOC_FREE(frame);
571 0 : return NT_STATUS_NO_MEMORY;
572 : }
573 :
574 36 : generate_random_buffer(chal, 8);
575 :
576 36 : SMBencrypt(password, chal, local_lm_response);
577 36 : rc = SMBNTencrypt(password, chal, local_nt_response);
578 36 : if (rc != 0) {
579 0 : TALLOC_FREE(frame);
580 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
581 : }
582 :
583 36 : lm.length = 24;
584 36 : lm.data = local_lm_response;
585 :
586 36 : nt.length = 24;
587 36 : nt.data = local_nt_response;
588 :
589 36 : network_info->identity_info.domain_name.string = domain;
590 36 : network_info->identity_info.parameter_control = logon_parameters;
591 36 : network_info->identity_info.logon_id = logon_id;
592 36 : network_info->identity_info.account_name.string = username;
593 36 : network_info->identity_info.workstation.string = workstation_slash;
594 :
595 36 : memcpy(network_info->challenge, chal, 8);
596 36 : network_info->nt = nt;
597 36 : network_info->lm = lm;
598 :
599 36 : logon->network = network_info;
600 :
601 36 : break;
602 : }
603 0 : default:
604 0 : DEBUG(0, ("switch value %d not supported\n",
605 : logon_type));
606 0 : TALLOC_FREE(frame);
607 0 : return NT_STATUS_INVALID_INFO_CLASS;
608 : }
609 :
610 42 : status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
611 : binding_handle,
612 : logon_type,
613 : logon,
614 : mem_ctx,
615 : &validation_level,
616 : &validation,
617 : authoritative,
618 : flags);
619 42 : if (!NT_STATUS_IS_OK(status)) {
620 12 : TALLOC_FREE(frame);
621 12 : return status;
622 : }
623 :
624 30 : TALLOC_FREE(frame);
625 30 : *_validation_level = validation_level;
626 30 : *_validation = validation;
627 :
628 30 : return NT_STATUS_OK;
629 : }
630 :
631 : /**
632 : * Logon domain user with an 'network' SAM logon
633 : *
634 : * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
635 : **/
636 :
637 :
638 0 : NTSTATUS rpccli_netlogon_network_logon(
639 : struct netlogon_creds_cli_context *creds_ctx,
640 : struct dcerpc_binding_handle *binding_handle,
641 : TALLOC_CTX *mem_ctx,
642 : uint32_t logon_parameters,
643 : const char *username,
644 : const char *domain,
645 : const char *workstation,
646 : const uint64_t logon_id,
647 : DATA_BLOB chal,
648 : DATA_BLOB lm_response,
649 : DATA_BLOB nt_response,
650 : enum netr_LogonInfoClass logon_type,
651 : uint8_t *authoritative,
652 : uint32_t *flags,
653 : uint16_t *_validation_level,
654 : union netr_Validation **_validation)
655 : {
656 0 : NTSTATUS status;
657 0 : const char *workstation_name_slash;
658 0 : union netr_LogonLevel *logon = NULL;
659 0 : struct netr_NetworkInfo *network_info;
660 0 : uint16_t validation_level = 0;
661 0 : union netr_Validation *validation = NULL;
662 0 : struct netr_ChallengeResponse lm;
663 0 : struct netr_ChallengeResponse nt;
664 :
665 0 : *_validation = NULL;
666 :
667 0 : ZERO_STRUCT(lm);
668 0 : ZERO_STRUCT(nt);
669 :
670 0 : switch (logon_type) {
671 0 : case NetlogonNetworkInformation:
672 : case NetlogonNetworkTransitiveInformation:
673 0 : break;
674 0 : default:
675 0 : DEBUG(0, ("switch value %d not supported\n",
676 : logon_type));
677 0 : return NT_STATUS_INVALID_INFO_CLASS;
678 : }
679 :
680 0 : logon = talloc_zero(mem_ctx, union netr_LogonLevel);
681 0 : if (!logon) {
682 0 : return NT_STATUS_NO_MEMORY;
683 : }
684 :
685 0 : network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo);
686 0 : if (!network_info) {
687 0 : return NT_STATUS_NO_MEMORY;
688 : }
689 :
690 0 : if (workstation == NULL) {
691 0 : workstation = lp_netbios_name();
692 : }
693 :
694 0 : if (workstation[0] != '\\' && workstation[1] != '\\') {
695 0 : workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
696 : } else {
697 0 : workstation_name_slash = workstation;
698 : }
699 :
700 0 : if (!workstation_name_slash) {
701 0 : DEBUG(0, ("talloc_asprintf failed!\n"));
702 0 : return NT_STATUS_NO_MEMORY;
703 : }
704 :
705 : /* Initialise input parameters */
706 :
707 0 : lm.data = lm_response.data;
708 0 : lm.length = lm_response.length;
709 0 : nt.data = nt_response.data;
710 0 : nt.length = nt_response.length;
711 :
712 0 : network_info->identity_info.domain_name.string = domain;
713 0 : network_info->identity_info.parameter_control = logon_parameters;
714 0 : network_info->identity_info.logon_id = logon_id;
715 0 : network_info->identity_info.account_name.string = username;
716 0 : network_info->identity_info.workstation.string = workstation_name_slash;
717 :
718 0 : if (chal.length != 8) {
719 0 : DBG_WARNING("Invalid challenge length %zd\n", chal.length);
720 0 : return NT_STATUS_INVALID_PARAMETER;
721 : }
722 :
723 0 : memcpy(network_info->challenge, chal.data, chal.length);
724 0 : network_info->nt = nt;
725 0 : network_info->lm = lm;
726 :
727 0 : logon->network = network_info;
728 :
729 : /* Marshall data and send request */
730 :
731 0 : status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
732 : binding_handle,
733 : logon_type,
734 : logon,
735 : mem_ctx,
736 : &validation_level,
737 : &validation,
738 : authoritative,
739 : flags);
740 0 : if (!NT_STATUS_IS_OK(status)) {
741 0 : return status;
742 : }
743 :
744 0 : *_validation_level = validation_level;
745 0 : *_validation = validation;
746 :
747 0 : return NT_STATUS_OK;
748 : }
749 :
750 0 : NTSTATUS rpccli_netlogon_interactive_logon(
751 : struct netlogon_creds_cli_context *creds_ctx,
752 : struct dcerpc_binding_handle *binding_handle,
753 : TALLOC_CTX *mem_ctx,
754 : uint32_t logon_parameters,
755 : const char *username,
756 : const char *domain,
757 : const char *workstation,
758 : const uint64_t logon_id,
759 : DATA_BLOB lm_hash,
760 : DATA_BLOB nt_hash,
761 : enum netr_LogonInfoClass logon_type,
762 : uint8_t *authoritative,
763 : uint32_t *flags,
764 : uint16_t *_validation_level,
765 : union netr_Validation **_validation)
766 : {
767 0 : TALLOC_CTX *frame = talloc_stackframe();
768 0 : NTSTATUS status;
769 0 : const char *workstation_name_slash;
770 0 : union netr_LogonLevel *logon = NULL;
771 0 : struct netr_PasswordInfo *password_info = NULL;
772 0 : uint16_t validation_level = 0;
773 0 : union netr_Validation *validation = NULL;
774 0 : struct netr_ChallengeResponse lm;
775 0 : struct netr_ChallengeResponse nt;
776 :
777 0 : *_validation = NULL;
778 :
779 0 : ZERO_STRUCT(lm);
780 0 : ZERO_STRUCT(nt);
781 :
782 0 : switch (logon_type) {
783 0 : case NetlogonInteractiveInformation:
784 : case NetlogonInteractiveTransitiveInformation:
785 0 : break;
786 0 : default:
787 0 : DEBUG(0, ("switch value %d not supported\n",
788 : logon_type));
789 0 : TALLOC_FREE(frame);
790 0 : return NT_STATUS_INVALID_INFO_CLASS;
791 : }
792 :
793 0 : logon = talloc_zero(mem_ctx, union netr_LogonLevel);
794 0 : if (logon == NULL) {
795 0 : TALLOC_FREE(frame);
796 0 : return NT_STATUS_NO_MEMORY;
797 : }
798 :
799 0 : password_info = talloc_zero(logon, struct netr_PasswordInfo);
800 0 : if (password_info == NULL) {
801 0 : TALLOC_FREE(frame);
802 0 : return NT_STATUS_NO_MEMORY;
803 : }
804 :
805 0 : if (workstation[0] != '\\' && workstation[1] != '\\') {
806 0 : workstation_name_slash = talloc_asprintf(frame, "\\\\%s", workstation);
807 : } else {
808 0 : workstation_name_slash = workstation;
809 : }
810 :
811 0 : if (workstation_name_slash == NULL) {
812 0 : TALLOC_FREE(frame);
813 0 : return NT_STATUS_NO_MEMORY;
814 : }
815 :
816 : /* Initialise input parameters */
817 :
818 0 : password_info->identity_info.domain_name.string = domain;
819 0 : password_info->identity_info.parameter_control = logon_parameters;
820 0 : password_info->identity_info.logon_id = logon_id;
821 0 : password_info->identity_info.account_name.string = username;
822 0 : password_info->identity_info.workstation.string = workstation_name_slash;
823 :
824 0 : if (nt_hash.length != sizeof(password_info->ntpassword.hash)) {
825 0 : TALLOC_FREE(frame);
826 0 : return NT_STATUS_INVALID_PARAMETER;
827 : }
828 0 : memcpy(password_info->ntpassword.hash, nt_hash.data, nt_hash.length);
829 0 : if (lm_hash.length != 0) {
830 0 : if (lm_hash.length != sizeof(password_info->lmpassword.hash)) {
831 0 : TALLOC_FREE(frame);
832 0 : return NT_STATUS_INVALID_PARAMETER;
833 : }
834 0 : memcpy(password_info->lmpassword.hash, lm_hash.data, lm_hash.length);
835 : }
836 :
837 0 : logon->password = password_info;
838 :
839 : /* Marshall data and send request */
840 :
841 0 : status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
842 : binding_handle,
843 : logon_type,
844 : logon,
845 : mem_ctx,
846 : &validation_level,
847 : &validation,
848 : authoritative,
849 : flags);
850 0 : if (!NT_STATUS_IS_OK(status)) {
851 0 : TALLOC_FREE(frame);
852 0 : return status;
853 : }
854 :
855 0 : *_validation_level = validation_level;
856 0 : *_validation = validation;
857 :
858 0 : TALLOC_FREE(frame);
859 0 : return NT_STATUS_OK;
860 : }
|