s4/asn1: Added torture suite for ASN1
[Samba/ekacnet.git] / source3 / utils / net_util.c
blobd0d1fc042144bf3c1a5e497aeb156b456fcc4788
1 /*
2 * Unix SMB/CIFS implementation.
3 * Helper routines for net
4 * Copyright (C) Volker Lendecke 2006
5 * Copyright (C) Kai Blin 2008
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.
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.
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/>.
22 #include "includes.h"
23 #include "utils/net.h"
25 NTSTATUS net_rpc_lookup_name(struct net_context *c,
26 TALLOC_CTX *mem_ctx, struct cli_state *cli,
27 const char *name, const char **ret_domain,
28 const char **ret_name, DOM_SID *ret_sid,
29 enum lsa_SidType *ret_type)
31 struct rpc_pipe_client *lsa_pipe;
32 struct policy_handle pol;
33 NTSTATUS result = NT_STATUS_OK;
34 const char **dom_names;
35 DOM_SID *sids;
36 enum lsa_SidType *types;
38 ZERO_STRUCT(pol);
40 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
41 &lsa_pipe);
42 if (!NT_STATUS_IS_OK(result)) {
43 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
44 return result;
47 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
48 SEC_FLAG_MAXIMUM_ALLOWED,
49 &pol);
50 if (!NT_STATUS_IS_OK(result)) {
51 d_fprintf(stderr, _("open_policy failed: %s\n"),
52 nt_errstr(result));
53 return result;
56 result = rpccli_lsa_lookup_names(lsa_pipe, mem_ctx, &pol, 1,
57 &name, &dom_names, 1, &sids, &types);
59 if (!NT_STATUS_IS_OK(result)) {
60 /* This can happen easily, don't log an error */
61 goto done;
64 if (ret_domain != NULL) {
65 *ret_domain = dom_names[0];
67 if (ret_name != NULL) {
68 *ret_name = talloc_strdup(mem_ctx, name);
70 if (ret_sid != NULL) {
71 sid_copy(ret_sid, &sids[0]);
73 if (ret_type != NULL) {
74 *ret_type = types[0];
77 done:
78 if (is_valid_policy_hnd(&pol)) {
79 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
81 TALLOC_FREE(lsa_pipe);
83 return result;
86 /****************************************************************************
87 Connect to \\server\service.
88 ****************************************************************************/
90 NTSTATUS connect_to_service(struct net_context *c,
91 struct cli_state **cli_ctx,
92 struct sockaddr_storage *server_ss,
93 const char *server_name,
94 const char *service_name,
95 const char *service_type)
97 NTSTATUS nt_status;
98 int flags = 0;
100 c->opt_password = net_prompt_pass(c, c->opt_user_name);
102 if (c->opt_kerberos) {
103 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
106 if (c->opt_kerberos && c->opt_password) {
107 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
110 nt_status = cli_full_connection(cli_ctx, NULL, server_name,
111 server_ss, c->opt_port,
112 service_name, service_type,
113 c->opt_user_name, c->opt_workgroup,
114 c->opt_password, flags, Undefined, NULL);
115 if (!NT_STATUS_IS_OK(nt_status)) {
116 d_fprintf(stderr, _("Could not connect to server %s\n"),
117 server_name);
119 /* Display a nicer message depending on the result */
121 if (NT_STATUS_V(nt_status) ==
122 NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
123 d_fprintf(stderr,
124 _("The username or password was not "
125 "correct.\n"));
127 if (NT_STATUS_V(nt_status) ==
128 NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
129 d_fprintf(stderr, _("The account was locked out.\n"));
131 if (NT_STATUS_V(nt_status) ==
132 NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
133 d_fprintf(stderr, _("The account was disabled.\n"));
134 return nt_status;
137 if (c->smb_encrypt) {
138 nt_status = cli_force_encryption(*cli_ctx,
139 c->opt_user_name,
140 c->opt_password,
141 c->opt_workgroup);
143 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
144 d_printf(_("Encryption required and "
145 "server that doesn't support "
146 "UNIX extensions - failing connect\n"));
147 } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNKNOWN_REVISION)) {
148 d_printf(_("Encryption required and "
149 "can't get UNIX CIFS extensions "
150 "version from server.\n"));
151 } else if (NT_STATUS_EQUAL(nt_status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
152 d_printf(_("Encryption required and "
153 "share %s doesn't support "
154 "encryption.\n"), service_name);
155 } else if (!NT_STATUS_IS_OK(nt_status)) {
156 d_printf(_("Encryption required and "
157 "setup failed with error %s.\n"),
158 nt_errstr(nt_status));
161 if (!NT_STATUS_IS_OK(nt_status)) {
162 cli_shutdown(*cli_ctx);
163 *cli_ctx = NULL;
167 return nt_status;
170 /****************************************************************************
171 Connect to \\server\ipc$.
172 ****************************************************************************/
174 NTSTATUS connect_to_ipc(struct net_context *c,
175 struct cli_state **cli_ctx,
176 struct sockaddr_storage *server_ss,
177 const char *server_name)
179 return connect_to_service(c, cli_ctx, server_ss, server_name, "IPC$",
180 "IPC");
183 /****************************************************************************
184 Connect to \\server\ipc$ anonymously.
185 ****************************************************************************/
187 NTSTATUS connect_to_ipc_anonymous(struct net_context *c,
188 struct cli_state **cli_ctx,
189 struct sockaddr_storage *server_ss,
190 const char *server_name)
192 NTSTATUS nt_status;
194 nt_status = cli_full_connection(cli_ctx, c->opt_requester_name,
195 server_name, server_ss, c->opt_port,
196 "IPC$", "IPC",
197 "", "",
198 "", 0, Undefined, NULL);
200 if (NT_STATUS_IS_OK(nt_status)) {
201 return nt_status;
202 } else {
203 DEBUG(1,("Cannot connect to server (anonymously). Error was %s\n", nt_errstr(nt_status)));
204 return nt_status;
208 /****************************************************************************
209 Return malloced user@realm for krb5 login.
210 ****************************************************************************/
212 static char *get_user_and_realm(const char *username)
214 char *user_and_realm = NULL;
216 if (!username) {
217 return NULL;
219 if (strchr_m(username, '@')) {
220 user_and_realm = SMB_STRDUP(username);
221 } else {
222 if (asprintf(&user_and_realm, "%s@%s", username, lp_realm()) == -1) {
223 user_and_realm = NULL;
226 return user_and_realm;
229 /****************************************************************************
230 Connect to \\server\ipc$ using KRB5.
231 ****************************************************************************/
233 NTSTATUS connect_to_ipc_krb5(struct net_context *c,
234 struct cli_state **cli_ctx,
235 struct sockaddr_storage *server_ss,
236 const char *server_name)
238 NTSTATUS nt_status;
239 char *user_and_realm = NULL;
241 /* FIXME: Should get existing kerberos ticket if possible. */
242 c->opt_password = net_prompt_pass(c, c->opt_user_name);
243 if (!c->opt_password) {
244 return NT_STATUS_NO_MEMORY;
247 user_and_realm = get_user_and_realm(c->opt_user_name);
248 if (!user_and_realm) {
249 return NT_STATUS_NO_MEMORY;
252 nt_status = cli_full_connection(cli_ctx, NULL, server_name,
253 server_ss, c->opt_port,
254 "IPC$", "IPC",
255 user_and_realm, c->opt_workgroup,
256 c->opt_password,
257 CLI_FULL_CONNECTION_USE_KERBEROS,
258 Undefined, NULL);
260 SAFE_FREE(user_and_realm);
262 if (!NT_STATUS_IS_OK(nt_status)) {
263 DEBUG(1,("Cannot connect to server using kerberos. Error was %s\n", nt_errstr(nt_status)));
264 return nt_status;
267 if (c->smb_encrypt) {
268 nt_status = cli_cm_force_encryption(*cli_ctx,
269 user_and_realm,
270 c->opt_password,
271 c->opt_workgroup,
272 "IPC$");
273 if (!NT_STATUS_IS_OK(nt_status)) {
274 cli_shutdown(*cli_ctx);
275 *cli_ctx = NULL;
279 return nt_status;
283 * Connect a server and open a given pipe
285 * @param cli_dst A cli_state
286 * @param pipe The pipe to open
287 * @param got_pipe boolean that stores if we got a pipe
289 * @return Normal NTSTATUS return.
291 NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
292 struct rpc_pipe_client **pp_pipe_hnd,
293 const struct ndr_syntax_id *interface)
295 NTSTATUS nt_status;
296 char *server_name = SMB_STRDUP("127.0.0.1");
297 struct cli_state *cli_tmp = NULL;
298 struct rpc_pipe_client *pipe_hnd = NULL;
300 if (server_name == NULL) {
301 return NT_STATUS_NO_MEMORY;
304 if (c->opt_destination) {
305 SAFE_FREE(server_name);
306 if ((server_name = SMB_STRDUP(c->opt_destination)) == NULL) {
307 return NT_STATUS_NO_MEMORY;
311 /* make a connection to a named pipe */
312 nt_status = connect_to_ipc(c, &cli_tmp, NULL, server_name);
313 if (!NT_STATUS_IS_OK(nt_status)) {
314 SAFE_FREE(server_name);
315 return nt_status;
318 nt_status = cli_rpc_pipe_open_noauth(cli_tmp, interface,
319 &pipe_hnd);
320 if (!NT_STATUS_IS_OK(nt_status)) {
321 DEBUG(0, ("couldn't not initialize pipe\n"));
322 cli_shutdown(cli_tmp);
323 SAFE_FREE(server_name);
324 return nt_status;
327 *cli_dst = cli_tmp;
328 *pp_pipe_hnd = pipe_hnd;
329 SAFE_FREE(server_name);
331 return nt_status;
334 /****************************************************************************
335 Use the local machine account (krb) and password for this session.
336 ****************************************************************************/
338 int net_use_krb_machine_account(struct net_context *c)
340 char *user_name = NULL;
342 if (!secrets_init()) {
343 d_fprintf(stderr,_("ERROR: Unable to open secrets database\n"));
344 exit(1);
347 c->opt_password = secrets_fetch_machine_password(
348 c->opt_target_workgroup, NULL, NULL);
349 if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
350 return -1;
352 c->opt_user_name = user_name;
353 return 0;
356 /****************************************************************************
357 Use the machine account name and password for this session.
358 ****************************************************************************/
360 int net_use_machine_account(struct net_context *c)
362 char *user_name = NULL;
364 if (!secrets_init()) {
365 d_fprintf(stderr,_("ERROR: Unable to open secrets database\n"));
366 exit(1);
369 c->opt_password = secrets_fetch_machine_password(
370 c->opt_target_workgroup, NULL, NULL);
371 if (asprintf(&user_name, "%s$", global_myname()) == -1) {
372 return -1;
374 c->opt_user_name = user_name;
375 return 0;
378 bool net_find_server(struct net_context *c,
379 const char *domain,
380 unsigned flags,
381 struct sockaddr_storage *server_ss,
382 char **server_name)
384 const char *d = domain ? domain : c->opt_target_workgroup;
386 if (c->opt_host) {
387 *server_name = SMB_STRDUP(c->opt_host);
390 if (c->opt_have_ip) {
391 *server_ss = c->opt_dest_ip;
392 if (!*server_name) {
393 char addr[INET6_ADDRSTRLEN];
394 print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip);
395 *server_name = SMB_STRDUP(addr);
397 } else if (*server_name) {
398 /* resolve the IP address */
399 if (!resolve_name(*server_name, server_ss, 0x20, false)) {
400 DEBUG(1,("Unable to resolve server name\n"));
401 return false;
403 } else if (flags & NET_FLAGS_PDC) {
404 fstring dc_name;
405 struct sockaddr_storage pdc_ss;
407 if (!get_pdc_ip(d, &pdc_ss)) {
408 DEBUG(1,("Unable to resolve PDC server address\n"));
409 return false;
412 if (is_zero_addr((struct sockaddr *)&pdc_ss)) {
413 return false;
416 if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
417 return false;
420 *server_name = SMB_STRDUP(dc_name);
421 *server_ss = pdc_ss;
422 } else if (flags & NET_FLAGS_DMB) {
423 struct sockaddr_storage msbrow_ss;
424 char addr[INET6_ADDRSTRLEN];
426 /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */
427 if (!resolve_name(d, &msbrow_ss, 0x1B, false)) {
428 DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
429 return false;
431 *server_ss = msbrow_ss;
432 print_sockaddr(addr, sizeof(addr), server_ss);
433 *server_name = SMB_STRDUP(addr);
434 } else if (flags & NET_FLAGS_MASTER) {
435 struct sockaddr_storage brow_ss;
436 char addr[INET6_ADDRSTRLEN];
437 if (!resolve_name(d, &brow_ss, 0x1D, false)) {
438 /* go looking for workgroups */
439 DEBUG(1,("Unable to resolve master browser via name lookup\n"));
440 return false;
442 *server_ss = brow_ss;
443 print_sockaddr(addr, sizeof(addr), server_ss);
444 *server_name = SMB_STRDUP(addr);
445 } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
446 if (!interpret_string_addr(server_ss,
447 "127.0.0.1", AI_NUMERICHOST)) {
448 DEBUG(1,("Unable to resolve 127.0.0.1\n"));
449 return false;
451 *server_name = SMB_STRDUP("127.0.0.1");
454 if (!*server_name) {
455 DEBUG(1,("no server to connect to\n"));
456 return false;
459 return true;
462 bool net_find_pdc(struct sockaddr_storage *server_ss,
463 fstring server_name,
464 const char *domain_name)
466 if (!get_pdc_ip(domain_name, server_ss)) {
467 return false;
469 if (is_zero_addr((struct sockaddr *)server_ss)) {
470 return false;
473 if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
474 return false;
477 return true;
480 NTSTATUS net_make_ipc_connection(struct net_context *c, unsigned flags,
481 struct cli_state **pcli)
483 return net_make_ipc_connection_ex(c, c->opt_workgroup, NULL, NULL, flags, pcli);
486 NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
487 const char *server,
488 struct sockaddr_storage *pss,
489 unsigned flags, struct cli_state **pcli)
491 char *server_name = NULL;
492 struct sockaddr_storage server_ss;
493 struct cli_state *cli = NULL;
494 NTSTATUS nt_status;
496 if ( !server || !pss ) {
497 if (!net_find_server(c, domain, flags, &server_ss,
498 &server_name)) {
499 d_fprintf(stderr, _("Unable to find a suitable server "
500 "for domain %s\n"), domain);
501 nt_status = NT_STATUS_UNSUCCESSFUL;
502 goto done;
504 } else {
505 server_name = SMB_STRDUP( server );
506 server_ss = *pss;
509 if (flags & NET_FLAGS_ANONYMOUS) {
510 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
511 server_name);
512 } else {
513 nt_status = connect_to_ipc(c, &cli, &server_ss,
514 server_name);
517 /* store the server in the affinity cache if it was a PDC */
519 if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
520 saf_store( cli->server_domain, cli->desthost );
522 SAFE_FREE(server_name);
523 if (!NT_STATUS_IS_OK(nt_status)) {
524 d_fprintf(stderr, _("Connection failed: %s\n"),
525 nt_errstr(nt_status));
526 cli = NULL;
527 } else if (c->opt_request_timeout) {
528 cli_set_timeout(cli, c->opt_request_timeout * 1000);
531 done:
532 if (pcli != NULL) {
533 *pcli = cli;
535 return nt_status;
538 /****************************************************************************
539 ****************************************************************************/
541 const char *net_prompt_pass(struct net_context *c, const char *user)
543 char *prompt = NULL;
544 const char *pass = NULL;
546 if (c->opt_password) {
547 return c->opt_password;
550 if (c->opt_machine_pass) {
551 return NULL;
554 if (c->opt_kerberos && !c->opt_user_specified) {
555 return NULL;
558 if (asprintf(&prompt, _("Enter %s's password:"), user) == -1) {
559 return NULL;
562 pass = getpass(prompt);
563 SAFE_FREE(prompt);
565 return pass;
568 int net_run_function(struct net_context *c, int argc, const char **argv,
569 const char *whoami, struct functable *table)
571 int i;
573 if (argc != 0) {
574 for (i=0; table[i].funcname != NULL; i++) {
575 if (StrCaseCmp(argv[0], table[i].funcname) == 0)
576 return table[i].fn(c, argc-1, argv+1);
580 if (c->display_usage == false) {
581 d_fprintf(stderr, _("Invalid command: %s %s\n"), whoami,
582 (argc > 0)?argv[0]:"");
584 d_printf("Usage:\n");
585 for (i=0; table[i].funcname != NULL; i++) {
586 if(c->display_usage == false)
587 d_printf("%s %-15s %s\n", whoami, table[i].funcname,
588 table[i].description);
589 else
590 d_printf("%s\n", table[i].usage);
593 return c->display_usage?0:-1;
596 void net_display_usage_from_functable(struct functable *table)
598 int i;
599 for (i=0; table[i].funcname != NULL; i++) {
600 d_printf("%s\n", table[i].usage);
604 const char *net_share_type_str(int num_type)
606 switch(num_type) {
607 case 0: return _("Disk");
608 case 1: return _("Print");
609 case 2: return _("Dev");
610 case 3: return _("IPC");
611 default: return _("Unknown");
615 NTSTATUS net_scan_dc(struct net_context *c,
616 struct cli_state *cli,
617 struct net_dc_info *dc_info)
619 TALLOC_CTX *mem_ctx = talloc_tos();
620 struct rpc_pipe_client *dssetup_pipe = NULL;
621 union dssetup_DsRoleInfo info;
622 NTSTATUS status;
624 ZERO_STRUCTP(dc_info);
626 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_dssetup.syntax_id,
627 &dssetup_pipe);
628 if (!NT_STATUS_IS_OK(status)) {
629 return status;
632 status = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(dssetup_pipe, mem_ctx,
633 DS_ROLE_BASIC_INFORMATION,
634 &info,
635 NULL);
636 TALLOC_FREE(dssetup_pipe);
638 if (!NT_STATUS_IS_OK(status)) {
639 return status;
642 dc_info->is_dc = (info.basic.role & (DS_ROLE_PRIMARY_DC|DS_ROLE_BACKUP_DC));
643 dc_info->is_pdc = (info.basic.role & DS_ROLE_PRIMARY_DC);
644 dc_info->is_ad = (info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING);
645 dc_info->is_mixed_mode = (info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE);
646 dc_info->netbios_domain_name = talloc_strdup(mem_ctx, info.basic.domain);
647 dc_info->dns_domain_name = talloc_strdup(mem_ctx, info.basic.dns_domain);
648 dc_info->forest_name = talloc_strdup(mem_ctx, info.basic.forest);
650 return NT_STATUS_OK;