1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-09 08:58:35 +03:00

jeremy is going to hate me for this.

created an "nmb-agent" utility that, yes: it connects to the 137 socket
and accepts unix socket connections which it redirects onto port 137.

it uses the name_trn_id field to filter requests to the correct
location.

name_query() and name_status() are the first victims to use this
feature (by specifying a file descriptor of -1).
This commit is contained in:
Luke Leighton -
parent 06390e792c
commit d923bc8da2
11 changed files with 784 additions and 50 deletions

View File

@ -297,6 +297,9 @@ MNT_OBJ = client/smbmnt.o \
UMOUNT_OBJ = client/smbumount.o \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
NMB_AGENT_OBJ = utils/nmb-agent.o $(PARAM_OBJ) $(UBIQX_OBJ) \
$(LIBSMB_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \
$(LIBSMB_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
@ -486,6 +489,10 @@ bin/smb-client: $(SMB_CLIENT_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMB_CLIENT_OBJ) $(LDFLAGS) $(LIBS)
bin/nmb-agent: $(NMB_AGENT_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(NMB_AGENT_OBJ) $(LDFLAGS) $(LIBS)
bin/smb-agent: $(SMB_AGENT_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMB_AGENT_OBJ) $(LDFLAGS) $(LIBS)

View File

@ -142,7 +142,7 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH,
enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME,
DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME};
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET};
enum packet_type {NMB_PACKET, DGRAM_PACKET, NMB_SOCK_PACKET, DGRAM_SOCK_PACKET };
enum master_state
{

View File

@ -613,6 +613,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
void reset_globals_after_fork(void);
char *client_name(int fd);
char *client_addr(int fd);
int open_pipe_sock(char *path);
/*The following definitions come from lib/util_status.c */
@ -838,6 +839,8 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
void sort_query_replies(char *data, int n, struct in_addr ip);
BOOL read_nmb_sock(int c, struct nmb_state *con);
int get_nmb_sock(void);
/*The following definitions come from libsmb/nterr.c */

View File

@ -1745,6 +1745,12 @@ struct field_info
#define MAX_MAX_MUX_LIMIT 16
struct nmb_state
{
struct in_addr ip;
int port;
};
#endif /* _SMB_H */
/* _SMB_H */

View File

@ -862,3 +862,35 @@ char *client_addr(int fd)
global_client_addr_done = True;
return addr_buf;
}
/*******************************************************************
opens and connects to a unix pipe socket
******************************************************************/
int open_pipe_sock(char *path)
{
int sock;
struct sockaddr_un sa;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
DEBUG(0, ("unix socket open failed\n"));
return sock;
}
ZERO_STRUCT(sa);
sa.sun_family = AF_UNIX;
safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path));
if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
close(sock);
return -1;
}
return sock;
}

View File

@ -2949,7 +2949,6 @@ static int cli_init_redirect(struct cli_state *cli,
const struct user_credentials *usr)
{
int sock;
struct sockaddr_un sa;
fstring ip_name;
struct cli_state cli_redir;
fstring path;
@ -2969,29 +2968,13 @@ static int cli_init_redirect(struct cli_state *cli,
srv_name = ip_name;
}
sock = socket(AF_UNIX, SOCK_STREAM, 0);
sock = open_pipe_sock(path);
if (sock < 0)
{
DEBUG(0, ("unix socket open failed\n"));
return sock;
}
ZERO_STRUCT(sa);
sa.sun_family = AF_UNIX;
safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path));
if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
close(sock);
return False;
}
DEBUG(10,("connect succeeded\n"));
ZERO_STRUCT(data);
p = &data[4];

View File

