Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Helper routines for net
4 : * Copyright (C) Volker Lendecke 2006
5 : * Copyright (C) Kai Blin 2008
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 3 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, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 :
22 : #include "includes.h"
23 : #include "utils/net.h"
24 : #include "libsmb/namequery.h"
25 : #include "rpc_client/cli_pipe.h"
26 : #include "../librpc/gen_ndr/ndr_lsa_c.h"
27 : #include "rpc_client/cli_lsarpc.h"
28 : #include "../librpc/gen_ndr/ndr_dssetup_c.h"
29 : #include "secrets.h"
30 : #include "../libcli/security/security.h"
31 : #include "libsmb/libsmb.h"
32 : #include "lib/param/param.h"
33 : #include "auth/gensec/gensec.h"
34 : #include "libcli/auth/netlogon_creds_cli.h"
35 : #include "lib/cmdline/cmdline.h"
36 :
37 0 : NTSTATUS net_rpc_lookup_name(struct net_context *c,
38 : TALLOC_CTX *mem_ctx, struct cli_state *cli,
39 : const char *name, const char **ret_domain,
40 : const char **ret_name, struct dom_sid *ret_sid,
41 : enum lsa_SidType *ret_type)
42 : {
43 0 : struct rpc_pipe_client *lsa_pipe = NULL;
44 0 : struct policy_handle pol;
45 0 : NTSTATUS status, result;
46 0 : const char **dom_names;
47 0 : struct dom_sid *sids;
48 0 : enum lsa_SidType *types;
49 0 : struct dcerpc_binding_handle *b;
50 :
51 0 : ZERO_STRUCT(pol);
52 :
53 0 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
54 : &lsa_pipe);
55 0 : if (!NT_STATUS_IS_OK(status)) {
56 0 : d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
57 0 : return status;
58 : }
59 :
60 0 : b = lsa_pipe->binding_handle;
61 :
62 0 : status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
63 : SEC_FLAG_MAXIMUM_ALLOWED,
64 : &pol);
65 0 : if (!NT_STATUS_IS_OK(status)) {
66 0 : d_fprintf(stderr, "open_policy %s: %s\n", _("failed"),
67 : nt_errstr(status));
68 0 : return status;
69 : }
70 :
71 0 : status = rpccli_lsa_lookup_names(lsa_pipe, mem_ctx, &pol, 1,
72 : &name, &dom_names, 1, &sids, &types);
73 :
74 0 : if (!NT_STATUS_IS_OK(status)) {
75 : /* This can happen easily, don't log an error */
76 0 : goto done;
77 : }
78 :
79 0 : if (ret_domain != NULL) {
80 0 : *ret_domain = dom_names[0];
81 : }
82 0 : if (ret_name != NULL) {
83 0 : *ret_name = talloc_strdup(mem_ctx, name);
84 : }
85 0 : if (ret_sid != NULL) {
86 0 : sid_copy(ret_sid, &sids[0]);
87 : }
88 0 : if (ret_type != NULL) {
89 0 : *ret_type = types[0];
90 : }
91 :
92 0 : done:
93 0 : if (is_valid_policy_hnd(&pol)) {
94 0 : dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
95 : }
96 0 : TALLOC_FREE(lsa_pipe);
97 :
98 0 : return status;
99 : }
100 :
101 : /****************************************************************************
102 : Connect to \\server\service.
103 : ****************************************************************************/
104 :
105 876 : NTSTATUS connect_to_service(struct net_context *c,
106 : struct cli_state **cli_ctx,
107 : const struct sockaddr_storage *server_ss,
108 : const char *server_name,
109 : const char *service_name,
110 : const char *service_type)
111 : {
112 0 : NTSTATUS nt_status;
113 876 : int flags = 0;
114 :
115 876 : if (strequal(service_type, "IPC")) {
116 876 : flags |= CLI_FULL_CONNECTION_IPC;
117 : }
118 :
119 876 : nt_status = cli_full_connection_creds(c,
120 : cli_ctx,
121 : NULL,
122 : server_name,
123 : server_ss,
124 : c->opt_port,
125 : service_name,
126 : service_type,
127 : c->creds,
128 : flags);
129 876 : if (!NT_STATUS_IS_OK(nt_status)) {
130 4 : d_fprintf(stderr, _("Could not connect to server %s\n"),
131 : server_name);
132 :
133 : /* Display a nicer message depending on the result */
134 :
135 4 : if (NT_STATUS_V(nt_status) ==
136 4 : NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
137 0 : d_fprintf(stderr,
138 0 : _("The username or password was not "
139 : "correct.\n"));
140 :
141 4 : if (NT_STATUS_V(nt_status) ==
142 4 : NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
143 0 : d_fprintf(stderr, _("The account was locked out.\n"));
144 :
145 4 : if (NT_STATUS_V(nt_status) ==
146 4 : NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
147 0 : d_fprintf(stderr, _("The account was disabled.\n"));
148 4 : return nt_status;
149 : }
150 :
151 872 : return nt_status;
152 : }
153 :
154 : /****************************************************************************
155 : Connect to \\server\ipc$.
156 : ****************************************************************************/
157 :
158 876 : NTSTATUS connect_to_ipc(struct net_context *c,
159 : struct cli_state **cli_ctx,
160 : const struct sockaddr_storage *server_ss,
161 : const char *server_name)
162 : {
163 876 : return connect_to_service(c, cli_ctx, server_ss, server_name, "IPC$",
164 : "IPC");
165 : }
166 :
167 : /****************************************************************************
168 : Connect to \\server\ipc$ anonymously.
169 : ****************************************************************************/
170 :
171 10 : NTSTATUS connect_to_ipc_anonymous(struct net_context *c,
172 : struct cli_state **cli_ctx,
173 : const struct sockaddr_storage *server_ss,
174 : const char *server_name)
175 : {
176 0 : NTSTATUS nt_status;
177 10 : struct cli_credentials *anon_creds = NULL;
178 :
179 10 : anon_creds = cli_credentials_init_anon(c);
180 10 : if (anon_creds == NULL) {
181 0 : DBG_ERR("cli_credentials_init_anon() failed\n");
182 0 : return NT_STATUS_NO_MEMORY;
183 : }
184 :
185 10 : nt_status = cli_full_connection_creds(c,
186 : cli_ctx,
187 : c->opt_requester_name,
188 : server_name,
189 : server_ss,
190 : c->opt_port,
191 : "IPC$",
192 : "IPC",
193 : anon_creds,
194 : CLI_FULL_CONNECTION_IPC);
195 :
196 10 : if (NT_STATUS_IS_OK(nt_status)) {
197 10 : return nt_status;
198 : } else {
199 0 : DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status)));
200 0 : return nt_status;
201 : }
202 : }
203 :
204 : /**
205 : * Connect a server and open a given pipe
206 : *
207 : * @param cli_dst A cli_state
208 : * @param pipe The pipe to open
209 : * @param got_pipe boolean that stores if we got a pipe
210 : *
211 : * @return Normal NTSTATUS return.
212 : **/
213 0 : NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
214 : struct rpc_pipe_client **pp_pipe_hnd,
215 : const struct ndr_interface_table *table)
216 : {
217 0 : NTSTATUS nt_status;
218 0 : char *server_name = SMB_STRDUP("127.0.0.1");
219 0 : struct cli_state *cli_tmp = NULL;
220 0 : struct rpc_pipe_client *pipe_hnd = NULL;
221 :
222 0 : if (server_name == NULL) {
223 0 : return NT_STATUS_NO_MEMORY;
224 : }
225 :
226 0 : if (c->opt_destination) {
227 0 : SAFE_FREE(server_name);
228 0 : if ((server_name = SMB_STRDUP(c->opt_destination)) == NULL) {
229 0 : return NT_STATUS_NO_MEMORY;
230 : }
231 : }
232 :
233 : /* make a connection to a named pipe */
234 0 : nt_status = connect_to_ipc(c, &cli_tmp, NULL, server_name);
235 0 : if (!NT_STATUS_IS_OK(nt_status)) {
236 0 : SAFE_FREE(server_name);
237 0 : return nt_status;
238 : }
239 :
240 0 : nt_status = cli_rpc_pipe_open_noauth(cli_tmp, table,
241 : &pipe_hnd);
242 0 : if (!NT_STATUS_IS_OK(nt_status)) {
243 0 : DEBUG(0, ("couldn't not initialize pipe\n"));
244 0 : cli_shutdown(cli_tmp);
245 0 : SAFE_FREE(server_name);
246 0 : return nt_status;
247 : }
248 :
249 0 : *cli_dst = cli_tmp;
250 0 : *pp_pipe_hnd = pipe_hnd;
251 0 : SAFE_FREE(server_name);
252 :
253 0 : return nt_status;
254 : }
255 :
256 : /****************************************************************************
257 : Use the local machine account (krb) and password for this session.
258 : ****************************************************************************/
259 :
260 40 : int net_use_krb_machine_account(struct net_context *c)
261 : {
262 40 : if (!secrets_init()) {
263 0 : d_fprintf(stderr,_("ERROR: Unable to open secrets database\n"));
264 0 : exit(1);
265 : }
266 :
267 40 : cli_credentials_set_machine_account(c->creds, c->lp_ctx);
268 40 : c->explicit_credentials = true;
269 40 : return 0;
270 : }
271 :
272 882 : bool net_find_server(struct net_context *c,
273 : const char *domain,
274 : unsigned flags,
275 : struct sockaddr_storage *server_ss,
276 : char **server_name)
277 : {
278 882 : const char *d = domain ? domain : c->opt_target_workgroup;
279 :
280 882 : if (c->opt_host) {
281 180 : *server_name = SMB_STRDUP(c->opt_host);
282 : }
283 :
284 882 : if (c->opt_have_ip) {
285 698 : *server_ss = c->opt_dest_ip;
286 698 : if (!*server_name) {
287 0 : char addr[INET6_ADDRSTRLEN];
288 698 : print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip);
289 698 : *server_name = SMB_STRDUP(addr);
290 : }
291 184 : } else if (*server_name) {
292 : /* resolve the IP address */
293 180 : if (!resolve_name(*server_name, server_ss, 0x20, false)) {
294 0 : DEBUG(1,("Unable to resolve server name\n"));
295 0 : return false;
296 : }
297 4 : } else if (flags & NET_FLAGS_PDC) {
298 0 : fstring dc_name;
299 0 : struct sockaddr_storage pdc_ss;
300 :
301 4 : if (!get_pdc_ip(d, &pdc_ss)) {
302 0 : DEBUG(1,("Unable to resolve PDC server address\n"));
303 0 : return false;
304 : }
305 :
306 4 : if (is_zero_addr(&pdc_ss)) {
307 0 : return false;
308 : }
309 :
310 4 : if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
311 0 : return false;
312 : }
313 :
314 4 : *server_name = SMB_STRDUP(dc_name);
315 4 : *server_ss = pdc_ss;
316 0 : } else if (flags & NET_FLAGS_DMB) {
317 0 : struct sockaddr_storage msbrow_ss;
318 0 : char addr[INET6_ADDRSTRLEN];
319 :
320 : /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */
321 0 : if (!resolve_name(d, &msbrow_ss, 0x1B, false)) {
322 0 : DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
323 0 : return false;
324 : }
325 0 : *server_ss = msbrow_ss;
326 0 : print_sockaddr(addr, sizeof(addr), server_ss);
327 0 : *server_name = SMB_STRDUP(addr);
328 0 : } else if (flags & NET_FLAGS_MASTER) {
329 0 : struct sockaddr_storage brow_ss;
330 0 : char addr[INET6_ADDRSTRLEN];
331 0 : if (!resolve_name(d, &brow_ss, 0x1D, false)) {
332 : /* go looking for workgroups */
333 0 : DEBUG(1,("Unable to resolve master browser via name lookup\n"));
334 0 : return false;
335 : }
336 0 : *server_ss = brow_ss;
337 0 : print_sockaddr(addr, sizeof(addr), server_ss);
338 0 : *server_name = SMB_STRDUP(addr);
339 0 : } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
340 0 : if (!interpret_string_addr(server_ss,
341 : "127.0.0.1", AI_NUMERICHOST)) {
342 0 : DEBUG(1,("Unable to resolve 127.0.0.1\n"));
343 0 : return false;
344 : }
345 0 : *server_name = SMB_STRDUP("127.0.0.1");
346 : }
347 :
348 882 : if (!*server_name) {
349 0 : DEBUG(1,("no server to connect to\n"));
350 0 : return false;
351 : }
352 :
353 882 : return true;
354 : }
355 :
356 4 : bool net_find_pdc(struct sockaddr_storage *server_ss,
357 : fstring server_name,
358 : const char *domain_name)
359 : {
360 4 : if (!get_pdc_ip(domain_name, server_ss)) {
361 0 : return false;
362 : }
363 4 : if (is_zero_addr(server_ss)) {
364 0 : return false;
365 : }
366 :
367 4 : if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
368 0 : return false;
369 : }
370 :
371 4 : return true;
372 : }
373 :
374 874 : NTSTATUS net_make_ipc_connection(struct net_context *c, unsigned flags,
375 : struct cli_state **pcli)
376 : {
377 874 : return net_make_ipc_connection_ex(c, c->opt_workgroup, NULL, NULL, flags, pcli);
378 : }
379 :
380 878 : NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
381 : const char *server,
382 : const struct sockaddr_storage *pss,
383 : unsigned flags, struct cli_state **pcli)
384 : {
385 878 : char *server_name = NULL;
386 0 : struct sockaddr_storage server_ss;
387 878 : struct cli_state *cli = NULL;
388 0 : NTSTATUS nt_status;
389 :
390 878 : if ( !server || !pss ) {
391 878 : if (!net_find_server(c, domain, flags, &server_ss,
392 : &server_name)) {
393 0 : d_fprintf(stderr, _("Unable to find a suitable server "
394 : "for domain %s\n"), domain);
395 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
396 0 : goto done;
397 : }
398 : } else {
399 0 : server_name = SMB_STRDUP( server );
400 0 : server_ss = *pss;
401 : }
402 :
403 878 : if (flags & NET_FLAGS_ANONYMOUS) {
404 6 : nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
405 : server_name);
406 : } else {
407 872 : nt_status = connect_to_ipc(c, &cli, &server_ss,
408 : server_name);
409 : }
410 :
411 : /* store the server in the affinity cache if it was a PDC */
412 :
413 878 : if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
414 10 : saf_store(cli->server_domain, server_name);
415 :
416 878 : SAFE_FREE(server_name);
417 878 : if (!NT_STATUS_IS_OK(nt_status)) {
418 0 : d_fprintf(stderr, _("Connection failed: %s\n"),
419 : nt_errstr(nt_status));
420 0 : cli = NULL;
421 878 : } else if (c->opt_request_timeout) {
422 0 : cli_set_timeout(cli, c->opt_request_timeout * 1000);
423 : }
424 :
425 878 : done:
426 878 : if (pcli != NULL) {
427 878 : *pcli = cli;
428 : }
429 878 : return nt_status;
430 : }
431 :
432 : /****************************************************************************
433 : ****************************************************************************/
434 :
435 7307 : int net_run_function(struct net_context *c, int argc, const char **argv,
436 : const char *whoami, struct functable *table)
437 : {
438 5 : int i;
439 :
440 7307 : if (argc != 0) {
441 96517 : for (i=0; table[i].funcname != NULL; i++) {
442 96517 : if (strcasecmp_m(argv[0], table[i].funcname) == 0)
443 7307 : return table[i].fn(c, argc-1, argv+1);
444 : }
445 : }
446 :
447 0 : if (c->display_usage == false) {
448 0 : d_fprintf(stderr, _("Invalid command: %s %s\n"), whoami,
449 : (argc > 0)?argv[0]:"");
450 : }
451 0 : d_printf(_("Usage:\n"));
452 0 : for (i=0; table[i].funcname != NULL; i++) {
453 0 : if(c->display_usage == false)
454 0 : d_printf("%s %-15s %s\n", whoami, table[i].funcname,
455 0 : _(table[i].description));
456 : else
457 0 : d_printf("%s\n", _(table[i].usage));
458 : }
459 :
460 0 : return c->display_usage?0:-1;
461 : }
462 :
463 0 : void net_display_usage_from_functable(struct functable *table)
464 : {
465 0 : int i;
466 0 : for (i=0; table[i].funcname != NULL; i++) {
467 0 : d_printf("%s\n", _(table[i].usage));
468 : }
469 0 : }
470 :
471 238 : void net_warn_member_options(void)
472 : {
473 238 : TALLOC_CTX *frame = talloc_stackframe();
474 238 : struct loadparm_context *lp_ctx = NULL;
475 :
476 238 : lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
477 238 : if (lp_ctx != NULL) {
478 238 : netlogon_creds_cli_warn_options(lp_ctx);
479 : }
480 :
481 238 : TALLOC_FREE(frame);
482 238 : }
483 :
484 0 : const char *net_share_type_str(int num_type)
485 : {
486 0 : switch(num_type) {
487 0 : case 0: return _("Disk");
488 0 : case 1: return _("Print");
489 0 : case 2: return _("Dev");
490 0 : case 3: return _("IPC");
491 0 : default: return _("Unknown");
492 : }
493 : }
494 :
495 0 : static NTSTATUS net_scan_dc_noad(struct net_context *c,
496 : struct cli_state *cli,
497 : struct net_dc_info *dc_info)
498 : {
499 0 : TALLOC_CTX *mem_ctx = talloc_tos();
500 0 : struct rpc_pipe_client *pipe_hnd = NULL;
501 0 : struct dcerpc_binding_handle *b;
502 0 : NTSTATUS status, result;
503 0 : struct policy_handle pol;
504 0 : union lsa_PolicyInformation *info;
505 :
506 0 : ZERO_STRUCTP(dc_info);
507 0 : ZERO_STRUCT(pol);
508 :
509 0 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
510 : &pipe_hnd);
511 0 : if (!NT_STATUS_IS_OK(status)) {
512 0 : return status;
513 : }
514 :
515 0 : b = pipe_hnd->binding_handle;
516 :
517 0 : status = dcerpc_lsa_open_policy(b, mem_ctx,
518 : false,
519 : SEC_FLAG_MAXIMUM_ALLOWED,
520 : &pol,
521 : &result);
522 0 : if (!NT_STATUS_IS_OK(status)) {
523 0 : goto done;
524 : }
525 0 : if (!NT_STATUS_IS_OK(result)) {
526 0 : status = result;
527 0 : goto done;
528 : }
529 :
530 0 : status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
531 : &pol,
532 : LSA_POLICY_INFO_ACCOUNT_DOMAIN,
533 : &info,
534 : &result);
535 0 : if (!NT_STATUS_IS_OK(status)) {
536 0 : goto done;
537 : }
538 0 : if (!NT_STATUS_IS_OK(result)) {
539 0 : status = result;
540 0 : goto done;
541 : }
542 :
543 0 : dc_info->netbios_domain_name = talloc_strdup(mem_ctx, info->account_domain.name.string);
544 0 : if (dc_info->netbios_domain_name == NULL) {
545 0 : status = NT_STATUS_NO_MEMORY;
546 0 : goto done;
547 : }
548 :
549 0 : done:
550 0 : if (is_valid_policy_hnd(&pol)) {
551 0 : dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
552 : }
553 :
554 0 : TALLOC_FREE(pipe_hnd);
555 :
556 0 : return status;
557 : }
558 :
559 0 : NTSTATUS net_scan_dc(struct net_context *c,
560 : struct cli_state *cli,
561 : struct net_dc_info *dc_info)
562 : {
563 0 : TALLOC_CTX *mem_ctx = talloc_tos();
564 0 : struct rpc_pipe_client *dssetup_pipe = NULL;
565 0 : struct dcerpc_binding_handle *dssetup_handle = NULL;
566 0 : union dssetup_DsRoleInfo info;
567 0 : NTSTATUS status;
568 0 : WERROR werr;
569 :
570 0 : ZERO_STRUCTP(dc_info);
571 :
572 0 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_dssetup,
573 : &dssetup_pipe);
574 0 : if (!NT_STATUS_IS_OK(status)) {
575 0 : DEBUG(10,("net_scan_dc: failed to open dssetup pipe with %s, "
576 : "retrying with lsa pipe\n", nt_errstr(status)));
577 0 : return net_scan_dc_noad(c, cli, dc_info);
578 : }
579 0 : dssetup_handle = dssetup_pipe->binding_handle;
580 :
581 0 : status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(dssetup_handle, mem_ctx,
582 : DS_ROLE_BASIC_INFORMATION,
583 : &info,
584 : &werr);
585 0 : TALLOC_FREE(dssetup_pipe);
586 :
587 0 : if (NT_STATUS_IS_OK(status)) {
588 0 : status = werror_to_ntstatus(werr);
589 : }
590 0 : if (!NT_STATUS_IS_OK(status)) {
591 0 : return status;
592 : }
593 :
594 0 : dc_info->is_dc = (info.basic.role & (DS_ROLE_PRIMARY_DC|DS_ROLE_BACKUP_DC));
595 0 : dc_info->is_pdc = (info.basic.role & DS_ROLE_PRIMARY_DC);
596 0 : dc_info->is_ad = (info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING);
597 0 : dc_info->is_mixed_mode = (info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE);
598 0 : dc_info->netbios_domain_name = talloc_strdup(mem_ctx, info.basic.domain);
599 0 : dc_info->dns_domain_name = talloc_strdup(mem_ctx, info.basic.dns_domain);
600 0 : dc_info->forest_name = talloc_strdup(mem_ctx, info.basic.forest);
601 :
602 0 : return NT_STATUS_OK;
603 : }
|