r11232: Added ab's POSIX statvfs vfs call. Sorry for the delay ab.
[gd/samba/.git] / source / utils / net_lookup.c
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "includes.h"
21 #include "utils/net.h"
22
23 int net_lookup_usage(int argc, const char **argv)
24 {
25         d_printf(
26 "  net lookup [host] HOSTNAME[#<type>]\n\tgives IP for a hostname\n\n"
27 "  net lookup ldap [domain]\n\tgives IP of domain's ldap server\n\n"
28 "  net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n"
29 "  net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n"
30 "  net lookup master [domain|wg]\n\tgive IP of master browser\n\n"
31 );
32         return -1;
33 }
34
35 /* lookup a hostname giving an IP */
36 static int net_lookup_host(int argc, const char **argv)
37 {
38         struct in_addr ip;
39         int name_type = 0x20;
40         const char *name = argv[0];
41         char *p;
42
43         if (argc == 0) 
44                 return net_lookup_usage(argc, argv);
45
46         p = strchr_m(name,'#');
47         if (p) {
48                 *p = '\0';
49                 sscanf(++p,"%x",&name_type);
50         }
51         
52         if (!resolve_name(name, &ip, name_type)) {
53                 /* we deliberately use DEBUG() here to send it to stderr 
54                    so scripts aren't mucked up */
55                 DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
56                 return -1;
57         }
58
59         d_printf("%s\n", inet_ntoa(ip));
60         return 0;
61 }
62
63 #ifdef HAVE_LDAP
64 static void print_ldap_srvlist(char *srvlist)
65 {
66         char *cur, *next;
67         struct in_addr ip;
68         BOOL printit;
69
70         cur = srvlist;
71         do {
72                 next = strchr(cur,':');
73                 if (next) *next++='\0';
74                 printit = resolve_name(cur, &ip, 0x20);
75                 cur=next;
76                 next=cur ? strchr(cur,' ') :NULL;
77                 if (next)
78                         *next++='\0';
79                 if (printit)
80                         d_printf("%s:%s\n", inet_ntoa(ip), cur?cur:"");
81                 cur = next;
82         } while (next);
83 }
84 #endif
85
86 static int net_lookup_ldap(int argc, const char **argv)
87 {
88 #ifdef HAVE_LDAP
89         char *srvlist;
90         const char *domain;
91         int rc;
92         struct in_addr addr;
93         struct hostent *hostent;
94
95         if (argc > 0)
96                 domain = argv[0];
97         else
98                 domain = opt_target_workgroup;
99
100         DEBUG(9, ("Lookup up ldap for domain %s\n", domain));
101         rc = ldap_domain2hostlist(domain, &srvlist);
102         if ((rc == LDAP_SUCCESS) && srvlist) {
103                 print_ldap_srvlist(srvlist);
104                 return 0;
105         }
106
107         DEBUG(9, ("Looking up DC for domain %s\n", domain));
108         if (!get_pdc_ip(domain, &addr))
109                 return -1;
110
111         hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr),
112                                 AF_INET);
113         if (!hostent)
114                 return -1;
115
116         DEBUG(9, ("Found DC with DNS name %s\n", hostent->h_name));
117         domain = strchr(hostent->h_name, '.');
118         if (!domain)
119                 return -1;
120         domain++;
121
122         DEBUG(9, ("Looking up ldap for domain %s\n", domain));
123         rc = ldap_domain2hostlist(domain, &srvlist);
124         if ((rc == LDAP_SUCCESS) && srvlist) {
125                 print_ldap_srvlist(srvlist);
126                 return 0;
127         }
128         return -1;
129 #endif
130         DEBUG(1,("No LDAP support\n"));
131         return -1;
132 }
133
134 static int net_lookup_dc(int argc, const char **argv)
135 {
136         struct ip_service *ip_list;
137         struct in_addr addr;
138         char *pdc_str = NULL;
139         const char *domain=opt_target_workgroup;
140         int count, i;
141
142         if (argc > 0)
143                 domain=argv[0];
144
145         /* first get PDC */
146         if (!get_pdc_ip(domain, &addr))
147                 return -1;
148
149         asprintf(&pdc_str, "%s", inet_ntoa(addr));
150         d_printf("%s\n", pdc_str);
151
152         if (!get_sorted_dc_list(domain, &ip_list, &count, False)) {
153                 SAFE_FREE(pdc_str);
154                 return 0;
155         }
156         for (i=0;i<count;i++) {
157                 char *dc_str = inet_ntoa(ip_list[i].ip);
158                 if (!strequal(pdc_str, dc_str))
159                         d_printf("%s\n", dc_str);
160         }
161         SAFE_FREE(pdc_str);
162         return 0;
163 }
164
165 static int net_lookup_master(int argc, const char **argv)
166 {
167         struct in_addr master_ip;
168         const char *domain=opt_target_workgroup;
169
170         if (argc > 0)
171                 domain=argv[0];
172
173         if (!find_master_ip(domain, &master_ip))
174                 return -1;
175         d_printf("%s\n", inet_ntoa(master_ip));
176         return 0;
177 }
178
179 static int net_lookup_kdc(int argc, const char **argv)
180 {
181 #ifdef HAVE_KRB5
182         krb5_error_code rc;
183         krb5_context ctx;
184         struct sockaddr_in *addrs;
185         int num_kdcs,i;
186         krb5_data realm;
187         char **realms;
188
189         rc = krb5_init_context(&ctx);
190         if (rc) {
191                 DEBUG(1,("krb5_init_context failed (%s)\n", 
192                          error_message(rc)));
193                 return -1;
194         }
195
196         if (argc>0) {
197                 realm.data = CONST_DISCARD(krb5_pointer, argv[0]);
198                 realm.length = strlen(argv[0]);
199         } else if (lp_realm() && *lp_realm()) {
200                 realm.data = (krb5_pointer) lp_realm();
201                 realm.length = strlen(realm.data);
202         } else {
203                 rc = krb5_get_host_realm(ctx, NULL, &realms);
204                 if (rc) {
205                         DEBUG(1,("krb5_gethost_realm failed (%s)\n",
206                                  error_message(rc)));
207                         return -1;
208                 }
209                 realm.data = (krb5_pointer) *realms;
210                 realm.length = strlen(realm.data);
211         }
212
213         rc = krb5_locate_kdc(ctx, &realm, (struct sockaddr **) &addrs, &num_kdcs, 0);
214         if (rc) {
215                 DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
216                 return -1;
217         }
218         for (i=0;i<num_kdcs;i++)
219                 if (addrs[i].sin_family == AF_INET) 
220                         d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr),
221                                  ntohs(addrs[i].sin_port));
222         return 0;
223
224 #endif  
225         DEBUG(1, ("No kerberos support\n"));
226         return -1;
227 }
228
229
230 /* lookup hosts or IP addresses using internal samba lookup fns */
231 int net_lookup(int argc, const char **argv)
232 {
233         int i;
234
235         struct functable table[] = {
236                 {"HOST", net_lookup_host},
237                 {"LDAP", net_lookup_ldap},
238                 {"DC", net_lookup_dc},
239                 {"MASTER", net_lookup_master},
240                 {"KDC", net_lookup_kdc},
241                 {NULL, NULL}
242         };
243
244         if (argc < 1) {
245                 d_printf("\nUsage: \n");
246                 return net_lookup_usage(argc, argv);
247         }
248         for (i=0; table[i].funcname; i++) {
249                 if (StrCaseCmp(argv[0], table[i].funcname) == 0)
250                         return table[i].fn(argc-1, argv+1);
251         }
252
253         /* Default to lookup a hostname so 'net lookup foo#1b' can be 
254            used instead of 'net lookup host foo#1b'.  The host syntax
255            is a bit confusing as non #00 names can't really be 
256            considered hosts as such. */
257
258         return net_lookup_host(argc, argv);
259 }