mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
r3162: Add client-side support for the ncalrpc: and ncacn_unix_stream: transports.
ncalrpc uses the new config option "ncalrpc dir" for creating unix sockets.
This commit is contained in:
parent
a953d4a42c
commit
b15cfbe251
@ -46,6 +46,7 @@ INSTALLPERMS = 0755
|
||||
LOGFILEBASE = \@logfilebase\@
|
||||
CONFIGFILE = \$(CONFIGDIR)/smb.conf
|
||||
LMHOSTSFILE = \$(CONFIGDIR)/lmhosts
|
||||
NCALRPCDIR = \@localstatedir\@/ncalrpc
|
||||
|
||||
# This is where smbpasswd et al go
|
||||
PRIVATEDIR = \@privatedir\@
|
||||
@ -64,7 +65,7 @@ PATH_FLAGS3 = \$(PATH_FLAGS2) -DLMHOSTSFILE=\\\"\$(LMHOSTSFILE)\\\"
|
||||
PATH_FLAGS4 = \$(PATH_FLAGS3) -DLOCKDIR=\\\"\$(LOCKDIR)\\\" -DPIDDIR=\\\"\$(PIDDIR)\\\"
|
||||
PATH_FLAGS5 = \$(PATH_FLAGS4) -DLIBDIR=\\\"\$(LIBDIR)\\\" \\
|
||||
-DLOGFILEBASE=\\\"\$(LOGFILEBASE)\\\" -DSHLIBEXT=\\\"\@SHLIBEXT\@\\\"
|
||||
PATH_FLAGS6 = \$(PATH_FLAGS5) -DCONFIGDIR=\\\"\$(CONFIGDIR)\\\"
|
||||
PATH_FLAGS6 = \$(PATH_FLAGS5) -DCONFIGDIR=\\\"\$(CONFIGDIR)\\\" -DNCALRPCDIR=\\\"\@NCALRPCDIR\@\\\"
|
||||
PATH_FLAGS = \$(PATH_FLAGS6) \$(PASSWD_FLAGS)
|
||||
";
|
||||
return $output;
|
||||
|
@ -48,6 +48,8 @@ pstring dyn_CONFIGFILE = CONFIGFILE; /**< Location of smb.conf file. **/
|
||||
/** Log file directory. **/
|
||||
const char *dyn_LOGFILEBASE = LOGFILEBASE;
|
||||
|
||||
const char *dyn_NCALRPCDIR = NCALRPCDIR;
|
||||
|
||||
/** Statically configured LanMan hosts. **/
|
||||
pstring dyn_LMHOSTSFILE = LMHOSTSFILE;
|
||||
|
||||
|
@ -29,6 +29,7 @@ extern char const *dyn_SBINDIR,
|
||||
*dyn_BINDIR;
|
||||
|
||||
extern pstring dyn_CONFIGFILE;
|
||||
extern const char *dyn_NCALRPCDIR;
|
||||
extern const char *dyn_LOGFILEBASE;
|
||||
extern pstring dyn_LMHOSTSFILE;
|
||||
extern pstring dyn_LIBDIR;
|
||||
|
@ -56,7 +56,7 @@ SMB_SUBSYSTEM(LIBRPC_RAW,[],
|
||||
librpc/rpc/dcerpc_ntlm.o
|
||||
librpc/rpc/dcerpc_spnego.o
|
||||
librpc/rpc/dcerpc_smb.o
|
||||
librpc/rpc/dcerpc_tcp.o])
|
||||
librpc/rpc/dcerpc_sock.o])
|
||||
|
||||
SMB_SUBSYSTEM(LIBRPC,[],[],[],
|
||||
[LIBNDR_RAW LIBRPC_RAW])
|
||||
|
@ -7,7 +7,8 @@
|
||||
[ uuid(1ff70682-0a51-30e8-076d-740be8cee98b),
|
||||
version(1.0),
|
||||
pointer_default(unique),
|
||||
helpstring("Queue/List/Remove jobs for later execution")
|
||||
helpstring("Queue/List/Remove jobs for later execution"),
|
||||
endpoint("ncacn_np:[\\pipe\\atsvc]", "ncalrpc:")
|
||||
] interface atsvc
|
||||
{
|
||||
typedef struct {
|
||||
|
@ -1,7 +1,8 @@
|
||||
[
|
||||
uuid(6bffd098-a112-3610-9833-012892020162),
|
||||
version(0.0),
|
||||
helpstring("Browsing")
|
||||
helpstring("Browsing"),
|
||||
endpoint("lcalrpc:")
|
||||
]
|
||||
interface browser
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
[
|
||||
uuid(60a15ec5-4de8-11d7-a637-005056a20182),
|
||||
endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:"),
|
||||
endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:", "ncalrpc:"),
|
||||
version(1.0),
|
||||
helpstring("Simple echo pipe")
|
||||
]
|
||||
|
@ -11,7 +11,8 @@ http://www.opengroup.org/onlinepubs/9629399/chap6.htm#tagcjh_11_02_03_01: bindin
|
||||
[
|
||||
uuid(e1af8308-5d1f-11c9-91a4-08002b14a0fa),
|
||||
version(3.0),
|
||||
endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]"),
|
||||
endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]",
|
||||
"ncalrpc:[EPMAPPER]", "ncacn_unix_stream:[/tmp/epmapper]"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface epmapper
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
[ uuid(12345778-1234-abcd-ef00-0123456789ab),
|
||||
version(0.0),
|
||||
endpoint("ncacn_np:[\\pipe\\lsarpc]","ncacn_np:[\\pipe\\lsass]","ncacn_ip_tcp:"),
|
||||
endpoint("ncacn_np:[\\pipe\\lsarpc]","ncacn_np:[\\pipe\\lsass]", "ncacn_ip_tcp:"),
|
||||
pointer_default(unique),
|
||||
helpstring("Local Server Authentication(?)")
|
||||
] interface lsarpc
|
||||
|
@ -15,7 +15,7 @@
|
||||
[
|
||||
uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
|
||||
helpstring("Object Exporter ID Resolver"),
|
||||
endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]"),
|
||||
endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]", "ncalrpc:"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IOXIDResolver
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
[ uuid(12345778-1234-abcd-ef00-0123456789ac),
|
||||
version(1.0),
|
||||
endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:"),
|
||||
endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"),
|
||||
pointer_default(unique)
|
||||
] interface samr
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
[ uuid(367abb81-9844-35f1-ad32-98f038001003),
|
||||
version(2.0),
|
||||
pointer_default(unique),
|
||||
endpoint("ncacn_np:[\\pipe\\svcctl]", "ncalrpc:"),
|
||||
helpstring("Service Control")
|
||||
] interface svcctl
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
[ uuid(338cd001-2244-31f1-aaaa-900038001003),
|
||||
version(1.0),
|
||||
endpoint("ncacn_np:[\\pipe\\winreg]","ncacn_ip_tcp:"),
|
||||
endpoint("ncacn_np:[\\pipe\\winreg]","ncacn_ip_tcp:","ncalrpc:"),
|
||||
pointer_default(unique),
|
||||
helpstring("Remote Registry Service")
|
||||
] interface winreg
|
||||
|
536
source/librpc/rpc/dcerpc_sock.c
Normal file
536
source/librpc/rpc/dcerpc_sock.c
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
dcerpc over standard sockets transport
|
||||
|
||||
Copyright (C) Andrew Tridgell 2003
|
||||
Copyright (C) Jelmer Vernooij 2004
|
||||
|
||||
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"
|
||||
|
||||
#define MIN_HDR_SIZE 16
|
||||
|
||||
struct sock_blob {
|
||||
struct sock_blob *next, *prev;
|
||||
DATA_BLOB data;
|
||||
};
|
||||
|
||||
/* transport private information used by general socket pipe transports */
|
||||
struct sock_private {
|
||||
struct event_context *event_ctx;
|
||||
struct fd_event *fde;
|
||||
int fd;
|
||||
char *server_name;
|
||||
uint32_t port;
|
||||
|
||||
struct sock_blob *pending_send;
|
||||
|
||||
struct {
|
||||
size_t received;
|
||||
DATA_BLOB data;
|
||||
uint_t pending_count;
|
||||
} recv;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
mark the socket dead
|
||||
*/
|
||||
static void sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
|
||||
if (sock && sock->fd != -1) {
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
}
|
||||
|
||||
/* wipe any pending sends */
|
||||
while (sock->pending_send) {
|
||||
struct sock_blob *blob = sock->pending_send;
|
||||
DLIST_REMOVE(sock->pending_send, blob);
|
||||
talloc_free(blob);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
p->transport.recv_data(p, NULL, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
process send requests
|
||||
*/
|
||||
static void sock_process_send(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
|
||||
while (sock->pending_send) {
|
||||
struct sock_blob *blob = sock->pending_send;
|
||||
ssize_t ret = write(sock->fd, blob->data.data, blob->data.length);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret == 0) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
break;
|
||||
}
|
||||
|
||||
blob->data.data += ret;
|
||||
blob->data.length -= ret;
|
||||
|
||||
if (blob->data.length != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
DLIST_REMOVE(sock->pending_send, blob);
|
||||
talloc_free(blob);
|
||||
}
|
||||
|
||||
if (sock->pending_send == NULL) {
|
||||
sock->fde->flags &= ~EVENT_FD_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
process recv requests
|
||||
*/
|
||||
static void sock_process_recv(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
ssize_t ret;
|
||||
|
||||
if (sock->recv.data.data == NULL) {
|
||||
sock->recv.data = data_blob_talloc(sock, NULL, MIN_HDR_SIZE);
|
||||
}
|
||||
|
||||
/* read in the base header to get the fragment length */
|
||||
if (sock->recv.received < MIN_HDR_SIZE) {
|
||||
uint32_t frag_length;
|
||||
|
||||
ret = read(sock->fd, sock->recv.data.data,
|
||||
MIN_HDR_SIZE - sock->recv.received);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ret == 0) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
sock->recv.received += ret;
|
||||
|
||||
if (sock->recv.received != MIN_HDR_SIZE) {
|
||||
return;
|
||||
}
|
||||
frag_length = dcerpc_get_frag_length(&sock->recv.data);
|
||||
|
||||
sock->recv.data.data = talloc_realloc(sock, sock->recv.data.data,
|
||||
frag_length);
|
||||
if (sock->recv.data.data == NULL) {
|
||||
sock_dead(p, NT_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
sock->recv.data.length = frag_length;
|
||||
}
|
||||
|
||||
/* read in the rest of the packet */
|
||||
ret = read(sock->fd, sock->recv.data.data + sock->recv.received,
|
||||
sock->recv.data.length - sock->recv.received);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ret == 0) {
|
||||
sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
sock->recv.received += ret;
|
||||
|
||||
if (sock->recv.received != sock->recv.data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* we have a full packet */
|
||||
p->transport.recv_data(p, &sock->recv.data, NT_STATUS_OK);
|
||||
talloc_free(sock->recv.data.data);
|
||||
sock->recv.data = data_blob(NULL, 0);
|
||||
sock->recv.received = 0;
|
||||
sock->recv.pending_count--;
|
||||
if (sock->recv.pending_count == 0) {
|
||||
sock->fde->flags &= ~EVENT_FD_READ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
called when a IO is triggered by the events system
|
||||
*/
|
||||
static void sock_io_handler(struct event_context *ev, struct fd_event *fde,
|
||||
time_t t, uint16_t flags)
|
||||
{
|
||||
struct dcerpc_pipe *p = fde->private;
|
||||
struct sock_private *sock = p->transport.private;
|
||||
|
||||
if (flags & EVENT_FD_WRITE) {
|
||||
sock_process_send(p);
|
||||
}
|
||||
|
||||
if (sock->fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & EVENT_FD_READ) {
|
||||
sock_process_recv(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
initiate a read request
|
||||
*/
|
||||
static NTSTATUS sock_send_read(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
|
||||
sock->recv.pending_count++;
|
||||
if (sock->recv.pending_count == 1) {
|
||||
sock->fde->flags |= EVENT_FD_READ;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
send an initial pdu in a multi-pdu sequence
|
||||
*/
|
||||
static NTSTATUS sock_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL trigger_read)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
struct sock_blob *blob;
|
||||
|
||||
blob = talloc_p(sock, struct sock_blob);
|
||||
if (blob == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
blob->data = data_blob_talloc(blob, data->data, data->length);
|
||||
if (blob->data.data == NULL) {
|
||||
talloc_free(blob);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
DLIST_ADD_END(sock->pending_send, blob, struct sock_blob *);
|
||||
|
||||
sock->fde->flags |= EVENT_FD_WRITE;
|
||||
|
||||
if (trigger_read) {
|
||||
sock_send_read(p);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
return the event context so the caller can process asynchronously
|
||||
*/
|
||||
static struct event_context *sock_event_context(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
|
||||
return sock->event_ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
shutdown sock pipe connection
|
||||
*/
|
||||
static NTSTATUS sock_shutdown_pipe(struct dcerpc_pipe *p)
|
||||
{
|
||||
sock_dead(p, NT_STATUS_OK);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
return sock server name
|
||||
*/
|
||||
static const char *sock_peer_name(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct sock_private *sock = p->transport.private;
|
||||
return sock->server_name;
|
||||
}
|
||||
|
||||
/*
|
||||
open a rpc connection to a named pipe
|
||||
*/
|
||||
NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p,
|
||||
const char *server,
|
||||
uint32_t port,
|
||||
int family)
|
||||
{
|
||||
struct sock_private *sock;
|
||||
int fd, gai_err;
|
||||
struct fd_event fde;
|
||||
struct addrinfo hints, *res, *tmpres;
|
||||
char portname[16];
|
||||
|
||||
if (port == 0) {
|
||||
port = EPMAPPER_PORT;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(portname, sizeof(portname)-1, "%d", port);
|
||||
|
||||
gai_err = getaddrinfo(server, portname, &hints, &res);
|
||||
if (gai_err < 0)
|
||||
{
|
||||
DEBUG(0, ("Unable to connect to %s:%d : %s\n", server, port, gai_strerror(gai_err)));
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
tmpres = res;
|
||||
|
||||
while (tmpres) {
|
||||
fd = socket(tmpres->ai_family, tmpres->ai_socktype, tmpres->ai_protocol);
|
||||
|
||||
if(fd >= 0) {
|
||||
if (connect(fd, tmpres->ai_addr, tmpres->ai_addrlen) == 0)
|
||||
break;
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
tmpres = tmpres->ai_next;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (fd == -1) {
|
||||
return NT_STATUS_PORT_CONNECTION_REFUSED;
|
||||
}
|
||||
|
||||
set_socket_options(fd, lp_socket_options());
|
||||
|
||||
if (!(*p = dcerpc_pipe_init())) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
fill in the transport methods
|
||||
*/
|
||||
(*p)->transport.transport = NCACN_IP_TCP;
|
||||
(*p)->transport.private = NULL;
|
||||
|
||||
(*p)->transport.send_request = sock_send_request;
|
||||
(*p)->transport.send_read = sock_send_read;
|
||||
(*p)->transport.event_context = sock_event_context;
|
||||
(*p)->transport.recv_data = NULL;
|
||||
|
||||
(*p)->transport.shutdown_pipe = sock_shutdown_pipe;
|
||||
(*p)->transport.peer_name = sock_peer_name;
|
||||
|
||||
sock = talloc((*p), sizeof(*sock));
|
||||
if (!sock) {
|
||||
dcerpc_pipe_close(*p);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
sock->fd = fd;
|
||||
sock->server_name = talloc_strdup((*p), server);
|
||||
sock->event_ctx = event_context_init(sock);
|
||||
sock->pending_send = NULL;
|
||||
sock->recv.received = 0;
|
||||
sock->recv.data = data_blob(NULL, 0);
|
||||
sock->recv.pending_count = 0;
|
||||
|
||||
fde.fd = fd;
|
||||
fde.flags = 0;
|
||||
fde.handler = sock_io_handler;
|
||||
fde.private = *p;
|
||||
|
||||
sock->fde = event_add_fd(sock->event_ctx, &fde);
|
||||
|
||||
(*p)->transport.private = sock;
|
||||
|
||||
/* ensure we don't get SIGPIPE */
|
||||
BlockSignals(True,SIGPIPE);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
open a rpc connection to a unix socket
|
||||
*/
|
||||
NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_pipe **p,
|
||||
const char *path)
|
||||
{
|
||||
struct sock_private *sock;
|
||||
int fd;
|
||||
struct fd_event fde;
|
||||
struct sockaddr_un sa;
|
||||
|
||||
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
sa.sun_family = AF_UNIX;
|
||||
strncpy(sa.sun_path, path, sizeof(sa.sun_path));
|
||||
|
||||
if (connect(fd, &sa, sizeof(sa)) < 0) {
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
set_socket_options(fd, lp_socket_options());
|
||||
|
||||
if (!(*p = dcerpc_pipe_init())) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
fill in the transport methods
|
||||
*/
|
||||
(*p)->transport.transport = NCACN_UNIX_STREAM;
|
||||
(*p)->transport.private = NULL;
|
||||
|
||||
(*p)->transport.send_request = sock_send_request;
|
||||
(*p)->transport.send_read = sock_send_read;
|
||||
(*p)->transport.event_context = sock_event_context;
|
||||
(*p)->transport.recv_data = NULL;
|
||||
|
||||
(*p)->transport.shutdown_pipe = sock_shutdown_pipe;
|
||||
(*p)->transport.peer_name = sock_peer_name;
|
||||
|
||||
sock = talloc((*p), sizeof(*sock));
|
||||
if (!sock) {
|
||||
dcerpc_pipe_close(*p);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
sock->fd = fd;
|
||||
sock->server_name = talloc_strdup((*p), path);
|
||||
sock->event_ctx = event_context_init(sock);
|
||||
sock->pending_send = NULL;
|
||||
sock->recv.received = 0;
|
||||
sock->recv.data = data_blob(NULL, 0);
|
||||
sock->recv.pending_count = 0;
|
||||
|
||||
fde.fd = fd;
|
||||
fde.flags = 0;
|
||||
fde.handler = sock_io_handler;
|
||||
fde.private = *p;
|
||||
|
||||
sock->fde = event_add_fd(sock->event_ctx, &fde);
|
||||
|
||||
(*p)->transport.private = sock;
|
||||
|
||||
/* ensure we don't get SIGPIPE */
|
||||
BlockSignals(True,SIGPIPE);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
open a rpc connection to a named pipe
|
||||
*/
|
||||
NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p,
|
||||
const char *identifier)
|
||||
{
|
||||
struct sock_private *sock;
|
||||
int fd;
|
||||
struct fd_event fde;
|
||||
struct sockaddr_un sa;
|
||||
char *canon, *full_path;
|
||||
|
||||
if (!(*p = dcerpc_pipe_init())) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
canon = talloc_strdup(*p, identifier);
|
||||
|
||||
string_replace(canon, '/', '\\');
|
||||
|
||||
full_path = talloc_asprintf(*p, "%s/%s", lp_ncalrpc_dir(), canon);
|
||||
|
||||
fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
sa.sun_family = AF_UNIX;
|
||||
strncpy(sa.sun_path, full_path, sizeof(sa.sun_path));
|
||||
|
||||
if (connect(fd, &sa, sizeof(sa)) < 0) {
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
set_socket_options(fd, lp_socket_options());
|
||||
|
||||
/*
|
||||
fill in the transport methods
|
||||
*/
|
||||
(*p)->transport.transport = NCALRPC;
|
||||
(*p)->transport.private = NULL;
|
||||
|
||||
(*p)->transport.send_request = sock_send_request;
|
||||
(*p)->transport.send_read = sock_send_read;
|
||||
(*p)->transport.event_context = sock_event_context;
|
||||
(*p)->transport.recv_data = NULL;
|
||||
|
||||
(*p)->transport.shutdown_pipe = sock_shutdown_pipe;
|
||||
(*p)->transport.peer_name = sock_peer_name;
|
||||
|
||||
sock = talloc((*p), sizeof(*sock));
|
||||
if (!sock) {
|
||||
dcerpc_pipe_close(*p);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
sock->fd = fd;
|
||||
sock->server_name = full_path;
|
||||
sock->event_ctx = event_context_init(sock);
|
||||
sock->pending_send = NULL;
|
||||
sock->recv.received = 0;
|
||||
sock->recv.data = data_blob(NULL, 0);
|
||||
sock->recv.pending_count = 0;
|
||||
|
||||
fde.fd = fd;
|
||||
fde.flags = 0;
|
||||
fde.handler = sock_io_handler;
|
||||
fde.private = *p;
|
||||
|
||||
sock->fde = event_add_fd(sock->event_ctx, &fde);
|
||||
|
||||
(*p)->transport.private = sock;
|
||||
|
||||
/* ensure we don't get SIGPIPE */
|
||||
BlockSignals(True,SIGPIPE);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
@ -1,382 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
dcerpc over TCP transport
|
||||
|
||||
Copyright (C) Andrew Tridgell 2003
|
||||
|
||||
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"
|
||||
|
||||
#define MIN_HDR_SIZE 16
|
||||
|
||||
struct tcp_blob {
|
||||
struct tcp_blob *next, *prev;
|
||||
DATA_BLOB data;
|
||||
};
|
||||
|
||||
/* transport private information used by TCP pipe transport */
|
||||
struct tcp_private {
|
||||
struct event_context *event_ctx;
|
||||
struct fd_event *fde;
|
||||
int fd;
|
||||
char *server_name;
|
||||
uint32_t port;
|
||||
|
||||
struct tcp_blob *pending_send;
|
||||
|
||||
struct {
|
||||
size_t received;
|
||||
DATA_BLOB data;
|
||||
uint_t pending_count;
|
||||
} recv;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
mark the socket dead
|
||||
*/
|
||||
static void tcp_sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
|
||||
if (tcp && tcp->fd != -1) {
|
||||
close(tcp->fd);
|
||||
tcp->fd = -1;
|
||||
}
|
||||
|
||||
/* wipe any pending sends */
|
||||
while (tcp->pending_send) {
|
||||
struct tcp_blob *blob = tcp->pending_send;
|
||||
DLIST_REMOVE(tcp->pending_send, blob);
|
||||
talloc_free(blob);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
p->transport.recv_data(p, NULL, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
process send requests
|
||||
*/
|
||||
static void tcp_process_send(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
|
||||
while (tcp->pending_send) {
|
||||
struct tcp_blob *blob = tcp->pending_send;
|
||||
ssize_t ret = write(tcp->fd, blob->data.data, blob->data.length);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret == 0) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
break;
|
||||
}
|
||||
|
||||
blob->data.data += ret;
|
||||
blob->data.length -= ret;
|
||||
|
||||
if (blob->data.length != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
DLIST_REMOVE(tcp->pending_send, blob);
|
||||
talloc_free(blob);
|
||||
}
|
||||
|
||||
if (tcp->pending_send == NULL) {
|
||||
tcp->fde->flags &= ~EVENT_FD_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
process recv requests
|
||||
*/
|
||||
static void tcp_process_recv(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
ssize_t ret;
|
||||
|
||||
if (tcp->recv.data.data == NULL) {
|
||||
tcp->recv.data = data_blob_talloc(tcp, NULL, MIN_HDR_SIZE);
|
||||
}
|
||||
|
||||
/* read in the base header to get the fragment length */
|
||||
if (tcp->recv.received < MIN_HDR_SIZE) {
|
||||
uint32_t frag_length;
|
||||
|
||||
ret = read(tcp->fd, tcp->recv.data.data,
|
||||
MIN_HDR_SIZE - tcp->recv.received);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ret == 0) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
tcp->recv.received += ret;
|
||||
|
||||
if (tcp->recv.received != MIN_HDR_SIZE) {
|
||||
return;
|
||||
}
|
||||
frag_length = dcerpc_get_frag_length(&tcp->recv.data);
|
||||
|
||||
tcp->recv.data.data = talloc_realloc(tcp, tcp->recv.data.data,
|
||||
frag_length);
|
||||
if (tcp->recv.data.data == NULL) {
|
||||
tcp_sock_dead(p, NT_STATUS_NO_MEMORY);
|
||||
return;
|
||||
}
|
||||
tcp->recv.data.length = frag_length;
|
||||
}
|
||||
|
||||
/* read in the rest of the packet */
|
||||
ret = read(tcp->fd, tcp->recv.data.data + tcp->recv.received,
|
||||
tcp->recv.data.length - tcp->recv.received);
|
||||
if (ret == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ret == 0) {
|
||||
tcp_sock_dead(p, NT_STATUS_NET_WRITE_FAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
tcp->recv.received += ret;
|
||||
|
||||
if (tcp->recv.received != tcp->recv.data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* we have a full packet */
|
||||
p->transport.recv_data(p, &tcp->recv.data, NT_STATUS_OK);
|
||||
talloc_free(tcp->recv.data.data);
|
||||
tcp->recv.data = data_blob(NULL, 0);
|
||||
tcp->recv.received = 0;
|
||||
tcp->recv.pending_count--;
|
||||
if (tcp->recv.pending_count == 0) {
|
||||
tcp->fde->flags &= ~EVENT_FD_READ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
called when a IO is triggered by the events system
|
||||
*/
|
||||
static void tcp_io_handler(struct event_context *ev, struct fd_event *fde,
|
||||
time_t t, uint16_t flags)
|
||||
{
|
||||
struct dcerpc_pipe *p = fde->private;
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
|
||||
if (flags & EVENT_FD_WRITE) {
|
||||
tcp_process_send(p);
|
||||
}
|
||||
|
||||
if (tcp->fd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & EVENT_FD_READ) {
|
||||
tcp_process_recv(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
initiate a read request
|
||||
*/
|
||||
static NTSTATUS tcp_send_read(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
|
||||
tcp->recv.pending_count++;
|
||||
if (tcp->recv.pending_count == 1) {
|
||||
tcp->fde->flags |= EVENT_FD_READ;
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
send an initial pdu in a multi-pdu sequence
|
||||
*/
|
||||
static NTSTATUS tcp_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL trigger_read)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
struct tcp_blob *blob;
|
||||
|
||||
blob = talloc_p(tcp, struct tcp_blob);
|
||||
if (blob == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
blob->data = data_blob_talloc(blob, data->data, data->length);
|
||||
if (blob->data.data == NULL) {
|
||||
talloc_free(blob);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
DLIST_ADD_END(tcp->pending_send, blob, struct tcp_blob *);
|
||||
|
||||
tcp->fde->flags |= EVENT_FD_WRITE;
|
||||
|
||||
if (trigger_read) {
|
||||
tcp_send_read(p);
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
return the event context so the caller can process asynchronously
|
||||
*/
|
||||
static struct event_context *tcp_event_context(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
|
||||
return tcp->event_ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
shutdown TCP pipe connection
|
||||
*/
|
||||
static NTSTATUS tcp_shutdown_pipe(struct dcerpc_pipe *p)
|
||||
{
|
||||
tcp_sock_dead(p, NT_STATUS_OK);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
return TCP server name
|
||||
*/
|
||||
static const char *tcp_peer_name(struct dcerpc_pipe *p)
|
||||
{
|
||||
struct tcp_private *tcp = p->transport.private;
|
||||
return tcp->server_name;
|
||||
}
|
||||
|
||||
/*
|
||||
open a rpc connection to a named pipe
|
||||
*/
|
||||
NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p,
|
||||
const char *server,
|
||||
uint32_t port,
|
||||
int family)
|
||||
{
|
||||
struct tcp_private *tcp;
|
||||
int fd, gai_err;
|
||||
struct fd_event fde;
|
||||
struct addrinfo hints, *res, *tmpres;
|
||||
char portname[16];
|
||||
|
||||
if (port == 0) {
|
||||
port = EPMAPPER_PORT;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(portname, sizeof(portname)-1, "%d", port);
|
||||
|
||||
gai_err = getaddrinfo(server, portname, &hints, &res);
|
||||
if (gai_err < 0)
|
||||
{
|
||||
DEBUG(0, ("Unable to connect to %s:%d : %s\n", server, port, gai_strerror(gai_err)));
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
tmpres = res;
|
||||
|
||||
while (tmpres) {
|
||||
fd = socket(tmpres->ai_family, tmpres->ai_socktype, tmpres->ai_protocol);
|
||||
|
||||
if(fd >= 0) {
|
||||
if (connect(fd, tmpres->ai_addr, tmpres->ai_addrlen) == 0)
|
||||
break;
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
tmpres = tmpres->ai_next;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
if (fd == -1) {
|
||||
return NT_STATUS_PORT_CONNECTION_REFUSED;
|
||||
}
|
||||
|
||||
set_socket_options(fd, lp_socket_options());
|
||||
|
||||
if (!(*p = dcerpc_pipe_init())) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
fill in the transport methods
|
||||
*/
|
||||
(*p)->transport.transport = NCACN_IP_TCP;
|
||||
(*p)->transport.private = NULL;
|
||||
|
||||
(*p)->transport.send_request = tcp_send_request;
|
||||
(*p)->transport.send_read = tcp_send_read;
|
||||
(*p)->transport.event_context = tcp_event_context;
|
||||
(*p)->transport.recv_data = NULL;
|
||||
|
||||
(*p)->transport.shutdown_pipe = tcp_shutdown_pipe;
|
||||
(*p)->transport.peer_name = tcp_peer_name;
|
||||
|
||||
tcp = talloc((*p), sizeof(*tcp));
|
||||
if (!tcp) {
|
||||
dcerpc_pipe_close(*p);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
tcp->fd = fd;
|
||||
tcp->server_name = talloc_strdup((*p), server);
|
||||
tcp->event_ctx = event_context_init(tcp);
|
||||
tcp->pending_send = NULL;
|
||||
tcp->recv.received = 0;
|
||||
tcp->recv.data = data_blob(NULL, 0);
|
||||
tcp->recv.pending_count = 0;
|
||||
|
||||
fde.fd = fd;
|
||||
fde.flags = 0;
|
||||
fde.handler = tcp_io_handler;
|
||||
fde.private = *p;
|
||||
|
||||
tcp->fde = event_add_fd(tcp->event_ctx, &fde);
|
||||
|
||||
(*p)->transport.private = tcp;
|
||||
|
||||
/* ensure we don't get SIGPIPE */
|
||||
BlockSignals(True,SIGPIPE);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
@ -715,6 +715,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *
|
||||
tower->floors[2 + i].lhs.protocol = protseq[i];
|
||||
tower->floors[2 + i].lhs.info.lhs_data = data_blob_talloc(mem_ctx, NULL, 0);
|
||||
ZERO_STRUCT(tower->floors[2 + i].rhs);
|
||||
floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], "");
|
||||
}
|
||||
|
||||
/* The 4th floor contains the endpoint */
|
||||
@ -724,6 +725,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* The 5th contains the network address */
|
||||
if (num_protocols >= 3 && binding->host) {
|
||||
status = floor_set_rhs_data(mem_ctx, &tower->floors[4], binding->host);
|
||||
@ -845,6 +847,106 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* open a rpc connection to a rpc pipe on SMP using the binding
|
||||
structure to determine the endpoint and options */
|
||||
static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
|
||||
struct dcerpc_binding *binding,
|
||||
const char *pipe_uuid,
|
||||
uint32_t pipe_version,
|
||||
const char *domain,
|
||||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
/* FIXME: Look up identifier using the epmapper */
|
||||
if (!binding->options || !binding->options[0]) {
|
||||
DEBUG(0, ("Identifier not specified\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
status = dcerpc_pipe_open_pipe(p, binding->options[0]);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", binding->options[0]));
|
||||
return status;
|
||||
}
|
||||
|
||||
(*p)->flags = binding->flags;
|
||||
|
||||
/* remember the binding string for possible secondary connections */
|
||||
(*p)->binding_string = dcerpc_binding_string((*p), binding);
|
||||
|
||||
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
|
||||
status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
|
||||
domain, username, password);
|
||||
} else if (username && username[0]) {
|
||||
status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
|
||||
} else {
|
||||
status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Failed to bind to uuid %s - %s\n",
|
||||
pipe_uuid, nt_errstr(status)));
|
||||
dcerpc_pipe_close(*p);
|
||||
*p = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* open a rpc connection to a rpc pipe on SMP using the binding
|
||||
structure to determine the endpoint and options */
|
||||
static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p,
|
||||
struct dcerpc_binding *binding,
|
||||
const char *pipe_uuid,
|
||||
uint32_t pipe_version,
|
||||
const char *domain,
|
||||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
/* FIXME: Look up path via the epmapper */
|
||||
if (!binding->options || !binding->options[0]) {
|
||||
DEBUG(0, ("Path to unix socket not specified\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
status = dcerpc_pipe_open_unix_stream(p, binding->options[0]);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Failed to open unix socket %s\n", binding->options[0]));
|
||||
return status;
|
||||
}
|
||||
|
||||
(*p)->flags = binding->flags;
|
||||
|
||||
/* remember the binding string for possible secondary connections */
|
||||
(*p)->binding_string = dcerpc_binding_string((*p), binding);
|
||||
|
||||
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
|
||||
status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
|
||||
domain, username, password);
|
||||
} else if (username && username[0]) {
|
||||
status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
|
||||
} else {
|
||||
status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Failed to bind to uuid %s - %s\n",
|
||||
pipe_uuid, nt_errstr(status)));
|
||||
dcerpc_pipe_close(*p);
|
||||
*p = NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* open a rpc connection to a rpc pipe on SMP using the binding
|
||||
structure to determine the endpoint and options */
|
||||
@ -928,6 +1030,12 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
|
||||
status = dcerpc_pipe_connect_ncacn_ip_tcp(p, binding, pipe_uuid, pipe_version,
|
||||
domain, username, password);
|
||||
break;
|
||||
case NCACN_UNIX_STREAM:
|
||||
status = dcerpc_pipe_connect_ncacn_unix_stream(p, binding, pipe_uuid, pipe_version, domain, username, password);
|
||||
break;
|
||||
case NCALRPC:
|
||||
status = dcerpc_pipe_connect_ncalrpc(p, binding, pipe_uuid, pipe_version, domain, username, password);
|
||||
break;
|
||||
default:
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ typedef struct
|
||||
char **smb_ports;
|
||||
char *dos_charset;
|
||||
char *unix_charset;
|
||||
char *ncalrpc_dir;
|
||||
char *display_charset;
|
||||
char *szPrintcapname;
|
||||
char *szLockDir;
|
||||
@ -505,6 +506,7 @@ static struct parm_struct parm_table[] = {
|
||||
|
||||
{"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
|
||||
{"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
|
||||
@ -916,6 +918,8 @@ static void init_globals(void)
|
||||
|
||||
do_parameter("pid directory", dyn_PIDDIR);
|
||||
do_parameter("lock dir", dyn_LOCKDIR);
|
||||
do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
|
||||
|
||||
do_parameter("socket address", "0.0.0.0");
|
||||
do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
|
||||
|
||||
@ -1113,6 +1117,7 @@ FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
|
||||
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
|
||||
FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
|
||||
FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
|
||||
FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
|
||||
FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
|
||||
FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
|
||||
FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
|
||||
|
@ -141,11 +141,6 @@ static BOOL test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
r.out.entry_handle = &handle;
|
||||
r.in.max_towers = 100;
|
||||
|
||||
if (twr->tower.num_floors != 5) {
|
||||
printf(" tower has %d floors - skipping test_Map\n", twr->tower.num_floors);
|
||||
return True;
|
||||
}
|
||||
|
||||
uuid_str = GUID_string(mem_ctx, &twr->tower.floors[0].lhs.info.uuid.uuid);
|
||||
|
||||
printf("epm_Map results for '%s':\n",
|
||||
@ -201,6 +196,8 @@ static BOOL test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
|
||||
|
||||
return True;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user