LCOV - code coverage report
Current view: top level - source3/utils - net_util.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 67 261 25.7 %
Date: 2021-09-23 10:06:22 Functions: 9 17 52.9 %

          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             : }

Generated by: LCOV version 1.13