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