summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-12-05 01:34:34 +0000
committerLuke Leighton <lkcl@samba.org>1999-12-05 01:34:34 +0000
commit92bc7a4263ba27f113306b31721dc3bbaa94baf3 (patch)
treeb1e93ef359740f89d9470a61e8973822605b832e
parent854f35e20fa4748312e4b0fbae6bb38342ab0389 (diff)
downloadsamba-92bc7a4263ba27f113306b31721dc3bbaa94baf3.tar.gz
samba-92bc7a4263ba27f113306b31721dc3bbaa94baf3.tar.bz2
samba-92bc7a4263ba27f113306b31721dc3bbaa94baf3.zip
first version of msrpc agent redirector code. client-side only.
(This used to be commit 5e5a1dceee0b6088822697284d3e0af04d197477)
-rw-r--r--source3/Makefile.in5
-rw-r--r--source3/include/proto.h37
-rw-r--r--source3/include/smb.h11
-rw-r--r--source3/lib/msrpc-agent.c261
-rw-r--r--source3/lib/msrpc-client.c318
-rw-r--r--source3/lib/msrpc_use.c321
-rw-r--r--source3/lib/util_array.c4
-rw-r--r--source3/rpc_client/cli_use.c2
8 files changed, 953 insertions, 6 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 6984baf7c3..6dac160ffe 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -150,7 +150,10 @@ RPC_PARSE_OBJ1 = rpc_parse/parse_lsa.o \
rpc_parse/parse_brs.o
RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o rpc_parse/parse_prs.o \
- rpc_parse/parse_misc.o
+ rpc_parse/parse_misc.o \
+ lib/msrpc-agent.o \
+ lib/msrpc-client.o \
+ lib/msrpc_use.o \
RPC_PARSE_OBJ = $(RPC_PARSE_OBJ1) $(RPC_PARSE_OBJ2)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0cea6792c6..ed1f1aef58 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -280,6 +280,39 @@ BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size, BOOL force_grow)
uint32 mem_buf_len(struct mem_buf *buf);
char *mem_data(struct mem_buf **buf, uint32 offset);
+/*The following definitions come from lib/msrpc-agent.c */
+
+void start_msrpc_agent(char *pipe_name);
+
+/*The following definitions come from lib/msrpc-client.c */
+
+BOOL msrpc_receive(struct msrpc_state *msrpc);
+BOOL msrpc_send(struct msrpc_state *msrpc, BOOL show);
+BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
+void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_credentials *usr);
+void msrpc_close_socket(struct msrpc_state *msrpc);
+void msrpc_sockopt(struct msrpc_state *msrpc, char *options);
+BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
+ const char* pipename,
+ const struct user_credentials *usr);
+struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc);
+void msrpc_shutdown(struct msrpc_state *msrpc);
+BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
+ const char *pipe_name);
+
+/*The following definitions come from lib/msrpc_use.c */
+
+void init_msrpc_use(void);
+void free_msrpc_use(void);
+struct msrpc_state *msrpc_use_add(const char* pipe_name,
+ const struct user_credentials *usr_creds,
+ BOOL redir);
+BOOL msrpc_use_del(const char* pipe_name,
+ const struct user_credentials *usr_creds,
+ BOOL force_close,
+ BOOL *connection_closed);
+void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use);
+
/*The following definitions come from lib/netmask.c */
int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
@@ -494,8 +527,8 @@ void free_void_array(uint32 num_entries, void **entries,
void* add_copy_to_array(uint32 *len, void ***array, const void *item,
void*(item_dup)(const void*), BOOL alloc_anyway);
void* add_item_to_array(uint32 *len, void ***array, void *item);
-void free_use_array(uint32 num_entries, struct use_info **entries);
-struct use_info* add_use_to_array(uint32 *len, struct use_info ***array,
+void free_use_info_array(uint32 num_entries, struct use_info **entries);
+struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
const struct use_info *name);
void free_char_array(uint32 num_entries, char **entries);
char* add_chars_to_array(uint32 *len, char ***array, const char *name);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index d4d2f6712a..d75b1fe0ad 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1754,6 +1754,17 @@ struct nmb_state
int port;
};
+struct msrpc_state
+{
+ fstring pipe_name;
+ struct user_credentials usr;
+ int fd;
+ BOOL redirect;
+ BOOL initialised;
+ char *inbuf;
+ char *outbuf;
+};
+
#endif /* _SMB_H */
/* _SMB_H */
diff --git a/source3/lib/msrpc-agent.c b/source3/lib/msrpc-agent.c
new file mode 100644
index 0000000000..4612aae14f
--- /dev/null
+++ b/source3/lib/msrpc-agent.c
@@ -0,0 +1,261 @@
+/*
+ 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;
+
+static char packet[BUFFER_SIZE];
+
+/****************************************************************************
+terminate sockent connection
+***********************************************************<*****************/
+static void free_sock(void *sock)
+{
+ if (sock != NULL)
+ {
+ struct msrpc_state *n = (struct msrpc_state*)sock;
+ msrpc_use_del(n->pipe_name, &n->usr, False, NULL);
+ }
+}
+
+static struct msrpc_state *init_client_connection(int c)
+{
+ pstring buf;
+ uchar ntpw[16];
+ uchar lmpw[16];
+ fstring pipe_name;
+ struct user_credentials usr;
+ char *p = buf;
+ int rl;
+ uint32 len;
+ uint16 version;
+ uint16 command;
+ BOOL new_con = False;
+
+ ZERO_STRUCT(usr);
+
+ DEBUG(10,("first request\n"));
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl != sizeof(len))
+ {
+ DEBUG(0,("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return NULL;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0,("length %d too long\n", len));
+ return NULL;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0,("Unable to read from connection\n"));
+ return NULL;
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+ version = SVAL(p, 0);
+ p += 2;
+ command = SVAL(p, 0);
+ p += 2;
+
+ fstrcpy(pipe_name, p);
+ p = skip_string(p, 1);
+ fstrcpy(usr.user_name, p);
+ p = skip_string(p, 1);
+ fstrcpy(usr.domain, p);
+ p = skip_string(p, 1);
+
+ if (PTR_DIFF(p, buf) < rl)
+ {
+ memcpy(lmpw, p, 16);
+ p += 16;
+ memcpy(ntpw, p, 16);
+ p += 16;
+ pwd_set_lm_nt_16(&usr.pwd, lmpw, ntpw);
+ }
+ else
+ {
+ pwd_set_nullpwd(&usr.pwd);
+ }
+
+ if (PTR_DIFF(p, buf) != rl)
+ {
+ DEBUG(0,("Buffer size %d %d!\n",
+ PTR_DIFF(p, buf), rl));
+ return NULL;
+ }
+
+ switch (command)
+ {
+ case AGENT_CMD_CON:
+ {
+ new_con = True;
+ break;
+ }
+ case AGENT_CMD_CON_REUSE:
+ {
+ new_con = True;
+ usr.reuse = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("unknown command %d\n", command));
+ return NULL;
+ }
+ }
+
+ if (new_con)
+ {
+ struct msrpc_state *n;
+ uint32 status = 0;
+ n = msrpc_use_add(pipe_name, &usr, False);
+
+ if (n == NULL)
+ {
+ DEBUG(0,("Unable to connect to %s\n", pipe_name));
+ status = 0x1;
+ }
+ else
+ {
+ fstrcpy(n->pipe_name, pipe_name);
+ copy_user_creds(&n->usr, &usr);
+ }
+
+ if (write(c, &status, sizeof(status)) != sizeof(status))
+ {
+ DEBUG(0,("Could not write connection down pipe.\n"));
+ if (n != NULL)
+ {
+ msrpc_use_del(pipe_name, &usr, False, NULL);
+ n = NULL;
+ }
+ }
+ return n;
+ }
+ return NULL;
+}
+
+static BOOL process_cli_sock(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock)
+{
+ struct msrpc_state *n = (struct msrpc_state*)sock->n;
+ if (n == NULL)
+ {
+ n = init_client_connection(sock->c);
+ if (n == NULL)
+ {
+ return False;
+ }
+ sock->n = (void*)n;
+ sock->s = n->fd;
+ }
+ else
+ {
+ if (!receive_smb(sock->c, packet, 0))
+ {
+ DEBUG(0,("client closed connection\n"));
+ return False;
+ }
+
+ if (!send_smb(sock->s, packet))
+ {
+ DEBUG(0,("server is dead\n"));
+ return False;
+ }
+ }
+ return True;
+}
+
+static BOOL process_srv_sock(struct sock_redir **socks, uint32 num_socks,
+ int fd)
+{
+ int i;
+ if (!receive_smb(fd, packet, 0))
+ {
+ DEBUG(0,("server closed connection\n"));
+ return False;
+ }
+
+ DEBUG(10,("process_srv_sock:\tfd:\t%d\n", fd));
+
+ for (i = 0; i < num_socks; i++)
+ {
+ struct msrpc_state *n;
+ if (socks[i] == NULL || socks[i]->n == NULL)
+ {
+ continue;
+ }
+ n = (struct msrpc_state*)socks[i]->n;
+ DEBUG(10,("list:\tfd:\t%d\n",
+ socks[i]->s));
+ if (!send_smb(socks[i]->c, packet))
+ {
+ DEBUG(0,("client is dead\n"));
+ return False;
+ }
+ return True;
+ }
+ return False;
+}
+
+static int get_agent_sock(char *pipe_name)
+{
+ fstring path;
+ fstring dir;
+
+ slprintf(dir, sizeof(dir)-1, "/tmp/.msrpc/.%s", pipe_name);
+ slprintf(path, sizeof(path)-1, "%s/agent", dir);
+
+ return create_pipe_socket(dir, S_IRUSR|S_IWUSR|S_IXUSR, path, 0);
+}
+
+void start_msrpc_agent(char *pipe_name)
+{
+ struct vagent_ops va =
+ {
+ free_sock,
+ get_agent_sock,
+ process_cli_sock,
+ process_srv_sock,
+ pipe_name,
+ NULL,
+ 0
+ };
+
+ CatchChild();
+
+ start_agent(&va);
+}
+
diff --git a/source3/lib/msrpc-client.c b/source3/lib/msrpc-client.c
new file mode 100644
index 0000000000..eacc25341e
--- /dev/null
+++ b/source3/lib/msrpc-client.c
@@ -0,0 +1,318 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB msrpcent generic functions
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-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.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+recv an smb
+****************************************************************************/
+BOOL msrpc_receive(struct msrpc_state *msrpc)
+{
+ return receive_smb(msrpc->fd,msrpc->inbuf,0);
+}
+
+/****************************************************************************
+ send an smb to a fd and re-establish if necessary
+****************************************************************************/
+BOOL msrpc_send(struct msrpc_state *msrpc, BOOL show)
+{
+ size_t len;
+ size_t nwritten=0;
+ ssize_t ret;
+
+ len = smb_len(msrpc->outbuf) + 4;
+
+ dump_data(10, msrpc->outbuf, len);
+
+ while (nwritten < len)
+ {
+ ret = write_socket(msrpc->fd,msrpc->outbuf+nwritten,len - nwritten);
+ if (ret <= 0)
+ {
+ DEBUG(0,("Error writing %d bytes to msrpcent. %d. Exiting\n",
+ len,ret));
+ return False;
+ }
+ nwritten += ret;
+ }
+
+ return True;
+}
+
+
+
+/****************************************************************************
+open the msrpcent sockets
+****************************************************************************/
+BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name)
+{
+ fstring path;
+ slprintf(path, sizeof(path)-1, "/tmp/.msrpc/%s", pipe_name);
+
+ fstrcpy(msrpc->pipe_name, pipe_name);
+
+ msrpc->fd = open_pipe_sock(path);
+
+ if (msrpc->fd == -1)
+ {
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_credentials *usr)
+{
+ copy_user_creds(&msrpc->usr, usr);
+}
+
+/****************************************************************************
+close the socket descriptor
+****************************************************************************/
+void msrpc_close_socket(struct msrpc_state *msrpc)
+{
+ if (msrpc->fd != -1)
+ {
+ close(msrpc->fd);
+ }
+ msrpc->fd = -1;
+}
+
+
+/****************************************************************************
+set socket options on a open connection
+****************************************************************************/
+void msrpc_sockopt(struct msrpc_state *msrpc, char *options)
+{
+ set_socket_options(msrpc->fd, options);
+}
+
+
+static int msrpc_init_redirect(struct msrpc_state *msrpc,
+ const char* pipe_name,
+ const struct user_credentials *usr)
+{
+ int sock;
+ struct msrpc_state msrpc_redir;
+ fstring path;
+
+ pstring data;
+ uint32 len;
+ char *p;
+ char *in = msrpc->inbuf;
+ char *out = msrpc->outbuf;
+
+ slprintf(path, sizeof(path)-1, "/tmp/.msrpc/.%s/agent", pipe_name);
+
+ sock = open_pipe_sock(path);
+
+ if (sock < 0)
+ {
+ return sock;
+ }
+
+ ZERO_STRUCT(data);
+
+ p = &data[4];
+ SSVAL(p, 0, 0);
+ p += 2;
+
+ SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON);
+ p += 2;
+
+ safe_strcpy(p, pipe_name, 16);
+ p = skip_string(p, 1);
+ safe_strcpy(p, usr != NULL ? usr->user_name : "", 16);
+ p = skip_string(p, 1);
+ safe_strcpy(p, usr != NULL ? usr->domain : "", 16);
+ p = skip_string(p, 1);
+
+ if (usr != NULL && !pwd_is_nullpwd(&usr->pwd))
+ {
+ uchar lm16[16];
+ uchar nt16[16];
+
+ pwd_get_lm_nt_16(&usr->pwd, lm16, nt16);
+ memcpy(p, lm16, 16);
+ p += 16;
+ memcpy(p, nt16, 16);
+ p += 16;
+ }
+
+ len = PTR_DIFF(p, data);
+ SIVAL(data, 0, len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("data len: %d\n", len));
+ dump_data(100, data, len);
+#endif
+
+ if (write(sock, data, len) <= 0)
+ {
+ DEBUG(0,("write failed\n"));
+ close(sock);
+ return False;
+ }
+
+ len = read(sock, &msrpc_redir, sizeof(msrpc_redir));
+
+ if (len != sizeof(msrpc_redir))
+ {
+ DEBUG(0,("read failed\n"));
+ close(sock);
+ return False;
+ }
+
+ memcpy(msrpc, &msrpc_redir, sizeof(msrpc_redir));
+ msrpc->inbuf = in;
+ msrpc->outbuf = out;
+ msrpc->fd = sock;
+ msrpc->usr.reuse = False;
+
+ return sock;
+}
+
+BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
+ const char* pipename,
+ const struct user_credentials *usr)
+{
+ ZERO_STRUCTP(msrpc);
+ if (!msrpc_initialise(msrpc))
+ {
+ DEBUG(0,("unable to initialise msrpcent connection.\n"));
+ return False;
+ }
+
+ msrpc_init_creds(msrpc, usr);
+
+ if (!msrpc_establish_connection(msrpc, pipename))
+ {
+ msrpc_shutdown(msrpc);
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc)
+{
+ if (!msrpc) {
+ msrpc = (struct msrpc_state *)malloc(sizeof(*msrpc));
+ if (!msrpc)
+ return NULL;
+ ZERO_STRUCTP(msrpc);
+ }
+
+ if (msrpc->initialised) {
+ msrpc_shutdown(msrpc);
+ }
+
+ ZERO_STRUCTP(msrpc);
+
+ msrpc->fd = -1;
+ msrpc->outbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
+ msrpc->inbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
+ if (!msrpc->outbuf || !msrpc->inbuf)
+ {
+ return False;
+ }
+
+ msrpc->initialised = 1;
+ msrpc_init_creds(msrpc, NULL);
+
+ return msrpc;
+}
+
+
+/****************************************************************************
+shutdown a msrpcent structure
+****************************************************************************/
+void msrpc_shutdown(struct msrpc_state *msrpc)
+{
+ DEBUG(10,("msrpc_shutdown\n"));
+ if (msrpc->outbuf)
+ {
+ free(msrpc->outbuf);
+ }
+ if (msrpc->inbuf)
+ {
+ free(msrpc->inbuf);
+ }
+ msrpc_close_socket(msrpc);
+ memset(msrpc, 0, sizeof(*msrpc));
+}
+
+/****************************************************************************
+establishes a connection right up to doing tconX, reading in a password.
+****************************************************************************/
+BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
+ const char *pipe_name)
+{
+ DEBUG(5,("msrpc_establish_connection: connecting to %s (%s) - %s\n",
+ pipe_name,
+ msrpc->usr.user_name, msrpc->usr.domain));
+
+ /* establish connection */
+
+ if ((!msrpc->initialised))
+ {
+ return False;
+ }
+
+ if (msrpc->fd == -1 && msrpc->redirect)
+ {
+ if (msrpc_init_redirect(msrpc, pipe_name, &msrpc->usr))
+ {
+ DEBUG(10,("msrpc_establish_connection: redirected OK\n"));
+ return True;
+ }
+ else
+ {
+ DEBUG(10,("redirect FAILED\n"));
+ return False;
+ }
+ }
+ if (msrpc->fd == -1)
+ {
+ if (!msrpc_connect(msrpc, pipe_name))
+ {
+ DEBUG(1,("msrpc_establish_connection: failed %s)\n",
+ pipe_name));
+
+ return False;
+ }
+ }
+
+ return True;
+}
+
diff --git a/source3/lib/msrpc_use.c b/source3/lib/msrpc_use.c
new file mode 100644
index 0000000000..a8fb009df0
--- /dev/null
+++ b/source3/lib/msrpc_use.c
@@ -0,0 +1,321 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client generic functions
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-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.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+#include "trans2.h"
+
+extern int DEBUGLEVEL;
+extern pstring scope;
+extern pstring global_myname;
+
+struct msrpc_use
+{
+ struct msrpc_state *cli;
+ uint32 num_users;
+};
+
+static struct msrpc_use **msrpcs = NULL;
+uint32 num_msrpcs = 0;
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+static void msrpc_use_free(struct msrpc_use *cli)
+{
+ if (cli->cli != NULL)
+ {
+ if (cli->cli->initialised)
+ {
+ msrpc_shutdown(cli->cli);
+ }
+ free(cli->cli);
+ }
+
+ free(cli);
+}
+
+/****************************************************************************
+free a client array
+****************************************************************************/
+static void free_msrpc_array(uint32 num_entries, struct msrpc_use **entries)
+{
+ void(*fn)(void*) = (void(*)(void*))&msrpc_use_free;
+ free_void_array(num_entries, (void**)entries, *fn);
+}
+
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct msrpc_use* add_msrpc_to_array(uint32 *len,
+ struct msrpc_use ***array,
+ struct msrpc_use *cli)
+{
+ int i;
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ if (msrpcs[i] == NULL)
+ {
+ msrpcs[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct msrpc_use*)add_item_to_array(len,
+ (void***)array, (void*)cli);
+
+}
+
+/****************************************************************************
+initiate client array
+****************************************************************************/
+void init_msrpc_use(void)
+{
+ msrpcs = NULL;
+ num_msrpcs = 0;
+}
+
+/****************************************************************************
+terminate client array
+****************************************************************************/
+void free_msrpc_use(void)
+{
+ free_msrpc_array(num_msrpcs, msrpcs);
+ init_msrpc_use();
+}
+
+/****************************************************************************
+find client state. server name, user name, domain name and password must all
+match.
+****************************************************************************/
+static struct msrpc_use *msrpc_find(const char* pipe_name,
+ const struct user_credentials *usr_creds)
+{
+ int i;
+ struct user_credentials null_usr;
+
+ copy_user_creds(&null_usr, usr_creds);
+ usr_creds = &null_usr;
+
+ DEBUG(10,("msrpc_find: %s %s %s\n",
+ pipe_name,
+ usr_creds->user_name,
+ usr_creds->domain));
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ char *msrpc_name = NULL;
+ struct msrpc_use *c = msrpcs[i];
+
+ if (c == NULL) continue;
+
+ msrpc_name = c->cli->pipe_name;
+
+ DEBUG(10,("msrpc_find[%d]: %s %s %s\n",
+ i, msrpc_name,
+ c->cli->usr.user_name,
+ c->cli->usr.domain));
+
+ if (!strequal(msrpc_name, pipe_name))
+ {
+ continue;
+ }
+ if (!strequal(usr_creds->user_name, c->cli->usr.user_name))
+ {
+ continue;
+ }
+ if (!usr_creds->reuse &&
+ !pwd_compare(&usr_creds->pwd, &c->cli->usr.pwd))
+ {
+ DEBUG(100,("password doesn't match\n"));
+ continue;
+ }
+ if (usr_creds->domain[0] == 0)
+ {
+ return c;
+ }
+ if (strequal(usr_creds->domain, c->cli->usr.domain))
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct msrpc_use *msrpc_use_get(const char* pipe_name,
+ const struct user_credentials *usr_creds)
+{
+ struct msrpc_use *cli = (struct msrpc_use*)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = msrpc_initialise(NULL);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ msrpc_init_creds(cli->cli, usr_creds);
+
+ return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct msrpc_state *msrpc_use_add(const char* pipe_name,
+ const struct user_credentials *usr_creds,
+ BOOL redir)
+{
+ struct msrpc_use *cli = msrpc_find(pipe_name, usr_creds);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ return cli->cli;
+ }
+
+ /* reuse an existing connection requested, and one was not found */
+ if (usr_creds != NULL && usr_creds->reuse && !redir)
+ {
+ return False;
+ }
+
+ /*
+ * allocate
+ */
+
+ cli = msrpc_use_get(pipe_name, usr_creds);
+ cli->cli->redirect = redir;
+
+ if (!msrpc_establish_connection(cli->cli, pipe_name))
+ {
+ DEBUG(0,("msrpc_net_use_add: connection failed\n"));
+ cli->cli = NULL;
+ msrpc_use_free(cli);
+ return NULL;
+ }
+
+ add_msrpc_to_array(&num_msrpcs, &msrpcs, cli);
+ cli->num_users++;
+
+ return cli->cli;
+}
+
+/****************************************************************************
+delete a client state
+****************************************************************************/
+BOOL msrpc_use_del(const char* pipe_name,
+ const struct user_credentials *usr_creds,
+ BOOL force_close,
+ BOOL *connection_closed)
+{
+ int i;
+
+ DEBUG(10,("msrpc_net_use_del: %s. force close: %s\n",
+ pipe_name, BOOLSTR(force_close)));
+
+ if (connection_closed != NULL)
+ {
+ *connection_closed = False;
+ }
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ char *msrpc_name = NULL;
+
+ if (msrpcs[i] == NULL) continue;
+ if (msrpcs[i]->cli == NULL) continue;
+
+ msrpc_name = msrpcs[i]->cli->pipe_name;
+
+ if (!strequal(msrpc_name, pipe_name)) continue;
+
+ if (strequal(usr_creds->user_name,
+ msrpcs[i]->cli->usr.user_name) &&
+ strequal(usr_creds->domain,
+ msrpcs[i]->cli->usr.domain))
+ {
+ /* decrement number of users */
+ msrpcs[i]->num_users--;
+
+ DEBUG(10,("idx: %i num_users now: %d\n",
+ i, msrpcs[i]->num_users));
+
+ if (force_close || msrpcs[i]->num_users == 0)
+ {
+ msrpc_use_free(msrpcs[i]);
+ msrpcs[i] = NULL;
+ if (connection_closed != NULL)
+ {
+ *connection_closed = True;
+ }
+ }
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/****************************************************************************
+enumerate client states
+****************************************************************************/
+void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use)
+{
+ int i;
+
+ *num_cons = 0;
+ *use = NULL;
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ struct use_info item;
+
+ ZERO_STRUCT(item);
+
+ if (msrpcs[i] == NULL) continue;
+
+ item.connected = msrpcs[i]->cli != NULL ? True : False;
+
+ if (item.connected)
+ {
+ item.srv_name = msrpcs[i]->cli->pipe_name;
+ item.user_name = msrpcs[i]->cli->usr.user_name;
+ item.domain = msrpcs[i]->cli->usr.domain;
+ }
+
+ add_use_info_to_array(num_cons, use, &item);
+ }
+}
+
diff --git a/source3/lib/util_array.c b/source3/lib/util_array.c
index 71cd19e65d..5a21053cc6 100644
--- a/source3/lib/util_array.c
+++ b/source3/lib/util_array.c
@@ -125,13 +125,13 @@ static struct use_info *use_info_dup(const struct use_info *from)
return NULL;
}
-void free_use_array(uint32 num_entries, struct use_info **entries)
+void free_use_info_array(uint32 num_entries, struct use_info **entries)
{
void(*fn)(void*) = (void(*)(void*))&use_info_free;
free_void_array(num_entries, (void**)entries, *fn);
}
-struct use_info* add_use_to_array(uint32 *len, struct use_info ***array,
+struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
const struct use_info *name)
{
void*(*fn)(const void*) = (void*(*)(const void*))&use_info_dup;
diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c
index 1dc39f3cb2..93a85d748d 100644
--- a/source3/rpc_client/cli_use.c
+++ b/source3/rpc_client/cli_use.c
@@ -366,7 +366,7 @@ void cli_net_use_enum(uint32 *num_cons, struct use_info ***use)
item.domain = clis[i]->cli->usr.domain;
}
- add_use_to_array(num_cons, use, &item);
+ add_use_info_to_array(num_cons, use, &item);
}
}