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:
parent
add8bdce8c
commit
a7330127a2
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user