diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-05-29 15:51:24 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-05-29 15:51:24 +0200 |
commit | b302d3273a3b9e6acc1ff90bbca02fbe2ceb1160 (patch) | |
tree | 5201509b5f932788feeeee2ec6acface46581d34 /source4 | |
parent | 1e7dc5675280d567db1b6a243d48c5617dba5872 (diff) | |
parent | 617ef56aa3378c384026b72871af5a7253b8df33 (diff) | |
download | samba-b302d3273a3b9e6acc1ff90bbca02fbe2ceb1160.tar.gz samba-b302d3273a3b9e6acc1ff90bbca02fbe2ceb1160.tar.bz2 samba-b302d3273a3b9e6acc1ff90bbca02fbe2ceb1160.zip |
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-defs
(This used to be commit 3947327f8c4ca530d99bc5ac3d1f6f54727f477a)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/Makefile | 1 | ||||
-rw-r--r-- | source4/build/m4/check_path.m4 | 19 | ||||
-rw-r--r-- | source4/dynconfig/config.mk | 3 | ||||
-rw-r--r-- | source4/dynconfig/dynconfig.c | 3 | ||||
-rw-r--r-- | source4/dynconfig/dynconfig.h | 1 | ||||
-rw-r--r-- | source4/headermap.txt | 1 | ||||
-rw-r--r-- | source4/lib/ldb-samba/ldif_handlers.c | 198 | ||||
-rw-r--r-- | source4/librpc/config.mk | 2 | ||||
-rw-r--r-- | source4/librpc/idl/ntp_signd.idl | 14 | ||||
-rw-r--r-- | source4/ntp_signd/ntp_signd.c | 151 | ||||
-rw-r--r-- | source4/param/loadparm.c | 7 | ||||
-rw-r--r-- | source4/param/param.h | 2 | ||||
-rwxr-xr-x | source4/script/installmisc.sh | 1 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 14 | ||||
-rw-r--r-- | source4/setup/prefixMap.txt | 34 | ||||
-rw-r--r-- | source4/setup/provision_schema_basedn_modify.ldif | 18 |
16 files changed, 426 insertions, 43 deletions
diff --git a/source4/Makefile b/source4/Makefile index 14d0fe3b20..b7d5206868 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -167,6 +167,7 @@ showlayout:: @echo ' torturedir: $(TORTUREDIR)' @echo ' datadir: $(datadir)' @echo ' winbindd_socket_dir: $(winbindd_socket_dir)' + @echo ' ntp_signd_socket_dir: $(ntp_signd_socket_dir)' showflags:: @echo ' srcdir = $(srcdir)' diff --git a/source4/build/m4/check_path.m4 b/source4/build/m4/check_path.m4 index 08a858ebb2..c0b81f1a8d 100644 --- a/source4/build/m4/check_path.m4 +++ b/source4/build/m4/check_path.m4 @@ -20,6 +20,7 @@ piddir="${localstatedir}/run" privatedir="\${prefix}/private" modulesdir="\${prefix}/modules" winbindd_socket_dir="${localstatedir}/run/winbind_pipe" +ntp_signd_socket_dir="${localstatedir}/run/ntp_signd" AC_ARG_WITH(fhs, [ --with-fhs Use FHS-compliant paths (default=no)], @@ -31,6 +32,7 @@ AC_ARG_WITH(fhs, modulesdir="${libdir}/samba" datadir="${datadir}/samba" includedir="${includedir}/samba-4.0" + ntp_signd_socket_dir="${localstatedir}/run/samba/ntp_signd" winbindd_socket_dir="${localstatedir}/run/samba/winbind_pipe" ) @@ -67,6 +69,22 @@ AC_ARG_WITH(winbindd-socket-dir, esac]) ################################################# +# set where the NTP signing deamon socket should be put +AC_ARG_WITH(ntp-signd-socket-dir, +[ --with-ntp-signd-socket-dir=DIR Where to put the NTP signing deamon socket ($ac_default_prefix/run/ntp_signd)], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-ntp-signd-socketdir called without argument - will use default]) + ;; + * ) + ntp_signd_socket_dir="$withval" + ;; + esac]) + +################################################# # set lock directory location AC_ARG_WITH(lockdir, [ --with-lockdir=DIR Where to put lock files ($ac_default_prefix/var/locks)], @@ -122,6 +140,7 @@ AC_SUBST(privatedir) AC_SUBST(bindir) AC_SUBST(sbindir) AC_SUBST(winbindd_socket_dir) +AC_SUBST(ntp_signd_socket_dir) AC_SUBST(modulesdir) ################################################# diff --git a/source4/dynconfig/config.mk b/source4/dynconfig/config.mk index 5f2887f8b6..a353ba1214 100644 --- a/source4/dynconfig/config.mk +++ b/source4/dynconfig/config.mk @@ -19,5 +19,6 @@ $(dynconfigsrcdir)/dynconfig.o: CFLAGS+=-DCONFIGFILE=\"$(CONFIGFILE)\" -DBINDIR= -DPRIVATE_DIR=\"$(privatedir)\" \ -DMODULESDIR=\"$(modulesdir)\" -DJSDIR=\"$(JSDIR)\" \ -DTORTUREDIR=\"$(TORTUREDIR)\" \ - -DSETUPDIR=\"$(SETUPDIR)\" -DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\" + -DSETUPDIR=\"$(SETUPDIR)\" -DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\" \ + -DNTP_SIGND_SOCKET_DIR=\"$(ntp_signd_socket_dir)\" diff --git a/source4/dynconfig/dynconfig.c b/source4/dynconfig/dynconfig.c index 6dbbf872d9..ef5c40d698 100644 --- a/source4/dynconfig/dynconfig.c +++ b/source4/dynconfig/dynconfig.c @@ -84,3 +84,6 @@ _PUBLIC_ const char *dyn_JSDIR = JSDIR; /** Where to find the winbindd socket */ _PUBLIC_ const char *dyn_WINBINDD_SOCKET_DIR = WINBINDD_SOCKET_DIR; + +/** Where to find the NTP signing deamon socket */ +_PUBLIC_ const char *dyn_NTP_SIGND_SOCKET_DIR = NTP_SIGND_SOCKET_DIR; diff --git a/source4/dynconfig/dynconfig.h b/source4/dynconfig/dynconfig.h index ac54db63d6..e77c13bab3 100644 --- a/source4/dynconfig/dynconfig.h +++ b/source4/dynconfig/dynconfig.h @@ -38,3 +38,4 @@ extern const char *dyn_SWATDIR; extern const char *dyn_JSDIR; extern const char *dyn_SETUPDIR; extern const char *dyn_WINBINDD_SOCKET_DIR; +extern const char *dyn_NTP_SIGND_SOCKET_DIR; diff --git a/source4/headermap.txt b/source4/headermap.txt index 4949710aab..e2bbb167ed 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -48,7 +48,6 @@ lib/torture/torture.h: torture.h libcli/libcli.h: client.h librpc/gen_ndr/nbt.h: gen_ndr/nbt.h librpc/gen_ndr/ntp_signd.h: gen_ndr/ntp_signd.h -librpc/gen_ndr/ndr_ntp_signd.h: gen_ndr/ndr_ntp_signd.h librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index 5c29d001c2..1f718cc1c5 100644 --- a/source4/lib/ldb-samba/ldif_handlers.c +++ b/source4/lib/ldb-samba/ldif_handlers.c @@ -26,7 +26,9 @@ #include "dsdb/samdb/samdb.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" #include "libcli/security/security.h" +#include "param/param.h" /* convert a ldif formatted objectSid to a NDR formatted blob @@ -371,10 +373,199 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx return ret; } +/* + convert a ldif formatted prefixMap to a NDR formatted blob +*/ +static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; + char *string, *line, *p, *oid; + + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + if (tmp_ctx == NULL) { + return -1; + } + + blob = talloc_zero(tmp_ctx, struct prefixMapBlob); + if (blob == NULL) { + talloc_free(blob); + return -1; + } + + blob->version = PREFIX_MAP_VERSION_DSDB; + + string = talloc_strndup(mem_ctx, (const char *)in->data, in->length); + if (string == NULL) { + talloc_free(blob); + return -1; + } + + line = string; + while (line && line[0]) { + p=strchr(line, ';'); + if (p) { + p[0] = '\0'; + } else { + p=strchr(line, '\n'); + if (p) { + p[0] = '\0'; + } + } + /* allow a traling seperator */ + if (line == p) { + break; + } + + blob->ctr.dsdb.mappings = talloc_realloc(blob, + blob->ctr.dsdb.mappings, + struct drsuapi_DsReplicaOIDMapping, + blob->ctr.dsdb.num_mappings+1); + if (!blob->ctr.dsdb.mappings) { + talloc_free(tmp_ctx); + return -1; + } + + blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10); + + if (oid[0] != ':') { + talloc_free(tmp_ctx); + return -1; + } + + /* we know there must be at least ":" */ + oid++; + + blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.oid + = talloc_strdup(blob->ctr.dsdb.mappings, oid); + + blob->ctr.dsdb.num_mappings++; + + /* Now look past the terminator we added above */ + if (p) { + line = p + 1; + } else { + line = NULL; + } + } + + ndr_err = ndr_push_struct_blob(out, mem_ctx, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + blob, + (ndr_push_flags_fn_t)ndr_push_prefixMapBlob); + talloc_free(tmp_ctx); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return -1; + } + return 0; +} + +/* + convert a NDR formatted blob to a ldif formatted prefixMap +*/ +static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct prefixMapBlob *blob; + enum ndr_err_code ndr_err; + char *string; + uint32_t i; + + blob = talloc(mem_ctx, struct prefixMapBlob); + if (blob == NULL) { + return -1; + } + ndr_err = ndr_pull_struct_blob(in, blob, + lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), + blob, + (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(blob); + return -1; + } + if (blob->version != PREFIX_MAP_VERSION_DSDB) { + return -1; + } + string = talloc_strdup(mem_ctx, ""); + if (string == NULL) { + return -1; + } + + for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { + if (i > 0) { + string = talloc_asprintf_append(string, ";"); + } + string = talloc_asprintf_append(string, "%u:%s", + blob->ctr.dsdb.mappings[i].id_prefix, + blob->ctr.dsdb.mappings[i].oid.oid); + if (string == NULL) { + return -1; + } + } + + talloc_free(blob); + *out = data_blob_string_const(string); + return 0; +} + +static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v) +{ + if (v->length < 4) { + return true; + } + + if (IVAL(v->data, 0) == PREFIX_MAP_VERSION_DSDB) { + return false; + } + + return true; +} + +/* + canonicalise a prefixMap +*/ +static int ldif_canonicalise_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (ldif_comparision_prefixMap_isString(in)) { + return ldif_read_prefixMap(ldb, mem_ctx, in, out); + } + return ldb_handler_copy(ldb, mem_ctx, in, out); +} + +static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, + const struct ldb_val *v2) +{ + + int ret, ret1, ret2; + struct ldb_val v1_canon, v2_canon; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + /* I could try and bail if tmp_ctx was NULL, but what return + * value would I use? + * + * It seems easier to continue on the NULL context + */ + ret1 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v1, &v1_canon); + ret2 = ldif_canonicalise_prefixMap(ldb, tmp_ctx, v2, &v2_canon); + + if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) { + ret = data_blob_cmp(&v1_canon, &v2_canon); + } else { + ret = data_blob_cmp(v1, v2); + } + talloc_free(tmp_ctx); + return ret; +} + #define LDB_SYNTAX_SAMBA_SID "LDB_SYNTAX_SAMBA_SID" #define LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR "LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR" #define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID" #define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY" +#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP" static const struct ldb_schema_syntax samba_syntaxes[] = { { @@ -401,6 +592,12 @@ static const struct ldb_schema_syntax samba_syntaxes[] = { .ldif_write_fn = ldb_handler_copy, .canonicalise_fn= ldif_canonicalise_objectCategory, .comparison_fn = ldif_comparison_objectCategory + },{ + .name = LDB_SYNTAX_SAMBA_PREFIX_MAP, + .ldif_read_fn = ldif_read_prefixMap, + .ldif_write_fn = ldif_write_prefixMap, + .canonicalise_fn= ldif_canonicalise_prefixMap, + .comparison_fn = ldif_comparison_prefixMap } }; @@ -435,6 +632,7 @@ static const struct { { "masteredBy", LDB_SYNTAX_DN }, { "msDs-masteredBy", LDB_SYNTAX_DN }, { "fSMORoleOwner", LDB_SYNTAX_DN }, + { "prefixMap", LDB_SYNTAX_SAMBA_PREFIX_MAP } }; /* diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index fd628a2788..d2e11959e8 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -343,8 +343,6 @@ 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 diff --git a/source4/librpc/idl/ntp_signd.idl b/source4/librpc/idl/ntp_signd.idl index 2863401389..2b2fbc7662 100644 --- a/source4/librpc/idl/ntp_signd.idl +++ b/source4/librpc/idl/ntp_signd.idl @@ -12,10 +12,18 @@ interface ntp_signd { + typedef [v1_enum] enum { + SIGN_TO_CLIENT = 0, + ASK_SERVER_TO_SIGN = 1, + CHECK_SERVER_SIGNATURE = 2, + SIGNING_SUCCESS = 3, + SIGNING_FAILURE = 4 + } ntp_signd_op; + typedef [flag(NDR_BIG_ENDIAN),public] struct { uint32 version; - uint32 op; - uint32 packet_id; + ntp_signd_op op; + uint16 packet_id; [flag(NDR_LITTLE_ENDIAN)] uint32 key_id; [flag(NDR_REMAINING)] DATA_BLOB packet_to_sign; @@ -23,7 +31,7 @@ interface ntp_signd typedef [flag(NDR_BIG_ENDIAN),public] struct samba_key_out { uint32 version; - uint32 op; + ntp_signd_op op; uint32 packet_id; [flag(NDR_REMAINING)] DATA_BLOB signed_packet; } signed_reply; diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c index 35016d5c61..fdd97e475c 100644 --- a/source4/ntp_signd/ntp_signd.c +++ b/source4/ntp_signd/ntp_signd.c @@ -34,6 +34,8 @@ #include "libcli/security/security.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" +#include "lib/crypto/md5.h" +#include "system/passwd.h" /* top level context structure for the ntp_signd server @@ -61,27 +63,76 @@ static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_sign stream_terminate_connection(ntp_signdconn->conn, reason); } +static NTSTATUS signing_failure(struct ntp_signd_connection *ntp_signdconn, + uint32_t packet_id) +{ + NTSTATUS status; + struct signed_reply signed_reply; + TALLOC_CTX *tmp_ctx = talloc_new(ntp_signdconn); + DATA_BLOB reply, blob; + enum ndr_err_code ndr_err; + + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); + + signed_reply.version = 1; + signed_reply.op = SIGNING_FAILURE; + signed_reply.packet_id = packet_id; + signed_reply.signed_packet = data_blob(NULL, 0); + + ndr_err = ndr_push_struct_blob(&reply, tmp_ctx, + lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx), + &signed_reply, + (ndr_push_flags_fn_t)ndr_push_signed_reply); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(1,("failed to push ntp error reply\n")); + talloc_free(tmp_ctx); + return ndr_map_error2ntstatus(ndr_err); + } + + 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 a full packet on a NTP_SIGND connection */ -static NTSTATUS ntp_signd_recv(void *private, DATA_BLOB blob) +static NTSTATUS ntp_signd_recv(void *private, DATA_BLOB wrapped_input) { 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; + DATA_BLOB input, output, wrapped_output; const struct dom_sid *domain_sid; struct dom_sid *sid; struct sign_request sign_request; + struct signed_reply signed_reply; enum ndr_err_code ndr_err; struct ldb_result *res; const char *attrs[] = { "unicodePwd", NULL }; + struct MD5Context ctx; + struct samr_Password *nt_hash; int ret; - talloc_steal(tmp_ctx, blob.data); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); + + talloc_steal(tmp_ctx, wrapped_input.data); - input = data_blob_const(blob.data + 4, blob.length - 4); + input = data_blob_const(wrapped_input.data + 4, wrapped_input.length - 4); ndr_err = ndr_pull_struct_blob_all(&input, tmp_ctx, lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx), @@ -94,43 +145,98 @@ static NTSTATUS ntp_signd_recv(void *private, DATA_BLOB blob) return ndr_map_error2ntstatus(ndr_err); } + /* We need to implement 'check signature' and 'request server + * to sign' operations at some point */ + if (sign_request.op != SIGN_TO_CLIENT) { + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); + } + domain_sid = samdb_domain_sid(ntp_signdconn->ntp_signd->samdb); if (!domain_sid) { - return NT_STATUS_INVALID_PARAMETER; + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); } + /* The top bit is a 'key selector' */ sid = dom_sid_add_rid(tmp_ctx, domain_sid, sign_request.key_id & 0x7FFFFFFF); if (!sid) { - return NT_STATUS_NO_MEMORY; + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); } - /* 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; + DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: %s\n", dom_sid_string(tmp_ctx, sid), + ldb_errstring(ntp_signdconn->ntp_signd->samdb))); + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); + } + + if (res->count == 0) { + DEBUG(5, ("Failed to find SID %s in SAM for NTP signing\n", dom_sid_string(tmp_ctx, sid))); + } else if (res->count != 1) { + DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n", dom_sid_string(tmp_ctx, sid), res->count)); + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); + } + + nt_hash = samdb_result_hash(tmp_ctx, res->msgs[0], "unicodePwd"); + if (!nt_hash) { + DEBUG(1, ("No unicodePwd found on record of SID %s for NTP signing\n", dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); } - if (res->count != 1) { - return NT_STATUS_NO_SUCH_USER; + /* Generate the reply packet */ + signed_reply.version = 1; + signed_reply.packet_id = sign_request.packet_id; + signed_reply.op = SIGNING_SUCCESS; + signed_reply.signed_packet = data_blob_talloc(tmp_ctx, + NULL, + sign_request.packet_to_sign.length + 20); + + if (!signed_reply.signed_packet.data) { + talloc_free(tmp_ctx); + return signing_failure(ntp_signdconn, sign_request.packet_id); } + memcpy(signed_reply.signed_packet.data, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length); + SIVAL(signed_reply.signed_packet.data, sign_request.packet_to_sign.length, sign_request.key_id); + /* Sign the NTP response with the unicodePwd */ + MD5Init(&ctx); + MD5Update(&ctx, nt_hash->hash, sizeof(nt_hash->hash)); + MD5Update(&ctx, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length); + MD5Final(signed_reply.signed_packet.data + sign_request.packet_to_sign.length + 4, &ctx); + /* Place it into the packet for the wire */ + ndr_err = ndr_push_struct_blob(&output, tmp_ctx, + lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx), + &signed_reply, + (ndr_push_flags_fn_t)ndr_push_signed_reply); - blob = data_blob_talloc(ntp_signdconn, NULL, reply.length + 4); - if (!blob.data) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(1,("failed to push ntp error reply\n")); + talloc_free(tmp_ctx); + return ndr_map_error2ntstatus(ndr_err); + } + + wrapped_output = data_blob_talloc(ntp_signdconn, NULL, output.length + 4); + if (!wrapped_output.data) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - RSIVAL(blob.data, 0, reply.length); - memcpy(blob.data + 4, reply.data, reply.length); + /* The 'wire' transport for this is wrapped with a 4 byte network byte order length */ + RSIVAL(wrapped_output.data, 0, output.length); + memcpy(wrapped_output.data + 4, output.data, output.length); - status = packet_send(ntp_signdconn->packet, blob); + status = packet_send(ntp_signdconn->packet, wrapped_output); /* the call isn't needed any more */ talloc_free(tmp_ctx); @@ -215,7 +321,15 @@ static void ntp_signd_task_init(struct task_server *task) const struct model_ops *model_ops; - const char *address = "/tmp/ux_demo"; + const char *address; + + if (!directory_create_or_exist(lp_ntp_signd_socket_directory(task->lp_ctx), geteuid(), 0755)) { + char *error = talloc_asprintf(task, "Cannot create NTP signd pipe directory: %s", + lp_ntp_signd_socket_directory(task->lp_ctx)); + task_server_terminate(task, + error); + return; + } /* 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 @@ -236,12 +350,15 @@ static void ntp_signd_task_init(struct task_server *task) 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)); + /* Must be system to get at the password hashes */ + ntp_signd->samdb = samdb_connect(ntp_signd, task->event_ctx, task->lp_ctx, system_session(ntp_signd, task->lp_ctx)); if (ntp_signd->samdb == NULL) { task_server_terminate(task, "ntp_signd failed to open samdb"); return; } + address = talloc_asprintf(ntp_signd, "%s/socket", lp_ntp_signd_socket_directory(task->lp_ctx)); + status = stream_setup_socket(ntp_signd->task->event_ctx, ntp_signd->task->lp_ctx, model_ops, diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index ad1752a7e7..0a7aec1985 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -179,6 +179,7 @@ struct loadparm_global int bUnixExtensions; int bDisableNetbios; int bRpcBigEndian; + char *szNTPSignDSocketDirectory; struct param_opt *param_opt; }; @@ -489,6 +490,8 @@ static struct parm_struct parm_table[] = { {"template homedir", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateHomedir), NULL, NULL }, {"idmap trusted only", P_BOOL, P_GLOBAL, GLOBAL_VAR(bIdmapTrustedOnly), NULL, NULL}, + {"ntp signd socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szNTPSignDSocketDirectory), NULL, NULL }, + {NULL, P_BOOL, P_NONE, 0, NULL, NULL} }; @@ -730,6 +733,8 @@ _PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode) _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, server_signing) _PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, client_signing) +_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_ntp_signd_socket_directory, szNTPSignDSocketDirectory) + /* local prototypes */ static int map_parameter(const char *pszParmName); static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx, @@ -2410,6 +2415,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lp_do_global_parameter(lp_ctx, "prefork children:smb", "4"); + lp_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR); + for (i = 0; parm_table[i].label; i++) { if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { lp_ctx->flags[i] |= FLAG_DEFAULT; diff --git a/source4/param/param.h b/source4/param/param.h index 0b276cdff2..06a42575ad 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -186,6 +186,8 @@ int lp_dir_mask(struct loadparm_service *, struct loadparm_service *); int lp_force_dir_mode(struct loadparm_service *, struct loadparm_service *); int lp_server_signing(struct loadparm_context *); int lp_client_signing(struct loadparm_context *); +const char *lp_ntp_signd_socket_directory(struct loadparm_context *); + const char *lp_get_parametric(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *type, const char *option); diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh index 4707aafdbd..5f7e11f083 100755 --- a/source4/script/installmisc.sh +++ b/source4/script/installmisc.sh @@ -25,6 +25,7 @@ cp setup/*.reg $SETUPDIR || exit 1 cp setup/*.zone $SETUPDIR || exit 1 cp setup/*.conf $SETUPDIR || exit 1 cp setup/*.php $SETUPDIR || exit 1 +cp setup/*.txt $SETUPDIR || exit 1 cp setup/provision.smb.conf.dc $SETUPDIR || exit 1 cp setup/provision.smb.conf.member $SETUPDIR || exit 1 cp setup/provision.smb.conf.standalone $SETUPDIR || exit 1 diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3914fa8376..71c1ac3187 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -797,13 +797,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") + + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": names.schemadn, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "PREFIXMAP_B64": b64encode(prefixmap) }) message("Setting up sam.ldb Samba4 schema") @@ -969,7 +973,7 @@ def provision(setup_dir, message, session_info, if ldap_backend is not None: if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + ldap_backend = "ldapi://%s" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): @@ -1389,12 +1393,16 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + prefixmap = b64encode(prefixmap) + head_data = open(setup_path("provision_schema_basedn_modify.ldif"), 'r').read() head_data = substitute_var(head_data, { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE":sitename + "DEFAULTSITE":sitename, + "PREFIXMAP_B64":prefixmap }) samdb.attach_schema_from_ldif(head_data, schema_data) diff --git a/source4/setup/prefixMap.txt b/source4/setup/prefixMap.txt new file mode 100644 index 0000000000..8ba9b9531c --- /dev/null +++ b/source4/setup/prefixMap.txt @@ -0,0 +1,34 @@ +0:2.5.4 +1:2.5.6 +2:1.2.840.113556.1.2 +3:1.2.840.113556.1.3 +4:2.16.840.1.101.2.2.1 +5:2.16.840.1.101.2.2.3 +6:2.16.840.1.101.2.1.5 +7:2.16.840.1.101.2.1.4 +8:2.5.5 +9:1.2.840.113556.1.4 +10:1.2.840.113556.1.5 +19:0.9.2342.19200300.100 +20:2.16.840.1.113730.3 +21:0.9.2342.19200300.100.1 +22:2.16.840.1.113730.3.1 +23:1.2.840.113556.1.5.7000 +24:2.5.21 +25:2.5.18 +26:2.5.20 +11:1.2.840.113556.1.4.260 +12:1.2.840.113556.1.5.56 +13:1.2.840.113556.1.4.262 +14:1.2.840.113556.1.5.57 +15:1.2.840.113556.1.4.263 +16:1.2.840.113556.1.5.58 +17:1.2.840.113556.1.5.73 +18:1.2.840.113556.1.4.305 +27:1.3.6.1.4.1.1466.101.119 +28:2.16.840.1.113730.3.2 +29:1.3.6.1.4.1.250.1 +30:1.2.840.113549.1.9 +31:0.9.2342.19200300.100.4 +32:1.3.6.1.4.1.7165.4.1 +33:1.3.6.1.4.1.7165.4.2 diff --git a/source4/setup/provision_schema_basedn_modify.ldif b/source4/setup/provision_schema_basedn_modify.ldif index 4e8267a303..d6c458904e 100644 --- a/source4/setup/provision_schema_basedn_modify.ldif +++ b/source4/setup/provision_schema_basedn_modify.ldif @@ -10,19 +10,5 @@ replace: objectVersion objectVersion: 30 - replace: prefixMap -prefixMap:: QkRTRAAAAAAiAAAAAAACACIAAAAAAAAAAgAAAAQAAgABAAAAAgAAAAgAAgACAAAACA - AAAAwAAgADAAAACAAAABAAAgAEAAAACAAAABQAAgAFAAAACAAAABgAAgAGAAAACAAAABwAAgAHAAA - ACAAAACAAAgAIAAAAAgAAACQAAgAJAAAACAAAACgAAgAKAAAACAAAACwAAgATAAAACAAAADAAAgAU - AAAACAAAADQAAgAVAAAACQAAADgAAgAWAAAACQAAADwAAgAXAAAACgAAAEAAAgAYAAAAAgAAAEQAA - gAZAAAAAgAAAEgAAgAaAAAAAgAAAEwAAgALAAAACgAAAFAAAgAMAAAACQAAAFQAAgANAAAACgAAAF - gAAgAOAAAACQAAAFwAAgAPAAAACgAAAGAAAgAQAAAACQAAAGQAAgARAAAACQAAAGgAAgASAAAACgA - AAGwAAgAbAAAACQAAAHAAAgAcAAAACQAAAHQAAgAdAAAACAAAAHgAAgAeAAAACAAAAHwAAgAfAAAA - CQAAAIAAAgAgAAAACQAAAIQAAgAhAAAACQAAAIgAAgACAAAAVQQAAAIAAABVBgAACAAAACqGSIb3F - AECCAAAACqGSIb3FAEDCAAAAGCGSAFlAgIBCAAAAGCGSAFlAgIDCAAAAGCGSAFlAgEFCAAAAGCGSA - FlAgEEAgAAAFUFAAAIAAAAKoZIhvcUAQQIAAAAKoZIhvcUAQUIAAAACZImiZPyLGQIAAAAYIZIAYb - 4QgMJAAAACZImiZPyLGQBAAAACQAAAGCGSAGG+EIDAQAAAAoAAAAqhkiG9xQBBbZYAAACAAAAVRUA - AAIAAABVEgAAAgAAAFUUAAAKAAAAKoZIhvcUAQSCBAAACQAAACqGSIb3FAEFOAAAAAoAAAAqhkiG9 - xQBBIIGAAAJAAAAKoZIhvcUAQU5AAAACgAAACqGSIb3FAEEggcAAAkAAAAqhkiG9xQBBToAAAAJAA - AAKoZIhvcUAQVJAAAACgAAACqGSIb3FAEEgjEAAAkAAAArBgEEAYs6ZXcAAAAJAAAAYIZIAYb4QgM - CAAAACAAAACsGAQQBgXoBCAAAACqGSIb3DQEJCQAAAAmSJomT8ixkBAAAAAkAAAArBgEEAbd9BAEA - AAAJAAAAKwYBBAG3fQQC +prefixMap:: ${PREFIXMAP_B64} + |