summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/nameserv.h12
-rw-r--r--source3/include/proto.h5
-rw-r--r--source3/namedbname.c111
-rw-r--r--source3/nameserv.c21
-rw-r--r--source3/nameservreply.c31
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
{