summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2007-09-03 13:13:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 15:03:39 -0500
commit8e2d624a588552f5d06f21fe37281615f3ec6296 (patch)
tree72d45a64cf0e3defd2537fb08596df58233d90be /source4/rpc_server
parent6a92d816a7dc97b8ca8a1b2419c31515add5ac87 (diff)
downloadsamba-8e2d624a588552f5d06f21fe37281615f3ec6296.tar.gz
samba-8e2d624a588552f5d06f21fe37281615f3ec6296.tar.bz2
samba-8e2d624a588552f5d06f21fe37281615f3ec6296.zip
r24937: Merge tests spoolss RPC callbacks.
(This used to be commit 9b256a0ca232ea6e89771bf73a1adf877273a752)
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/config.mk5
-rw-r--r--source4/rpc_server/dcerpc_server.c97
-rw-r--r--source4/rpc_server/service_rpc.c (renamed from source4/rpc_server/dcerpc_sock.c)105
-rw-r--r--source4/rpc_server/spoolss/dcesrv_spoolss.c75
4 files changed, 180 insertions, 102 deletions
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index 0de09b572e..7a39e56060 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -157,7 +157,8 @@ OBJ_FILES = \
PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
NDR_SPOOLSS \
- ntptr
+ ntptr \
+ RPC_NDR_SPOOLSS
# End MODULE dcerpc_spoolss
################################################
@@ -182,7 +183,6 @@ PUBLIC_HEADERS = dcerpc_server.h
PUBLIC_PROTO_HEADER = dcerpc_server_proto.h
OBJ_FILES = \
dcerpc_server.o \
- dcerpc_sock.o \
dcesrv_auth.o \
dcesrv_mgmt.o \
handles.o
@@ -196,5 +196,6 @@ PRIVATE_DEPENDENCIES = \
[MODULE::DCESRV]
INIT_FUNCTION = server_service_rpc_init
+OBJ_FILES = service_rpc.o
SUBSYSTEM = service
PRIVATE_DEPENDENCIES = dcerpc_server
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index 35b37b3af6..466d35c373 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -39,11 +39,11 @@ extern const struct dcesrv_interface dcesrv_mgmt_interface;
/*
see if two endpoints match
*/
-static BOOL endpoints_match(const struct dcerpc_binding *ep1,
+static bool endpoints_match(const struct dcerpc_binding *ep1,
const struct dcerpc_binding *ep2)
{
if (ep1->transport != ep2->transport) {
- return False;
+ return false;
}
if (!ep1->endpoint || !ep2->endpoint) {
@@ -51,9 +51,9 @@ static BOOL endpoints_match(const struct dcerpc_binding *ep1,
}
if (strcasecmp(ep1->endpoint, ep2->endpoint) != 0)
- return False;
+ return false;
- return True;
+ return true;
}
/*
@@ -1246,7 +1246,7 @@ _PUBLIC_ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
return status;
}
-static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
+_PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
{
NTSTATUS status;
struct dcesrv_context *dce_ctx;
@@ -1282,21 +1282,6 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s
return NT_STATUS_OK;
}
-/*
- initialise the dcerpc server context for ncacn_np based services
-*/
-_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx)
-{
- NTSTATUS status;
- struct dcesrv_context *dce_ctx;
-
- status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx);
- NT_STATUS_NOT_OK_RETURN(status);
-
- *_dce_ctx = dce_ctx;
- return NT_STATUS_OK;
-}
-
/* the list of currently registered DCERPC endpoint servers.
*/
static struct ep_server {
@@ -1379,78 +1364,18 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void)
}
/*
- open the dcerpc server sockets
+ initialise the dcerpc server context for ncacn_np based services
*/
-static void dcesrv_task_init(struct task_server *task)
+_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx)
{
NTSTATUS status;
struct dcesrv_context *dce_ctx;
- struct dcesrv_endpoint *e;
- task_server_set_title(task, "task[dcesrv]");
-
- status = dcesrv_init_context(task->event_ctx,
- lp_dcerpc_endpoint_servers(),
- &dce_ctx);
- if (!NT_STATUS_IS_OK(status)) goto failed;
-
- /* Make sure the directory for NCALRPC exists */
- if (!directory_exist(lp_ncalrpc_dir())) {
- mkdir(lp_ncalrpc_dir(), 0755);
- }
-
- for (e=dce_ctx->endpoint_list;e;e=e->next) {
- switch (e->ep_description->transport) {
- case NCACN_UNIX_STREAM:
- status = dcesrv_add_ep_unix(dce_ctx, e, task->event_ctx, task->model_ops);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- break;
-
- case NCALRPC:
- status = dcesrv_add_ep_ncalrpc(dce_ctx, e, task->event_ctx, task->model_ops);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- break;
-
- case NCACN_IP_TCP:
- status = dcesrv_add_ep_tcp(dce_ctx, e, task->event_ctx, task->model_ops);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- break;
-
- case NCACN_NP:
- status = dcesrv_add_ep_np(dce_ctx, e, task->event_ctx, task->model_ops);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- break;
-
- default:
- status = NT_STATUS_NOT_SUPPORTED;
- if (!NT_STATUS_IS_OK(status)) goto failed;
- }
- }
-
- return;
-failed:
- task_server_terminate(task, "Failed to startup dcerpc server task");
-}
+ status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx);
+ NT_STATUS_NOT_OK_RETURN(status);
-/*
- called on startup of the smb server service It's job is to start
- listening on all configured sockets
-*/
-static NTSTATUS dcesrv_init(struct event_context *event_context,
- const struct model_ops *model_ops)
-{
- return task_server_startup(event_context, model_ops, dcesrv_task_init);
+ *_dce_ctx = dce_ctx;
+ return NT_STATUS_OK;
}
-NTSTATUS server_service_rpc_init(void)
-{
- init_module_fn static_init[] = STATIC_dcerpc_server_MODULES;
- init_module_fn *shared_init = load_samba_modules(NULL, "dcerpc_server");
-
- run_init_functions(static_init);
- run_init_functions(shared_init);
- talloc_free(shared_init);
-
- return register_server_service("rpc", dcesrv_init);
-}
diff --git a/source4/rpc_server/dcerpc_sock.c b/source4/rpc_server/service_rpc.c
index 834758356b..6d70dd0bae 100644
--- a/source4/rpc_server/dcerpc_sock.c
+++ b/source4/rpc_server/service_rpc.c
@@ -1,12 +1,12 @@
/*
Unix SMB/CIFS implementation.
- server side dcerpc using various kinds of sockets (tcp, unix domain)
-
- Copyright (C) Andrew Tridgell 2003
- Copyright (C) Stefan (metze) Metzmacher 2004-2005
- Copyright (C) Jelmer Vernooij 2004
+ smbd-specific dcerpc server code
+ Copyright (C) Andrew Tridgell 2003-2005
+ Copyright (C) Stefan (metze) Metzmacher 2004-2005
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2004,2007
+
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 3 of the License, or
@@ -22,15 +22,22 @@
*/
#include "includes.h"
-#include "lib/socket/socket.h"
-#include "lib/events/events.h"
+#include "librpc/gen_ndr/ndr_dcerpc.h"
+#include "auth/auth.h"
+#include "auth/gensec/gensec.h"
+#include "lib/util/dlinklist.h"
#include "rpc_server/dcerpc_server.h"
+#include "lib/events/events.h"
+#include "smbd/service_task.h"
#include "smbd/service_stream.h"
#include "smbd/service.h"
+#include "system/filesys.h"
+#include "libcli/security/security.h"
+#include "lib/socket/socket.h"
#include "lib/messaging/irpc.h"
#include "system/network.h"
#include "lib/socket/netif.h"
-#include "auth/auth.h"
+#include "build.h"
struct dcesrv_socket_context {
const struct dcesrv_endpoint *endpoint;
@@ -209,7 +216,7 @@ static const struct stream_server_ops dcesrv_stream_ops = {
NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
+ struct event_context *event_ctx, const struct model_ops *model_ops)
{
struct dcesrv_socket_context *dcesrv_sock;
uint16_t port = 1;
@@ -234,7 +241,7 @@ NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx, struct dcesrv_endpoi
}
NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
+ struct event_context *event_ctx, const struct model_ops *model_ops)
{
struct dcesrv_socket_context *dcesrv_sock;
uint16_t port = 1;
@@ -369,3 +376,81 @@ NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, struct dcesrv_endpoin
return NT_STATUS_OK;
}
+
+
+NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
+ struct event_context *event_ctx, const struct model_ops *model_ops)
+{
+ switch (e->ep_description->transport) {
+ case NCACN_UNIX_STREAM:
+ return dcesrv_add_ep_unix(dce_ctx, e, event_ctx, model_ops);
+
+ case NCALRPC:
+ return dcesrv_add_ep_ncalrpc(dce_ctx, e, event_ctx, model_ops);
+
+ case NCACN_IP_TCP:
+ return dcesrv_add_ep_tcp(dce_ctx, e, event_ctx, model_ops);
+
+ case NCACN_NP:
+ return dcesrv_add_ep_np(dce_ctx, e, event_ctx, model_ops);
+
+ default:
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+}
+
+/*
+ open the dcerpc server sockets
+*/
+static void dcesrv_task_init(struct task_server *task)
+{
+ NTSTATUS status;
+ struct dcesrv_context *dce_ctx;
+ struct dcesrv_endpoint *e;
+
+ task_server_set_title(task, "task[dcesrv]");
+
+ status = dcesrv_init_context(task->event_ctx,
+ lp_dcerpc_endpoint_servers(),
+ &dce_ctx);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ /* Make sure the directory for NCALRPC exists */
+ if (!directory_exist(lp_ncalrpc_dir())) {
+ mkdir(lp_ncalrpc_dir(), 0755);
+ }
+
+ for (e=dce_ctx->endpoint_list;e;e=e->next) {
+ status = dcesrv_add_ep(dce_ctx, e, task->event_ctx, task->model_ops);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+ }
+
+ return;
+failed:
+ task_server_terminate(task, "Failed to startup dcerpc server task");
+}
+
+/*
+ called on startup of the smb server service It's job is to start
+ listening on all configured sockets
+*/
+static NTSTATUS dcesrv_init(struct event_context *event_context,
+ const struct model_ops *model_ops)
+{
+ return task_server_startup(event_context, model_ops, dcesrv_task_init);
+}
+
+NTSTATUS server_service_rpc_init(void)
+{
+ init_module_fn static_init[] = STATIC_dcerpc_server_MODULES;
+ init_module_fn *shared_init = load_samba_modules(NULL, "dcerpc_server");
+
+ run_init_functions(static_init);
+ run_init_functions(shared_init);
+
+ talloc_free(shared_init);
+
+ return register_server_service("rpc", dcesrv_init);
+}
+
+
diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c
index 2dca178245..cd39bcda3d 100644
--- a/source4/rpc_server/spoolss/dcesrv_spoolss.c
+++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c
@@ -27,6 +27,12 @@
#include "ntptr/ntptr.h"
#include "lib/socket/socket.h"
#include "smbd/service_stream.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "auth/credentials/credentials.h"
+
+enum spoolss_handle {
+ SPOOLSS_NOTIFY
+};
#define SPOOLSS_BUFFER_UNION(fn,info,level) \
((info)?ndr_size_##fn(info, level, 0):0)
@@ -1036,7 +1042,16 @@ static WERROR dcesrv_spoolss_RouterFindFirstPrinterChangeNotificationOld(struct
static WERROR dcesrv_spoolss_ReplyOpenPrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_ReplyOpenPrinter *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+ struct dcesrv_handle *handle;
+
+ handle = dcesrv_handle_new(dce_call->context, SPOOLSS_NOTIFY);
+ W_ERROR_HAVE_NO_MEMORY(handle);
+
+ /* For now, just return a handle */
+
+ *r->out.handle = handle->wire_handle;
+
+ return WERR_OK;
}
@@ -1056,9 +1071,16 @@ static WERROR dcesrv_spoolss_RouterReplyPrinter(struct dcesrv_call_state *dce_ca
static WERROR dcesrv_spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_ReplyClosePrinter *r)
{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
+ struct dcesrv_handle *handle;
+
+ DCESRV_PULL_HANDLE_WERR(handle, r->in.handle, SPOOLSS_NOTIFY);
+ talloc_free(handle);
+
+ ZERO_STRUCTP(r->out.handle);
+
+ return WERR_OK;
+}
/*
spoolss_AddPortEx
@@ -1106,11 +1128,56 @@ static WERROR dcesrv_spoolss_ResetPrinterEx(struct dcesrv_call_state *dce_call,
static WERROR dcesrv_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
{
+ struct dcerpc_pipe *p;
+ struct dcerpc_binding *binding;
+ NTSTATUS status;
+ struct spoolss_ReplyOpenPrinter rop;
+ struct cli_credentials *creds;
+ struct policy_handle notify_handle;
+
+ DEBUG(2, ("Received RFFPCNex from %s\n", r->in.str));
+
/*
- * TODO: for now just return ok,
+ * TODO: for now just open a connection to the client and drop it again
* to keep the w2k3 PrintServer
* happy to allow to open the Add Printer GUI
+ * and the torture suite passing
*/
+
+ binding = talloc_zero(mem_ctx, struct dcerpc_binding);
+
+ binding->transport = NCACN_NP;
+ if (strncmp(r->in.str, "\\\\", 2))
+ return WERR_INVALID_COMPUTERNAME;
+ binding->host = r->in.str+2;
+
+ creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */
+
+ status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_spoolss,
+ creds, NULL);
+
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(0, ("unable to call back to %s\n", r->in.str));
+ return WERR_SERVER_UNAVAILABLE;
+ }
+
+ ZERO_STRUCT(rop);
+ rop.in.server_name = lp_netbios_name();
+ W_ERROR_HAVE_NO_MEMORY(rop.in.server_name);
+ rop.in.printer_local = 0;
+ rop.in.type = REG_NONE;
+ rop.in.unknown1 = 0;
+ rop.in.unknown2 = 0;
+ rop.out.handle = &notify_handle;
+
+ status = dcerpc_spoolss_ReplyOpenPrinter(p, mem_ctx, &rop);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(0, ("unable to open remote printer %s\n", r->in.str));
+ return WERR_SERVER_UNAVAILABLE;
+ }
+
+ talloc_free(p);
+
return WERR_OK;
}