1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

- 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 commit is contained in:
Samba Release Account 0001-01-01 00:00:00 +00:00
parent add8bdce8c
commit a7330127a2
5 changed files with 119 additions and 61 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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++;
}

View File

@ -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
{