summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-12-04 21:55:39 +0000
committerLuke Leighton <lkcl@samba.org>1999-12-04 21:55:39 +0000
commitf6077db3173c7b6520d5735f78d06138ac273174 (patch)
tree8a919b198a0edf3567c11b9b523ea562b6faa68f
parent9b44e117f955872ae42dcd5eee128394ca4d9ccd (diff)
downloadsamba-f6077db3173c7b6520d5735f78d06138ac273174.tar.gz
samba-f6077db3173c7b6520d5735f78d06138ac273174.tar.bz2
samba-f6077db3173c7b6520d5735f78d06138ac273174.zip
cool! created higher-order function table for agent redirection.
(This used to be commit 7bb2e55d0d3a00a97bba99ebed722a4adf84093c)
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/include/proto.h6
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/include/vagent.h51
-rw-r--r--source3/lib/vagent.c242
-rw-r--r--source3/utils/smb-agent.c253
6 files changed, 340 insertions, 216 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index cb102e0607..6984baf7c3 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -113,6 +113,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/util_file.o mem_man/mem_man.o \
lib/util_sock.o lib/unix_sec_ctxt.o \
lib/util_array.o \
+ lib/vagent.o \
lib/util_hnd.o
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 24dfd6ed1a..5e423e3726 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -138,6 +138,12 @@ BOOL allow_access(char *deny_list,char *allow_list,
char *cname,char *caddr);
BOOL check_access(int sock, char *allow_list, char *deny_list);
+/*The following definitions come from lib/agent.c */
+
+void init_sock_redir(struct vagent_ops*va);
+void free_sock_redir(struct vagent_ops*va);
+void start_agent(struct vagent_ops *va);
+
/*The following definitions come from lib/bitmap.c */
struct bitmap *bitmap_allocate(int n);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 8adfa5e690..d4d2f6712a 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -550,6 +550,9 @@ typedef struct
#include "vfs.h"
+
+#include "vagent.h"
+
typedef struct connection_struct
{
struct connection_struct *next, *prev;
diff --git a/source3/include/vagent.h b/source3/include/vagent.h
new file mode 100644
index 0000000000..19bb976635
--- /dev/null
+++ b/source3/include/vagent.h
@@ -0,0 +1,51 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Vagent structures and parameters
+ Copyright (C) Luke Kenneth Casson Leighton 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.
+*/
+
+#ifndef _VAGENT_H
+#define _VAGENT_H
+
+/* Vagent operations structure */
+
+struct sock_redir
+{
+ int c;
+ int s;
+ int c_id;
+ int s_id;
+ void *n;
+};
+
+struct vagent_ops
+{
+ void (*free_sock)(void* sock);
+ int (*get_agent_sock)(void* id);
+
+ BOOL (*process_cli_sock)(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock);
+ BOOL (*process_srv_sock)(struct sock_redir **socks, uint32 num_socks,
+ int fd);
+
+ void* id;
+ struct sock_redir **socks;
+ uint32 num_socks;
+};
+
+#endif /* _VAGENT_H */
diff --git a/source3/lib/vagent.c b/source3/lib/vagent.c
new file mode 100644
index 0000000000..96df03e2f3
--- /dev/null
+++ b/source3/lib/vagent.c
@@ -0,0 +1,242 @@
+/*
+ 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"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+terminate socket connection
+****************************************************************************/
+static void sock_redir_free(struct vagent_ops *va, struct sock_redir *sock)
+{
+ if (sock->c != -1)
+ {
+ close(sock->c);
+ sock->c = -1;
+ }
+ if (sock->n != NULL)
+ {
+ va->free_sock(sock->n);
+ sock->n = NULL;
+ }
+ free(sock);
+}
+
+/****************************************************************************
+free a sockent array
+****************************************************************************/
+static void free_sock_array(struct vagent_ops*va)
+{
+ void(*fn)(void*) = (void(*)(void*))&va->free_sock;
+ free_void_array(va->num_socks, (void**)va->socks, *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 < (*len); i++)
+ {
+ if ((*array)[i] == NULL)
+ {
+ (*array)[i] = sock;
+ return sock;
+ }
+ }
+
+ return (struct sock_redir*)add_item_to_array(len,
+ (void***)array, (void*)sock);
+
+}
+
+/****************************************************************************
+initiate sockent array
+****************************************************************************/
+void init_sock_redir(struct vagent_ops*va)
+{
+ va->socks = NULL;
+ va->num_socks = 0;
+}
+
+/****************************************************************************
+terminate sockent array
+****************************************************************************/
+void free_sock_redir(struct vagent_ops*va)
+{
+ free_sock_array(va);
+ init_sock_redir(va);
+}
+
+/****************************************************************************
+create a new sockent state from user credentials
+****************************************************************************/
+static struct sock_redir *sock_redir_get(struct vagent_ops *va, int fd)
+{
+ struct sock_redir *sock = (struct sock_redir*)malloc(sizeof(*sock));
+
+ if (sock == NULL)
+ {
+ return NULL;
+ }
+
+ ZERO_STRUCTP(sock);
+
+ sock->c = fd;
+ sock->n = NULL;
+
+ DEBUG(10,("sock_redir_get:\tfd:\t%d\n", fd));
+
+ return sock;
+}
+/****************************************************************************
+init sock state
+****************************************************************************/
+static void sock_add(struct vagent_ops *va, int fd)
+{
+ struct sock_redir *sock;
+ sock = sock_redir_get(va, fd);
+ if (sock != NULL)
+ {
+ add_sock_to_array(&va->num_socks, &va->socks, sock);
+ }
+}
+
+/****************************************************************************
+delete a sockent state
+****************************************************************************/
+static BOOL sock_del(struct vagent_ops *va, int fd)
+{
+ int i;
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] == NULL) continue;
+ if (va->socks[i]->c == fd)
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ return True;
+ }
+ }
+
+ return False;
+}
+
+void start_agent(struct vagent_ops *va)
+{
+ int s, c;
+
+ s = va->get_agent_sock(va->id);
+
+ while (1)
+ {
+ int i;
+ fd_set fds;
+ int num;
+ struct sockaddr_un addr;
+ int in_addrlen = sizeof(addr);
+ int maxfd = s;
+
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] != NULL)
+ {
+ int fd = va->socks[i]->c;
+ FD_SET(fd, &fds);
+ maxfd = MAX(maxfd, fd);
+
+ if (va->socks[i]->n != NULL)
+ {
+ fd = va->socks[i]->s;
+ FD_SET(fd, &fds);
+ maxfd = MAX(fd, maxfd);
+ }
+ }
+ }
+
+ dbgflush();
+ num = sys_select(maxfd+1,&fds,NULL, NULL);
+
+ if (num <= 0)
+ {
+ continue;
+ }
+
+ if (FD_ISSET(s, &fds))
+ {
+ FD_CLR(s, &fds);
+ c = accept(s, (struct sockaddr*)&addr, &in_addrlen);
+ if (c != -1)
+ {
+ sock_add(va, c);
+ }
+ }
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] == NULL)
+ {
+ continue;
+ }
+ if (FD_ISSET(va->socks[i]->c, &fds))
+ {
+ FD_CLR(va->socks[i]->c, &fds);
+ if (!va->process_cli_sock(va->socks,
+ va->num_socks,
+ va->socks[i]))
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ }
+ }
+ if (va->socks[i] == NULL)
+ {
+ continue;
+ }
+ if (va->socks[i]->n == NULL)
+ {
+ continue;
+ }
+ if (FD_ISSET(va->socks[i]->s, &fds))
+ {
+ FD_CLR(va->socks[i]->s, &fds);
+ if (!va->process_srv_sock(va->socks,
+ va->num_socks,
+ va->socks[i]->s))
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ }
+ }
+ }
+ }
+}
+
diff --git a/source3/utils/smb-agent.c b/source3/utils/smb-agent.c
index 457631c307..5d1aa4db04 100644
--- a/source3/utils/smb-agent.c
+++ b/source3/utils/smb-agent.c
@@ -38,139 +38,19 @@ static char packet[BUFFER_SIZE];
extern int DEBUGLEVEL;
-struct sock_redir
-{
- int c;
- int s;
- int mid_offset;
- struct cli_state *n;
-};
-
-static uint32 num_socks = 0;
-static struct sock_redir **socks = NULL;
static uint16 mid_offset = 0x0;
/****************************************************************************
terminate sockent connection
****************************************************************************/
-static void sock_redir_free(struct sock_redir *sock)
-{
- close(sock->c);
- sock->c = -1;
- if (sock->n != NULL)
- {
- sock->n->fd = sock->s;
- cli_net_use_del(sock->n->desthost, &sock->n->usr,
- False, NULL);
- sock->n = NULL;
- }
- free(sock);
-}
-
-/****************************************************************************
-free a sockent array
-****************************************************************************/
-static void free_sock_array(uint32 num_entries, struct sock_redir **entries)
+static void free_sock(void *sock)
{
- 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 = (struct sock_redir*)malloc(sizeof(*sock));
-
- if (sock == NULL)
- {
- return NULL;
- }
-
- ZERO_STRUCTP(sock);
-
- sock->c = fd;
- sock->n = NULL;
- sock->mid_offset = mid_offset;
-
- DEBUG(10,("sock_redir_get:\tfd:\t%d\tmidoff:\t%d\n", fd, mid_offset));
-
- 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;
- }
+ struct cli_state *n = (struct cli_state*)sock;
+ cli_net_use_del(n->desthost, &n->usr,
+ False, NULL);
}
-
- return False;
}
static struct cli_state *init_client_connection(int c)
@@ -325,9 +205,10 @@ static void filter_reply(char *buf, int moff)
}
-static BOOL process_cli_sock(struct sock_redir *sock)
+static BOOL process_cli_sock(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock)
{
- struct cli_state *n = sock->n;
+ struct cli_state *n = (struct cli_state*)sock->n;
if (n == NULL)
{
n = init_client_connection(sock->c);
@@ -335,7 +216,9 @@ static BOOL process_cli_sock(struct sock_redir *sock)
{
return False;
}
- sock->n = n;
+ sock->n = (void*)n;
+ sock->s_id = mid_offset;
+ sock->s = n->fd;
}
else
{
@@ -345,7 +228,7 @@ static BOOL process_cli_sock(struct sock_redir *sock)
return False;
}
- filter_reply(packet, sock->mid_offset);
+ filter_reply(packet, sock->s_id);
/* ignore keep-alives */
if (CVAL(packet, 0) != 0x85)
{
@@ -371,7 +254,8 @@ static int get_smbmid(char *buf)
return SVAL(buf,smb_mid);
}
-static BOOL process_srv_sock(int fd)
+static BOOL process_srv_sock(struct sock_redir **socks, uint32 num_socks,
+ int fd)
{
int smbmid;
int i;
@@ -393,16 +277,18 @@ static BOOL process_srv_sock(int fd)
for (i = 0; i < num_socks; i++)
{
int moff;
+ struct cli_state *n;
if (socks[i] == NULL || socks[i]->n == NULL)
{
continue;
}
- moff = socks[i]->mid_offset;
+ moff = socks[i]->s_id;
+ n = (struct cli_state*)socks[i]->n;
DEBUG(10,("list:\tfd:\t%d\tmid:\t%d\tmoff:\t%d\n",
socks[i]->s,
- socks[i]->n->mid,
+ n->mid,
moff));
- if (smbmid != socks[i]->n->mid + moff)
+ if (smbmid != n->mid + moff)
{
continue;
}
@@ -417,15 +303,13 @@ static BOOL process_srv_sock(int fd)
return False;
}
-static void start_agent(void)
+static int get_agent_sock(void *id)
{
- int s, c;
+ int s;
struct sockaddr_un sa;
fstring path;
fstring dir;
- CatchChild();
-
slprintf(dir, sizeof(dir)-1, "/tmp/.smb.%d", getuid());
mkdir(dir, S_IRUSR|S_IWUSR|S_IXUSR);
@@ -470,88 +354,25 @@ static void start_agent(void)
DEBUG(0,("listen failed\n"));
remove(path);
}
+ return s;
+}
- while (1)
+static void start_smb_agent(void)
+{
+ struct vagent_ops va =
{
- int i;
- fd_set fds;
- int num;
- struct sockaddr_un addr;
- int in_addrlen = sizeof(addr);
- int maxfd = s;
-
- FD_ZERO(&fds);
- FD_SET(s, &fds);
-
- for (i = 0; i < num_socks; i++)
- {
- if (socks[i] != NULL)
- {
- int fd = socks[i]->c;
- FD_SET(fd, &fds);
- maxfd = MAX(maxfd, fd);
-
- if (socks[i]->n != NULL)
- {
- fd = socks[i]->s;
- FD_SET(fd, &fds);
- maxfd = MAX(fd, maxfd);
- }
- }
- }
-
- dbgflush();
- num = sys_select(maxfd+1,&fds,NULL, NULL);
-
- if (num <= 0)
- {
- continue;
- }
-
- if (FD_ISSET(s, &fds))
- {
- FD_CLR(s, &fds);
- c = accept(s, (struct sockaddr*)&addr, &in_addrlen);
- if (c != -1)
- {
- sock_add(c);
- }
- }
+ free_sock,
+ get_agent_sock,
+ process_cli_sock,
+ process_srv_sock,
+ NULL,
+ NULL,
+ 0
+ };
+
+ CatchChild();
- for (i = 0; i < num_socks; i++)
- {
- if (socks[i] == NULL)
- {
- continue;
- }
- if (FD_ISSET(socks[i]->c, &fds))
- {
- FD_CLR(socks[i]->c, &fds);
- if (!process_cli_sock(socks[i]))
- {
- sock_redir_free(socks[i]);
- socks[i] = NULL;
- }
- }
- if (socks[i] == NULL)
- {
- continue;
- }
- if (socks[i]->n == NULL)
- {
- continue;
- }
- if (FD_ISSET(socks[i]->s, &fds))
- {
- FD_CLR(socks[i]->s, &fds);
- if (!process_srv_sock(socks[i]->s))
- {
- sock_redir_free(socks[i]);
- socks[i] = NULL;
- }
- }
- }
- }
+ start_agent(&va);
}
/****************************************************************************
@@ -612,7 +433,7 @@ int main(int argc, char *argv[])
become_daemon();
}
- start_agent();
+ start_smb_agent();
return 0;
}