summaryrefslogtreecommitdiff
path: root/source3/rpc_client
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2000-07-07 06:20:46 +0000
committerGerald Carter <jerry@samba.org>2000-07-07 06:20:46 +0000
commitd2b40a7de259377d937492acedd39988ddd108a4 (patch)
treef0849ba6679575e80500b43b8989b3dddf16e2a4 /source3/rpc_client
parent9de93aa8188293671a92e84b2b9dc104cc7eb64c (diff)
downloadsamba-d2b40a7de259377d937492acedd39988ddd108a4.tar.gz
samba-d2b40a7de259377d937492acedd39988ddd108a4.tar.bz2
samba-d2b40a7de259377d937492acedd39988ddd108a4.zip
More rpcclient merge issues:
* fixes some readline bugs from the merge * first attempt at commands (spoolenum almost works) * no changes to existing functions in HEAD; only additions of new functions. I'll weed out what I can as I go. --jerry (This used to be commit 61d2aad5dc2b212b11c981f1eca47efa627e9fc8)
Diffstat (limited to 'source3/rpc_client')
-rw-r--r--source3/rpc_client/cli_connect.c216
-rw-r--r--source3/rpc_client/cli_pipe.c2
-rw-r--r--source3/rpc_client/cli_spoolss.c95
-rw-r--r--source3/rpc_client/cli_use.c3
-rw-r--r--source3/rpc_client/msrpc_spoolss.c221
-rw-r--r--source3/rpc_client/ncacn_np_use.c279
-rw-r--r--source3/rpc_client/ncalrpc_l_use.c158
7 files changed, 972 insertions, 2 deletions
diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c
index ded3e50354..6f098d74ae 100644
--- a/source3/rpc_client/cli_connect.c
+++ b/source3/rpc_client/cli_connect.c
@@ -57,6 +57,17 @@ struct user_creds *usr_creds = NULL;
vuser_key *user_key = NULL;
extern int DEBUGLEVEL;
+extern pstring global_myname;
+cli_auth_fns cli_noauth_fns =
+{
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
void init_connections(void)
@@ -75,6 +86,16 @@ static void free_con_array(uint32 num_entries,
}
+static struct cli_connection *add_con_to_array(uint32 * len,
+ struct cli_connection ***array,
+ struct cli_connection *con)
+{
+ return (struct cli_connection *)add_item_to_array(len,
+ (void ***)array,
+ (void *)con);
+
+}
+
void free_connections(void)
{
DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
@@ -84,6 +105,128 @@ void free_connections(void)
init_connections();
}
+static struct cli_connection *cli_con_get(const char *srv_name,
+ const char *pipe_name,
+ cli_auth_fns * auth,
+ void *auth_creds, BOOL reuse)
+{
+ struct cli_connection *con = NULL;
+ BOOL is_new_connection = False;
+ CREDS_NT usr;
+
+ vuser_key key;
+
+ con = (struct cli_connection *)malloc(sizeof(*con));
+
+ if (con == NULL)
+ {
+ return NULL;
+ }
+
+ memset(con, 0, sizeof(*con));
+ con->type = MSRPC_NONE;
+
+ copy_user_creds(&con->usr_creds, NULL);
+ con->usr_creds.reuse = reuse;
+
+ if (srv_name != NULL)
+ {
+ con->srv_name = strdup(srv_name);
+ }
+ if (pipe_name != NULL)
+ {
+ con->pipe_name = strdup(pipe_name);
+ }
+
+#if 0 /* commented out by JERRY */
+ if (strequal(srv_name, "\\\\."))
+ {
+ con->type = MSRPC_LOCAL;
+ become_root(False);
+ con->msrpc.local = ncalrpc_l_use_add(pipe_name, user_key,
+ reuse,
+ &is_new_connection);
+ unbecome_root(False);
+ }
+ else
+#endif /* commented of by JERRY */
+ {
+ struct ntuser_creds *ntc = NULL;
+ if (usr_creds != NULL)
+ {
+ ntc = &usr_creds->ntc;
+ }
+ con->type = MSRPC_SMB;
+ con->msrpc.smb =
+ ncacn_np_use_add(pipe_name, user_key, srv_name,
+ ntc, reuse,
+ &is_new_connection);
+
+ if (con->msrpc.smb == NULL)
+ return NULL;
+
+ key = con->msrpc.smb->smb->key;
+ con->msrpc.smb->smb->key.pid = 0;
+ con->msrpc.smb->smb->key.vuid = UID_FIELD_INVALID;
+ create_ntc_from_cli_state ( &usr, con->msrpc.smb->smb );
+ copy_nt_creds(&con->usr_creds.ntc, &usr);
+ }
+
+ if (con->msrpc.cli != NULL)
+ {
+ if (is_new_connection)
+ {
+ con->auth_info = NULL;
+ con->auth_creds = auth_creds;
+
+ if (auth != NULL)
+ {
+ con->auth = auth;
+ }
+ else
+ {
+ con->auth = &cli_noauth_fns;
+ }
+
+ if (!rpc_pipe_bind(con->msrpc.smb->smb, pipe_name, global_myname))
+ {
+ DEBUG(0, ("rpc_pipe_bind failed\n"));
+ cli_connection_free(con);
+ return NULL;
+ }
+ }
+ else
+ {
+ con->auth_info = cli_conn_get_auth_creds(con);
+ con->auth = cli_conn_get_authfns(con);
+ if (con->auth_info != NULL)
+ {
+ DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
+ cli_connection_free(con);
+ return NULL;
+ }
+ else
+ {
+ con->auth = &cli_noauth_fns;
+ }
+ }
+ }
+
+ if (con->msrpc.cli == NULL)
+ {
+ cli_connection_free(con);
+ return NULL;
+ }
+
+ if (con->type == MSRPC_SMB)
+ {
+ con->msrpc.smb->smb->key = key;
+ }
+ add_con_to_array(&num_cons, &con_list, con);
+ return con;
+}
+
+
/****************************************************************************
terminate client connection
****************************************************************************/
@@ -188,3 +331,76 @@ void cli_connection_free(struct cli_connection *con)
free(con);
}
+
+void cli_connection_unlink(struct cli_connection *con)
+{
+ if (con != NULL)
+ {
+ cli_connection_free(con);
+ }
+ return;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con)
+{
+ return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds)
+{
+ BOOL reuse = True;
+
+ /*
+ * allocate
+ */
+
+ DEBUG(10, ("cli_connection_init_auth: %s %s\n",
+ srv_name != NULL ? srv_name : "<null>", pipe_name));
+
+ *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
+
+ return (*con) != NULL;
+}
+
+/****************************************************************************
+ get auth functions associated with an msrpc session.
+****************************************************************************/
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
+{
+ return con != NULL ? con->auth : NULL;
+}
+
+
+/****************************************************************************
+ get auth info associated with an msrpc session.
+****************************************************************************/
+void *cli_conn_get_auth_creds(struct cli_connection *con)
+{
+ return con != NULL ? con->auth_creds : NULL;
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata)
+{
+ BOOL ret;
+ DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
+ op_num, data->data_offset, data->buffer_size));
+ prs_dump("in_rpcclient", (int)op_num, data);
+ prs_realloc_data(data, data->data_offset);
+ ret = rpc_api_pipe_req(con->msrpc.smb->smb, op_num, data, rdata);
+ prs_dump("out_rpcclient", (int)op_num, rdata);
+ return ret;
+}
+
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 8711ab116e..ade31dbb5b 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -1079,7 +1079,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
Do an rpc bind.
****************************************************************************/
-static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
{
RPC_IFACE abstract;
RPC_IFACE transfer;
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
new file mode 100644
index 0000000000..22d0e8c2b5
--- /dev/null
+++ b/source3/rpc_client/cli_spoolss.c
@@ -0,0 +1,95 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-2000,
+ * Copyright (C) Jean Francois Micouleau 1998-2000,
+ *
+ * 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 "rpc_parse.h"
+#include "rpc_client.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a SPOOLSS Enum Printers
+****************************************************************************/
+uint32 spoolss_enum_printers(uint32 flags, fstring srv_name, uint32 level,
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed, uint32 *returned)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPRINTERS q_o;
+ SPOOL_R_ENUMPRINTERS r_o;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ return False;
+
+ prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+ prs_init(&rbuf, 0, 4, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
+
+ DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", srv_name, level));
+
+ make_spoolss_q_enumprinters(&q_o, flags, "", level, buffer, offered);
+
+ /* turn parameters into data stream */
+ if (!spoolss_io_q_enumprinters("", &q_o, &buf, 0) ) {
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+ }
+
+ if(!rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERS, &buf, &rbuf)) {
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+ }
+
+ prs_free_data(&buf );
+ ZERO_STRUCT(r_o);
+
+ buffer->prs.io=UNMARSHALL;
+ buffer->prs.data_offset=0;
+ r_o.buffer=buffer;
+
+ if(!new_spoolss_io_r_enumprinters("", &r_o, &rbuf, 0)) {
+ prs_free_data(&rbuf);
+ cli_connection_unlink(con);
+ }
+
+ *needed=r_o.needed;
+ *returned=r_o.returned;
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return r_o.status;
+}
+
diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c
index 10997f028f..43f8ec8717 100644
--- a/source3/rpc_client/cli_use.c
+++ b/source3/rpc_client/cli_use.c
@@ -48,7 +48,8 @@ static void cli_use_free(struct cli_use *cli)
{
if (cli->cli->initialised)
{
- cli_ulogoff(cli->cli);
+ if (cli->cli->fd != -1)
+ cli_ulogoff(cli->cli);
cli_shutdown(cli->cli);
}
free(cli->cli);
diff --git a/source3/rpc_client/msrpc_spoolss.c b/source3/rpc_client/msrpc_spoolss.c
new file mode 100644
index 0000000000..9ff88ed23c
--- /dev/null
+++ b/source3/rpc_client/msrpc_spoolss.c
@@ -0,0 +1,221 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Jean-Francois Micouleau 1999-2000
+
+ 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 "nterr.h"
+#include "rpc_parse.h"
+#include "rpc_client.h"
+#include "rpcclient.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+extern struct user_creds *usr_creds;
+
+static void init_buffer(NEW_BUFFER *buffer, uint32 size)
+{
+ int new_size = 0;
+
+ buffer->ptr = (size!=0)? 1:0;
+ buffer->size=size;
+ buffer->string_at_end=size;
+ prs_init(&(buffer->prs), MAX_PDU_FRAG_LEN, 4, MARSHALL);
+ new_size = MAX(size,buffer->prs.buffer_size) - MIN(size,buffer->prs.buffer_size);
+ prs_grow(&(buffer->prs), new_size);
+ buffer->prs.io=MARSHALL;
+ buffer->prs.data_offset=0;
+}
+
+static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_0 **info)
+{
+ uint32 i;
+ PRINTER_INFO_0 *inf;
+
+ inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_1 **info)
+{
+ uint32 i;
+ PRINTER_INFO_1 *inf;
+
+ inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_2 **info)
+{
+ uint32 i;
+ PRINTER_INFO_2 *inf;
+
+ inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, PRINTER_INFO_3 **info)
+{
+ uint32 i;
+ PRINTER_INFO_3 *inf;
+
+ inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_1 **info)
+{
+ uint32 i;
+ DRIVER_INFO_1 *inf;
+
+ inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_2 **info)
+{
+ uint32 i;
+ DRIVER_INFO_2 *inf;
+
+ inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_3 **info)
+{
+ uint32 i;
+ DRIVER_INFO_3 *inf;
+
+ inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
+{
+/* DRIVER_DIRECTORY_1 *inf;
+
+ inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
+*/
+ buffer->prs.data_offset=0;
+
+ new_smb_io_driverdir_1("", buffer, info, 0);
+
+/* *info=inf;*/
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags, uint32 level, PRINTER_INFO_CTR ctr)
+{
+ uint32 status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+
+ init_buffer(&buffer, 0);
+
+ /* send a NULL buffer first */
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0, &needed, &returned);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed);
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer, needed, &needed, &returned);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_NO_PROBLEMO)
+ return False;
+
+ switch (level) {
+ case 1:
+ decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
+ break;
+ case 2:
+ decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
+ break;
+ case 3:
+ decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
+ break;
+ }
+
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+ return True;
+}
+
+
diff --git a/source3/rpc_client/ncacn_np_use.c b/source3/rpc_client/ncacn_np_use.c
index e658edbd63..12c2f2381d 100644
--- a/source3/rpc_client/ncacn_np_use.c
+++ b/source3/rpc_client/ncacn_np_use.c
@@ -61,6 +61,30 @@ static void ncacn_np_shutdown(struct ncacn_np *cli)
}
}
+static BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ const char *pipe_name,
+ BOOL reuse)
+{
+ BOOL new_smb_conn;
+ cli->smb = cli_net_use_add(srv_name, ntc,
+ True, &new_smb_conn);
+ if (cli->smb == NULL)
+ {
+ return False;
+ }
+ /* if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum)) by JERRY */
+ if (!cli_nt_session_open(cli->smb, pipe_name))
+ {
+ cli_net_use_del(srv_name, ntc, False, NULL);
+ return False;
+ }
+ fstrcpy(cli->pipe_name, pipe_name);
+ return True;
+}
+
+
/****************************************************************************
terminate client connection
@@ -80,6 +104,31 @@ static void ncacn_np_use_free(struct ncacn_np_use *cli)
free(cli);
}
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncacn_np_use *add_ncacn_np_to_array(uint32 * len,
+ struct ncacn_np_use
+ ***array,
+ struct ncacn_np_use *cli)
+{
+ int i;
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ if (msrpcs[i] == NULL)
+ {
+ msrpcs[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct ncacn_np_use *)add_item_to_array(len,
+ (void ***)array,
+ (void *)cli);
+
+}
+
+
/****************************************************************************
delete a client state
@@ -171,3 +220,233 @@ BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
return False;
}
+/****************************************************************************
+find client state. server name, user name, domain name and password must all
+match.
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_find(const char *srv_name,
+ const char *pipe_name,
+ const vuser_key * key,
+ const struct ntuser_creds
+ *usr_creds, BOOL reuse)
+{
+ int i;
+ const char *sv_name = srv_name;
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ if (strnequal("\\\\", sv_name, 2))
+ {
+ sv_name = &sv_name[2];
+ }
+
+ if (usr_creds != NULL)
+ {
+ DEBUG(10, ("ncacn_np_find: %s %s %s",
+ srv_name, usr_creds->user_name, usr_creds->domain));
+ }
+ else
+ {
+ DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name));
+ }
+
+ if (key != NULL)
+ {
+ DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
+ }
+ DEBUG(10, ("\n"));
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ char *ncacn_np_srv_name = NULL;
+ struct ncacn_np_use *c = msrpcs[i];
+ vuser_key k;
+
+ char *ncacn_np_name = NULL;
+
+ if (c == NULL || c->cli == NULL || c->cli->smb == NULL ||
+ c->cli->smb->fd == -1 ||
+ !c->cli->initialised)
+ {
+ continue;
+ }
+
+ ncacn_np_name = c->cli->pipe_name;
+ ncacn_np_srv_name = c->cli->smb->desthost;
+
+ k = c->cli->smb->key;
+
+ DEBUG(10, ("ncacn_np_find[%d]: %s %s %s %s [%d,%x]\n",
+ i, ncacn_np_name, ncacn_np_srv_name,
+ c->cli->smb->user_name,
+ c->cli->smb->domain, k.pid, k.vuid));
+
+ if (strnequal("\\\\", ncacn_np_srv_name, 2))
+ {
+ ncacn_np_srv_name = &ncacn_np_srv_name[2];
+ }
+
+ if (strnequal("\\PIPE\\", ncacn_np_name, 6))
+ {
+ ncacn_np_name = &ncacn_np_name[6];
+ }
+
+ if (!strequal(ncacn_np_name, pipe_name))
+ {
+ continue;
+ }
+ if (!strequal(ncacn_np_srv_name, sv_name))
+ {
+ continue;
+ }
+ if (key != NULL && (k.pid != key->pid || k.vuid != key->vuid))
+ {
+ continue;
+ }
+ if (usr_creds == NULL)
+ {
+ if (reuse)
+ {
+ return c;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ if (!strequal
+ (usr_creds->user_name, c->cli->smb->user_name))
+ {
+ continue;
+ }
+ if (!reuse
+ && !pwd_compare(&usr_creds->pwd, &c->cli->smb->pwd))
+ {
+ DEBUG(100, ("password doesn't match\n"));
+ continue;
+ }
+ if (usr_creds->domain[0] == 0)
+ {
+ return c;
+ }
+ if (strequal(usr_creds->domain, c->cli->smb->domain))
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key)
+{
+ if (!msrpc)
+ {
+ msrpc = (struct ncacn_np *)malloc(sizeof(*msrpc));
+ if (!msrpc)
+ return NULL;
+ ZERO_STRUCTP(msrpc);
+ }
+
+ if (msrpc->initialised)
+ {
+ ncacn_np_shutdown(msrpc);
+ }
+
+ ZERO_STRUCTP(msrpc);
+
+ msrpc->fnum = -1;
+ msrpc->initialised = 1;
+
+ return msrpc;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_use_get(const char *pipe_name,
+ const vuser_key * key)
+{
+ struct ncacn_np_use *cli =
+ (struct ncacn_np_use *)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = ncacn_np_initialise(NULL, key);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL reuse, BOOL *is_new_connection)
+{
+ struct ncacn_np_use *cli;
+ DEBUG(10, ("ncacn_np_use_add: %s\n", pipe_name));
+
+ (*is_new_connection) = False;
+ cli = ncacn_np_find(srv_name, pipe_name, key, ntc, reuse);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ return cli->cli;
+ }
+
+ /*
+ * allocate
+ */
+
+ (*is_new_connection) = True;
+
+ cli = ncacn_np_use_get(pipe_name, key);
+
+ if (!ncacn_np_establish_connection
+ (cli->cli, srv_name, ntc, pipe_name, True))
+ {
+ DEBUG(0, ("ncacn_np_use_add: connection failed\n"));
+ cli->cli = NULL;
+ ncacn_np_use_free(cli);
+ return NULL;
+ }
+
+ if (key != NULL)
+ {
+ cli->cli->smb->key = *key;
+ }
+ else
+ {
+ cli->cli->smb->key.pid = sys_getpid();
+ cli->cli->smb->key.vuid = UID_FIELD_INVALID;
+ }
+
+ add_ncacn_np_to_array(&num_msrpcs, &msrpcs, cli);
+ cli->num_users++;
+ return cli->cli;
+}
+
+
+
diff --git a/source3/rpc_client/ncalrpc_l_use.c b/source3/rpc_client/ncalrpc_l_use.c
index 81ade8e1a6..c876fe4b5a 100644
--- a/source3/rpc_client/ncalrpc_l_use.c
+++ b/source3/rpc_client/ncalrpc_l_use.c
@@ -37,6 +37,29 @@ static struct ncalrpc_use **clis = NULL;
static uint32 num_clis = 0;
/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncalrpc_use *add_cli_to_array(uint32 * len,
+ struct ncalrpc_use ***array,
+ struct ncalrpc_use *cli)
+{
+ int i;
+ for (i = 0; i < num_clis; i++)
+ {
+ if (clis[i] == NULL)
+ {
+ clis[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct ncalrpc_use *)add_item_to_array(len,
+ (void ***)array,
+ (void *)cli);
+
+}
+
+/****************************************************************************
terminate client connection
****************************************************************************/
static void ncalrpc_use_free(struct ncalrpc_use *cli)
@@ -54,6 +77,141 @@ static void ncalrpc_use_free(struct ncalrpc_use *cli)
}
/****************************************************************************
+find client state. server name, user name, vuid name and password must all
+match.
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_l_find(const char *pipe_name,
+ const vuser_key * key, BOOL reuse)
+{
+ int i;
+ vuser_key null_usr;
+
+ if (key == NULL)
+ {
+ key = &null_usr;
+ null_usr.pid = sys_getpid();
+ null_usr.vuid = UID_FIELD_INVALID;
+ }
+
+ DEBUG(10, ("ncalrpc_l_find: %s [%d,%x]\n",
+ pipe_name, key->pid, key->vuid));
+
+ for (i = 0; i < num_clis; i++)
+ {
+ char *cli_name = NULL;
+ struct ncalrpc_use *c = clis[i];
+
+ if (c == NULL || !c->cli->initialised)
+ {
+ continue;
+ }
+
+ cli_name = c->cli->pipe_name;
+
+ DEBUG(10, ("ncalrpc_l_find[%d]: %s [%d,%x]\n",
+ i, cli_name,
+ c->cli->nt.key.pid, c->cli->nt.key.vuid));
+
+ if (!strequal(cli_name, pipe_name))
+ {
+ continue;
+ }
+ if (reuse)
+ {
+ return c;
+ }
+ if (key->vuid == c->cli->nt.key.vuid &&
+ key->pid == c->cli->nt.key.pid)
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_use_get(const char *pipe_name,
+ const vuser_key * key)
+{
+ struct ncalrpc_use *cli = (struct ncalrpc_use *)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = ncalrpc_l_initialise(NULL, key);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ return cli;
+}
+
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+ const vuser_key * key,
+ BOOL reuse, BOOL *is_new)
+{
+ struct ncalrpc_use *cli;
+
+ DEBUG(10, ("ncalrpc_l_use_add\n"));
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ cli = ncalrpc_l_find(pipe_name, key, reuse);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ DEBUG(10,
+ ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+ (*is_new) = False;
+ return cli->cli;
+ }
+
+ /*
+ * allocate
+ */
+
+ cli = ncalrpc_use_get(pipe_name, key);
+
+ /*
+ * connect
+ */
+
+ if (!ncalrpc_l_establish_connection(cli->cli, pipe_name))
+ {
+ DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
+ cli->cli = NULL;
+ ncalrpc_use_free(cli);
+ return NULL;
+ }
+
+ add_cli_to_array(&num_clis, &clis, cli);
+ cli->num_users++;
+
+ DEBUG(10, ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+
+ (*is_new) = True;
+
+ return cli->cli;
+}
+
+/****************************************************************************
delete a client state
****************************************************************************/
BOOL ncalrpc_l_use_del(const char *pipe_name,