diff options
Diffstat (limited to 'source4/utils/net_lookup.c')
-rw-r--r-- | source4/utils/net_lookup.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/source4/utils/net_lookup.c b/source4/utils/net_lookup.c new file mode 100644 index 0000000000..271094480c --- /dev/null +++ b/source4/utils/net_lookup.c @@ -0,0 +1,234 @@ +/* + Samba Unix/Linux SMB client library + net lookup command + Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "../utils/net.h" + +int net_lookup_usage(int argc, const char **argv) +{ + d_printf( +" net lookup host HOSTNAME <type>\n\tgives IP for a hostname\n\n" +" net lookup ldap [domain]\n\tgives IP of domain's ldap server\n\n" +" net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n" +" net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n" +" net lookup master [domain|wg]\n\tgive IP of master browser\n\n" +); + return -1; +} + +/* lookup a hostname giving an IP */ +static int net_lookup_host(int argc, const char **argv) +{ + struct in_addr ip; + int name_type = 0x20; + + if (argc == 0) return net_lookup_usage(argc, argv); + if (argc > 1) name_type = strtol(argv[1], NULL, 0); + + if (!resolve_name(argv[0], &ip, name_type)) { + /* we deliberately use DEBUG() here to send it to stderr + so scripts aren't mucked up */ + DEBUG(0,("Didn't find %s#%02x\n", argv[0], name_type)); + return -1; + } + + d_printf("%s\n", inet_ntoa(ip)); + return 0; +} + +static void print_ldap_srvlist(char *srvlist) +{ + char *cur, *next; + struct in_addr ip; + BOOL printit; + + cur = srvlist; + do { + next = strchr(cur,':'); + if (next) *next++='\0'; + printit = resolve_name(cur, &ip, 0x20); + cur=next; + next=cur ? strchr(cur,' ') :NULL; + if (next) + *next++='\0'; + if (printit) + d_printf("%s:%s\n", inet_ntoa(ip), cur?cur:""); + cur = next; + } while (next); +} + + +static int net_lookup_ldap(int argc, const char **argv) +{ +#ifdef HAVE_LDAP + char *srvlist; + const char *domain; + int rc; + struct in_addr addr; + struct hostent *hostent; + + if (argc > 0) + domain = argv[0]; + else + domain = opt_target_workgroup; + + DEBUG(9, ("Lookup up ldap for domain %s\n", domain)); + rc = ldap_domain2hostlist(domain, &srvlist); + if ((rc == LDAP_SUCCESS) && srvlist) { + print_ldap_srvlist(srvlist); + return 0; + } + + DEBUG(9, ("Looking up DC for domain %s\n", domain)); + if (!get_pdc_ip(domain, &addr)) + return -1; + + hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr), + AF_INET); + if (!hostent) + return -1; + + DEBUG(9, ("Found DC with DNS name %s\n", hostent->h_name)); + domain = strchr(hostent->h_name, '.'); + if (!domain) + return -1; + domain++; + + DEBUG(9, ("Looking up ldap for domain %s\n", domain)); + rc = ldap_domain2hostlist(domain, &srvlist); + if ((rc == LDAP_SUCCESS) && srvlist) { + print_ldap_srvlist(srvlist); + return 0; + } + return -1; +#endif + DEBUG(1,("No LDAP support\n")); + return -1; +} + +static int net_lookup_dc(int argc, const char **argv) +{ + struct in_addr *ip_list, addr; + char *pdc_str = NULL; + const char *domain=opt_target_workgroup; + int count, i; + BOOL list_ordered; + + if (argc > 0) + domain=argv[0]; + + /* first get PDC */ + if (!get_pdc_ip(domain, &addr)) + return -1; + + asprintf(&pdc_str, "%s", inet_ntoa(addr)); + d_printf("%s\n", pdc_str); + + if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) { + SAFE_FREE(pdc_str); + return 0; + } + for (i=0;i<count;i++) { + char *dc_str = inet_ntoa(ip_list[i]); + if (!strequal(pdc_str, dc_str)) + d_printf("%s\n", dc_str); + } + SAFE_FREE(pdc_str); + return 0; +} + +static int net_lookup_master(int argc, const char **argv) +{ + struct in_addr master_ip; + const char *domain=opt_target_workgroup; + + if (argc > 0) + domain=argv[0]; + + if (!find_master_ip(domain, &master_ip)) + return -1; + d_printf("%s\n", inet_ntoa(master_ip)); + return 0; +} + +static int net_lookup_kdc(int argc, const char **argv) +{ +#ifdef HAVE_KRB5 + krb5_error_code rc; + krb5_context ctx; + struct sockaddr_in *addrs; + int num_kdcs,i; + krb5_data realm; + char **realms; + + rc = krb5_init_context(&ctx); + if (rc) { + DEBUG(1,("krb5_init_context failed (%s)\n", + error_message(rc))); + return -1; + } + + if (argc>0) { + realm.data = (krb5_pointer) argv[0]; + realm.length = strlen(argv[0]); + } else if (lp_realm() && *lp_realm()) { + realm.data = (krb5_pointer) lp_realm(); + realm.length = strlen(realm.data); + } else { + rc = krb5_get_host_realm(ctx, NULL, &realms); + if (rc) { + DEBUG(1,("krb5_gethost_realm failed (%s)\n", + error_message(rc))); + return -1; + } + realm.data = (krb5_pointer) *realms; + realm.length = strlen(realm.data); + } + + rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0); + if (rc) { + DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc))); + return -1; + } + for (i=0;i<num_kdcs;i++) + if (addrs[i].sin_family == AF_INET) + d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr), + ntohs(addrs[i].sin_port)); + return 0; + +#endif + DEBUG(1, ("No kerberos support\n")); + return -1; +} + + +/* lookup hosts or IP addresses using internal samba lookup fns */ +int net_lookup(int argc, const char **argv) +{ + struct functable func[] = { + {"HOST", net_lookup_host}, + {"LDAP", net_lookup_ldap}, + {"DC", net_lookup_dc}, + {"MASTER", net_lookup_master}, + {"KDC", net_lookup_kdc}, + {NULL, NULL} + }; + + return net_run_function(argc, argv, func, net_lookup_usage); +} |