mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +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/parse_brs.o
|
||||||
|
|
||||||
RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o rpc_parse/parse_prs.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)
|
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);
|
uint32 mem_buf_len(struct mem_buf *buf);
|
||||||
char *mem_data(struct mem_buf **buf, uint32 offset);
|
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 */
|
/*The following definitions come from lib/netmask.c */
|
||||||
|
|
||||||
int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
|
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* add_copy_to_array(uint32 *len, void ***array, const void *item,
|
||||||
void*(item_dup)(const void*), BOOL alloc_anyway);
|
void*(item_dup)(const void*), BOOL alloc_anyway);
|
||||||
void* add_item_to_array(uint32 *len, void ***array, void *item);
|
void* add_item_to_array(uint32 *len, void ***array, void *item);
|
||||||
void free_use_array(uint32 num_entries, struct use_info **entries);
|
void free_use_info_array(uint32 num_entries, struct use_info **entries);
|
||||||
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);
|
const struct use_info *name);
|
||||||
void free_char_array(uint32 num_entries, char **entries);
|
void free_char_array(uint32 num_entries, char **entries);
|
||||||
char* add_chars_to_array(uint32 *len, char ***array, const char *name);
|
char* add_chars_to_array(uint32 *len, char ***array, const char *name);
|
||||||
|
@ -1754,6 +1754,17 @@ struct nmb_state
|
|||||||
int port;
|
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 */
|
#endif /* _SMB_H */
|
||||||
|
|
||||||
/* _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;
|
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;
|
void(*fn)(void*) = (void(*)(void*))&use_info_free;
|
||||||
free_void_array(num_entries, (void**)entries, *fn);
|
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)
|
const struct use_info *name)
|
||||||
{
|
{
|
||||||
void*(*fn)(const void*) = (void*(*)(const void*))&use_info_dup;
|
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;
|
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