]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
first version of msrpc agent redirector code. client-side only.
authorLuke Leighton <lkcl@samba.org>
Sun, 5 Dec 1999 01:34:34 +0000 (01:34 +0000)
committerLuke Leighton <lkcl@samba.org>
Sun, 5 Dec 1999 01:34:34 +0000 (01:34 +0000)
(This used to be commit 5e5a1dceee0b6088822697284d3e0af04d197477)

source3/Makefile.in
source3/include/proto.h
source3/include/smb.h
source3/lib/msrpc-agent.c [new file with mode: 0644]
source3/lib/msrpc-client.c [new file with mode: 0644]
source3/lib/msrpc_use.c [new file with mode: 0644]
source3/lib/util_array.c
source3/rpc_client/cli_use.c

index 6984baf7c3c3759a791b836b3be1d327277a2905..6dac160ffe6cf44803746d6360aad0520c47fdd6 100644 (file)
@@ -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)
 
index 0cea6792c687877e2a03e3ec62922958b0be898c..ed1f1aef58f2ca28e49eafcb8eca6e32638b4561 100644 (file)
@@ -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);
index d4d2f6712a1ff4f08d89277979bead02de6d2839..d75b1fe0ad5ac2695743956dd94d22a976408a78 100644 (file)
@@ -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 (file)
index 0000000..4612aae
--- /dev/null
@@ -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 (file)
index 0000000..eacc253
--- /dev/null
@@ -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 (file)
index 0000000..a8fb009
--- /dev/null
@@ -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);
+       }
+}
+
index 71cd19e65d514ecfac9d66db2e2da87cdd9b2581..5a21053cc6b56ebe4d6246d00fa64caf33cd8694 100644 (file)
@@ -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;
index 1dc39f3cb2413499d628813cb62bafd65e92118e..93a85d748d97371017b351165cf2789bd0a3b7f7 100644 (file)
@@ -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);
        }
 }