1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00
samba-mirror/source3/lib/msrpc-client.c
Gerald Carter f296a8d087 All changes related to rpcclient...
- cleaned up some code
- Fixed a few memory leaks of my own making
- Add AddPrinterDriver(); I'm missing some of the semantics
  here as the call is done correctly, but I'm not getting all
  the information right in the DRIVER_INFO_3 struct I think.
  Will work on it tomorrow some more...



--jerry
(This used to be commit 3bf9a29f34)
2000-08-08 06:57:48 +00:00

404 lines
8.6 KiB
C

/*
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;
/****************************************************************************
read an msrpc pdu from a fd.
The timeout is in milliseconds.
****************************************************************************/
BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout)
{
BOOL ok;
size_t len;
RPC_HDR hdr;
prs_init(data, 0, 4, NULL, True);
ok = prs_read(data, fd, 16, timeout);
if (!ok)
{
prs_mem_free(data);
return False;
}
if (!smb_io_rpc_hdr("hdr", &hdr, data, 0))
{
prs_mem_free(data);
return False;
}
len = hdr.frag_len - 16;
if (len > 0)
{
ok = prs_read(data, fd, hdr.frag_len, 0);
if (!ok)
{
prs_mem_free(data);
return False;
}
data->data_offset = hdr.frag_len;
return True;
}
prs_mem_free(data);
return False;
}
/****************************************************************************
send an smb to a fd and re-establish if necessary
****************************************************************************/
BOOL msrpc_send(int fd, prs_struct *ps)
{
size_t len = ps != NULL ? ps->buffer_size : 0;
size_t nwritten=0;
ssize_t ret;
char *outbuf = ps->data_p;
DEBUG(10,("msrpc_send_prs: data: %p len %d\n", outbuf, len));
dbgflush();
dump_data(10, outbuf, len);
while (nwritten < len)
{
ret = write_socket(fd,outbuf+nwritten,len - nwritten);
if (ret <= 0)
{
DEBUG(0,("Error writing %d msrpc bytes. %d.\n",
len,ret));
prs_mem_free(ps);
return False;
}
nwritten += ret;
}
prs_mem_free(ps);
return True;
}
/****************************************************************************
receive msrpc packet
****************************************************************************/
BOOL msrpc_receive(int fd, prs_struct *ps)
{
int len;
DEBUG(10,("msrpc_receive: %d\n", __LINE__));
if (!receive_msrpc(fd, ps, 0))
{
return False;
}
len = ps->buffer_size;
if (ps->data_p == NULL || len <= 0)
{
return False;
}
dump_data(10, ps->data_p, len);
DEBUG(10,("msrpc_receive: len %d\n", len));
return True;
}
/****************************************************************************
open the msrpcent sockets
****************************************************************************/
BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name)
{
fstring path;
slprintf(path, sizeof(path)-1, "%s/.msrpc/%s", LOCKDIR, 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_creds *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 BOOL msrpc_authenticate(struct msrpc_state *msrpc,
struct user_creds *usr)
{
struct msrpc_state msrpc_redir;
int sock = msrpc->fd;
char *data;
prs_struct ps;
uint32 len;
char *in = msrpc->inbuf;
char *out = msrpc->outbuf;
uint16 command;
command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command,
msrpc->pid, usr))
{
DEBUG(0,("could not parse credentials\n"));
close(sock);
return False;
}
len = ps.data_offset;
data = ps.data_p;
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"));
return False;
}
if (msrpc->redirect)
{
len = read(sock, &msrpc_redir, sizeof(msrpc_redir));
if (len != sizeof(msrpc_redir))
{
DEBUG(0,("read failed\n"));
return False;
}
memcpy(msrpc, &msrpc_redir, sizeof(msrpc_redir));
msrpc->inbuf = in;
msrpc->outbuf = out;
msrpc->fd = sock;
msrpc->usr.reuse = False;
}
else
{
uint32 status;
len = read(sock, &status, sizeof(status));
return len == sizeof(status) && status == 0x0;
}
return True;
}
static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
const char* pipe_name,
struct user_creds *usr)
{
int sock;
fstring path;
slprintf(path, sizeof(path)-1, "/tmp/.msrpc/.%s/agent", pipe_name);
sock = open_pipe_sock(path);
if (sock < 0)
{
return False;
}
msrpc->fd = sock;
if (!msrpc_authenticate(msrpc, usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
}
return True;
}
BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
uint32 pid,
const char* pipename,
const struct user_creds *usr)
{
ZERO_STRUCTP(msrpc);
if (!msrpc_initialise(msrpc, pid))
{
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, uint32 pid)
{
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);
msrpc->pid = pid;
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.ntc.user_name, msrpc->usr.ntc.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;
}
}
if (!msrpc_authenticate(msrpc, &msrpc->usr))
{
DEBUG(0,("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
}
return True;
}