diff options
author | Gerald Carter <jerry@samba.org> | 2000-07-07 06:20:46 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2000-07-07 06:20:46 +0000 |
commit | d2b40a7de259377d937492acedd39988ddd108a4 (patch) | |
tree | f0849ba6679575e80500b43b8989b3dddf16e2a4 /source3/rpc_client | |
parent | 9de93aa8188293671a92e84b2b9dc104cc7eb64c (diff) | |
download | samba-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.c | 216 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 2 | ||||
-rw-r--r-- | source3/rpc_client/cli_spoolss.c | 95 | ||||
-rw-r--r-- | source3/rpc_client/cli_use.c | 3 | ||||
-rw-r--r-- | source3/rpc_client/msrpc_spoolss.c | 221 | ||||
-rw-r--r-- | source3/rpc_client/ncacn_np_use.c | 279 | ||||
-rw-r--r-- | source3/rpc_client/ncalrpc_l_use.c | 158 |
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, |