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