summaryrefslogtreecommitdiff
path: root/source3/nmbd
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
commitb2edf254eda92f775e7d3d9b6793b4d77f9000b6 (patch)
tree18eb2564a769678c774a19bb07c00fc4aa7b2758 /source3/nmbd
parent669a39fae36f8bc60753c9b352556ef8ffaeb568 (diff)
downloadsamba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.gz
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.bz2
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.zip
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
Diffstat (limited to 'source3/nmbd')
-rw-r--r--source3/nmbd/asyncdns.c1
-rw-r--r--source3/nmbd/nmbd.c11
-rw-r--r--source3/nmbd/nmbd_become_dmb.c2
-rw-r--r--source3/nmbd/nmbd_mynames.c2
-rw-r--r--source3/nmbd/nmbd_nameregister.c22
-rw-r--r--source3/nmbd/nmbd_packets.c25
-rw-r--r--source3/nmbd/nmbd_processlogon.c113
7 files changed, 146 insertions, 30 deletions
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index 6c2f8de3b1..c86ee69a09 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -122,6 +122,7 @@ void kill_async_dns_child(void)
{
if (child_pid > 0) {
kill(child_pid, SIGTERM);
+ child_pid = -1;
}
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index d30efb550c..05ea4997d5 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -269,9 +269,8 @@ static BOOL reload_interfaces(time_t t)
static BOOL reload_nmbd_services(BOOL test)
{
BOOL ret;
- extern fstring remote_machine;
- fstrcpy( remote_machine, "nmbd" );
+ set_remote_machine_name("nmbd");
if ( lp_loaded() ) {
pstring fname;
@@ -861,8 +860,10 @@ static void usage(char *pname)
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
- if ( !open_sockets( is_daemon, global_nmb_port ) )
+ if ( !open_sockets( is_daemon, global_nmb_port ) ) {
+ kill_async_dns_child();
return 1;
+ }
/* Determine all the IP addresses we have. */
load_interfaces();
@@ -871,6 +872,7 @@ static void usage(char *pname)
if( False == create_subnets() )
{
DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
+ kill_async_dns_child();
exit(1);
}
@@ -882,6 +884,7 @@ static void usage(char *pname)
if( !initialise_wins() )
{
DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
+ kill_async_dns_child();
exit(1);
}
@@ -896,6 +899,7 @@ static void usage(char *pname)
if( False == register_my_workgroup_and_names() )
{
DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
+ kill_async_dns_child();
exit(1);
}
@@ -906,5 +910,6 @@ static void usage(char *pname)
if (dbf)
x_fclose(dbf);
+ kill_async_dns_child();
return(0);
}
diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c
index 7f4a7a2144..ccc1f7e8ad 100644
--- a/source3/nmbd/nmbd_become_dmb.c
+++ b/source3/nmbd/nmbd_become_dmb.c
@@ -347,7 +347,7 @@ static void become_domain_master_browser_wins(char *workgroup_name)
we can become a domain master browser.
*/
- DEBUG(0,("become_domain_master_browser_wins: querying WINS server at IP %s \
+ DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
for domain master browser name %s on workgroup %s\n",
inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
diff --git a/source3/nmbd/nmbd_mynames.c b/source3/nmbd/nmbd_mynames.c
index 345245c57d..ba7d509a77 100644
--- a/source3/nmbd/nmbd_mynames.c
+++ b/source3/nmbd/nmbd_mynames.c
@@ -225,7 +225,7 @@ void refresh_my_names(time_t t)
wins_refresh_name(namerec);
}
namerec->data.death_time = t + lp_max_ttl();
- namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
+ namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
}
}
}
diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c
index 4ac5473d4a..b6d3c20d99 100644
--- a/source3/nmbd/nmbd_nameregister.c
+++ b/source3/nmbd/nmbd_nameregister.c
@@ -106,17 +106,7 @@ static void register_name_response(struct subnet_record *subrec,
success = False;
} else {
/* Unicast - check to see if the response allows us to have the name. */
- if(nmb->header.rcode != 0) {
- /* Error code - we didn't get the name. */
- success = False;
-
- DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
- subrec==unicast_subnet?"WINS ":"",
- inet_ntoa(p->ip),
- nmb_namestr(answer_name),
- reg_name,
- nmb->header.rcode));
- } else if (nmb->header.opcode == NMB_WACK_OPCODE) {
+ if (nmb->header.opcode == NMB_WACK_OPCODE) {
/* WINS server is telling us to wait. Pretend we didn't get
the response but don't send out any more register requests. */
@@ -128,6 +118,16 @@ static void register_name_response(struct subnet_record *subrec,
rrec->repeat_time = p->timestamp + nmb->answers->ttl;
rrec->num_msgs--;
return;
+ } else if (nmb->header.rcode != 0) {
+ /* Error code - we didn't get the name. */
+ success = False;
+
+ DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
+ subrec==unicast_subnet?"WINS ":"",
+ inet_ntoa(p->ip),
+ nmb_namestr(answer_name),
+ reg_name,
+ nmb->header.rcode));
} else {
success = True;
/* Get the data we need to pass to the success function. */
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index a20ebf16fd..d252b98ed6 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -705,14 +705,33 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
{
struct packet_struct *p;
struct response_record *rrec;
+ struct in_addr to_ip;
if(assert_check_subnet(subrec))
return NULL;
+ to_ip = subrec->bcast_ip;
+
+ /* queries to the WINS server turn up here as queries to IP 0.0.0.0
+ These need to be handled a bit differently */
+ if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
+ /* what we really need to do is loop over each of our wins
+ * servers and wins server tags here, but that just doesn't
+ * fit our architecture at the moment (userdata may already
+ * be used when we get here). For now we just query the first
+ * active wins server on the first tag. */
+ char **tags = wins_srv_tags();
+ if (!tags) {
+ return NULL;
+ }
+ to_ip = wins_srv_ip_tag(tags[0], to_ip);
+ wins_srv_tags_free(tags);
+ }
+
if(( p = create_and_init_netbios_packet(nmbname,
(subrec != unicast_subnet),
(subrec == unicast_subnet),
- subrec->bcast_ip)) == NULL)
+ to_ip)) == NULL)
return NULL;
if(lp_bind_interfaces_only()) {
@@ -1670,7 +1689,7 @@ void retransmit_or_expire_response_records(time_t t)
to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
subrec->subnet_name));
}
- rrec->repeat_time += rrec->repeat_interval;
+ rrec->repeat_time = t + rrec->repeat_interval;
rrec->repeat_count--;
}
else
@@ -1950,7 +1969,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
/* Setup the smb part. */
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy(tmp,ptr,4);
- set_message(ptr,17,17 + len,True);
+ set_message(ptr,17,23 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 23e4f935ca..d6605d08f5 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -4,6 +4,8 @@
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jim McDonough 2002
+ Copyright (C) Anthony Liguori 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -284,19 +286,108 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* Construct reply. */
q = outbuf;
- if (SVAL(uniuser, 0) == 0) {
- SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
- } else {
- SSVAL(q, 0, SAMLOGON_R);
- }
- q += 2;
-
- q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
- q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
- q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
+ /* we want the simple version unless we are an ADS PDC..which means */
+ /* never, at least for now */
+ if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
+ if (SVAL(uniuser, 0) == 0) {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ } else {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
+
+ q += 2;
+
+ q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
+ q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
+ q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
+ }
+#ifdef HAVE_ADS
+ else {
+ GUID domain_guid;
+ pstring domain;
+ char *component, *dc, *q1;
+ uint8 size;
+
+ safe_strcpy(domain, lp_realm(), sizeof(domain));
+
+ if (SVAL(uniuser, 0) == 0) {
+ SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */
+ } else {
+ SSVAL(q, 0, SAMLOGON_AD_R);
+ }
+ q += 2;
+
+ SSVAL(q, 0, 0);
+ q += 2;
+ SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
+ ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
+ q += 4;
+
+ /* Push Domain GUID */
+ if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
+ DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
+ return;
+ }
+ memcpy(q, &domain_guid, sizeof(domain_guid));
+ q += sizeof(domain_guid);
+
+ /* Push domain components */
+ dc = domain;
+ q1 = q;
+ while ((component = strsep(&dc, "."))) {
+ size = push_ascii(&q[1], component, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ }
+ SCVAL(q, 0, 0); q++;
+ SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
+ q += 2; /* it must follow the domain name. */
+
+ /* Push dns host name */
+ size = push_ascii(&q[1], global_myname, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */
+ q += 2; /* it must follow the domain name. */
+
+ /* Push NETBIOS of domain */
+ size = push_ascii(&q[1], domain, -1, STR_UPPER);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
+ /* null terminator would not be needed because size is included */
+
+ /* Push NETBIOS of hostname */
+ size = push_ascii(&q[1], my_name, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+ SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
+
+ /* Push user account */
+ size = push_ascii(&q[1], ascuser, -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+
+ /* Push 'Default-First-Site-Name' */
+ size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
+ SCVAL(q, 0, size);
+ q += (size + 1);
+
+ SSVAL(q, 0, 0xc000); /* unknown */
+ SCVAL(q, 2, PTR_DIFF(q,q1));
+ SCVAL(q, 3, 0x10); /* unknown */
+ q += 4;
+
+ SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
+ SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
+ SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
+ SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
+ }
+#endif
/* tell the client what version we are */
- SIVAL(q, 0, 1); /* our ntversion */
+ SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
+ /* our ntversion */
SSVAL(q, 4, 0xffff); /* our lmnttoken */
SSVAL(q, 6, 0xffff); /* our lm20token */
q += 8;