summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-12-04 19:14:37 +0000
committerLuke Leighton <lkcl@samba.org>1999-12-04 19:14:37 +0000
commitf521205cb3d188fdcadcbd205dcfda4a7dcb89a0 (patch)
tree19135ba0b36cd2108543a462c3b9ec47d4e1dd18 /source3/libsmb
parent8a8a7da5186596ee86b0b188156bca7d5e664784 (diff)
downloadsamba-f521205cb3d188fdcadcbd205dcfda4a7dcb89a0.tar.gz
samba-f521205cb3d188fdcadcbd205dcfda4a7dcb89a0.tar.bz2
samba-f521205cb3d188fdcadcbd205dcfda4a7dcb89a0.zip
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 used to be commit d923bc8da2cf996408194d98381409191dd81a16)
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c19
-rw-r--r--source3/libsmb/namequery.c74
-rw-r--r--source3/libsmb/nmblib.c151
3 files changed, 205 insertions, 39 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index fea105887f..86edfa8bec 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -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];
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 8aaeb165cd..79fb27bd6f 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -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;
+ }
- retries--;
-
- while (1)
+ while (retries >= 0)
{
struct timeval tval2;
+
+ retries--;
+
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;
}
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index ba951a809a..127cfeb130 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -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;
- length = read_udp_socket(fd,buf,sizeof(buf));
+ 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);
- return(send_udp(p->fd,buf,len,p->ip,p->port));
+ 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);
+}