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
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "../librpc/gen_ndr/svcctl.h"
+#include "nmbd/nmbd.h"
-extern BOOL found_lm_clients;
+extern bool found_lm_clients;
#if 0
Process an incoming host announcement packet.
*******************************************************************/
-void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
int ttl = IVAL(buf,1)/1000;
- nstring announce_name;
- uint32 servertype = IVAL(buf,23);
+ unstring announce_name;
+ uint32_t servertype = IVAL(buf,23);
fstring comment;
struct work_record *work;
struct server_record *servrec;
- nstring work_name;
- nstring source_name;
-
- START_PROFILE(host_announce);
+ unstring work_name;
+ unstring source_name;
pull_ascii_fstring(comment, buf+31);
- comment[42] = 0;
- pull_ascii_nstring(announce_name, buf+5);
- pull_ascii_nstring(source_name, dgram->source_name.name);
+ pull_ascii_nstring(announce_name, sizeof(announce_name), buf+5);
+ pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
}
/* For a host announce the workgroup name is the destination name. */
- pull_ascii_nstring(work_name, dgram->dest_name.name);
+ pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);
/*
* Syntax servers version 5.1 send HostAnnounce packets to
* to be our primary workgroup name.
*/
- if(strequal(work_name, global_myname()))
- nstrcpy(work_name,lp_workgroup());
+ if(strequal(work_name, lp_netbios_name()))
+ unstrcpy(work_name,lp_workgroup());
/*
* We are being very agressive here in adding a workgroup
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
+ strlcpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment));
}
} else {
/*
subrec->work_changed = True;
done:
-
- END_PROFILE(host_announce);
+ return;
}
/*******************************************************************
Process an incoming WORKGROUP announcement packet.
*******************************************************************/
-void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
int ttl = IVAL(buf,1)/1000;
- nstring workgroup_announce_name;
- nstring master_name;
- uint32 servertype = IVAL(buf,23);
+ unstring workgroup_announce_name;
+ unstring master_name;
+ uint32_t servertype = IVAL(buf,23);
struct work_record *work;
- nstring source_name;
- nstring dest_name;
+ unstring source_name;
+ unstring dest_name;
- START_PROFILE(workgroup_announce);
-
- pull_ascii_nstring(workgroup_announce_name,buf+5);
- pull_ascii_nstring(master_name,buf+31);
- pull_ascii_nstring(source_name,dgram->source_name.name);
- pull_ascii_nstring(dest_name,dgram->dest_name.name);
+ pull_ascii_nstring(workgroup_announce_name,sizeof(workgroup_announce_name),buf+5);
+ pull_ascii_nstring(master_name,sizeof(master_name),buf+31);
+ pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name);
+ pull_ascii_nstring(dest_name,sizeof(dest_name),dgram->dest_name.name);
DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
%s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
subrec->work_changed = True;
done:
-
- END_PROFILE(workgroup_announce);
+ return;
}
/*******************************************************************
Process an incoming local master browser announcement packet.
*******************************************************************/
-void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
int ttl = IVAL(buf,1)/1000;
- nstring server_name;
- uint32 servertype = IVAL(buf,23);
+ unstring server_name;
+ uint32_t servertype = IVAL(buf,23);
fstring comment;
- nstring work_name;
- struct work_record *work;
+ unstring work_name;
+ struct work_record *work = NULL;
struct server_record *servrec;
- nstring source_name;
-
- START_PROFILE(local_master_announce);
+ unstring source_name;
- pull_ascii_nstring(server_name,buf+5);
+ pull_ascii_nstring(server_name,sizeof(server_name),buf+5);
pull_ascii_fstring(comment, buf+31);
- comment[42] = 0;
- pull_ascii_nstring(source_name, dgram->source_name.name);
- pull_ascii_nstring(work_name, dgram->dest_name.name);
+ pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
+ pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);
DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl(servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
+ strlcpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment));
}
set_workgroup_local_master_browser_name( work, server_name );
* This server is announcing it is going down. Remove it from the
* workgroup.
*/
- if(!is_myname(server_name) && (work != NULL) &&
+ if(!is_myname(server_name) &&
((servrec = find_server_in_workgroup( work, server_name))!=NULL)) {
remove_server_from_workgroup( work, servrec);
}
subrec->work_changed = True;
done:
-
- END_PROFILE(local_master_announce);
+ return;
}
/*******************************************************************
******************************************************************/
void process_master_browser_announce(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
+ struct packet_struct *p,const char *buf)
{
- nstring local_master_name;
+ unstring local_master_name;
struct work_record *work;
struct browse_cache_record *browrec;
- START_PROFILE(master_browser_announce);
-
- pull_ascii_nstring(local_master_name,buf);
+ pull_ascii_nstring(local_master_name,sizeof(local_master_name),buf);
DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
local_master_name, inet_ntoa(p->ip)));
}
done:
-
- END_PROFILE(master_browser_announce);
+ return;
}
/*******************************************************************
Process an incoming LanMan host announcement packet.
*******************************************************************/
-void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf, int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
- uint32 servertype = IVAL(buf,1);
+ uint32_t servertype = IVAL(buf,1);
int osmajor=CVAL(buf,5); /* major version of node software */
int osminor=CVAL(buf,6); /* minor version of node software */
int ttl = SVAL(buf,7);
- nstring announce_name;
+ unstring announce_name;
struct work_record *work;
struct server_record *servrec;
- nstring work_name;
- nstring source_name;
+ unstring work_name;
+ unstring source_name;
fstring comment;
- char *s = buf+9;
+ char *s = get_safe_str_ptr(buf,len,discard_const_p(char, buf),9);
- START_PROFILE(lm_host_announce);
- s = skip_string(s,1);
+ if (!s) {
+ goto done;
+ }
+ s = skip_string(buf,len,s);
+ if (!s) {
+ goto done;
+ }
pull_ascii(comment, s, sizeof(fstring), 43, STR_TERMINATE);
- pull_ascii_nstring(announce_name,buf+9);
- pull_ascii_nstring(source_name,dgram->source_name.name);
+ pull_ascii_nstring(announce_name,sizeof(announce_name),buf+9);
+ pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name);
/* For a LanMan host announce the workgroup name is the destination name. */
- pull_ascii_nstring(work_name,dgram->dest_name.name);
+ pull_ascii_nstring(work_name,sizeof(work_name),dgram->dest_name.name);
DEBUG(3,("process_lm_host_announce: LM Announcement from %s IP %s to \
%s for server %s.\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
* not needed in the LanMan announce code, but it won't hurt.
*/
- if(strequal(work_name, global_myname()))
- nstrcpy(work_name,lp_workgroup());
+ if(strequal(work_name, lp_netbios_name()))
+ unstrcpy(work_name,lp_workgroup());
/*
* We are being very agressive here in adding a workgroup
/* Update the record. */
servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
update_server_ttl( servrec, ttl);
- fstrcpy(servrec->serv.comment,comment);
+ strlcpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment));
}
} else {
/*
found_lm_clients = True;
done:
-
- END_PROFILE(lm_host_announce);
+ return;
}
/****************************************************************************
Send a backup list response.
*****************************************************************************/
-static void send_backup_list_response(struct subnet_record *subrec,
+static void send_backup_list_response(struct subnet_record *subrec,
struct work_record *work,
struct nmb_name *send_to_name,
unsigned char max_number_requested,
- uint32 token, struct in_addr sendto_ip,
+ uint32_t token, struct in_addr sendto_ip,
int port)
-{
+{
char outbuf[1024];
char *p, *countptr;
unsigned int count = 0;
- nstring send_to_namestr;
+ unstring send_to_namestr;
#if 0
struct server_record *servrec;
#endif
- fstring myname;
+ unstring myname;
memset(outbuf,'\0',sizeof(outbuf));
DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
-
+
p = outbuf;
-
+
SCVAL(p,0,ANN_GetBackupListResp); /* Backup list response opcode. */
p++;
SIVAL(p,0,token); /* The sender's unique info. */
p += 4;
-
+
/* We always return at least one name - our own. */
count = 1;
- fstrcpy(myname, global_myname());
- strupper_m(myname);
+ unstrcpy(myname, lp_netbios_name());
+ if (!strupper_m(myname)) {
+ DEBUG(4,("strupper_m %s failed\n", myname));
+ return;
+ }
myname[15]='\0';
- push_pstring_base(p, myname, outbuf);
+ push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p);
/* Look for backup browsers in this workgroup. */
if(count >= (unsigned int)max_number_requested)
break;
- if(strnequal(servrec->serv.name, global_myname(),15))
+ if(strnequal(servrec->serv.name, lp_netbios_name(),15))
continue;
if(!(servrec->serv.type & SV_TYPE_BACKUP_BROWSER))
DEBUG(5,("send_backup_list_response: Adding server %s number %d\n",
p, count));
- p = skip_string(p,1);
+ p = skip_string(outbuf,sizeof(outbuf),p);
}
#endif
SCVAL(countptr, 0, count);
- pull_ascii_nstring(send_to_namestr, send_to_name->name);
+ pull_ascii_nstring(send_to_namestr, sizeof(send_to_namestr), send_to_name->name);
DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
send_to_namestr, inet_ntoa(sendto_ip), count));
send_mailslot(True, BROWSE_MAILSLOT,
outbuf,PTR_DIFF(p,outbuf),
- global_myname(), 0,
+ lp_netbios_name(), 0,
send_to_namestr,0,
sendto_ip, subrec->myip, port);
}
********************************************************************/
void process_get_backup_list_request(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
+ struct packet_struct *p,const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct work_record *work;
unsigned char max_number_requested = CVAL(buf,0);
- uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
+ uint32_t token = IVAL(buf,1); /* Sender's key index for the workgroup. */
int name_type = dgram->dest_name.name_type;
- nstring workgroup_name;
+ unstring workgroup_name;
struct subnet_record *search_subrec = subrec;
- START_PROFILE(get_backup_list);
- pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+ pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
max_number_requested, token, p->ip, p->port);
done:
-
- END_PROFILE(get_backup_list);
+ return;
}
/*******************************************************************
******************************************************************/
void process_reset_browser(struct subnet_record *subrec,
- struct packet_struct *p,char *buf)
+ struct packet_struct *p,const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
int state = CVAL(buf,0);
struct subnet_record *sr;
- START_PROFILE(reset_browser);
-
DEBUG(1,("process_reset_browser: received diagnostic browser reset \
request from %s IP %s state=0x%X\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
/* Request to stop browsing altogether. */
if (state & 0x4)
DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
-
- END_PROFILE(reset_browser);
}
/*******************************************************************
announcement is needed soon.
******************************************************************/
-void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct work_record *work;
- nstring workgroup_name;
+ unstring workgroup_name;
- START_PROFILE(announce_request);
-
- pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+ pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
nmb_namestr(&dgram->dest_name)));
work->needannounce = True;
done:
-
- END_PROFILE(lm_host_announce);
+ return;
}
/*******************************************************************
through the "lm announce" parameter in smb.conf)
******************************************************************/
-void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
+void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, const char *buf, int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
- nstring workgroup_name;
-
- START_PROFILE(lm_announce_request);
+ unstring workgroup_name;
- pull_ascii_nstring(workgroup_name, dgram->dest_name.name);
+ pull_ascii_nstring(workgroup_name, sizeof(workgroup_name), dgram->dest_name.name);
DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
nmb_namestr(&dgram->dest_name)));
found_lm_clients = True;
done:
-
- END_PROFILE(lm_host_announce);
+ return;
}