mirror of
https://github.com/samba-team/samba.git
synced 2025-03-08 04:58:40 +03:00
first version of msrpc agent redirector code. client-side only.
This commit is contained in:
parent
a3af3b4312
commit
5e5a1dceee
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
261
source/lib/msrpc-agent.c
Normal file
261
source/lib/msrpc-agent.c
Normal file
@ -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);
|
||||
}
|
||||
|
318
source/lib/msrpc-client.c
Normal file
318
source/lib/msrpc-client.c
Normal file
@ -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;
|
||||
}
|
||||
|
321
source/lib/msrpc_use.c
Normal file
321
source/lib/msrpc_use.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user