@ -29,6 +29,8 @@ extern int DEBUGLEVEL;
/* nmbd.c sets this to True. */
BOOL global_in_nmbd = False;
static int name_trn_id = 0;
/****************************************************************************
interpret a node status response
****************************************************************************/
@ -99,8 +101,19 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
static int name_trn_id = 0;
int packet_type = NMB_PACKET;
if (fd == -1)
{
retries = 1;
packet_type = NMB_SOCK_PACKET;
fd = get_nmb_sock();
if (fd < 0)
{
return False;
}
}
bzero((char *)&p,sizeof(p));
if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
@ -130,12 +143,15 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
p.packet_type = packet_type;
GetTimeOfDay(&tval);
if (!send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
return(False);
}
retries--;
@ -146,12 +162,15 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
if (TvalDiff(&tval,&tval2) > retry_time) {
if (!retries) break;
if (!found && !send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
return False;
}
GetTimeOfDay(&tval);
retries--;
}
if ((p2=receive_packet(fd,NMB_PACKET,90)))
if ((p2=receive_packet(fd,packet_type,90)))
{
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
@ -179,6 +198,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
free_packet(p2);
if (packet_type == NMB_SOCK_PACKET) close(fd);
return(True);
}
}
@ -186,6 +206,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
DEBUG(0,("No status response (this is not unusual)\n"));
if (packet_type == NMB_SOCK_PACKET) close(fd);
return(False);
}
@ -205,8 +226,20 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
static int name_trn_id = 0;
struct in_addr *ip_list = NULL;
BOOL packet_type = NMB_PACKET;
if (fd == -1)
{
retries = 0;
packet_type = NMB_SOCK_PACKET;
fd = get_nmb_sock();
if (fd < 0)
{
return NULL;
}
}
bzero((char *)&p,sizeof(p));
(*count) = 0;
@ -238,30 +271,34 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
p.packet_type = NMB_PACKET;
p.packet_type = packet_type;
GetTimeOfDay(&tval);
if (!send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
return NULL;
}
while (retries >= 0)
{
struct timeval tval2;
retries--;
while (1)
{
struct timeval tval2;
GetTimeOfDay(&tval2);
if (TvalDiff(&tval,&tval2) > retry_time)
{
if (!retries)
break;
if (!found && !send_packet(&p))
{
if (packet_type == NMB_SOCK_PACKET) close(fd);
return NULL;
}
GetTimeOfDay(&tval);
retries--;
}
if ((p2=receive_packet(fd,NMB_PACKET,90)))
if ((p2=receive_packet(fd,packet_type,90)))
{
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
@ -269,6 +306,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
!nmb2->header.response)
{
DEBUG(10,("packet not for us (received %d, expected %d\n",
nmb2->header.name_trn_id, nmb->header.name_trn_id));
/*
* Its not for us - maybe deal with it later
* (put it on the queue?).
@ -314,16 +353,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
if (fn)
break;
/*
* If we're doing a unicast lookup we only
* expect one reply. Don't wait the full 2
* seconds if we got one. JRA.
*/
if(!bcast && found)
if(found)
{
DEBUG(10,("returning OK\n"));
break;
}
}
}
if (packet_type == NMB_SOCK_PACKET) close(fd);
return ip_list;
}

View File

