From 92bc7a4263ba27f113306b31721dc3bbaa94baf3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 5 Dec 1999 01:34:34 +0000 Subject: first version of msrpc agent redirector code. client-side only. (This used to be commit 5e5a1dceee0b6088822697284d3e0af04d197477) --- source3/Makefile.in | 5 +- source3/include/proto.h | 37 ++++- source3/include/smb.h | 11 ++ source3/lib/msrpc-agent.c | 261 +++++++++++++++++++++++++++++++++++ source3/lib/msrpc-client.c | 318 ++++++++++++++++++++++++++++++++++++++++++ source3/lib/msrpc_use.c | 321 +++++++++++++++++++++++++++++++++++++++++++ source3/lib/util_array.c | 4 +- source3/rpc_client/cli_use.c | 2 +- 8 files changed, 953 insertions(+), 6 deletions(-) create mode 100644 source3/lib/msrpc-agent.c create mode 100644 source3/lib/msrpc-client.c create mode 100644 source3/lib/msrpc_use.c 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); } } -- cgit