source: branches/samba-3.0/source/rpc_client/cli_netlogon.c

Last change on this file was 165, checked in by Paul Smedley, 17 years ago

Add 'missing' 3.0.34 diffs

File size: 29.2 KB
Line 
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
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/* LSA Request Challenge. Sends our challenge to server, then gets
26 server response. These are used to generate the credentials.
27 The sent and received challenges are stored in the netlog pipe
28 private data. Only call this via rpccli_netlogon_setup_creds(). JRA.
29*/
30
31static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli,
32 TALLOC_CTX *mem_ctx,
33 const char *server_name,
34 const char *clnt_name,
35 const DOM_CHAL *clnt_chal_in,
36 DOM_CHAL *srv_chal_out)
37{
38 prs_struct qbuf, rbuf;
39 NET_Q_REQ_CHAL q;
40 NET_R_REQ_CHAL r;
41 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
42
43 /* create and send a MSRPC command with api NET_REQCHAL */
44
45 DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
46 clnt_name, server_name));
47
48 /* store the parameters */
49 init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in);
50
51 /* Marshall data and send request */
52 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL,
53 q, r,
54 qbuf, rbuf,
55 net_io_q_req_chal,
56 net_io_r_req_chal,
57 NT_STATUS_UNSUCCESSFUL);
58
59 result = r.status;
60
61 /* Return result */
62
63 if (NT_STATUS_IS_OK(result)) {
64 /* Store the returned server challenge. */
65 *srv_chal_out = r.srv_chal;
66 }
67
68 return result;
69}
70
71#if 0
72/****************************************************************************
73LSA Authenticate 2
74
75Send the client credential, receive back a server credential.
76Ensure that the server credential returned matches the session key
77encrypt of the server challenge originally received. JRA.
78****************************************************************************/
79
80 NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
81 uint16 sec_chan,
82 uint32 *neg_flags, DOM_CHAL *srv_chal)
83{
84 prs_struct qbuf, rbuf;
85 NET_Q_AUTH_2 q;
86 NET_R_AUTH_2 r;
87 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
88 fstring machine_acct;
89
90 if ( sec_chan == SEC_CHAN_DOMAIN )
91 fstr_sprintf( machine_acct, "%s$", lp_workgroup() );
92 else
93 fstrcpy( machine_acct, cli->mach_acct );
94
95 /* create and send a MSRPC command with api NET_AUTH2 */
96
97 DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
98 cli->srv_name_slash, machine_acct, sec_chan, global_myname(),
99 credstr(cli->clnt_cred.challenge.data), *neg_flags));
100
101 /* store the parameters */
102
103 init_q_auth_2(&q, cli->srv_name_slash, machine_acct,
104 sec_chan, global_myname(), &cli->clnt_cred.challenge,
105 *neg_flags);
106
107 /* turn parameters into data stream */
108
109 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
110 q, r,
111 qbuf, rbuf,
112 net_io_q_auth_2,
113 net_io_r_auth_2,
114 NT_STATUS_UNSUCCESSFUL);
115
116 result = r.status;
117
118 if (NT_STATUS_IS_OK(result)) {
119 UTIME zerotime;
120
121 /*
122 * Check the returned value using the initial
123 * server received challenge.
124 */
125
126 zerotime.time = 0;
127 if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
128
129 /*
130 * Server replied with bad credential. Fail.
131 */
132 DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
133password ?).\n", cli->cli->desthost ));
134 return NT_STATUS_ACCESS_DENIED;
135 }
136 *neg_flags = r.srv_flgs.neg_flags;
137 }
138
139 return result;
140}
141#endif
142
143/****************************************************************************
144 LSA Authenticate 2
145
146 Send the client credential, receive back a server credential.
147 The caller *must* ensure that the server credential returned matches the session key
148 encrypt of the server challenge originally received. JRA.
149****************************************************************************/
150
151static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
152 TALLOC_CTX *mem_ctx,
153 const char *server_name,
154 const char *account_name,
155 uint16 sec_chan_type,
156 const char *computer_name,
157 uint32 *neg_flags_inout,
158 const DOM_CHAL *clnt_chal_in,
159 DOM_CHAL *srv_chal_out)
160{
161 prs_struct qbuf, rbuf;
162 NET_Q_AUTH_2 q;
163 NET_R_AUTH_2 r;
164 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
165
166 /* create and send a MSRPC command with api NET_AUTH2 */
167
168 DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
169 server_name, account_name, sec_chan_type, computer_name,
170 *neg_flags_inout));
171
172 /* store the parameters */
173
174 init_q_auth_2(&q, server_name, account_name, sec_chan_type,
175 computer_name, clnt_chal_in, *neg_flags_inout);
176
177 /* turn parameters into data stream */
178
179 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
180 q, r,
181 qbuf, rbuf,
182 net_io_q_auth_2,
183 net_io_r_auth_2,
184 NT_STATUS_UNSUCCESSFUL);
185
186 result = r.status;
187
188 *neg_flags_inout = r.srv_flgs.neg_flags;
189
190 if (NT_STATUS_IS_OK(result)) {
191 *srv_chal_out = r.srv_chal;
192 }
193
194 return result;
195}
196
197#if 0 /* not currebntly used */
198/****************************************************************************
199 LSA Authenticate 3
200
201 Send the client credential, receive back a server credential.
202 The caller *must* ensure that the server credential returned matches the session key
203 encrypt of the server challenge originally received. JRA.
204****************************************************************************/
205
206static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli,
207 TALLOC_CTX *mem_ctx,
208 const char *server_name,
209 const char *account_name,
210 uint16 sec_chan_type,
211 const char *computer_name,
212 uint32 *neg_flags_inout,
213 const DOM_CHAL *clnt_chal_in,
214 DOM_CHAL *srv_chal_out)
215{
216 prs_struct qbuf, rbuf;
217 NET_Q_AUTH_3 q;
218 NET_R_AUTH_3 r;
219 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
220
221 /* create and send a MSRPC command with api NET_AUTH2 */
222
223 DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
224 server_name, account_name, sec_chan_type, computer_name,
225 credstr(clnt_chal_in->data), *neg_flags_inout));
226
227 /* store the parameters */
228 init_q_auth_3(&q, server_name, account_name, sec_chan_type,
229 computer_name, clnt_chal_in, *neg_flags_inout);
230
231 /* turn parameters into data stream */
232
233 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3,
234 q, r,
235 qbuf, rbuf,
236 net_io_q_auth_3,
237 net_io_r_auth_3,
238 NT_STATUS_UNSUCCESSFUL);
239
240 if (NT_STATUS_IS_OK(result)) {
241 *srv_chal_out = r.srv_chal;
242 *neg_flags_inout = r.srv_flgs.neg_flags;
243 }
244
245 return result;
246}
247#endif /* not currebntly used */
248
249/****************************************************************************
250 Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
251 credentials chain. Stores the credentials in the struct dcinfo in the
252 netlogon pipe struct.
253****************************************************************************/
254
255NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
256 const char *server_name,
257 const char *domain,
258 const char *clnt_name,
259 const char *machine_account,
260 const unsigned char machine_pwd[16],
261 uint32 sec_chan_type,
262 uint32 *neg_flags_inout)
263{
264 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
265 DOM_CHAL clnt_chal_send;
266 DOM_CHAL srv_chal_recv;
267 struct dcinfo *dc;
268 bool retried = false;
269
270 SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
271
272 dc = cli->dc;
273 if (!dc) {
274 return NT_STATUS_INVALID_PARAMETER;
275 }
276
277 /* Ensure we don't reuse any of this state. */
278 ZERO_STRUCTP(dc);
279
280 /* Store the machine account password we're going to use. */
281 memcpy(dc->mach_pw, machine_pwd, 16);
282
283 fstrcpy(dc->remote_machine, "\\\\");
284 fstrcat(dc->remote_machine, server_name);
285
286 fstrcpy(dc->domain, domain);
287
288 fstr_sprintf( dc->mach_acct, "%s$", machine_account);
289
290 again:
291 /* Create the client challenge. */
292 generate_random_buffer(clnt_chal_send.data, 8);
293
294 /* Get the server challenge. */
295 result = rpccli_net_req_chal(cli,
296 cli->mem_ctx,
297 dc->remote_machine,
298 clnt_name,
299 &clnt_chal_send,
300 &srv_chal_recv);
301
302 if (!NT_STATUS_IS_OK(result)) {
303 return result;
304 }
305
306 /* Calculate the session key and client credentials */
307 creds_client_init(*neg_flags_inout,
308 dc,
309 &clnt_chal_send,
310 &srv_chal_recv,
311 machine_pwd,
312 &clnt_chal_send);
313
314 /*
315 * Send client auth-2 challenge and receive server repy.
316 */
317
318 result = rpccli_net_auth2(cli,
319 cli->mem_ctx,
320 dc->remote_machine,
321 dc->mach_acct,
322 sec_chan_type,
323 clnt_name,
324 neg_flags_inout,
325 &clnt_chal_send, /* input. */
326 &srv_chal_recv); /* output */
327
328 /* we might be talking to NT4, so let's downgrade in that case and retry
329 * with the returned neg_flags - gd */
330
331 if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) && !retried) {
332 retried = true;
333 goto again;
334 }
335
336 if (!NT_STATUS_IS_OK(result)) {
337 return result;
338 }
339
340 /*
341 * Check the returned value using the initial
342 * server received challenge.
343 */
344
345 if (!creds_client_check(dc, &srv_chal_recv)) {
346 /*
347 * Server replied with bad credential. Fail.
348 */
349 DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
350 "replied with bad credential\n",
351 cli->cli->desthost ));
352 return NT_STATUS_ACCESS_DENIED;
353 }
354
355 DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
356 "chain established.\n",
357 cli->cli->desthost ));
358
359 return NT_STATUS_OK;
360}
361
362/* Logon Control 2 */
363
364NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
365 uint32 query_level)
366{
367 prs_struct qbuf, rbuf;
368 NET_Q_LOGON_CTRL2 q;
369 NET_R_LOGON_CTRL2 r;
370 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
371 fstring server;
372
373 ZERO_STRUCT(q);
374 ZERO_STRUCT(r);
375
376 /* Initialise input parameters */
377
378 slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
379 init_net_q_logon_ctrl2(&q, server, query_level);
380
381 /* Marshall data and send request */
382
383 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
384 q, r,
385 qbuf, rbuf,
386 net_io_q_logon_ctrl2,
387 net_io_r_logon_ctrl2,
388 NT_STATUS_UNSUCCESSFUL);
389
390 result = r.status;
391 return result;
392}
393
394/* GetAnyDCName */
395
396WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli,
397 TALLOC_CTX *mem_ctx, const char *mydcname,
398 const char *domainname, fstring newdcname)
399{
400 prs_struct qbuf, rbuf;
401 NET_Q_GETANYDCNAME q;
402 NET_R_GETANYDCNAME r;
403 WERROR result;
404 fstring mydcname_slash;
405
406 ZERO_STRUCT(q);
407 ZERO_STRUCT(r);
408
409 /* Initialise input parameters */
410
411 slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname);
412 init_net_q_getanydcname(&q, mydcname_slash, domainname);
413
414 /* Marshall data and send request */
415
416 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME,
417 q, r,
418 qbuf, rbuf,
419 net_io_q_getanydcname,
420 net_io_r_getanydcname,
421 WERR_GENERAL_FAILURE);
422
423 result = r.status;
424
425 if (W_ERROR_IS_OK(result)) {
426 rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
427 }
428
429 return result;
430}
431
432static WERROR pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX *mem_ctx,
433 struct DS_DOMAIN_CONTROLLER_INFO **info_out,
434 NET_R_DSR_GETDCNAME *r)
435{
436 struct DS_DOMAIN_CONTROLLER_INFO *info;
437
438 info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO);
439 if (!info) {
440 return WERR_NOMEM;
441 }
442
443 if (&r->uni_dc_unc) {
444
445 char *tmp;
446 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_unc);
447 if (tmp == NULL) {
448 return WERR_GENERAL_FAILURE;
449 }
450 if (*tmp == '\\') tmp += 1;
451 if (*tmp == '\\') tmp += 1;
452
453 info->domain_controller_name = talloc_strdup(mem_ctx, tmp);
454 if (info->domain_controller_name == NULL) {
455 return WERR_GENERAL_FAILURE;
456 }
457 }
458
459 if (&r->uni_dc_address) {
460
461 char *tmp;
462 tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_address);
463 if (tmp == NULL) {
464 return WERR_GENERAL_FAILURE;
465 }
466 if (*tmp == '\\') tmp += 1;
467 if (*tmp == '\\') tmp += 1;
468
469 info->domain_controller_address = talloc_strdup(mem_ctx, tmp);
470 if (info->domain_controller_address == NULL) {
471 return WERR_GENERAL_FAILURE;
472 }
473 }
474
475 info->domain_controller_address_type = r->dc_address_type;
476
477 info->domain_guid = talloc_memdup(mem_ctx, &r->domain_guid, sizeof(struct GUID));
478 if (!info->domain_guid) {
479 return WERR_GENERAL_FAILURE;
480 }
481
482 if (&r->uni_domain_name) {
483 info->domain_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_domain_name);
484 if (!info->domain_name) {
485 return WERR_GENERAL_FAILURE;
486 }
487 }
488
489 if (&r->uni_forest_name) {
490 info->dns_forest_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_forest_name);
491 if (!info->dns_forest_name) {
492 return WERR_GENERAL_FAILURE;
493 }
494 }
495
496 info->flags = r->dc_flags;
497
498 if (&r->uni_dc_site_name) {
499 info->dc_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_site_name);
500 if (!info->dc_site_name) {
501 return WERR_GENERAL_FAILURE;
502 }
503 }
504
505 if (&r->uni_client_site_name) {
506 info->client_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_client_site_name);
507 if (!info->client_site_name) {
508 return WERR_GENERAL_FAILURE;
509 }
510 }
511
512 *info_out = info;
513
514 return WERR_OK;
515}
516
517/* Dsr_GetDCName */
518
519WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
520 TALLOC_CTX *mem_ctx,
521 const char *server_name,
522 const char *domain_name,
523 struct GUID *domain_guid,
524 struct GUID *site_guid,
525 uint32_t flags,
526 struct DS_DOMAIN_CONTROLLER_INFO **info_out)
527{
528 prs_struct qbuf, rbuf;
529 NET_Q_DSR_GETDCNAME q;
530 NET_R_DSR_GETDCNAME r;
531 char *tmp_str;
532
533 ZERO_STRUCT(q);
534 ZERO_STRUCT(r);
535
536 /* Initialize input parameters */
537
538 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
539 if (tmp_str == NULL) {
540 return WERR_NOMEM;
541 }
542
543 init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
544 site_guid, flags);
545
546 /* Marshall data and send request */
547
548 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
549 q, r,
550 qbuf, rbuf,
551 net_io_q_dsr_getdcname,
552 net_io_r_dsr_getdcname,
553 WERR_GENERAL_FAILURE);
554
555 if (!W_ERROR_IS_OK(r.result)) {
556 return r.result;
557 }
558
559 r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
560 if (!W_ERROR_IS_OK(r.result)) {
561 return r.result;
562 }
563
564 return WERR_OK;
565}
566
567/* Dsr_GetDCNameEx */
568
569WERROR rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli,
570 TALLOC_CTX *mem_ctx,
571 const char *server_name,
572 const char *domain_name,
573 struct GUID *domain_guid,
574 const char *site_name,
575 uint32_t flags,
576 struct DS_DOMAIN_CONTROLLER_INFO **info_out)
577{
578 prs_struct qbuf, rbuf;
579 NET_Q_DSR_GETDCNAMEEX q;
580 NET_R_DSR_GETDCNAME r;
581 char *tmp_str;
582
583 ZERO_STRUCT(q);
584 ZERO_STRUCT(r);
585
586 /* Initialize input parameters */
587
588 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
589 if (tmp_str == NULL) {
590 return WERR_NOMEM;
591 }
592
593 init_net_q_dsr_getdcnameex(&q, server_name, domain_name, domain_guid,
594 site_name, flags);
595
596 /* Marshall data and send request */
597
598 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX,
599 q, r,
600 qbuf, rbuf,
601 net_io_q_dsr_getdcnameex,
602 net_io_r_dsr_getdcname,
603 WERR_GENERAL_FAILURE);
604
605 if (!W_ERROR_IS_OK(r.result)) {
606 return r.result;
607 }
608
609 r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
610 if (!W_ERROR_IS_OK(r.result)) {
611 return r.result;
612 }
613
614 return WERR_OK;
615}
616
617/* Dsr_GetDCNameEx */
618
619WERROR rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli,
620 TALLOC_CTX *mem_ctx,
621 const char *server_name,
622 const char *client_account,
623 uint32 mask,
624 const char *domain_name,
625 struct GUID *domain_guid,
626 const char *site_name,
627 uint32_t flags,
628 struct DS_DOMAIN_CONTROLLER_INFO **info_out)
629{
630 prs_struct qbuf, rbuf;
631 NET_Q_DSR_GETDCNAMEEX2 q;
632 NET_R_DSR_GETDCNAME r;
633 char *tmp_str;
634
635 ZERO_STRUCT(q);
636 ZERO_STRUCT(r);
637
638 /* Initialize input parameters */
639
640 tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
641 if (tmp_str == NULL) {
642 return WERR_NOMEM;
643 }
644
645 init_net_q_dsr_getdcnameex2(&q, server_name, domain_name, client_account,
646 mask, domain_guid, site_name, flags);
647
648 /* Marshall data and send request */
649
650 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX2,
651 q, r,
652 qbuf, rbuf,
653 net_io_q_dsr_getdcnameex2,
654 net_io_r_dsr_getdcname,
655 WERR_GENERAL_FAILURE);
656
657 if (!W_ERROR_IS_OK(r.result)) {
658 return r.result;
659 }
660
661 r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r);
662 if (!W_ERROR_IS_OK(r.result)) {
663 return r.result;
664 }
665
666 return WERR_OK;
667}
668
669
670/* Dsr_GetSiteName */
671
672WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
673 TALLOC_CTX *mem_ctx,
674 const char *computer_name,
675 char **site_name)
676{
677 prs_struct qbuf, rbuf;
678 NET_Q_DSR_GETSITENAME q;
679 NET_R_DSR_GETSITENAME r;
680
681 ZERO_STRUCT(q);
682 ZERO_STRUCT(r);
683
684 /* Initialize input parameters */
685
686 init_net_q_dsr_getsitename(&q, computer_name);
687
688 /* Marshall data and send request */
689
690 CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
691 q, r,
692 qbuf, rbuf,
693 net_io_q_dsr_getsitename,
694 net_io_r_dsr_getsitename,
695 WERR_GENERAL_FAILURE);
696
697 if (!W_ERROR_IS_OK(r.result)) {
698 return r.result;
699 }
700
701 if ((site_name != NULL) &&
702 ((*site_name = rpcstr_pull_unistr2_talloc(
703 mem_ctx, &r.uni_site_name)) == NULL)) {
704 return WERR_GENERAL_FAILURE;
705 }
706
707 return WERR_OK;
708}
709
710
711
712/* Sam synchronisation */
713
714NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
715 uint32 database_id, uint32 next_rid, uint32 *num_deltas,
716 SAM_DELTA_HDR **hdr_deltas,
717 SAM_DELTA_CTR **deltas)
718{
719 prs_struct qbuf, rbuf;
720 NET_Q_SAM_SYNC q;
721 NET_R_SAM_SYNC r;
722 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
723 DOM_CRED clnt_creds;
724 DOM_CRED ret_creds;
725
726 ZERO_STRUCT(q);
727 ZERO_STRUCT(r);
728
729 ZERO_STRUCT(ret_creds);
730
731 /* Initialise input parameters */
732
733 creds_client_step(cli->dc, &clnt_creds);
734
735 init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
736 &clnt_creds, &ret_creds, database_id, next_rid);
737
738 /* Marshall data and send request */
739
740 CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
741 q, r,
742 qbuf, rbuf,
743 net_io_q_sam_sync,
744 net_io_r_sam_sync,
745 NT_STATUS_UNSUCCESSFUL);
746
747 /* Return results */
748
749 result = r.status;
750 *num_deltas = r.num_deltas2;
751 *hdr_deltas = r.hdr_deltas;
752 *deltas = r.deltas;
753
754 if (!NT_STATUS_IS_ERR(result)) {
755 /* Check returned credentials. */
756 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
757 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
758 return NT_STATUS_ACCESS_DENIED;
759 }
760 }
761
762 return result;
763}
764
765/* Sam synchronisation */
766
767NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
768 uint32 database_id, uint64 seqnum,
769 uint32 *num_deltas,
770 SAM_DELTA_HDR **hdr_deltas,
771 SAM_DELTA_CTR **deltas)
772{
773 prs_struct qbuf, rbuf;
774 NET_Q_SAM_DELTAS q;
775 NET_R_SAM_DELTAS r;
776 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
777 DOM_CRED clnt_creds;
778
779 ZERO_STRUCT(q);
780 ZERO_STRUCT(r);
781
782 /* Initialise input parameters */
783
784 creds_client_step(cli->dc, &clnt_creds);
785
786 init_net_q_sam_deltas(&q, cli->dc->remote_machine,
787 global_myname(), &clnt_creds,
788 database_id, seqnum);
789
790 /* Marshall data and send request */
791
792 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
793 q, r,
794 qbuf, rbuf,
795 net_io_q_sam_deltas,
796 net_io_r_sam_deltas,
797 NT_STATUS_UNSUCCESSFUL);
798
799 /* Return results */
800
801 result = r.status;
802 *num_deltas = r.num_deltas2;
803 *hdr_deltas = r.hdr_deltas;
804 *deltas = r.deltas;
805
806 if (!NT_STATUS_IS_ERR(result)) {
807 /* Check returned credentials. */
808 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
809 DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
810 return NT_STATUS_ACCESS_DENIED;
811 }
812 }
813
814 return result;
815}
816
817/* Logon domain user */
818
819NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
820 TALLOC_CTX *mem_ctx,
821 uint32 logon_parameters,
822 const char *domain,
823 const char *username,
824 const char *password,
825 const char *workstation,
826 int logon_type)
827{
828 prs_struct qbuf, rbuf;
829 NET_Q_SAM_LOGON q;
830 NET_R_SAM_LOGON r;
831 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
832 DOM_CRED clnt_creds;
833 DOM_CRED ret_creds;
834 NET_ID_INFO_CTR ctr;
835 NET_USER_INFO_3 user;
836 int validation_level = 3;
837 fstring clnt_name_slash;
838
839 ZERO_STRUCT(q);
840 ZERO_STRUCT(r);
841 ZERO_STRUCT(ret_creds);
842
843 if (workstation) {
844 fstr_sprintf( clnt_name_slash, "\\\\%s", workstation );
845 } else {
846 fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
847 }
848
849 /* Initialise input parameters */
850
851 creds_client_step(cli->dc, &clnt_creds);
852
853 q.validation_level = validation_level;
854
855 ctr.switch_value = logon_type;
856
857 switch (logon_type) {
858 case INTERACTIVE_LOGON_TYPE: {
859 unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
860
861 nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
862
863 init_id_info1(&ctr.auth.id1, domain,
864 logon_parameters, /* param_ctrl */
865 0xdead, 0xbeef, /* LUID? */
866 username, clnt_name_slash,
867 (const char *)cli->dc->sess_key, lm_owf_user_pwd,
868 nt_owf_user_pwd);
869
870 break;
871 }
872 case NET_LOGON_TYPE: {
873 uint8 chal[8];
874 unsigned char local_lm_response[24];
875 unsigned char local_nt_response[24];
876
877 generate_random_buffer(chal, 8);
878
879 SMBencrypt(password, chal, local_lm_response);
880 SMBNTencrypt(password, chal, local_nt_response);
881
882 init_id_info2(&ctr.auth.id2, domain,
883 logon_parameters, /* param_ctrl */
884 0xdead, 0xbeef, /* LUID? */
885 username, clnt_name_slash, chal,
886 local_lm_response, 24, local_nt_response, 24);
887 break;
888 }
889 default:
890 DEBUG(0, ("switch value %d not supported\n",
891 ctr.switch_value));
892 return NT_STATUS_INVALID_INFO_CLASS;
893 }
894
895 r.user = &user;
896
897 init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
898 &clnt_creds, &ret_creds, logon_type,
899 &ctr);
900
901 /* Marshall data and send request */
902
903 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
904 q, r,
905 qbuf, rbuf,
906 net_io_q_sam_logon,
907 net_io_r_sam_logon,
908 NT_STATUS_UNSUCCESSFUL);
909
910 /* Return results */
911
912 result = r.status;
913
914 if (r.buffer_creds) {
915 /* Check returned credentials if present. */
916 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
917 DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
918 return NT_STATUS_ACCESS_DENIED;
919 }
920 }
921
922 return result;
923}
924
925
926/**
927 * Logon domain user with an 'network' SAM logon
928 *
929 * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
930 **/
931
932NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
933 TALLOC_CTX *mem_ctx,
934 uint32 logon_parameters,
935 const char *server,
936 const char *username,
937 const char *domain,
938 const char *workstation,
939 const uint8 chal[8],
940 DATA_BLOB lm_response,
941 DATA_BLOB nt_response,
942 NET_USER_INFO_3 *info3)
943{
944 prs_struct qbuf, rbuf;
945 NET_Q_SAM_LOGON q;
946 NET_R_SAM_LOGON r;
947 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
948 NET_ID_INFO_CTR ctr;
949 int validation_level = 3;
950 const char *workstation_name_slash;
951 const char *server_name_slash;
952 static uint8 zeros[16];
953 DOM_CRED clnt_creds;
954 DOM_CRED ret_creds;
955 int i;
956
957 ZERO_STRUCT(q);
958 ZERO_STRUCT(r);
959 ZERO_STRUCT(ret_creds);
960
961 creds_client_step(cli->dc, &clnt_creds);
962
963 if (server[0] != '\\' && server[1] != '\\') {
964 server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
965 } else {
966 server_name_slash = server;
967 }
968
969 if (workstation[0] != '\\' && workstation[1] != '\\') {
970 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
971 } else {
972 workstation_name_slash = workstation;
973 }
974
975 if (!workstation_name_slash || !server_name_slash) {
976 DEBUG(0, ("talloc_asprintf failed!\n"));
977 return NT_STATUS_NO_MEMORY;
978 }
979
980 /* Initialise input parameters */
981
982 q.validation_level = validation_level;
983
984 ctr.switch_value = NET_LOGON_TYPE;
985
986 init_id_info2(&ctr.auth.id2, domain,
987 logon_parameters, /* param_ctrl */
988 0xdead, 0xbeef, /* LUID? */
989 username, workstation_name_slash, (const uchar*)chal,
990 lm_response.data, lm_response.length, nt_response.data, nt_response.length);
991
992 init_sam_info(&q.sam_id, server_name_slash, global_myname(),
993 &clnt_creds, &ret_creds, NET_LOGON_TYPE,
994 &ctr);
995
996 r.user = info3;
997
998 /* Marshall data and send request */
999
1000 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
1001 q, r,
1002 qbuf, rbuf,
1003 net_io_q_sam_logon,
1004 net_io_r_sam_logon,
1005 NT_STATUS_UNSUCCESSFUL);
1006
1007 if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
1008 SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
1009 } else {
1010 memset(info3->user_sess_key, '\0', 16);
1011 }
1012
1013 if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
1014 SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
1015 } else {
1016 memset(info3->lm_sess_key, '\0', 8);
1017 }
1018
1019 for (i=0; i < 7; i++) {
1020 memset(&info3->unknown[i], '\0', 4);
1021 }
1022
1023 /* Return results */
1024
1025 result = r.status;
1026
1027 if (r.buffer_creds) {
1028 /* Check returned credentials if present. */
1029 if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
1030 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
1031 return NT_STATUS_ACCESS_DENIED;
1032 }
1033 }
1034
1035 return result;
1036}
1037
1038/***************************************************************************
1039LSA Server Password Set.
1040****************************************************************************/
1041
1042NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1043 const char *machine_name, const uint8 hashed_mach_pwd[16])
1044{
1045 prs_struct rbuf;
1046 prs_struct qbuf;
1047 DOM_CRED clnt_creds;
1048 NET_Q_SRV_PWSET q;
1049 NET_R_SRV_PWSET r;
1050 uint16 sec_chan_type = 2;
1051 NTSTATUS result;
1052
1053 creds_client_step(cli->dc, &clnt_creds);
1054
1055 DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
1056 cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
1057
1058 /* store the parameters */
1059 init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
1060 cli->dc->mach_acct, sec_chan_type, machine_name,
1061 &clnt_creds, hashed_mach_pwd);
1062
1063 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
1064 q, r,
1065 qbuf, rbuf,
1066 net_io_q_srv_pwset,
1067 net_io_r_srv_pwset,
1068 NT_STATUS_UNSUCCESSFUL);
1069
1070 result = r.status;
1071
1072 if (!NT_STATUS_IS_OK(result)) {
1073 /* report error code */
1074 DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
1075 }
1076
1077 /* Always check returned credentials. */
1078 if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
1079 DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
1080 return NT_STATUS_ACCESS_DENIED;
1081 }
1082
1083 return result;
1084}
1085
1086/***************************************************************************
1087LSA Server Password Set2.
1088****************************************************************************/
1089
1090NTSTATUS rpccli_net_srv_pwset2(struct rpc_pipe_client *cli,
1091 TALLOC_CTX *mem_ctx,
1092 const char *machine_name,
1093 const char *clear_text_mach_pwd)
1094{
1095 prs_struct rbuf;
1096 prs_struct qbuf;
1097 DOM_CRED clnt_creds;
1098 NET_Q_SRV_PWSET2 q;
1099 NET_R_SRV_PWSET2 r;
1100 uint16 sec_chan_type = 2;
1101 NTSTATUS result;
1102
1103 creds_client_step(cli->dc, &clnt_creds);
1104
1105 DEBUG(4,("cli_net_srv_pwset2: srv:%s acct:%s sc: %d mc: %s\n",
1106 cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
1107
1108 /* store the parameters */
1109 init_q_srv_pwset2(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
1110 cli->dc->mach_acct, sec_chan_type, machine_name,
1111 &clnt_creds, clear_text_mach_pwd);
1112
1113 CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET2,
1114 q, r,
1115 qbuf, rbuf,
1116 net_io_q_srv_pwset2,
1117 net_io_r_srv_pwset2,
1118 NT_STATUS_UNSUCCESSFUL);
1119
1120 result = r.status;
1121
1122 if (!NT_STATUS_IS_OK(result)) {
1123 /* report error code */
1124 DEBUG(0,("cli_net_srv_pwset2: %s\n", nt_errstr(result)));
1125 }
1126
1127 /* Always check returned credentials. */
1128 if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
1129 DEBUG(0,("rpccli_net_srv_pwset2: credentials chain check failed\n"));
1130 return NT_STATUS_ACCESS_DENIED;
1131 }
1132
1133 return result;
1134}
Note: See TracBrowser for help on using the repository browser.