@ -651,15 +651,38 @@ void free_packet(struct packet_struct *packet)
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
{
extern struct in_addr lastip;
struct nmb_state con;
extern int lastport;
struct packet_struct *packet;
char buf[MAX_DGRAM_SIZE];
int length;
BOOL ok=False;
if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
{
uint16 trn_id = 0;
if (!read_nmb_sock(fd, &con))
{
return False;
}
if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
{
return False;
}
}
length = read_udp_socket(fd,buf,sizeof(buf));
dump_data(100, buf, length);
if (length < MIN_DGRAM_SIZE) return(NULL);
if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
{
lastip = con.ip;
lastport = con.port;
}
packet = (struct packet_struct *)malloc(sizeof(*packet));
if (!packet) return(NULL);
@ -674,15 +697,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
switch (packet_type)
{
case NMB_PACKET:
case NMB_SOCK_PACKET:
ok = parse_nmb(buf,length,&packet->packet.nmb);
break;
case DGRAM_PACKET:
case DGRAM_SOCK_PACKET:
ok = parse_dgram(buf,length,&packet->packet.dgram);
break;
}
if (!ok) {
DEBUG(10,("parse_nmb: discarding packet id = %d\n",
DEBUG(10,("read_packet: discarding packet id = %d\n",
packet->packet.nmb.header.name_trn_id));
free(packet);
return(NULL);
@ -880,18 +905,65 @@ BOOL send_packet(struct packet_struct *p)
switch (p->packet_type)
{
case NMB_PACKET:
case NMB_SOCK_PACKET:
len = build_nmb(buf,p);
debug_nmb_packet(p);
break;
case DGRAM_PACKET:
case DGRAM_SOCK_PACKET:
len = build_dgram(buf,p);
break;
}
if (!len) return(False);
switch (p->packet_type)
{
case DGRAM_PACKET:
case NMB_PACKET:
return(send_udp(p->fd,buf,len,p->ip,p->port));
break;
case NMB_SOCK_PACKET:
case DGRAM_SOCK_PACKET:
{
fstring qbuf;
struct nmb_state nmb;
int qlen;
uint16 trn_id;
char *q = qbuf + 4;
nmb.ip = p->ip;
nmb.port = p->port;
SSVAL(q, 0, 0);
q += 2;
SSVAL(q, 0, 0);
q += 2;
memcpy(q, &nmb, sizeof(nmb));
q += sizeof(nmb);
qlen = PTR_DIFF(q, qbuf);
SIVAL(qbuf, 0, qlen);
dump_data(100, qbuf, qlen);
if (write(p->fd,qbuf,qlen) != qlen)
{
return False;
}
qlen = read(p->fd, &trn_id, sizeof(trn_id));
if (qlen != sizeof(trn_id))
{
return False;
}
return write(p->fd,buf,len) == len;
}
}
return False;
}
/****************************************************************************
@ -961,3 +1033,76 @@ void sort_query_replies(char *data, int n, struct in_addr ip)
qsort(data, n, 6, QSORT_CAST name_query_comp);
}
BOOL read_nmb_sock(int c, struct nmb_state *con)
{
fstring buf;
char *p = buf;
int rl;
uint32 len;
uint16 version;
uint16 command;
ZERO_STRUCTP(con);
rl = read(c, &buf, sizeof(len));
if (rl < 0)
{
DEBUG(0,("read_nmb_sock: error\n"));
return False;
}
if (rl != sizeof(len))
{
DEBUG(0,("Unable to read length\n"));
dump_data(0, buf, sizeof(len));
return False;
}
len = IVAL(buf, 0);
if (len > sizeof(buf))
{
DEBUG(0,("length %d too long\n", len));
return False;
}
rl = read(c, buf, len);
if (rl < 0)
{
DEBUG(0,("Unable to read from connection\n"));
return False;
}
#ifdef DEBUG_PASSWORD
dump_data(100, buf, rl);
#endif
version = SVAL(p, 0);
p += 2;
command = SVAL(p, 0);
p += 2;
memcpy(con, p, sizeof(*con));
p += sizeof(*con);
DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
inet_ntoa(con->ip), con->port));
if (PTR_DIFF(p, buf) != rl)
{
DEBUG(0,("Buffer size %d %d!\n",
PTR_DIFF(p, buf), rl));
return False;
}
return True;
}
int get_nmb_sock(void)
{
fstring path;
slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
return open_pipe_sock(path);
}

View File

@ -260,6 +260,7 @@ struct cli_state *cli_net_use_add(const char* srv_name,
False, True))
{
DEBUG(0,("cli_net_use_add: connection failed\n"));
cli->cli = NULL;
cli_use_free(cli);
return NULL;
}

515
source/utils/nmb-agent.c Normal file
View File

@ -0,0 +1,515 @@
/*
Unix SMB/Netbios implementation.
Version 2
SMB agent/socket plugin
Copyright (C) Andrew Tridgell 1999
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.
*/
#include "includes.h"
#include "smb.h"
#define SECURITY_MASK 0
#define SECURITY_SET 0
/* this forces non-unicode */
#define CAPABILITY_MASK CAP_UNICODE
#define CAPABILITY_SET 0
/* and non-unicode for the client too */
#define CLI_CAPABILITY_MASK CAP_UNICODE
#define CLI_CAPABILITY_SET 0
extern int DEBUGLEVEL;
static int ClientNMB = -1;
struct sock_redir
{
int c;
int c_trn_id;
int s_trn_id;
struct nmb_state *n;
time_t time;
};
static uint32 num_socks = 0;
static struct sock_redir **socks = NULL;
/****************************************************************************
terminate sockent connection
****************************************************************************/
static void sock_redir_free(struct sock_redir *sock)
{
close(sock->c);
sock->c = -1;
if (sock->n != NULL)
{
#if 0
free(sock->n);
#endif
sock->n = NULL;
}
#if 0
free(sock);
#endif
ZERO_STRUCTP(sock);
}
/****************************************************************************
free a sockent array
****************************************************************************/
static void free_sock_array(uint32 num_entries, struct sock_redir **entries)
{
void(*fn)(void*) = (void(*)(void*))&sock_redir_free;
free_void_array(num_entries, (void**)entries, *fn);
}
/****************************************************************************
add a sockent state to the array
****************************************************************************/
static struct sock_redir* add_sock_to_array(uint32 *len,
struct sock_redir ***array,
struct sock_redir *sock)
{
int i;
for (i = 0; i < num_socks; i++)
{
if (socks[i] == NULL)
{
socks[i] = sock;
return sock;
}
}
return (struct sock_redir*)add_item_to_array(len,
(void***)array, (void*)sock);
}
/****************************************************************************
initiate sockent array
****************************************************************************/
void init_sock_redir(void)
{
socks = NULL;
num_socks = 0;
}
/****************************************************************************
terminate sockent array
****************************************************************************/
void free_sock_redir(void)
{
free_sock_array(num_socks, socks);
init_sock_redir();
}
/****************************************************************************
create a new sockent state from user credentials
****************************************************************************/
static struct sock_redir *sock_redir_get(int fd)
{
struct sock_redir *sock;
sock = (struct sock_redir*)malloc(sizeof(*sock));
if (sock == NULL)
{
return NULL;
}
ZERO_STRUCTP(sock);
sock->c = fd;
sock->n = NULL;
sock->time = time(NULL);
DEBUG(10,("sock_redir_get:\tfd:\t%d\t\n", fd));
return sock;
}
/****************************************************************************
init sock state
****************************************************************************/
static void sock_add(int fd)
{
struct sock_redir *sock;
sock = sock_redir_get(fd);
if (sock != NULL)
{
add_sock_to_array(&num_socks, &socks, sock);
}
}
/****************************************************************************
delete a sockent state
****************************************************************************/
static BOOL sock_del(int fd)
{
int i;
for (i = 0; i < num_socks; i++)
{
if (socks[i] == NULL) continue;
if (socks[i]->c == fd)
{
sock_redir_free(socks[i]);
socks[i] = NULL;
return True;
}
}
return False;
}
static void filter_reply(struct packet_struct *p, int tr_id)
{
p->packet.nmb.header.name_trn_id = tr_id;
}
static BOOL process_cli_sock(struct sock_redir **sock)
{
struct packet_struct *p;
struct nmb_state *nmb;
static uint16 trn_id = 0x0;
p = receive_packet((*sock)->c, NMB_SOCK_PACKET, 0);
if (p == NULL)
{
DEBUG(0,("client closed connection\n"));
return False;
}
nmb = (struct nmb_state*)malloc(sizeof(struct nmb_state));
if (nmb == NULL)
{
return False;
}
(*sock)->n = nmb;
(*sock)->c_trn_id = p->packet.nmb.header.name_trn_id;
(*sock)->s_trn_id = trn_id;
trn_id++;
if (trn_id > 0xffff)
{
trn_id = 0x0;
}
DEBUG(10,("new trn_id: %d\n", trn_id));
filter_reply(p, (*sock)->s_trn_id);
nmb->ip = p->ip;
nmb->port = p->port;
p->fd = ClientNMB;
p->packet_type = NMB_PACKET;
if (!send_packet(p))
{
DEBUG(0,("server is dead\n"));
return False;
}
return True;
}
static BOOL process_srv_sock(struct sock_redir *sock, struct packet_struct *p)
{
int nmb_id;
int tr_id;
if (p == NULL)
{
return False;
}
nmb_id = p->packet.nmb.header.name_trn_id;
tr_id = sock->s_trn_id;
DEBUG(10,("process_srv_sock:\tnmb_id:\t%d\n", nmb_id));
DEBUG(10,("list:\tfd:\t%d\tnmb_id:\t%d\ttr_id:\t%d\n",
sock->c,
nmb_id,
tr_id));
if (nmb_id != tr_id)
{
return False;
}
filter_reply(p, sock->c_trn_id);
p->fd = sock->c;
p->packet_type = NMB_SOCK_PACKET;
if (!send_packet(p))
{
DEBUG(0,("client is dead\n"));
}
return True;
}
static void start_agent(void)
{
int s, c;
struct sockaddr_un sa;
fstring path;
fstring dir;
CatchChild();
slprintf(dir, sizeof(dir)-1, "/tmp/.nmb");
mkdir(dir, 0777);
slprintf(path, sizeof(path)-1, "%s/agent", dir);
if (chmod(dir, 0777) < 0)
{
fprintf(stderr, "chmod on %s failed\n", sa.sun_path);
exit(1);
}
/* start listening on unix socket */
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0)
{
fprintf(stderr, "socket open failed\n");
exit(1);
}
ZERO_STRUCT(sa);
sa.sun_family = AF_UNIX;
safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
fprintf(stderr, "socket bind to %s failed\n", sa.sun_path);
close(s);
remove(path);
exit(1);
}
if (s == -1)
{
DEBUG(0,("bind failed\n"));
remove(path);
exit(1);
}
if (listen(s, 5) == -1)
{
DEBUG(0,("listen failed\n"));
remove(path);
}
while (1)
{
int i;
fd_set fds;
int num;
struct sockaddr_un addr;
int in_addrlen = sizeof(addr);
int maxfd = s;
struct packet_struct *p = NULL;
time_t current_time = time(NULL);
FD_ZERO(&fds);
FD_SET(s, &fds);
FD_SET(ClientNMB, &fds);
maxfd = MAX(ClientNMB, maxfd);
for (i = 0; i < num_socks; i++)
{
if (socks[i] != NULL)
{
int fd = socks[i]->c;
FD_SET(fd, &fds);
maxfd = MAX(maxfd, fd);
}
}
dbgflush();
num = sys_select(maxfd+1,&fds,NULL, NULL);
if (num <= 0)
{
continue;
}
if (FD_ISSET(s, &fds))
{
c = accept(s, (struct sockaddr*)&addr, &in_addrlen);
if (c != -1)
{
sock_add(c);
}
}
if (FD_ISSET(ClientNMB, &fds))
{
p = receive_packet(ClientNMB, NMB_PACKET, 0);
if (p && !p->packet.nmb.header.response)
{
free(p);
p = NULL;
}
}
else
{
p = NULL;
}
for (i = 0; i < num_socks; i++)
{
if (socks[i] == NULL)
{
continue;
}
if (FD_ISSET(socks[i]->c, &fds))
{
if (!process_cli_sock(&socks[i]))
{
sock_redir_free(socks[i]);
socks[i] = NULL;
}
}
if (p == NULL)
{
continue;
}
if (socks[i] == NULL)
{
continue;
}
if (process_srv_sock(socks[i], p) ||
current_time > socks[i]->time + 5)
{
sock_redir_free(socks[i]);
socks[i] = NULL;
}
}
if (p != NULL)
{
free(p);
p = NULL;
}
}
}
/**************************************************************************** **
open the socket communication
**************************************************************************** */
static BOOL open_sockets(BOOL isdaemon, int port)
{
/* The sockets opened here will be used to receive broadcast
packets *only*. Interface specific sockets are opened in
make_subnet() in namedbsubnet.c. Thus we bind to the
address "0.0.0.0". The parameter 'socket address' is
now deprecated.
*/
if ( isdaemon )
ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0);
else
ClientNMB = 0;
if ( ClientNMB == -1 )
return( False );
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
set_socket_options( ClientNMB, "SO_BROADCAST" );
DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
return( True );
} /* open_sockets */
/****************************************************************************
usage on the program
****************************************************************************/
static void usage(char *pname)
{
printf("Usage: %s [-D]", pname);
printf("\nVersion %s\n",VERSION);
printf("\t-D run as a daemon\n");
printf("\t-h usage\n");
printf("\n");
}
int main(int argc, char *argv[])
{
pstring configfile;
BOOL is_daemon = False;
int opt;
extern pstring debugf;
int global_nmb_port = NMB_PORT;
TimeInit();
pstrcpy(configfile,CONFIGFILE);
while ((opt = getopt(argc, argv, "Dh")) != EOF)
{
switch (opt)
{
case 'D':
{
is_daemon = True;
break;
}
case 'h':
default:
{
usage(argv[0]);
break;
}
}
}
slprintf(debugf, sizeof(debugf)-1, "log.%s", argv[0]);
setup_logging(argv[0], !is_daemon);
charset_initialise();
if (!lp_load(configfile,True,False,False))
{
DEBUG(0,("Unable to load config file\n"));
}
if (is_daemon)
{
DEBUG(0,("%s: becoming daemon\n", argv[0]));
become_daemon();
}
if (!open_sockets(True, global_nmb_port))
{
return 1;
}
start_agent();
return 0;
}

View File

@ -33,24 +33,28 @@ extern struct in_addr ipzero;
int ServerFD= -1;
int RootPort = 0;
BOOL RootPort = False;
/****************************************************************************
open the socket communication
**************************************************************************/
static BOOL open_sockets(void)
{
if (RootPort)
{
ServerFD = open_socket_in( SOCK_DGRAM,
(RootPort ? 137 :0),
137,
3,
interpret_addr(lp_socket_address()) );
if (ServerFD == -1)
{
return(False);
}
set_socket_options(ServerFD,"SO_BROADCAST");
DEBUG(3, ("Socket opened.\n"));
}
return True;
}
@ -152,7 +156,7 @@ int main(int argc,char *argv[])
pstrcpy(servicesf, optarg);
break;
case 'r':
RootPort = -1;
RootPort = True;
break;
case 'h':
usage();