diff options
| author | Andrew Tridgell <tridge@samba.org> | 2008-05-28 17:00:21 +1000 | 
|---|---|---|
| committer | Andrew Tridgell <tridge@samba.org> | 2008-05-28 17:00:21 +1000 | 
| commit | 1499a7b160f72d8dfa76d281cca52b4263b54ff0 (patch) | |
| tree | c8dc71262f0326af69d000eebbcb28e8ecdfb751 | |
| parent | 0eb4ecc81a2fa1f37e09b60e750854d75ac425a0 (diff) | |
| parent | 93d2f8ff9e627dd915b90b77161ce3ee5473fa32 (diff) | |
| download | samba-1499a7b160f72d8dfa76d281cca52b4263b54ff0.tar.gz samba-1499a7b160f72d8dfa76d281cca52b4263b54ff0.tar.bz2 samba-1499a7b160f72d8dfa76d281cca52b4263b54ff0.zip  | |
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
(This used to be commit 7245e62f08e2bda96471318cac612b25697bc3e9)
| -rw-r--r-- | source4/Makefile | 1 | ||||
| -rw-r--r-- | source4/librpc/config.mk | 9 | ||||
| -rw-r--r-- | source4/librpc/idl/ntp_signd.idl | 36 | ||||
| -rw-r--r-- | source4/main.mk | 1 | ||||
| -rw-r--r-- | source4/ntp_signd/config.mk | 14 | ||||
| -rw-r--r-- | source4/ntp_signd/ntp_signd.c | 265 | ||||
| -rw-r--r-- | source4/param/loadparm.c | 2 | ||||
| -rw-r--r-- | source4/smbd/server.c | 1 | 
8 files changed, 327 insertions, 2 deletions
diff --git a/source4/Makefile b/source4/Makefile index 20a0876962..14d0fe3b20 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -97,6 +97,7 @@ libclisrcdir := libcli  ejsscriptsrcdir := scripting/ejs  pyscriptsrcdir := $(srcdir)/scripting/python  kdcsrcdir := kdc +ntp_signdsrcdir := ntp_signd  include data.mk diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index a39f50411b..fd628a2788 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -338,6 +338,13 @@ NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o  PUBLIC_HEADERS += $(gen_ndrsrcdir)/nbt.h +[SUBSYSTEM::NDR_NTP_SIGND] +PUBLIC_DEPENDENCIES = LIBNDR  + +NDR_NTP_SIGND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_ntp_signd.o + +PUBLIC_HEADERS += $(gen_ndrsrcdir)/ndr_ntp_signd.h +  [SUBSYSTEM::NDR_WINSREPL]  PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT @@ -373,7 +380,7 @@ PUBLIC_DEPENDENCIES = \  	NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \  	NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \  	NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ -	NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL +	NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND  NDR_TABLE_OBJ_FILES = $(ndrsrcdir)/ndr_table.o $(gen_ndrsrcdir)/tables.o diff --git a/source4/librpc/idl/ntp_signd.idl b/source4/librpc/idl/ntp_signd.idl new file mode 100644 index 0000000000..af3f4337e2 --- /dev/null +++ b/source4/librpc/idl/ntp_signd.idl @@ -0,0 +1,36 @@ +/* +  NTP signing IRPC interface +*/ + +#include "idl_types.h" + +[ +  uuid("0da00951-5b6c-4488-9a89-750cac70920c"), +  version(1.0), +  pointer_default(unique) +] +interface ntp_signd +{ + +	typedef [flag(NDR_BIG_ENDIAN),public] struct { +		uint32 version; +		uint32 op; +		uint32 packet_id; +		[flag(NDR_LITTLE_ENDIAN)] uint32 key_id; +		[flag(NDR_REMAINING)]	DATA_BLOB packet_to_sign; +		 +	} sign_request; + +	typedef [flag(NDR_BIG_ENDIAN),public] struct samba_key_out { +		uint32 version; +		uint32 op; +		uint32 packet_id; +		[flag(NDR_REMAINING)]	DATA_BLOB signed_packet; +	} signed_reply; + +	void decode_sign_requst( +		[in] sign_request request +		); + +	 +}
\ No newline at end of file diff --git a/source4/main.mk b/source4/main.mk index 4fd1502fae..3f3aea87e6 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -36,6 +36,7 @@ mkinclude winbind/config.mk  mkinclude nbt_server/config.mk  mkinclude wrepl_server/config.mk  mkinclude cldap_server/config.mk +mkinclude ntp_signd/config.mk  mkinclude utils/net/config.mk  mkinclude utils/config.mk  mkinclude ntvfs/config.mk diff --git a/source4/ntp_signd/config.mk b/source4/ntp_signd/config.mk new file mode 100644 index 0000000000..96e0de5583 --- /dev/null +++ b/source4/ntp_signd/config.mk @@ -0,0 +1,14 @@ +# NTP_SIGND server subsystem + +####################### +# Start SUBSYSTEM NTP_signd +[MODULE::NTP_SIGND] +INIT_FUNCTION = server_service_ntp_signd_init +SUBSYSTEM = smbd +PRIVATE_DEPENDENCIES = \ +		SAMDB NDR_NTP_SIGND +# End SUBSYSTEM NTP_SIGND +####################### + +NTP_SIGND_OBJ_FILES = $(addprefix $(ntp_signdsrcdir)/, ntp_signd.o) + diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c new file mode 100644 index 0000000000..35016d5c61 --- /dev/null +++ b/source4/ntp_signd/ntp_signd.c @@ -0,0 +1,265 @@ +/*  +   Unix SMB/CIFS implementation. + +   NTP packet signing server + +   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 +   Copyright (C) Andrew Tridgell	2005 +   Copyright (C) Stefan Metzmacher	2005 + +   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 +   (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, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "smbd/service_task.h" +#include "smbd/service.h" +#include "smbd/service_stream.h" +#include "smbd/process_model.h" +#include "lib/stream/packet.h" +#include "librpc/gen_ndr/ndr_ntp_signd.h" +#include "param/param.h" +#include "dsdb/samdb/samdb.h" +#include "auth/auth.h" +#include "libcli/security/security.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" + +/* +  top level context structure for the ntp_signd server +*/ +struct ntp_signd_server { +	struct task_server *task; +	struct ldb_context *samdb; +}; + +/* +  state of an open connection +*/ +struct ntp_signd_connection { +	/* stream connection we belong to */ +	struct stream_connection *conn; + +	/* the ntp_signd_server the connection belongs to */ +	struct ntp_signd_server *ntp_signd; + +	struct packet_context *packet; +}; + +static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_signdconn, const char *reason) +{ +	stream_terminate_connection(ntp_signdconn->conn, reason); +} + +/* +  receive a full packet on a NTP_SIGND connection +*/ +static NTSTATUS ntp_signd_recv(void *private, DATA_BLOB blob) +{ +	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(private,  +							     struct ntp_signd_connection); +	NTSTATUS status = NT_STATUS_UNSUCCESSFUL; +	TALLOC_CTX *tmp_ctx = talloc_new(ntp_signdconn); +	DATA_BLOB input, reply; +	const struct dom_sid *domain_sid; +	struct dom_sid *sid; +	struct sign_request sign_request; +	enum ndr_err_code ndr_err; +	struct ldb_result *res; +	const char *attrs[] = { "unicodePwd", NULL }; +	int ret; + +	talloc_steal(tmp_ctx, blob.data); + +	input = data_blob_const(blob.data + 4, blob.length - 4);  + +	ndr_err = ndr_pull_struct_blob_all(&input, tmp_ctx,  +					   lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx), +					   &sign_request, +					   (ndr_pull_flags_fn_t)ndr_pull_sign_request); + +	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { +		DEBUG(1,("failed to parse ntp signing request\n")); +		dump_data(1, input.data, input.length); +		return ndr_map_error2ntstatus(ndr_err); +	} + +	domain_sid = samdb_domain_sid(ntp_signdconn->ntp_signd->samdb); +	if (!domain_sid) { +		return NT_STATUS_INVALID_PARAMETER; +	} +	 +	sid = dom_sid_add_rid(tmp_ctx, domain_sid, sign_request.key_id & 0x7FFFFFFF); +	if (!sid) { +		return NT_STATUS_NO_MEMORY; +	} + +	/* Sign packet */ +	ret = ldb_search_exp_fmt(ntp_signdconn->ntp_signd->samdb, tmp_ctx, +				 &res, samdb_base_dn(ntp_signdconn->ntp_signd->samdb), +				 LDB_SCOPE_SUBTREE, attrs, "(&(objectSid=%s)(objectClass=computer))", +				 dom_sid_string(tmp_ctx, sid)); +	if (ret != LDB_SUCCESS) { +		return NT_STATUS_UNSUCCESSFUL; +	} + +	if (res->count != 1) { +		return NT_STATUS_NO_SUCH_USER; +	} + +	/* Sign the NTP response with the unicodePwd */ + +	/* Place it into the packet for the wire */ + +	blob = data_blob_talloc(ntp_signdconn, NULL, reply.length + 4); +	if (!blob.data) { +		talloc_free(tmp_ctx); +		return NT_STATUS_NO_MEMORY; +	} + +	RSIVAL(blob.data, 0, reply.length); +	memcpy(blob.data + 4, reply.data, reply.length);	 + +	status = packet_send(ntp_signdconn->packet, blob); + +	/* the call isn't needed any more */ +	talloc_free(tmp_ctx); +	return status; +} + +/* +  receive some data on a NTP_SIGND connection +*/ +static void ntp_signd_recv_handler(struct stream_connection *conn, uint16_t flags) +{ +	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(conn->private,  +							     struct ntp_signd_connection); +	packet_recv(ntp_signdconn->packet); +} + +/* +  called on a tcp recv error +*/ +static void ntp_signd_recv_error(void *private, NTSTATUS status) +{ +	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(private, struct ntp_signd_connection); +	ntp_signd_terminate_connection(ntp_signdconn, nt_errstr(status)); +} + +/* +  called when we can write to a connection +*/ +static void ntp_signd_send(struct stream_connection *conn, uint16_t flags) +{ +	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(conn->private,  +							     struct ntp_signd_connection); +	packet_queue_run(ntp_signdconn->packet); +} + +/* +  called when we get a new connection +*/ +static void ntp_signd_accept(struct stream_connection *conn) +{ +	struct ntp_signd_server *ntp_signd = talloc_get_type(conn->private, struct ntp_signd_server); +	struct ntp_signd_connection *ntp_signdconn; + +	ntp_signdconn = talloc_zero(conn, struct ntp_signd_connection); +	if (!ntp_signdconn) { +		stream_terminate_connection(conn, "ntp_signd_accept: out of memory"); +		return; +	} +	ntp_signdconn->conn	 = conn; +	ntp_signdconn->ntp_signd	 = ntp_signd; +	conn->private    = ntp_signdconn; + +	ntp_signdconn->packet = packet_init(ntp_signdconn); +	if (ntp_signdconn->packet == NULL) { +		ntp_signd_terminate_connection(ntp_signdconn, "ntp_signd_accept: out of memory"); +		return; +	} +	packet_set_private(ntp_signdconn->packet, ntp_signdconn); +	packet_set_socket(ntp_signdconn->packet, conn->socket); +	packet_set_callback(ntp_signdconn->packet, ntp_signd_recv); +	packet_set_full_request(ntp_signdconn->packet, packet_full_request_u32); +	packet_set_error_handler(ntp_signdconn->packet, ntp_signd_recv_error); +	packet_set_event_context(ntp_signdconn->packet, conn->event.ctx); +	packet_set_fde(ntp_signdconn->packet, conn->event.fde); +	packet_set_serialise(ntp_signdconn->packet); +} + +static const struct stream_server_ops ntp_signd_stream_ops = { +	.name			= "ntp_signd", +	.accept_connection	= ntp_signd_accept, +	.recv_handler		= ntp_signd_recv_handler, +	.send_handler		= ntp_signd_send +}; + +/* +  startup the ntp_signd task +*/ +static void ntp_signd_task_init(struct task_server *task) +{ +	struct ntp_signd_server *ntp_signd; +	NTSTATUS status; + +	const struct model_ops *model_ops; + +	const char *address = "/tmp/ux_demo"; + +	/* within the ntp_signd task we want to be a single process, so +	   ask for the single process model ops and pass these to the +	   stream_setup_socket() call. */ +	model_ops = process_model_byname("single"); +	if (!model_ops) { +		DEBUG(0,("Can't find 'single' process model_ops\n")); +		return; +	} + +	task_server_set_title(task, "task[ntp_signd]"); + +	ntp_signd = talloc(task, struct ntp_signd_server); +	if (ntp_signd == NULL) { +		task_server_terminate(task, "ntp_signd: out of memory"); +		return; +	} + +	ntp_signd->task = task; + +	ntp_signd->samdb = samdb_connect(ntp_signd, task->event_ctx, task->lp_ctx, anonymous_session(ntp_signd, task->event_ctx, task->lp_ctx)); +	if (ntp_signd->samdb == NULL) { +		task_server_terminate(task, "ntp_signd failed to open samdb"); +		return; +	} + +	status = stream_setup_socket(ntp_signd->task->event_ctx,  +				     ntp_signd->task->lp_ctx, +				     model_ops,  +				     &ntp_signd_stream_ops,  +				     "unix", address, NULL, +				     lp_socket_options(ntp_signd->task->lp_ctx),  +				     ntp_signd); +	if (!NT_STATUS_IS_OK(status)) { +		DEBUG(0,("Failed to bind to %s - %s\n", +			 address, nt_errstr(status))); +		return; +	} + +} + + +/* called at smbd startup - register ourselves as a server service */ +NTSTATUS server_service_ntp_signd_init(void) +{ +	return register_server_service("ntp_signd", ntp_signd_task_init); +} diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index b70e4c19f0..ad1752a7e7 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -2296,7 +2296,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)  	lp_do_global_parameter(lp_ctx, "max connections", "-1");  	lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo"); -	lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap kdc drepl winbind"); +	lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd");  	lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb");  	lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain");  	lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind"); diff --git a/source4/smbd/server.c b/source4/smbd/server.c index e1ebd133ce..c1c8b6368f 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -198,6 +198,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[  	extern NTSTATUS server_service_smb_init(void);  	extern NTSTATUS server_service_drepl_init(void);  	extern NTSTATUS server_service_rpc_init(void); +	extern NTSTATUS server_service_ntp_signd_init(void);  	init_module_fn static_init[] = { STATIC_smbd_MODULES };  	init_module_fn *shared_init;  	struct event_context *event_ctx;  | 
