LCOV - code coverage report
Current view: top level - source3/utils - net_lookup.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 59 262 22.5 %
Date: 2024-04-21 15:09:00 Functions: 6 12 50.0 %

          Line data    Source code
       1             : /*
       2             :    Samba Unix/Linux SMB client library
       3             :    net lookup command
       4             :    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      18             : 
      19             : #include "includes.h"
      20             : #include "utils/net.h"
      21             : #include "libsmb/namequery.h"
      22             : #include "libads/sitename_cache.h"
      23             : #include "lib/addns/dnsquery_srv.h"
      24             : #include "../librpc/gen_ndr/ndr_netlogon.h"
      25             : #include "smb_krb5.h"
      26             : #include "../libcli/security/security.h"
      27             : #include "passdb/lookup_sid.h"
      28             : #include "libsmb/dsgetdcname.h"
      29             : 
      30           0 : int net_lookup_usage(struct net_context *c, int argc, const char **argv)
      31             : {
      32           0 :         d_printf(_(
      33             : "  net lookup [host] HOSTNAME[#<type>]\n\tgives IP for a hostname\n\n"
      34             : "  net lookup ldap [domain] [sitename]\n\tgives IP of domain's ldap server\n\n"
      35             : "  net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n"
      36             : "  net lookup pdc [domain|realm]\n\tgives IP of realm's kerberos KDC\n\n"
      37             : "  net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n"
      38             : "  net lookup master [domain|wg]\n\tgive IP of master browser\n\n"
      39             : "  net lookup name [name]\n\tLookup name's sid and type\n\n"
      40             : "  net lookup sid [sid]\n\tGive sid's name and type\n\n"
      41             : "  net lookup dsgetdcname [name] [flags] [sitename]\n\n"
      42             : ));
      43           0 :         return -1;
      44             : }
      45             : 
      46             : /* lookup a hostname giving an IP */
      47           0 : static int net_lookup_host(struct net_context *c, int argc, const char **argv)
      48             : {
      49           0 :         struct sockaddr_storage ss;
      50           0 :         int name_type = 0x20;
      51           0 :         char addr[INET6_ADDRSTRLEN];
      52           0 :         const char *name = argv[0];
      53           0 :         char *p;
      54             : 
      55           0 :         if (argc == 0)
      56           0 :                 return net_lookup_usage(c, argc, argv);
      57             : 
      58           0 :         p = strchr_m(name,'#');
      59           0 :         if (p) {
      60           0 :                 *p = '\0';
      61           0 :                 sscanf(++p,"%x",&name_type);
      62             :         }
      63             : 
      64           0 :         if (!resolve_name(name, &ss, name_type, false)) {
      65             :                 /* we deliberately use DEBUG() here to send it to stderr
      66             :                    so scripts aren't mucked up */
      67           0 :                 DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
      68           0 :                 return -1;
      69             :         }
      70             : 
      71           0 :         print_sockaddr(addr, sizeof(addr), &ss);
      72           0 :         d_printf("%s\n", addr);
      73           0 :         return 0;
      74             : }
      75             : 
      76             : #ifdef HAVE_ADS
      77           6 : static void print_ldap_srvlist(struct dns_rr_srv *dclist, size_t numdcs)
      78             : {
      79           0 :         size_t i;
      80             : 
      81          12 :         for ( i=0; i<numdcs; i++ ) {
      82           6 :                 struct dns_rr_srv *dc = &dclist[i];
      83           0 :                 size_t j;
      84             : 
      85          16 :                 for (j=0; j<dc->num_ips; j++) {
      86          10 :                         struct sockaddr_storage *ss = &dc->ss_s[j];
      87           0 :                         char addr[INET6_ADDRSTRLEN];
      88             : 
      89          10 :                         print_sockaddr(addr, sizeof(addr), ss);
      90             : #ifdef HAVE_IPV6
      91          10 :                         if (ss->ss_family == AF_INET6) {
      92           4 :                                 d_printf("[%s]:%"PRIu16"\n", addr, dc->port);
      93             :                         }
      94             : #endif
      95          10 :                         if (ss->ss_family == AF_INET) {
      96           6 :                                 d_printf("%s:%"PRIu16"\n", addr, dc->port);
      97             :                         }
      98             :                 }
      99             :         }
     100           6 : }
     101             : #endif
     102             : 
     103           6 : static int net_lookup_ldap(struct net_context *c, int argc, const char **argv)
     104             : {
     105             : #ifdef HAVE_ADS
     106           0 :         const char *domain;
     107           0 :         struct sockaddr_storage ss;
     108           6 :         struct dns_rr_srv *dcs = NULL;
     109           6 :         size_t numdcs = 0;
     110           6 :         const char *sitename = NULL;
     111           0 :         TALLOC_CTX *ctx;
     112           0 :         NTSTATUS status;
     113           0 :         int ret;
     114           0 :         char h_name[MAX_DNS_NAME_LENGTH];
     115           6 :         char *query = NULL;
     116             : 
     117           6 :         if (argc > 0)
     118           6 :                 domain = argv[0];
     119             :         else
     120           0 :                 domain = c->opt_target_workgroup;
     121             : 
     122           6 :         if (argc > 1) {
     123           4 :                 sitename = argv[1];
     124             :         }
     125             : 
     126           6 :         if ( (ctx = talloc_init("net_lookup_ldap")) == NULL ) {
     127           0 :                 d_fprintf(stderr,"net_lookup_ldap: talloc_init() %s!\n",
     128             :                           _("failed"));
     129           0 :                 return -1;
     130             :         }
     131             : 
     132           6 :         if (sitename == NULL) {
     133           2 :                 sitename = sitename_fetch(ctx, domain);
     134             :         }
     135           6 :         query = ads_dns_query_string_dcs(ctx, domain);
     136             : 
     137           6 :         DEBUG(9, ("Lookup up ldap for domain %s\n", domain));
     138             : 
     139           6 :         status = ads_dns_query_srv(
     140             :                 ctx,
     141             :                 lp_get_async_dns_timeout(),
     142             :                 sitename,
     143             :                 query,
     144             :                 &dcs,
     145             :                 &numdcs);
     146           6 :         if ( NT_STATUS_IS_OK(status) && numdcs ) {
     147           6 :                 print_ldap_srvlist(dcs, numdcs);
     148           6 :                 TALLOC_FREE( ctx );
     149           6 :                 return 0;
     150             :         }
     151             : 
     152           0 :         DEBUG(9, ("Looking up PDC for domain %s\n", domain));
     153           0 :         if (!get_pdc_ip(domain, &ss)) {
     154           0 :                 TALLOC_FREE( ctx );
     155           0 :                 return -1;
     156             :         }
     157             : 
     158           0 :         ret = sys_getnameinfo((struct sockaddr *)&ss,
     159             :                         sizeof(struct sockaddr_storage),
     160             :                         h_name, sizeof(h_name),
     161             :                         NULL, 0,
     162             :                         NI_NAMEREQD);
     163             : 
     164           0 :         if (ret) {
     165           0 :                 TALLOC_FREE( ctx );
     166           0 :                 return -1;
     167             :         }
     168             : 
     169           0 :         DEBUG(9, ("Found PDC with DNS name %s\n", h_name));
     170           0 :         domain = strchr(h_name, '.');
     171           0 :         if (!domain) {
     172           0 :                 TALLOC_FREE( ctx );
     173           0 :                 return -1;
     174             :         }
     175           0 :         domain++;
     176             : 
     177           0 :         DEBUG(9, ("Looking up ldap for domain %s\n", domain));
     178             : 
     179           0 :         status = ads_dns_query_srv(
     180             :                 ctx,
     181             :                 lp_get_async_dns_timeout(),
     182             :                 sitename,
     183             :                 query,
     184             :                 &dcs,
     185             :                 &numdcs);
     186           0 :         if ( NT_STATUS_IS_OK(status) && numdcs ) {
     187           0 :                 print_ldap_srvlist(dcs, numdcs);
     188           0 :                 TALLOC_FREE( ctx );
     189           0 :                 return 0;
     190             :         }
     191             : 
     192           0 :         TALLOC_FREE( ctx );
     193             : 
     194           0 :         return -1;
     195             : #endif
     196           0 :         DEBUG(1,("No ADS support\n"));
     197           0 :         return -1;
     198             : }
     199             : 
     200           0 : static int net_lookup_dc(struct net_context *c, int argc, const char **argv)
     201             : {
     202           0 :         struct samba_sockaddr *sa_list = NULL;
     203           0 :         struct sockaddr_storage ss;
     204           0 :         char *pdc_str = NULL;
     205           0 :         const char *domain = NULL;
     206           0 :         char *sitename = NULL;
     207           0 :         size_t count = 0;
     208           0 :         size_t i;
     209           0 :         char addr[INET6_ADDRSTRLEN];
     210           0 :         bool sec_ads = (lp_security() == SEC_ADS);
     211           0 :         NTSTATUS status;
     212             : 
     213           0 :         if (sec_ads) {
     214           0 :                 domain = lp_realm();
     215             :         } else {
     216           0 :                 domain = c->opt_target_workgroup;
     217             :         }
     218             : 
     219           0 :         if (argc > 0)
     220           0 :                 domain=argv[0];
     221             : 
     222             :         /* first get PDC */
     223           0 :         if (!get_pdc_ip(domain, &ss))
     224           0 :                 return -1;
     225             : 
     226           0 :         print_sockaddr(addr, sizeof(addr), &ss);
     227           0 :         if (asprintf(&pdc_str, "%s", addr) == -1) {
     228           0 :                 return -1;
     229             :         }
     230           0 :         d_printf("%s\n", pdc_str);
     231             : 
     232           0 :         sitename = sitename_fetch(talloc_tos(), domain);
     233           0 :         status = get_sorted_dc_list(talloc_tos(),
     234             :                                 domain,
     235             :                                 sitename,
     236             :                                 &sa_list,
     237             :                                 &count,
     238             :                                 sec_ads);
     239           0 :         if (!NT_STATUS_IS_OK(status)) {
     240           0 :                 SAFE_FREE(pdc_str);
     241           0 :                 TALLOC_FREE(sitename);
     242           0 :                 return 0;
     243             :         }
     244           0 :         TALLOC_FREE(sitename);
     245           0 :         for (i=0;i<count;i++) {
     246           0 :                 print_sockaddr(addr, sizeof(addr), &sa_list[i].u.ss);
     247           0 :                 if (!strequal(pdc_str, addr))
     248           0 :                         d_printf("%s\n", addr);
     249             :         }
     250           0 :         TALLOC_FREE(sa_list);
     251           0 :         SAFE_FREE(pdc_str);
     252           0 :         return 0;
     253             : }
     254             : 
     255           4 : static int net_lookup_pdc(struct net_context *c, int argc, const char **argv)
     256             : {
     257           0 :         struct sockaddr_storage ss;
     258           4 :         char *pdc_str = NULL;
     259           0 :         const char *domain;
     260           0 :         char addr[INET6_ADDRSTRLEN];
     261             : 
     262           4 :         if (lp_security() == SEC_ADS) {
     263           0 :                 domain = lp_realm();
     264             :         } else {
     265           4 :                 domain = c->opt_target_workgroup;
     266             :         }
     267             : 
     268           4 :         if (argc > 0)
     269           0 :                 domain=argv[0];
     270             : 
     271             :         /* first get PDC */
     272           4 :         if (!get_pdc_ip(domain, &ss))
     273           0 :                 return -1;
     274             : 
     275           4 :         print_sockaddr(addr, sizeof(addr), &ss);
     276           4 :         if (asprintf(&pdc_str, "%s", addr) == -1) {
     277           0 :                 return -1;
     278             :         }
     279           4 :         d_printf("%s\n", pdc_str);
     280           4 :         SAFE_FREE(pdc_str);
     281           4 :         return 0;
     282             : }
     283             : 
     284             : 
     285           4 : static int net_lookup_master(struct net_context *c, int argc, const char **argv)
     286             : {
     287           0 :         struct sockaddr_storage master_ss;
     288           4 :         const char *domain = c->opt_target_workgroup;
     289           0 :         char addr[INET6_ADDRSTRLEN];
     290             : 
     291           4 :         if (argc > 0)
     292           0 :                 domain=argv[0];
     293             : 
     294           4 :         if (!find_master_ip(domain, &master_ss))
     295           0 :                 return -1;
     296           4 :         print_sockaddr(addr, sizeof(addr), &master_ss);
     297           4 :         d_printf("%s\n", addr);
     298           4 :         return 0;
     299             : }
     300             : 
     301           0 : static int net_lookup_kdc(struct net_context *c, int argc, const char **argv)
     302             : {
     303             : #ifdef HAVE_KRB5
     304           0 :         krb5_error_code rc;
     305           0 :         krb5_context ctx;
     306           0 :         struct samba_sockaddr *kdcs = NULL;
     307           0 :         const char *realm;
     308           0 :         char **get_host_realms = NULL;
     309           0 :         size_t num_kdcs = 0;
     310           0 :         size_t i;
     311           0 :         NTSTATUS status;
     312             : 
     313           0 :         rc = smb_krb5_init_context_common(&ctx);
     314           0 :         if (rc) {
     315           0 :                 DBG_ERR("kerberos init context failed (%s)\n",
     316             :                         error_message(rc));
     317           0 :                 return -1;
     318             :         }
     319             : 
     320           0 :         if (argc > 0) {
     321           0 :                 realm = argv[0];
     322           0 :         } else if (lp_realm() && *lp_realm()) {
     323           0 :                 realm = lp_realm();
     324             :         } else {
     325           0 :                 rc = krb5_get_host_realm(ctx, NULL, &get_host_realms);
     326           0 :                 if (rc) {
     327           0 :                         DEBUG(1,("krb5_gethost_realm failed (%s)\n",
     328             :                                  error_message(rc)));
     329           0 :                         krb5_free_context(ctx);
     330           0 :                         return -1;
     331             :                 }
     332           0 :                 realm = (const char *) *get_host_realms;
     333             :         }
     334             : 
     335           0 :         status = get_kdc_list(talloc_tos(),
     336             :                                 realm,
     337             :                                 NULL,
     338             :                                 &kdcs,
     339             :                                 &num_kdcs);
     340           0 :         if (!NT_STATUS_IS_OK(status)) {
     341           0 :                 DBG_WARNING("get_kdc_list failed (%s)\n",
     342             :                         nt_errstr(status));
     343           0 :                 krb5_free_host_realm(ctx, get_host_realms);
     344           0 :                 krb5_free_context(ctx);
     345           0 :                 return -1;
     346             :         }
     347             : 
     348           0 :         for (i = 0; i < num_kdcs; i++) {
     349           0 :                 char addr[INET6_ADDRSTRLEN];
     350             : 
     351           0 :                 print_sockaddr(addr, sizeof(addr), &kdcs[i].u.ss);
     352             : 
     353           0 :                 d_printf("%s:88\n", addr);
     354             :         }
     355             : 
     356           0 :         krb5_free_host_realm(ctx, get_host_realms);
     357           0 :         krb5_free_context(ctx);
     358           0 :         TALLOC_FREE(kdcs);
     359           0 :         return 0;
     360             : #endif
     361             :         DEBUG(1, ("No kerberos support\n"));
     362             :         return -1;
     363             : }
     364             : 
     365           4 : static int net_lookup_name(struct net_context *c, int argc, const char **argv)
     366             : {
     367           0 :         const char *dom, *name;
     368           0 :         struct dom_sid sid;
     369           0 :         struct dom_sid_buf buf;
     370           0 :         enum lsa_SidType type;
     371             : 
     372           4 :         if (argc != 1) {
     373           0 :                 d_printf("%s\n%s",
     374             :                          _("Usage:"),
     375             :                          _(" net lookup name <name>\n"));
     376           0 :                 return -1;
     377             :         }
     378             : 
     379           4 :         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ALL,
     380             :                          &dom, &name, &sid, &type)) {
     381           0 :                 d_printf(_("Could not lookup name %s\n"), argv[0]);
     382           0 :                 return -1;
     383             :         }
     384             : 
     385           4 :         d_printf("%s %d (%s) %s\\%s\n", dom_sid_str_buf(&sid, &buf),
     386             :                  type, sid_type_lookup(type), dom, name);
     387           4 :         return 0;
     388             : }
     389             : 
     390           0 : static int net_lookup_sid(struct net_context *c, int argc, const char **argv)
     391             : {
     392           0 :         const char *dom, *name;
     393           0 :         struct dom_sid sid;
     394           0 :         struct dom_sid_buf buf;
     395           0 :         enum lsa_SidType type;
     396             : 
     397           0 :         if (argc != 1) {
     398           0 :                 d_printf("%s\n%s",
     399             :                          _("Usage:"),
     400             :                          _(" net lookup sid <sid>\n"));
     401           0 :                 return -1;
     402             :         }
     403             : 
     404           0 :         if (!string_to_sid(&sid, argv[0])) {
     405           0 :                 d_printf(_("Could not convert %s to SID\n"), argv[0]);
     406           0 :                 return -1;
     407             :         }
     408             : 
     409           0 :         if (!lookup_sid(talloc_tos(), &sid,
     410             :                         &dom, &name, &type)) {
     411           0 :                 d_printf(_("Could not lookup name %s\n"), argv[0]);
     412           0 :                 return -1;
     413             :         }
     414             : 
     415           0 :         d_printf("%s %d (%s) %s\\%s\n", dom_sid_str_buf(&sid, &buf),
     416             :                  type, sid_type_lookup(type), dom, name);
     417           0 :         return 0;
     418             : }
     419             : 
     420           0 : static int net_lookup_dsgetdcname(struct net_context *c, int argc, const char **argv)
     421             : {
     422           0 :         NTSTATUS status;
     423           0 :         const char *domain_name = NULL;
     424           0 :         const char *site_name = NULL;
     425           0 :         uint32_t flags = 0;
     426           0 :         struct netr_DsRGetDCNameInfo *info = NULL;
     427           0 :         TALLOC_CTX *mem_ctx;
     428           0 :         char *s = NULL;
     429             : 
     430           0 :         if (argc < 1 || argc > 3) {
     431           0 :                 d_printf("%s\n%s",
     432             :                          _("Usage:"),
     433             :                          _(" net lookup dsgetdcname "
     434             :                            "<name> <flags> <sitename>\n"));
     435           0 :                 return -1;
     436             :         }
     437             : 
     438           0 :         mem_ctx = talloc_init("net_lookup_dsgetdcname");
     439           0 :         if (!mem_ctx) {
     440           0 :                 return -1;
     441             :         }
     442             : 
     443           0 :         domain_name = argv[0];
     444             : 
     445           0 :         if (argc >= 2) {
     446           0 :                 sscanf(argv[1], "%x", &flags);
     447             :         }
     448             : 
     449           0 :         if (flags == 0) {
     450           0 :                 flags = DS_DIRECTORY_SERVICE_REQUIRED;
     451             :         }
     452             : 
     453           0 :         if (argc == 3) {
     454           0 :                 site_name = argv[2];
     455             :         }
     456             : 
     457           0 :         if (!c->msg_ctx) {
     458           0 :                 d_fprintf(stderr, _("Could not initialise message context. "
     459             :                         "Try running as root\n"));
     460           0 :                 return -1;
     461             :         }
     462             : 
     463           0 :         status = dsgetdcname(mem_ctx, c->msg_ctx, domain_name, NULL, site_name,
     464             :                              flags, &info);
     465           0 :         if (!NT_STATUS_IS_OK(status)) {
     466           0 :                 d_printf(_("failed with: %s\n"), nt_errstr(status));
     467           0 :                 TALLOC_FREE(mem_ctx);
     468           0 :                 return -1;
     469             :         }
     470             : 
     471           0 :         s = NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info);
     472           0 :         printf("%s\n", s);
     473           0 :         TALLOC_FREE(s);
     474             : 
     475           0 :         TALLOC_FREE(mem_ctx);
     476           0 :         return 0;
     477             : }
     478             : 
     479             : 
     480             : /* lookup hosts or IP addresses using internal samba lookup fns */
     481          18 : int net_lookup(struct net_context *c, int argc, const char **argv)
     482             : {
     483           0 :         int i;
     484             : 
     485          18 :         struct functable table[] = {
     486             :                 {
     487             :                         .funcname = "HOST",
     488             :                         .fn       = net_lookup_host,
     489             :                 },
     490             :                 {
     491             :                         .funcname = "LDAP",
     492             :                         .fn       = net_lookup_ldap,
     493             :                 },
     494             :                 {
     495             :                         .funcname = "DC",
     496             :                         .fn       = net_lookup_dc,
     497             :                 },
     498             :                 {
     499             :                         .funcname = "PDC",
     500             :                         .fn       = net_lookup_pdc,
     501             :                 },
     502             :                 {
     503             :                         .funcname = "MASTER",
     504             :                         .fn       = net_lookup_master,
     505             :                 },
     506             :                 {
     507             :                         .funcname = "KDC",
     508             :                         .fn       = net_lookup_kdc,
     509             :                 },
     510             :                 {
     511             :                         .funcname = "NAME",
     512             :                         .fn       = net_lookup_name,
     513             :                 },
     514             :                 {
     515             :                         .funcname = "SID",
     516             :                         .fn       = net_lookup_sid,
     517             :                 },
     518             :                 {
     519             :                         .funcname = "DSGETDCNAME",
     520             :                         .fn       = net_lookup_dsgetdcname,
     521             :                 },
     522             :                 {
     523             :                         .funcname = NULL,
     524             :                 },
     525             :         };
     526             : 
     527          18 :         if (argc < 1) {
     528           0 :                 d_printf(_("\nUsage: \n"));
     529           0 :                 return net_lookup_usage(c, argc, argv);
     530             :         }
     531          76 :         for (i=0; table[i].funcname; i++) {
     532          76 :                 if (strcasecmp_m(argv[0], table[i].funcname) == 0)
     533          18 :                         return table[i].fn(c, argc-1, argv+1);
     534             :         }
     535             : 
     536             :         /* Default to lookup a hostname so 'net lookup foo#1b' can be
     537             :            used instead of 'net lookup host foo#1b'.  The host syntax
     538             :            is a bit confusing as non #00 names can't really be
     539             :            considered hosts as such. */
     540             : 
     541           0 :         return net_lookup_host(c, argc, argv);
     542             : }

Generated by: LCOV version 1.14