From 82d718317cac27430b0be43a5d7ddc59c26fca22 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 17 Aug 1996 13:17:45 +0000 Subject: - started on support for 'Internet Group names' - type 0x1c NetBIOS names - 0x1d name query to a WINS server should always return FAIL (see WINS server help on nt/as) (This used to be commit a7330127a261f814c56e860b6de658dbef24c33f) --- source3/include/nameserv.h | 12 ++++- source3/include/proto.h | 5 ++ source3/namedbname.c | 111 ++++++++++++++++++++++++++++++--------------- source3/nameserv.c | 21 +++++---- source3/nameservreply.c | 31 ++++++++----- 5 files changed, 119 insertions(+), 61 deletions(-) diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h index 5162ebe2d7..a505f403ca 100644 --- a/source3/include/nameserv.h +++ b/source3/include/nameserv.h @@ -121,6 +121,14 @@ struct nmb_name { int name_type; }; +/* a netbios flags + ip address structure */ +/* this is used for multi-homed systems and for internet group names */ +struct nmb_ip +{ + struct in_addr ip; /* ip address of host that owns this name */ + int nb_flags; /* netbios flags */ +}; + /* this is the structure used for the local netbios name list */ struct name_record { @@ -128,8 +136,8 @@ struct name_record struct name_record *prev; struct nmb_name name; /* the netbios name */ - struct in_addr ip; /* ip address of host that owns this name */ - int nb_flags; /* netbios flags */ + struct nmb_ip *ip_flgs; /* the ip + flags */ + int num_ips; /* number of ip+flags entries */ enum name_source source; /* where the name came from */ diff --git a/source3/include/proto.h b/source3/include/proto.h index c1697dc641..87ad286df3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -796,6 +796,11 @@ BOOL become_user(int cnum, int uid); BOOL unbecome_user(void ); int smbrun(char *cmd,char *outfile); +/*The following definitions come from unxlog.c */ + +void write_utmp(int dologin, int connection, int pid, + char *from_addr, char *username); + /*The following definitions come from username.c */ char *get_home_dir(char *user); diff --git a/source3/namedbname.c b/source3/namedbname.c index 214926cfc9..3e6b8428cf 100644 --- a/source3/namedbname.c +++ b/source3/namedbname.c @@ -228,25 +228,50 @@ void dump_names(void) for (d = subnetlist; d; d = d->next) for (n = d->namelist; n; n = n->next) { - if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER) - { - /* XXXX i have little imagination as to how to output nb_flags as - anything other than as a hexadecimal number :-) */ - - fprintf(f, "%s#%02x %s %2x %ld\n", - n->name.name,n->name.name_type, /* XXXX ignore scope for now */ - inet_ntoa(n->ip), - n->nb_flags, - n->death_time); - } + int i; DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip))); DEBUG(3,("%15s ", inet_ntoa(d->mask_ip))); - DEBUG(3,("%-19s %15s NB=%2x TTL=%ld \n", + DEBUG(3,("%-19s TTL=%ld ", namestr(&n->name), - inet_ntoa(n->ip), - n->nb_flags, - n->death_time?n->death_time-t:0)); + n->death_time?n->death_time-t:0)); + + for (i = 0; i < n->num_ips; i++) + { + DEBUG(3,("%15s NB=%2x ", + inet_ntoa(n->ip_flgs[i].ip), + n->ip_flgs[i].nb_flags)); + + } + DEBUG(3,("\n")); + + if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER) + { + fstring data; + + /* XXXX i have little imagination as to how to output nb_flags as + anything other than as a hexadecimal number :-) */ + + sprintf(data, "%s#%02x %ld", + n->name.name,n->name.name_type, /* XXXX ignore scope for now */ + n->death_time); + fprintf(f, "%s", data); + for (i = 0; i < n->num_ips; i++) + { + DEBUG(3,("%15s NB=%2x ", + inet_ntoa(n->ip_flgs[i].ip), + n->ip_flgs[i].nb_flags)); + + sprintf(data, "%s %2x ", + inet_ntoa(n->ip_flgs[i].ip), + n->ip_flgs[i].nb_flags); + + fprintf(f, "%s", data); + } + DEBUG(3,("\n")); + fprintf(f, "\n"); + } + } fclose(f); @@ -291,12 +316,12 @@ void load_netbios_names(void) int type = 0; int nb_flags; time_t ttd; - struct in_addr ipaddr; + struct in_addr ipaddr; - enum name_source source; + enum name_source source; char *ptr; - int count = 0; + int count = 0; char *p; @@ -304,24 +329,24 @@ void load_netbios_names(void) if (*line == '#') continue; - ptr = line; + ptr = line; + + if (next_token(&ptr,name_str ,NULL)) ++count; + if (next_token(&ptr,ip_str ,NULL)) ++count; + if (next_token(&ptr,ttd_str ,NULL)) ++count; + if (next_token(&ptr,nb_flags_str,NULL)) ++count; + + if (count <= 0) continue; + + if (count != 4) { + DEBUG(0,("Ill formed wins line")); + DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line)); + continue; + } - if (next_token(&ptr,name_str ,NULL)) ++count; - if (next_token(&ptr,ip_str ,NULL)) ++count; - if (next_token(&ptr,nb_flags_str,NULL)) ++count; - if (next_token(&ptr,ttd_str ,NULL)) ++count; - - if (count <= 0) continue; - - if (count != 4) { - DEBUG(0,("Ill formed wins line")); - DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line)); - continue; - } - /* netbios name. # divides the name from the type (hex): netbios#xx */ strcpy(name,name_str); - + p = strchr(name,'#'); if (p) { @@ -418,10 +443,19 @@ struct name_record *add_netbios_entry(struct subnet_record *d, bzero((char *)n,sizeof(*n)); + n->num_ips = 1; /* XXXX ONLY USE THIS FUNCTION FOR ONE ENTRY */ + n->ip_flgs = (struct nmb_ip*)malloc(sizeof(*n->ip_flgs) * n->num_ips); + if (!n->ip_flgs) + { + free(n); + return NULL; + } + make_nmb_name(&n->name,name,type,scope); if ((n2 = find_name_search(&d, &n->name, search, new_only?ipzero:ip))) { + free(n->ip_flgs); free(n); if (new_only || (n2->source==SELF && source!=SELF)) return n2; n = n2; @@ -431,8 +465,10 @@ struct name_record *add_netbios_entry(struct subnet_record *d, n->death_time = time(NULL)+ttl*3; n->refresh_time = time(NULL)+GET_TTL(ttl); - n->ip = ip; - n->nb_flags = nb_flags; + /* XXXX only one entry expected with this function */ + n->ip_flgs[0].ip = ip; + n->ip_flgs[0].nb_flags = nb_flags; + n->source = source; if (!n2) add_name(d,n); @@ -469,6 +505,7 @@ void expire_names(time_t t) if (d->namelist == n) d->namelist = n->next; + free(n->ip_flgs); free(n); } else @@ -506,7 +543,7 @@ struct name_record *search_for_name(struct subnet_record **d, if (!n) { struct in_addr dns_ip; - uint32 a; + unsigned long a; /* only do DNS lookups if the query is for type 0x20 or type 0x0 */ if (!dns_type && name_type != 0x1b) @@ -551,7 +588,7 @@ struct name_record *search_for_name(struct subnet_record **d, return NULL; } - DEBUG(3,("OK %s\n",inet_ntoa(n->ip))); + DEBUG(3,("OK %s\n",inet_ntoa(n->ip_flgs[0].ip))); return n; } diff --git a/source3/nameserv.c b/source3/nameserv.c index 0297fee331..ed48adb623 100644 --- a/source3/nameserv.c +++ b/source3/nameserv.c @@ -66,11 +66,11 @@ void remove_name_entry(struct subnet_record *d, char *name,int type) if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero))) { /* check name isn't already being de-registered */ - if (NAME_DEREG(n2->nb_flags)) + if (NAME_DEREG(n2->ip_flgs[0].nb_flags)) return; /* mark the name as in the process of deletion. */ - n2->nb_flags &= NB_DEREG; + n2->ip_flgs[0].nb_flags &= NB_DEREG; } if (ip_equal(d->bcast_ip, ipgrp)) @@ -196,14 +196,14 @@ void add_my_names(void) add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,ip,False,wins); add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,ip,False,wins); - if (lp_domain_logons()) { - /* 0x1c is used to find logon servers for a domain */ - add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP); - } + if (lp_domain_logons()) { + /* XXXX the 0x1c is apparently something to do with domain logons */ + add_my_name_entry(d, my_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP); + } } if (lp_domain_master() && (d = find_subnet(ipgrp))) { - struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True); + struct work_record *work = find_workgroupstruct(d, my_workgroup(), True); if (work && work->state == MST_NONE) { work->state = MST_DOMAIN_NONE; @@ -256,7 +256,8 @@ void refresh_my_names(time_t t) if (n->source == SELF && n->refresh_time < time(NULL) && n->death_time != 0) { - add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags); + add_my_name_entry(d,n->name.name,n->name.name_type, + n->ip_flgs[0].nb_flags); } } } @@ -301,7 +302,7 @@ void query_refresh_names(void) /* only do unique, registered names */ if (n->source != REGISTER) continue; - if (!NAME_GROUP(n->nb_flags)) continue; + if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue; if (n->refresh_time < t) { @@ -310,7 +311,7 @@ void query_refresh_names(void) queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM, n->name.name, n->name.name_type, 0,0,0,NULL,NULL, - False,False,n->ip,n->ip); + False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip); count++; } diff --git a/source3/nameservreply.c b/source3/nameservreply.c index 5b45e88c5e..b77f9958b8 100644 --- a/source3/nameservreply.c +++ b/source3/nameservreply.c @@ -135,7 +135,7 @@ void reply_name_release(struct packet_struct *p) search, ip); /* XXXX under what conditions should we reject the removal?? */ - if (n && n->nb_flags == nb_flags) + if (n && n->ip_flgs[0].nb_flags == nb_flags) { success = True; @@ -212,14 +212,14 @@ void reply_name_reg(struct packet_struct *p) { if (!group) /* unique names */ { - if (n->source == SELF || NAME_GROUP(n->nb_flags)) + if (n->source == SELF || NAME_GROUP(n->ip_flgs[0].nb_flags)) { /* no-one can register one of samba's names, nor can they register a name that's a group name as a unique name */ success = False; } - else if(!ip_equal(ip, n->ip)) + else if(!ip_equal(ip, n->ip_flgs[0].ip)) { /* XXXX rfc1001.txt says: * if we are doing secured WINS, we must send a Wait-Acknowledge @@ -235,9 +235,9 @@ void reply_name_reg(struct packet_struct *p) } else { - n->ip = ip; + n->ip_flgs[0].ip = ip; n->death_time = ttl?p->timestamp+ttl*3:0; - DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip))); + DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip_flgs[0].ip))); } } else @@ -276,7 +276,7 @@ void reply_name_reg(struct packet_struct *p) { char rdata[2]; - /* XXXX luke is confused. RSVAL or SSVAL? assume NMB byte ordering */ + /* XXXX i am confused. RSVAL or SSVAL? assume NMB byte ordering */ RSSVAL(rdata,0,(nmb->header.opcode&0xf) + ((nb_flags&0xff) << 4)); /* XXXX mistake in rfc1002.txt? 4.2.16: NULL is 0xa see 4.2.1.3 @@ -296,7 +296,7 @@ void reply_name_reg(struct packet_struct *p) NAME_REGISTER_CHALLENGE, reply_name->name,reply_name->name_type, nb_flags,0,0,NULL,NULL, - False, False, n->ip, p->ip); + False, False, n->ip_flgs[0].ip, p->ip); } else { @@ -379,7 +379,7 @@ void reply_name_status(struct packet_struct *p) /* put name type and netbios flags in buffer */ buf[15] = name_type; - buf[16] = n->nb_flags; + buf[16] = n->ip_flgs[0].nb_flags; buf += 18; @@ -472,7 +472,7 @@ void reply_name_query(struct packet_struct *p) int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS; - if (name_type == 0x1b || name_type == 0x0 || name_type == 0x20) + if (name_type == 0x1b) { search |= FIND_WINS; } @@ -504,13 +504,20 @@ void reply_name_query(struct packet_struct *p) success = False; } + if (!bcast && name_type == 0x1d) + { + /* see WINS manager HELP - 'How WINS Handles Special Names' */ + /* a WINS query (unicasted) for a 0x1d name must always return False */ + success = False; + } + if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search))) { /* don't respond to broadcast queries unless the query is for a name we own or it is for a Primary Domain Controller name */ if (bcast && n->source != SELF && name_type != 0x1b) { - if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) { + if (!lp_wins_proxy() || same_net(p->ip,n->ip_flgs[0].ip,*iface_nmask(p->ip))) { /* never reply with a negative response to broadcast queries */ return; } @@ -527,8 +534,8 @@ void reply_name_query(struct packet_struct *p) not a WINS server ourselves */ ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0); - retip = n->ip; - nb_flags = n->nb_flags; + retip = n->ip_flgs[0].ip; + nb_flags = n->ip_flgs[0].nb_flags; } else { -- cgit