From c54af0f8b20e3f93c59da6a817920e1de6c4a870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 Mar 1998 20:59:47 +0000 Subject: Adding the same change as was added to 1.9.18 branch to add the "name resolve order" parameter. source/Makefile: Re-ordered link for name resolve order code. source/clientgen.c: source/clientutil.c: Added calls to resolve_name(). source/includes.h: Added HPUX zombie fix. source/loadparm.c: Added new name resolve order parameter. source/namequery.c: Re-wrote to include parsing of lmhosts file, new resolve_name() function requested by John. source/nmbd.c: Tell resolve_name not to do WINS lookups if we are the WINS server. source/nmbd_lmhosts.c: Call lmhosts parsing functions in namequery.c source/password.c: Call resolve_name() to lookup security=server name. source/reply.c: source/time.c: source/trans2.c: "fake directory create times" fix from Jim Hague - hague@research.canon.com.au. source/util.c: Removed isalnum() test in Get_Hostname() that seems to cause problems on many systems. Jeremy. (This used to be commit 7f118970da7c43eaddcf92dc056d3e849f1e7d5c) --- source3/libsmb/clientgen.c | 10 +- source3/libsmb/namequery.c | 263 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 319a77beb6..4585c8a544 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1343,13 +1343,9 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip) { - struct hostent *hp; - - if ((hp = Get_Hostbyname(cli->desthost)) == 0) { - return False; - } - - putip((char *)&dest_ip,(char *)hp->h_addr); + if(!resolve_name( cli->desthost, &dest_ip)) { + return False; + } } else { dest_ip = *ip; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 207f064670..6bf41b9f9e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -25,6 +25,8 @@ extern pstring scope; extern int DEBUGLEVEL; +/* nmbd.c sets this to True. */ +BOOL global_in_nmbd = False; /**************************************************************************** interpret a node status response @@ -303,3 +305,264 @@ struct in_addr *name_query(int fd,char *name,int name_type, return ip_list; } + +/******************************************************** + Start parsing the lmhosts file. +*********************************************************/ + +FILE *startlmhosts(char *fname) +{ + FILE *fp = fopen(fname,"r"); + if (!fp) { + DEBUG(2,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", + fname, strerror(errno))); + return NULL; + } + return fp; +} + +/******************************************************** + Parse the next line in the lmhosts file. +*********************************************************/ + +BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr) +{ + pstring line; + + while(!feof(fp) && !ferror(fp)) { + pstring ip,flags,extra; + char *ptr; + int count = 0; + + *name_type = -1; + + if (!fgets_slash(line,sizeof(pstring),fp)) + continue; + + if (*line == '#') + continue; + + strcpy(ip,""); + strcpy(name,""); + strcpy(flags,""); + + ptr = line; + + if (next_token(&ptr,ip ,NULL)) + ++count; + if (next_token(&ptr,name ,NULL)) + ++count; + if (next_token(&ptr,flags,NULL)) + ++count; + if (next_token(&ptr,extra,NULL)) + ++count; + + if (count <= 0) + continue; + + if (count > 0 && count < 2) + { + DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); + continue; + } + + if (count >= 4) + { + DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + continue; + } + + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + + if (strchr(flags,'G') || strchr(flags,'S')) + { + DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + continue; + } + + *ipaddr = *interpret_addr2(ip); + + /* Extra feature. If the name ends in '#XX', where XX is a hex number, + then only add that name type. */ + if((ptr = strchr(name, '#')) != NULL) + { + char *endptr; + + ptr++; + *name_type = (int)strtol(ptr, &endptr,0); + + if(!*ptr || (endptr == ptr)) + { + DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); + continue; + } + + *(--ptr) = '\0'; /* Truncate at the '#' */ + } + + return True; + } + + return False; +} + +/******************************************************** + Finish parsing the lmhosts file. +*********************************************************/ + +void endlmhosts(FILE *fp) +{ + fclose(fp); +} + +/******************************************************** + Resolve a name into an IP address. Use this function if + the string is either an IP address, DNS or host name + or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ + +BOOL resolve_name(char *name, struct in_addr *return_ip) +{ + char *p; + int i; + BOOL pure_address = True; + + if (strcmp(name,"0.0.0.0") == 0) { + return_ip->s_addr = 0; + return True; + } + if (strcmp(name,"255.255.255.255") == 0) { + return_ip->s_addr = 0xFFFFFFFF; + return True; + } + + for (i=0; pure_address && name[i]; i++) + if (!(isdigit(name[i]) || name[i] == '.')) + pure_address = False; + + /* if it's in the form of an IP address then get the lib to interpret it */ + if (pure_address) { + return_ip->s_addr = inet_addr(name); + return True; + } + + for (p=strtok(lp_name_resolve_order(),LIST_SEP); p; p = strtok(NULL,LIST_SEP)) { + if(strequal(p, "host") || strequal(p, "hosts")) { + + /* + * "host" means do a localhost, or dns lookup. + */ + + struct hostent *hp; + + DEBUG(3,("resolve_name: Attempting host lookup for name %s\n")); + + if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + putip((char *)return_ip,(char *)hp->h_addr); + return True; + } + + } else if(strequal( p, "lmhosts")) { + + /* + * "lmhosts" means parse the local lmhosts file. + */ + + FILE *fp; + pstring lmhost_name; + int name_type; + + DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n")); + + fp = startlmhosts( LMHOSTSFILE ); + if(fp) { + while( getlmhostsent(fp, lmhost_name, &name_type, return_ip ) ) { + if( strequal(name, lmhost_name )) { + endlmhosts(fp); + return True; + } + } + endlmhosts(fp); + } + + } else if(strequal( p, "wins")) { + + int sock; + + /* + * "wins" means do a unicast lookup to the WINS server. + * Ignore if there is no WINS server specified or if the + * WINS server is one of our interfaces (if we're being + * called from within nmbd - we can't do this call as we + * would then block). + */ + + DEBUG(3,("resolve_name: Attempting wins lookup for name %s\n")); + + if(*lp_wins_server()) { + struct in_addr wins_ip = *interpret_addr2(lp_wins_server()); + BOOL wins_ismyip = ismyip(wins_ip); + + if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + iplist = name_query(sock, name, 0x20, False, True, wins_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + close(sock); + } + } + } else { + DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); + } + } else if(strequal( p, "bcast")) { + + int sock; + + /* + * "bcast" means do a broadcast lookup on all the local interfaces. + */ + + DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s\n")); + + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + int num_interfaces = iface_count(); + set_socket_options(sock,"SO_BROADCAST"); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = 0; i < num_interfaces; i++) { + struct in_addr sendto_ip = *iface_bcast(*iface_n_ip(i)); + iplist = name_query(sock, name, 0x20, True, False, sendto_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + } + close(sock); + } + + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", p)); + } + } + + return False; +} -- cgit