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 23int 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" net lookup name [name]\n\tLookup name's sid and type\n\n" 32" net lookup sid [sid]\n\tGive sid's name and type\n\n" 33); 34 return -1; 35} 36 37/* lookup a hostname giving an IP */ 38static int net_lookup_host(int argc, const char **argv) 39{ 40 struct in_addr ip; 41 int name_type = 0x20; 42 const char *name = argv[0]; 43 char *p; 44 45 if (argc == 0) 46 return net_lookup_usage(argc, argv); 47 48 p = strchr_m(name,'#'); 49 if (p) { 50 *p = '\0'; 51 sscanf(++p,"%x",&name_type); 52 } 53 54 if (!resolve_name(name, &ip, name_type)) { 55 /* we deliberately use DEBUG() here to send it to stderr 56 so scripts aren't mucked up */ 57 DEBUG(0,("Didn't find %s#%02x\n", name, name_type)); 58 return -1; 59 } 60 61 d_printf("%s\n", inet_ntoa(ip)); 62 return 0; 63} 64 65#ifdef HAVE_ADS 66static void print_ldap_srvlist(struct dns_rr_srv *dclist, int numdcs ) 67{ 68 struct in_addr ip; 69 int i; 70 71 for ( i=0; i<numdcs; i++ ) { 72 if ( resolve_name(dclist[i].hostname, &ip, 0x20) ) { 73 d_printf("%s:%d\n", inet_ntoa(ip), dclist[i].port); 74 } 75 } 76} 77#endif 78 79static int net_lookup_ldap(int argc, const char **argv) 80{ 81#ifdef HAVE_ADS 82 const char *domain; 83 struct in_addr addr; 84 struct hostent *hostent; 85 struct dns_rr_srv *dcs = NULL; 86 int numdcs = 0; 87 char *sitename; 88 TALLOC_CTX *ctx; 89 NTSTATUS status; 90 91 if (argc > 0) 92 domain = argv[0]; 93 else 94 domain = opt_target_workgroup; 95 96 sitename = sitename_fetch(domain); 97 98 if ( (ctx = talloc_init("net_lookup_ldap")) == NULL ) { 99 d_fprintf(stderr, "net_lookup_ldap: talloc_inti() failed!\n"); 100 SAFE_FREE(sitename); 101 return -1; 102 } 103 104 DEBUG(9, ("Lookup up ldap for domain %s\n", domain)); 105 106 status = ads_dns_query_dcs( ctx, domain, sitename, &dcs, &numdcs ); 107 if ( NT_STATUS_IS_OK(status) && numdcs ) { 108 print_ldap_srvlist(dcs, numdcs); 109 TALLOC_FREE( ctx ); 110 SAFE_FREE(sitename); 111 return 0; 112 } 113 114 DEBUG(9, ("Looking up DC for domain %s\n", domain)); 115 if (!get_pdc_ip(domain, &addr)) { 116 TALLOC_FREE( ctx ); 117 SAFE_FREE(sitename); 118 return -1; 119 } 120 121 hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr), 122 AF_INET); 123 if (!hostent) { 124 TALLOC_FREE( ctx ); 125 SAFE_FREE(sitename); 126 return -1; 127 } 128 129 DEBUG(9, ("Found DC with DNS name %s\n", hostent->h_name)); 130 domain = strchr(hostent->h_name, '.'); 131 if (!domain) { 132 TALLOC_FREE( ctx ); 133 SAFE_FREE(sitename); 134 return -1; 135 } 136 domain++; 137 138 DEBUG(9, ("Looking up ldap for domain %s\n", domain)); 139 140 status = ads_dns_query_dcs( ctx, domain, sitename, &dcs, &numdcs ); 141 if ( NT_STATUS_IS_OK(status) && numdcs ) { 142 print_ldap_srvlist(dcs, numdcs); 143 TALLOC_FREE( ctx ); 144 SAFE_FREE(sitename); 145 return 0; 146 } 147 148 TALLOC_FREE( ctx ); 149 SAFE_FREE(sitename); 150 151 return -1; 152#endif 153 DEBUG(1,("No ADS support\n")); 154 return -1; 155} 156 157static int net_lookup_dc(int argc, const char **argv) 158{ 159 struct ip_service *ip_list; 160 struct in_addr addr; 161 char *pdc_str = NULL; 162 const char *domain=opt_target_workgroup; 163 char *sitename = NULL; 164 int count, i; 165 166 if (argc > 0) 167 domain=argv[0]; 168 169 /* first get PDC */ 170 if (!get_pdc_ip(domain, &addr)) 171 return -1; 172 173 asprintf(&pdc_str, "%s", inet_ntoa(addr)); 174 d_printf("%s\n", pdc_str); 175 176 sitename = sitename_fetch(domain); 177 if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, sitename, &ip_list, &count, False))) { 178 SAFE_FREE(pdc_str); 179 SAFE_FREE(sitename); 180 return 0; 181 } 182 SAFE_FREE(sitename); 183 for (i=0;i<count;i++) { 184 char *dc_str = inet_ntoa(ip_list[i].ip); 185 if (!strequal(pdc_str, dc_str)) 186 d_printf("%s\n", dc_str); 187 } 188 SAFE_FREE(pdc_str); 189 return 0; 190} 191 192static int net_lookup_master(int argc, const char **argv) 193{ 194 struct in_addr master_ip; 195 const char *domain=opt_target_workgroup; 196 197 if (argc > 0) 198 domain=argv[0]; 199 200 if (!find_master_ip(domain, &master_ip)) 201 return -1; 202 d_printf("%s\n", inet_ntoa(master_ip)); 203 return 0; 204} 205 206static int net_lookup_kdc(int argc, const char **argv) 207{ 208#ifdef HAVE_KRB5 209 krb5_error_code rc; 210 krb5_context ctx; 211 struct sockaddr_in *addrs; 212 int num_kdcs,i; 213 krb5_data realm; 214 char **realms; 215 216 initialize_krb5_error_table(); 217 rc = krb5_init_context(&ctx); 218 if (rc) { 219 DEBUG(1,("krb5_init_context failed (%s)\n", 220 error_message(rc))); 221 return -1; 222 } 223 224 if (argc>0) { 225 realm.data = CONST_DISCARD(char *, argv[0]); 226 realm.length = strlen(argv[0]); 227 } else if (lp_realm() && *lp_realm()) { 228 realm.data = lp_realm(); 229 realm.length = strlen((const char *)realm.data); 230 } else { 231 rc = krb5_get_host_realm(ctx, NULL, &realms); 232 if (rc) { 233 DEBUG(1,("krb5_gethost_realm failed (%s)\n", 234 error_message(rc))); 235 return -1; 236 } 237 realm.data = (char *) *realms; 238 realm.length = strlen((const char *)realm.data); 239 } 240 241 rc = smb_krb5_locate_kdc(ctx, &realm, (struct sockaddr **)(void *)&addrs, &num_kdcs, 0); 242 if (rc) { 243 DEBUG(1, ("smb_krb5_locate_kdc failed (%s)\n", error_message(rc))); 244 return -1; 245 } 246 for (i=0;i<num_kdcs;i++) 247 if (addrs[i].sin_family == AF_INET) 248 d_printf("%s:%hd\n", inet_ntoa(addrs[i].sin_addr), 249 ntohs(addrs[i].sin_port)); 250 return 0; 251 252#endif 253 DEBUG(1, ("No kerberos support\n")); 254 return -1; 255} 256 257static int net_lookup_name(int argc, const char **argv) 258{ 259 const char *dom, *name; 260 DOM_SID sid; 261 enum lsa_SidType type; 262 263 if (argc != 1) { 264 d_printf("usage: net lookup name <name>\n"); 265 return -1; 266 } 267 268 if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ALL, 269 &dom, &name, &sid, &type)) { 270 d_printf("Could not lookup name %s\n", argv[0]); 271 return -1; 272 } 273 274 d_printf("%s %d (%s) %s\\%s\n", sid_string_static(&sid), 275 type, sid_type_lookup(type), dom, name); 276 return 0; 277} 278 279static int net_lookup_sid(int argc, const char **argv) 280{ 281 const char *dom, *name; 282 DOM_SID sid; 283 enum lsa_SidType type; 284 285 if (argc != 1) { 286 d_printf("usage: net lookup sid <sid>\n"); 287 return -1; 288 } 289 290 if (!string_to_sid(&sid, argv[0])) { 291 d_printf("Could not convert %s to SID\n", argv[0]); 292 return -1; 293 } 294 295 if (!lookup_sid(tmp_talloc_ctx(), &sid, 296 &dom, &name, &type)) { 297 d_printf("Could not lookup name %s\n", argv[0]); 298 return -1; 299 } 300 301 d_printf("%s %d (%s) %s\\%s\n", sid_string_static(&sid), 302 type, sid_type_lookup(type), dom, name); 303 return 0; 304} 305 306/* lookup hosts or IP addresses using internal samba lookup fns */ 307int net_lookup(int argc, const char **argv) 308{ 309 int i; 310 311 struct functable table[] = { 312 {"HOST", net_lookup_host}, 313 {"LDAP", net_lookup_ldap}, 314 {"DC", net_lookup_dc}, 315 {"MASTER", net_lookup_master}, 316 {"KDC", net_lookup_kdc}, 317 {"NAME", net_lookup_name}, 318 {"SID", net_lookup_sid}, 319 {NULL, NULL} 320 }; 321 322 if (argc < 1) { 323 d_printf("\nUsage: \n"); 324 return net_lookup_usage(argc, argv); 325 } 326 for (i=0; table[i].funcname; i++) { 327 if (StrCaseCmp(argv[0], table[i].funcname) == 0) 328 return table[i].fn(argc-1, argv+1); 329 } 330 331 /* Default to lookup a hostname so 'net lookup foo#1b' can be 332 used instead of 'net lookup host foo#1b'. The host syntax 333 is a bit confusing as non #00 names can't really be 334 considered hosts as such. */ 335 336 return net_lookup_host(argc, argv); 337} 338