LCOV - code coverage report
Current view: top level - source3/utils - net_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 86 286 30.1 %
Date: 2024-05-31 13:13:24 Functions: 10 16 62.5 %

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

Generated by: LCOV version 1.14