diff options
Diffstat (limited to 'source4/rpc_server')
-rw-r--r-- | source4/rpc_server/config.mk | 5 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 97 | ||||
-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.c | 75 |
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 = ¬ify_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; } |