From 410115bb6b8e9674c9779fc9bc5d1cb7022bebcf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 May 2008 11:02:40 +1000 Subject: Cope with an empty mapping file in ad2oLschema (This used to be commit 5f36a605a9accfba1125bbae0e79bb14b936173c) --- source4/lib/ldb/tools/ad2oLschema.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c index 67b16dd06e..0a89656fa2 100644 --- a/source4/lib/ldb/tools/ad2oLschema.c +++ b/source4/lib/ldb/tools/ad2oLschema.c @@ -429,7 +429,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ /* We might have been asked to remap this oid, * due to a conflict, or lack of * implementation */ - for (j=0; syntax_oid && oid_map[j].old_oid; j++) { + for (j=0; syntax_oid && oid_map && oid_map[j].old_oid; j++) { if (strcasecmp(syntax_oid, oid_map[j].old_oid) == 0) { syntax_oid = oid_map[j].new_oid; break; @@ -494,7 +494,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } /* We might have been asked to remap this oid, due to a conflict */ - for (j=0; oid_map[j].old_oid; j++) { + for (j=0; oid_map && oid_map[j].old_oid; j++) { if (strcasecmp(oid, oid_map[j].old_oid) == 0) { oid = oid_map[j].new_oid; break; -- cgit From ff7c537e278194453311ce9a310a8e24cb410d32 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 May 2008 09:46:50 +1000 Subject: Remove JavaScript provision-backend script The library it relied on has already been removed. Andrew Bartlett (This used to be commit 97427731a520283fdd3c8e582ac1f8be7699013e) --- source4/setup/provision-backend.js | 188 ------------------------------------- 1 file changed, 188 deletions(-) delete mode 100644 source4/setup/provision-backend.js diff --git a/source4/setup/provision-backend.js b/source4/setup/provision-backend.js deleted file mode 100644 index 9482d8c435..0000000000 --- a/source4/setup/provision-backend.js +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/sh -exec smbscript "$0" ${1+"$@"} -/* - provision a Samba4 server - Copyright Andrew Tridgell 2005 - Released under the GNU GPL version 3 or later -*/ - -options = GetOptions(ARGV, - "POPT_AUTOHELP", - "POPT_COMMON_SAMBA", - "POPT_COMMON_VERSION", - "POPT_COMMON_CREDENTIALS", - 'realm=s', - 'host-name=s', - 'ldap-manager-pass=s', - 'root=s', - 'quiet', - 'ldap-backend-type=s', - 'ldap-backend-port=i'); - -if (options == undefined) { - println("Failed to parse options"); - return -1; -} - -sys = sys_init(); - -libinclude("base.js"); -libinclude("provision.js"); - -/* - print a message if quiet is not set -*/ -function message() -{ - if (options["quiet"] == undefined) { - print(vsprintf(arguments)); - } -} - -/* - show some help -*/ -function ShowHelp() -{ - print(" -Samba4 provisioning - -provision [options] - --realm REALM set realm - --host-name HOSTNAME set hostname - --ldap-manager-pass PASSWORD choose LDAP Manager password (otherwise random) - --root USERNAME choose 'root' unix username - --quiet Be quiet - --ldap-backend-type LDAPSERVER Select either \"openldap\" or \"fedora-ds\" as a target to configure - --ldap-backend-port PORT Select the TCP port (if any) that the LDAP backend should listen on (Fedora DS only) -You must provide at least a realm and ldap-backend-type - -"); - exit(1); -} - -if (options['host-name'] == undefined) { - options['host-name'] = hostname(); -} - -/* - main program -*/ -if (options["realm"] == undefined || - options["ldap-backend-type"] == undefined || - options["host-name"] == undefined) { - ShowHelp(); -} - -/* cope with an initially blank smb.conf */ -var lp = loadparm_init(); -lp.set("realm", options.realm); -lp.reload(); - -var subobj = provision_guess(); -for (r in options) { - var key = strupper(join("", split("-", r))); - subobj[key] = options[r]; -} - - - -var paths = provision_default_paths(subobj); -provision_fix_subobj(subobj, paths); -message("Provisioning LDAP backend for %s in realm %s into %s\n", subobj.HOSTNAME, subobj.REALM, subobj.LDAPDIR); -message("Using %s password: %s\n", subobj.LDAPMANAGERDN, subobj.LDAPMANAGERPASS); -var tmp_schema_ldb = subobj.LDAPDIR + "/schema-tmp.ldb"; -sys.mkdir(subobj.LDAPDIR, 0700); - -provision_schema(subobj, message, tmp_schema_ldb, paths); - -var mapping; -var backend_schema; -var slapd_command; -if (options["ldap-backend-type"] == "fedora-ds") { - mapping = "schema-map-fedora-ds-1.0"; - backend_schema = "99_ad.ldif"; - if (options["ldap-backend-port"] != undefined) { - message("Will listen on TCP port " + options["ldap-backend-port"] + "\n"); - subobj.SERVERPORT="ServerPort = " + options["ldap-backend-port"]; - } else { - message("Will listen on LDAPI only\n"); - subobj.SERVERPORT=""; - } - setup_file("fedorads.inf", message, subobj.LDAPDIR + "/fedorads.inf", subobj); - setup_file("fedorads-partitions.ldif", message, subobj.LDAPDIR + "/fedorads-partitions.ldif", subobj); - - slapd_command = "(see documentation)"; -} else if (options["ldap-backend-type"] == "openldap") { - mapping = "schema-map-openldap-2.3"; - backend_schema = "backend-schema.schema"; - setup_file("slapd.conf", message, subobj.LDAPDIR + "/slapd.conf", subobj); - setup_file("modules.conf", message, subobj.LDAPDIR + "/modules.conf", subobj); - sys.mkdir(subobj.LDAPDIR + "/db", 0700); - subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/user"; - sys.mkdir(subobj.LDAPDBDIR, 0700); - sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700); - sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700); - setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj); - subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/config"; - sys.mkdir(subobj.LDAPDBDIR, 0700); - sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700); - sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700); - setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj); - subobj.LDAPDBDIR = subobj.LDAPDIR + "/db/schema"; - sys.mkdir(subobj.LDAPDBDIR, 0700); - sys.mkdir(subobj.LDAPDBDIR + "/tmp", 0700); - sys.mkdir(subobj.LDAPDBDIR + "/bdb-logs", 0700); - setup_file("DB_CONFIG", message, subobj.LDAPDBDIR + "/DB_CONFIG", subobj); - if (options["ldap-backend-port"] != undefined) { - message("\nStart slapd with: \n"); - slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h \"ldap://0.0.0.0:" + options["ldap-backend-port"] + " " + subobj.LDAPI_URI "\""; - } else { - slapd_command = "slapd -f " + subobj.LDAPDIR + "/slapd.conf -h " + subobj.LDAPI_URI; - } - - var ldb = ldb_init(); - ldb.filename = tmp_schema_ldb; - - var connect_ok = ldb.connect(ldb.filename); - assert(connect_ok); - var attrs = new Array("linkID", "lDAPDisplayName"); - var res = ldb.search("(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", subobj.SCHEMADN, ldb.SCOPE_SUBTREE, attrs); - assert(res.error == 0); - var memberof_config = ""; - var refint_attributes = ""; - for (i=0; i < res.msgs.length; i++) { - var target = searchone(ldb, subobj.SCHEMADN, "(&(objectclass=attributeSchema)(linkID=" + (res.msgs[i].linkID + 1) + "))", "lDAPDisplayName"); - if (target != undefined) { - refint_attributes = refint_attributes + " " + target + " " + res.msgs[i].lDAPDisplayName; - memberof_config = memberof_config + "overlay memberof -memberof-dangling error -memberof-refint TRUE -memberof-group-oc top -memberof-member-ad " + res.msgs[i].lDAPDisplayName + " -memberof-memberof-ad " + target + " -memberof-dangling-error 32 - -"; - } - } - - memberof_config = memberof_config + " -overlay refint -refint_attributes" + refint_attributes + " -"; - - ok = sys.file_save(subobj.LDAPDIR + "/memberof.conf", memberof_config); - if (!ok) { - message("failed to create file: " + f + "\n"); - assert(ok); - } - -} -var schema_command = "ad2oLschema --option=convert:target=" + options["ldap-backend-type"] + " -I " + lp.get("setup directory") + "/" + mapping + " -H tdb://" + tmp_schema_ldb + " -O " + subobj.LDAPDIR + "/" + backend_schema; - -message("\nCreate a suitable schema file with:\n%s\n", schema_command); -message("\nStart slapd with: \n%s\n", slapd_command); - -message("All OK\n"); -return 0; -- cgit From 58e7f253eafecca6934162034e88ee19b103c6ee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 16 May 2008 13:03:01 +1000 Subject: Rework the CLDAP and NBT netlogon requests and responses. This now matches section 7.3.3 of the MS-ATDS specification, and all our current tests pass against windows. There is still more testing to do, and the server implementation to complete. Andrew Bartlett (This used to be commit 431d0c03965cbee85691cd0dc1e2a509c1a2b717) --- source4/libcli/cldap/cldap.c | 35 ++-- source4/libcli/cldap/cldap.h | 7 +- source4/libcli/config.mk | 13 +- source4/libcli/dgram/libdgram.h | 21 +-- source4/libcli/dgram/netlogon.c | 22 +-- source4/libcli/dgram/ntlogon.c | 128 -------------- source4/libnet/libnet_become_dc.c | 24 +-- source4/libnet/libnet_site.c | 7 +- source4/libnet/libnet_unbecome_dc.c | 21 +-- source4/librpc/config.mk | 2 +- source4/librpc/idl/nbt.idl | 325 +++++++++++++++--------------------- source4/torture/ldap/cldap.c | 67 ++++---- source4/torture/nbt/dgram.c | 68 +++----- source4/torture/rpc/dssync.c | 7 +- 14 files changed, 264 insertions(+), 483 deletions(-) delete mode 100644 source4/libcli/dgram/ntlogon.c diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 614bd51d2a..3867f3d3fd 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -595,7 +595,6 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_search search; struct cldap_socket *cldap; DATA_BLOB *data; @@ -618,18 +617,15 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - ndr_err = ndr_pull_union_blob_all(data, mem_ctx, - cldap->iconv_convenience, - &io->out.netlogon, - io->in.version & 0xF, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", - SVAL(data->data, 0))); - dump_data(10, data->data, data->length); - return ndr_map_error2ntstatus(ndr_err); + status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience, + &io->out.netlogon); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (io->in.map_response) { + map_netlogon_samlogon_response(&io->out.netlogon); } - return NT_STATUS_OK; } @@ -704,25 +700,20 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon) + struct netlogon_samlogon_response *netlogon) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_reply reply; struct ldap_SearchResEntry response; struct ldap_Result result; TALLOC_CTX *tmp_ctx = talloc_new(cldap); DATA_BLOB blob; - ndr_err = ndr_push_union_blob(&blob, tmp_ctx, - cldap->iconv_convenience, - netlogon, version & 0xF, - (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } + status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience, + netlogon); + if (!NT_STATUS_IS_OK(status)) { + } reply.messageid = message_id; reply.dest = src; reply.response = &response; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index eb0191d0f4..7c2daf0ca2 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -20,7 +20,7 @@ */ #include "lib/util/asn1.h" -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" struct ldap_message; @@ -161,9 +161,10 @@ struct cldap_netlogon { const char *domain_sid; int acct_control; uint32_t version; + bool map_response; } in; struct { - union nbt_cldap_netlogon netlogon; + struct netlogon_samlogon_response netlogon; } out; }; @@ -178,4 +179,4 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon); + struct netlogon_samlogon_response *netlogon); diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 95b45003be..08c08043a6 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -53,6 +53,14 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix libcli/nbt/, \ namerefresh.o \ namerelease.o) +[SUBSYSTEM::LIBCLI_NETLOGON] +PRIVATE_PROTO_HEADER = netlogon_proto.h +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ + NDR_SECURITY LIBSAMBA-UTIL + +LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ + netlogon.o) + [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG @@ -66,18 +74,17 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = libcli/swig/libcli_smb_wrap.o [SUBSYSTEM::LIBCLI_DGRAM] -PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE +PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON LIBCLI_DGRAM_OBJ_FILES = $(addprefix libcli/dgram/, \ dgramsocket.o \ mailslot.o \ netlogon.o \ - ntlogon.o \ browse.o) [SUBSYSTEM::LIBCLI_CLDAP] PUBLIC_DEPENDENCIES = LIBCLI_LDAP -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON LIBCLI_CLDAP_OBJ_FILES = libcli/cldap/cldap.o # PUBLIC_HEADERS += libcli/cldap/cldap.h diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 707cca8cc5..3eac78f5e8 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" /* a datagram name request @@ -121,6 +121,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot_name, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, @@ -131,23 +132,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon); - -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request); -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply); -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon); + struct nbt_netlogon_response *netlogon); NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 5c7dedc7bb..c097127083 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -32,6 +32,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -51,7 +52,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - NBT_MAILSLOT_NETLOGON, + mailslot, dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); @@ -109,21 +110,16 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon) + struct nbt_netlogon_response *netlogon) { + NTSTATUS status; DATA_BLOB data = dgram_mailslot_data(dgram); - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", - (int)data.length, nt_errstr(status))); - if (DEBUGLVL(10)) { - file_save("netlogon.dat", data.data, data.length); - } + + status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon); + if (!NT_STATUS_IS_OK(status)) { return status; } + return NT_STATUS_OK; } + diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c deleted file mode 100644 index 7b26ed7c00..0000000000 --- a/source4/libcli/dgram/ntlogon.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - handling for ntlogon dgram requests - - Copyright (C) Andrew Tridgell 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 . -*/ - -#include "includes.h" -#include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "libcli/resolve/resolve.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -/* - send a ntlogon mailslot request -*/ -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - - status = dgram_mailslot_send(dgmsock, msg_type, - NBT_MAILSLOT_NTLOGON, - dest_name, dest, - src_name, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - send a ntlogon mailslot reply -*/ -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - struct nbt_name myname; - struct socket_address *dest; - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - make_nbt_name_client(&myname, my_netbios_name); - - dest = socket_address_from_strings(tmp_ctx, - dgmsock->sock->backend_name, - request->src_addr, request->src_port); - if (!dest) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - - status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - mailslot_name, - &request->data.msg.source_name, - dest, - &myname, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - parse a ntlogon response. The packet must be a valid mailslot packet -*/ -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon) -{ - DATA_BLOB data = dgram_mailslot_data(dgram); - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n", - (int)data.length, nt_errstr(status))); - if (DEBUGLVL(10)) { - file_save("ntlogon.dat", data.data, data.length); - } - return status; - } - return NT_STATUS_OK; -} diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index e8a5329985..1c4c1d0732 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -30,6 +30,7 @@ #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_misc.h" #include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_nbt.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "auth/gensec/gensec.h" #include "param/param.h" @@ -687,7 +688,7 @@ struct libnet_BecomeDC_state { struct { struct cldap_socket *sock; struct cldap_netlogon io; - struct nbt_cldap_netlogon_5 netlogon5; + struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon; } cldap; struct becomeDC_ldap { @@ -745,7 +746,8 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s) s->cldap.io.in.domain_guid = NULL; s->cldap.io.in.domain_sid = NULL; s->cldap.io.in.acct_control = -1; - s->cldap.io.in.version = 6; + s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + s->cldap.io.in.map_response = true; s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx, lp_iconv_convenience(s->libnet->lp_ctx)); @@ -768,19 +770,19 @@ static void becomeDC_recv_cldap(struct cldap_request *req) c->status = cldap_netlogon_recv(req, s, &s->cldap.io); if (!composite_is_ok(c)) return; - s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5; + s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex; - s->domain.dns_name = s->cldap.netlogon5.dns_domain; - s->domain.netbios_name = s->cldap.netlogon5.domain; - s->domain.guid = s->cldap.netlogon5.domain_uuid; + s->domain.dns_name = s->cldap.netlogon.dns_domain; + s->domain.netbios_name = s->cldap.netlogon.domain; + s->domain.guid = s->cldap.netlogon.domain_uuid; - s->forest.dns_name = s->cldap.netlogon5.forest; + s->forest.dns_name = s->cldap.netlogon.forest; - s->source_dsa.dns_name = s->cldap.netlogon5.pdc_dns_name; - s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name; - s->source_dsa.site_name = s->cldap.netlogon5.server_site; + s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name; + s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name; + s->source_dsa.site_name = s->cldap.netlogon.server_site; - s->dest_dsa.site_name = s->cldap.netlogon5.client_site; + s->dest_dsa.site_name = s->cldap.netlogon.client_site; becomeDC_connect_ldap1(s); } diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c index f39d9e039c..bb65de1f54 100644 --- a/source4/libnet/libnet_site.c +++ b/source4/libnet/libnet_site.c @@ -53,11 +53,12 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li search.in.dest_address = r->in.dest_address; search.in.dest_port = r->in.cldap_port; search.in.acct_control = -1; - search.in.version = 6; + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + search.in.map_response = true; cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(global_loadparm)); status = cldap_netlogon(cldap, tmp_ctx, &search); - if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_IS_OK(status) || !search.out.netlogon.nt5_ex.client_site) { /* If cldap_netlogon() returns in error, default to using Default-First-Site-Name. @@ -71,7 +72,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li } } else { site_name_str = talloc_asprintf(tmp_ctx, "%s", - search.out.netlogon.logon5.client_site); + search.out.netlogon.nt5_ex.client_site); if (!site_name_str) { r->out.error_string = NULL; talloc_free(tmp_ctx); diff --git a/source4/libnet/libnet_unbecome_dc.c b/source4/libnet/libnet_unbecome_dc.c index 6f06585880..cff919018a 100644 --- a/source4/libnet/libnet_unbecome_dc.c +++ b/source4/libnet/libnet_unbecome_dc.c @@ -193,7 +193,7 @@ struct libnet_UnbecomeDC_state { struct { struct cldap_socket *sock; struct cldap_netlogon io; - struct nbt_cldap_netlogon_5 netlogon5; + struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon; } cldap; struct { @@ -265,7 +265,8 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s) s->cldap.io.in.domain_guid = NULL; s->cldap.io.in.domain_sid = NULL; s->cldap.io.in.acct_control = -1; - s->cldap.io.in.version = 6; + s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + s->cldap.io.in.map_response = true; s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx, lp_iconv_convenience(s->libnet->lp_ctx)); @@ -288,17 +289,17 @@ static void unbecomeDC_recv_cldap(struct cldap_request *req) c->status = cldap_netlogon_recv(req, s, &s->cldap.io); if (!composite_is_ok(c)) return; - s->cldap.netlogon5 = s->cldap.io.out.netlogon.logon5; + s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex; - s->domain.dns_name = s->cldap.netlogon5.dns_domain; - s->domain.netbios_name = s->cldap.netlogon5.domain; - s->domain.guid = s->cldap.netlogon5.domain_uuid; + s->domain.dns_name = s->cldap.netlogon.dns_domain; + s->domain.netbios_name = s->cldap.netlogon.domain; + s->domain.guid = s->cldap.netlogon.domain_uuid; - s->source_dsa.dns_name = s->cldap.netlogon5.pdc_dns_name; - s->source_dsa.netbios_name = s->cldap.netlogon5.pdc_name; - s->source_dsa.site_name = s->cldap.netlogon5.server_site; + s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name; + s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name; + s->source_dsa.site_name = s->cldap.netlogon.server_site; - s->dest_dsa.site_name = s->cldap.netlogon5.client_site; + s->dest_dsa.site_name = s->cldap.netlogon.client_site; unbecomeDC_connect_ldap(s); } diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 24fad8c9c4..0b136644d8 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -325,7 +325,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT NDR_SCHANNEL_OBJ_FILES = librpc/gen_ndr/ndr_schannel.o [SUBSYSTEM::NDR_NBT] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR NDR_NBT_OBJ_FILES = librpc/gen_ndr/ndr_nbt.o diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl index dddfa4e1ce..74e07210cd 100644 --- a/source4/librpc/idl/nbt.idl +++ b/source4/librpc/idl/nbt.idl @@ -8,7 +8,7 @@ encoding if it doesn't work out */ -import "misc.idl", "security.idl", "svcctl.idl"; +import "misc.idl", "security.idl", "svcctl.idl", "samr.idl"; [ helper("libcli/nbt/libnbt.h") ] @@ -338,52 +338,19 @@ interface nbt } nbt_dgram_packet; - /*******************************************/ - /* \MAILSLOT\NET\NETLOGON mailslot requests */ - typedef enum { - NETLOGON_QUERY_FOR_PDC = 0x7, - NETLOGON_ANNOUNCE_UAS = 0xa, - NETLOGON_RESPONSE_FROM_PDC = 0xc, - NETLOGON_QUERY_FOR_PDC2 = 0x12, - NETLOGON_RESPONSE_FROM_PDC2 = 0x17, - NETLOGON_RESPONSE_FROM_PDC_USER = 0x19 - } nbt_netlogon_command; - - /* query for pdc request */ - typedef struct { - astring computer_name; - astring mailslot_name; - [flag(NDR_ALIGN2)] DATA_BLOB _pad; - nstring unicode_name; - uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_netlogon_query_for_pdc; - - /* query for pdc request - new style */ - typedef struct { - uint16 request_count; - nstring computer_name; - nstring user_name; - astring mailslot_name; - uint32 unknown[2]; - uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_netlogon_query_for_pdc2; + /****************************************** + * \MAILSLOT\NET\NETLOGON mailslot requests + * and + * \MAILSLOT\NET\NTLOGON mailslot requests + */ - /* response from pdc */ - typedef struct { - astring pdc_name; - [flag(NDR_ALIGN2)] DATA_BLOB _pad; - nstring unicode_pdc_name; - nstring domain_name; - uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_netlogon_response_from_pdc; + typedef [public,gensize] struct { + uint32 sa_family; + [flag(NDR_BIG_ENDIAN)] ipv4address pdc_ip; + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } nbt_sockaddr; - typedef [bitmap32bit] bitmap { + typedef [bitmap32bit,public] bitmap { NBT_SERVER_PDC = 0x00000001, NBT_SERVER_GC = 0x00000004, NBT_SERVER_LDAP = 0x00000008, @@ -395,107 +362,81 @@ interface nbt NBT_SERVER_GOOD_TIMESERV = 0x00000200 } nbt_server_type; - /* response from pdc - type2 */ - typedef struct { - [flag(NDR_ALIGN4)] DATA_BLOB _pad; - nbt_server_type server_type; - GUID domain_uuid; - nbt_string forest; - nbt_string dns_domain; - nbt_string pdc_dns_name; - nbt_string domain; - nbt_string pdc_name; - nbt_string user_name; - nbt_string server_site; - nbt_string client_site; - uint8 unknown; - uint32 unknown2; - [flag(NDR_BIG_ENDIAN)] - ipv4address pdc_ip; - uint32 unknown3[2]; - uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_netlogon_response_from_pdc2; - - typedef enum netr_SamDatabaseID netr_SamDatabaseID; - - /* announce change to UAS or SAM */ - typedef struct { - netr_SamDatabaseID db_index; - hyper serial; - NTTIME timestamp; - } nbt_db_change; + typedef [bitmap32bit,public] bitmap { + NETLOGON_NT_VERSION_1 = 0x00000001, + NETLOGON_NT_VERSION_5 = 0x00000002, + NETLOGON_NT_VERSION_5EX = 0x00000004, + NETLOGON_NT_VERSION_5EX_WITH_IP = 0x00000008, + NETLOGON_NT_VERSION_WITH_CLOSEST_SITE = 0x00000010, + NETLOGON_NT_VERSION_AVIOD_NT4EMUL = 0x01000000, + NETLOGON_NT_VERSION_PDC = 0x10000000, + NETLOGON_NT_VERSION_IP = 0x20000000, + NETLOGON_NT_VERSION_LOCAL = 0x40000000, + NETLOGON_NT_VERSION_GC = 0x80000000 + } netlogon_nt_version_flags; + + + typedef [enum16bit,public] enum { + LOGON_PRIMARY_QUERY = 7, /* Was also NETLOGON_QUERY_FOR_PDC */ + NETLOGON_ANNOUNCE_UAS = 10, + NETLOGON_RESPONSE_FROM_PDC = 12, + LOGON_SAM_LOGON_REQUEST = 18, /* Was also NETLOGON_QUERY_FOR_PDC2, NTLOGON_SAM_LOGON */ + LOGON_SAM_LOGON_RESPONSE = 19, /* Was also NTLOGON_SAM_LOGON_REPLY */ + LOGON_SAM_LOGON_PAUSE_RESPONSE = 20, + LOGON_SAM_LOGON_USER_UNKNOWN = 21, /* Was also NTLOGON_SAM_LOGON_REPLY15 */ + LOGON_SAM_LOGON_RESPONSE_EX = 23, /* was NETLOGON_RESPONSE_FROM_PDC2 */ + LOGON_SAM_LOGON_PAUSE_RESPONSE_EX = 24, + LOGON_SAM_LOGON_USER_UNKNOWN_EX = 25 /* was NETLOGON_RESPONSE_FROM_PDC_USER */ + } netlogon_command; + + typedef bitmap samr_AcctFlags samr_AcctFlags; - /* used to announce SAM changes */ typedef struct { - uint32 serial_lo; - time_t timestamp; - uint32 pulse; - uint32 random; - astring pdc_name; - astring domain; - [flag(NDR_ALIGN2)] DATA_BLOB _pad; - nstring unicode_pdc_name; - nstring unicode_domain; - uint32 db_count; - nbt_db_change dbchange[db_count]; + uint16 request_count; + nstring computer_name; + nstring user_name; + astring mailslot_name; + samr_AcctFlags acct_control; [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; - uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_netlogon_announce_uas; - - typedef [nodiscriminant] union { - [case(NETLOGON_QUERY_FOR_PDC)] nbt_netlogon_query_for_pdc pdc; - [case(NETLOGON_QUERY_FOR_PDC2)] nbt_netlogon_query_for_pdc2 pdc2; - [case(NETLOGON_ANNOUNCE_UAS)] nbt_netlogon_announce_uas uas; - [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response; - [case(NETLOGON_RESPONSE_FROM_PDC2)] nbt_netlogon_response_from_pdc2 response2; - [case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2; - } nbt_netlogon_request; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_REQUEST; typedef [flag(NDR_NOALIGN),public] struct { - nbt_netlogon_command command; - [switch_is(command)] nbt_netlogon_request req; - } nbt_netlogon_packet; - - /*******************************************/ - /* CLDAP netlogon response */ - - /* note that these structures are very similar to, but not - quite identical to, the netlogon structures above */ - - typedef struct { - uint16 type; - nstring pdc_name; + netlogon_command command; + nstring server; nstring user_name; - nstring domain_name; - [value(1)] uint32 nt_version; + nstring domain; + netlogon_nt_version_flags nt_version; uint16 lmnt_token; - uint16 lm20_token; - } nbt_cldap_netlogon_1; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_RESPONSE_NT40; - typedef struct { - uint16 type; + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; nstring pdc_name; nstring user_name; nstring domain_name; GUID domain_uuid; - GUID unknown_uuid; + GUID zero_uuid; nbt_string forest; nbt_string dns_domain; nbt_string pdc_dns_name; ipv4address pdc_ip; nbt_server_type server_type; - [value(3)] uint32 nt_version; + netlogon_nt_version_flags nt_version; uint16 lmnt_token; uint16 lm20_token; - } nbt_cldap_netlogon_3; + } NETLOGON_SAM_LOGON_RESPONSE; - typedef struct { - uint32 type; + /* response from pdc hand marshaled (we have an additional + * function that uses this structure), as it has 'optional' + * parts */ + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + uint16 sbz; /* From the docs */ nbt_server_type server_type; GUID domain_uuid; nbt_string forest; @@ -506,85 +447,91 @@ interface nbt nbt_string user_name; nbt_string server_site; nbt_string client_site; - [value(5)] uint32 nt_version; - uint16 lmnt_token; - uint16 lm20_token; - } nbt_cldap_netlogon_5; - typedef struct { - uint32 type; - nbt_server_type server_type; - GUID domain_uuid; - nbt_string forest; - nbt_string dns_domain; - nbt_string pdc_dns_name; - nbt_string domain; - nbt_string pdc_name; - nbt_string user_name; - nbt_string server_site; - nbt_string client_site; - uint8 unknown; - uint32 unknown2; - [flag(NDR_BIG_ENDIAN)] - ipv4address pdc_ip; - uint32 unknown3[2]; - [value(13)] uint32 nt_version; + /* Optional on NETLOGON_NT_VERSION_5EX_WITH_IP */ + [value(ndr_size_nbt_sockaddr(&sockaddr, ndr->flags))] uint8 sockaddr_size; + [subcontext(0),subcontext_size(sockaddr_size)] nbt_sockaddr sockaddr; + + /* Optional on NETLOGON_NT_VERSION_WITH_CLOSEST_SITE */ + nbt_string next_closest_site; + + netlogon_nt_version_flags nt_version; uint16 lmnt_token; uint16 lm20_token; - } nbt_cldap_netlogon_13; - - typedef [flag(NDR_NOALIGN),public,nodiscriminant] union { - [case(0)] nbt_cldap_netlogon_1 logon1; - [case(1)] nbt_cldap_netlogon_1 logon1; - [case(2)] nbt_cldap_netlogon_3 logon3; - [case(3)] nbt_cldap_netlogon_3 logon3; - [case(4)] nbt_cldap_netlogon_5 logon5; - [case(5)] nbt_cldap_netlogon_5 logon5; - [case(6)] nbt_cldap_netlogon_5 logon5; - [case(7)] nbt_cldap_netlogon_5 logon5; - [default] nbt_cldap_netlogon_13 logon13; - } nbt_cldap_netlogon; - - /*******************************************/ - /* \MAILSLOT\NET\NTLOGON mailslot requests */ - typedef enum { - NTLOGON_SAM_LOGON = 0x12, - NTLOGON_SAM_LOGON_REPLY = 0x13, - NTLOGON_SAM_LOGON_REPLY15 = 0x15 - } nbt_ntlogon_command; + } NETLOGON_SAM_LOGON_RESPONSE_EX; + /* query for pdc request */ typedef struct { - uint16 request_count; - nstring computer_name; - nstring user_name; + astring computer_name; astring mailslot_name; - uint32 acct_control; - [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; - [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; - uint32 nt_version; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_name; + netlogon_nt_version_flags nt_version; uint16 lmnt_token; uint16 lm20_token; - } nbt_ntlogon_sam_logon; + } nbt_netlogon_query_for_pdc; - typedef struct { - nstring server; - nstring user_name; - nstring domain; - uint32 nt_version; + /* response from pdc */ + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + astring pdc_name; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_pdc_name; + nstring domain_name; + netlogon_nt_version_flags nt_version; uint16 lmnt_token; uint16 lm20_token; - } nbt_ntlogon_sam_logon_reply; + } nbt_netlogon_response_from_pdc; + + typedef enum netr_SamDatabaseID netr_SamDatabaseID; + + /* used to announce SAM changes - MS-NRPC 2.2.1.5.1 */ + typedef struct { + netr_SamDatabaseID db_index; + hyper serial; + NTTIME timestamp; + } nbt_db_change_info; + + typedef struct { + uint32 serial_lo; + time_t timestamp; + uint32 pulse; + uint32 random; + astring pdc_name; + astring domain; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_pdc_name; + nstring unicode_domain; + uint32 db_count; + nbt_db_change_info dbchange[db_count]; + [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; + [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; + uint32 message_format_version; + uint32 message_token; + } NETLOGON_DB_CHANGE; typedef [nodiscriminant] union { - [case(NTLOGON_SAM_LOGON)] nbt_ntlogon_sam_logon logon; - [case(NTLOGON_SAM_LOGON_REPLY)] nbt_ntlogon_sam_logon_reply reply; - [case(NTLOGON_SAM_LOGON_REPLY15)] nbt_ntlogon_sam_logon_reply reply; - } nbt_ntlogon_request; + [case(LOGON_SAM_LOGON_REQUEST)] NETLOGON_SAM_LOGON_REQUEST logon; + [case(LOGON_PRIMARY_QUERY)] nbt_netlogon_query_for_pdc pdc; + [case(NETLOGON_ANNOUNCE_UAS)] NETLOGON_DB_CHANGE uas; + } nbt_netlogon_request; + +#if 0 + [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response; + [case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2; + + [case(LOGON_SAM_LOGON_PAUSE_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_USER_UNKNOWN)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; + [case(LOGON_SAM_LOGON_PAUSE_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; + [case(LOGON_SAM_LOGON_USER_UNKNOWN_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; +#endif typedef [flag(NDR_NOALIGN),public] struct { - nbt_ntlogon_command command; - [switch_is(command)] nbt_ntlogon_request req; - } nbt_ntlogon_packet; + netlogon_command command; + [switch_is(command)] nbt_netlogon_request req; + } nbt_netlogon_packet; /********************************************************/ /* \MAILSLOT\BROWSE mailslot requests */ diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index ca4d9b7705..bb77acd2d0 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -41,7 +41,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) struct cldap_socket *cldap; NTSTATUS status; struct cldap_netlogon search, empty_search; - union nbt_cldap_netlogon n1; + struct netlogon_samlogon_response n1; struct GUID guid; int i; @@ -51,7 +51,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.dest_address = dest; search.in.dest_port = lp_cldap_port(tctx->lp_ctx); search.in.acct_control = -1; - search.in.version = 6; + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + search.in.map_response = true; empty_search = search; @@ -63,7 +64,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) n1 = search.out.netlogon; search.in.user = "Administrator"; - search.in.realm = n1.logon5.dns_domain; + search.in.realm = n1.nt5_ex.dns_domain; search.in.host = "__cldap_torture__"; printf("Scanning for netlogon levels\n"); @@ -91,8 +92,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.user = NULL; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); printf("Trying with User=Administrator\n"); @@ -100,8 +101,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); search.in.version = 6; status = cldap_netlogon(cldap, tctx, &search); @@ -112,8 +113,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.user = NULL; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); printf("Trying with User=Administrator\n"); @@ -121,16 +122,16 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); printf("Trying with a GUID\n"); search.in.realm = NULL; - search.in.domain_guid = GUID_string(tctx, &n1.logon5.domain_uuid); + search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid); status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC_USER); - CHECK_STRING(GUID_string(tctx, &search.out.netlogon.logon5.domain_uuid), search.in.domain_guid); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); + CHECK_STRING(GUID_string(tctx, &search.out.netlogon.nt5_ex.domain_uuid), search.in.domain_guid); printf("Trying with a incorrect GUID\n"); guid = GUID_random(); @@ -141,15 +142,15 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) printf("Trying with a AAC\n"); search.in.acct_control = 0x180; - search.in.realm = n1.logon5.dns_domain; + search.in.realm = n1.nt5_ex.dns_domain; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); printf("Trying with a bad AAC\n"); search.in.acct_control = 0xFF00FF00; - search.in.realm = n1.logon5.dns_domain; + search.in.realm = n1.nt5_ex.dns_domain; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); @@ -158,15 +159,15 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) search.in.user = "Administrator"; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain); - CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user); + CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); printf("Trying with just a bad username\n"); search.in.user = "___no_such_user___"; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.user_name, search.in.user); - CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); + CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); printf("Trying with just a bad domain\n"); search = empty_search; @@ -175,29 +176,29 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_NOT_FOUND); printf("Trying with a incorrect domain and correct guid\n"); - search.in.domain_guid = GUID_string(tctx, &n1.logon5.domain_uuid); + search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid); status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); + CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); printf("Trying with a incorrect domain and incorrect guid\n"); search.in.domain_guid = GUID_string(tctx, &guid); status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_NOT_FOUND); - CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); + CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); printf("Trying with a incorrect GUID and correct domain\n"); search.in.domain_guid = GUID_string(tctx, &guid); - search.in.realm = n1.logon5.dns_domain; + search.in.realm = n1.nt5_ex.dns_domain; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_STRING(search.out.netlogon.logon5.dns_domain, n1.logon5.dns_domain); - CHECK_STRING(search.out.netlogon.logon5.user_name, ""); - CHECK_VAL(search.out.netlogon.logon5.type, NETLOGON_RESPONSE_FROM_PDC2); + CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); + CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); return true; } diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index a3585896eb..e039aac509 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -42,7 +42,7 @@ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct socket_address *src) { NTSTATUS status; - struct nbt_netlogon_packet netlogon; + struct nbt_netlogon_response netlogon; int *replies = (int *)dgmslot->private; printf("netlogon reply from %s:%d\n", src->addr, src->port); @@ -54,8 +54,6 @@ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, return; } - NDR_PRINT_DEBUG(nbt_netlogon_packet, &netlogon); - (*replies)++; } @@ -101,7 +99,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx) /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from - some windows versions won't be seen */ + most windows versions won't be seen */ status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { talloc_free(socket_address); @@ -117,7 +115,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx) netlogon_handler, &replies); ZERO_STRUCT(logon); - logon.command = NETLOGON_QUERY_FOR_PDC; + logon.command = LOGON_PRIMARY_QUERY; logon.req.pdc.computer_name = TEST_NAME; logon.req.pdc.mailslot_name = dgmslot->mailslot_name; logon.req.pdc.unicode_name = TEST_NAME; @@ -132,6 +130,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx) torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, + NBT_MAILSLOT_NETLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); @@ -200,14 +199,14 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) ZERO_STRUCT(logon); - logon.command = NETLOGON_QUERY_FOR_PDC2; - logon.req.pdc2.request_count = 0; - logon.req.pdc2.computer_name = TEST_NAME; - logon.req.pdc2.user_name = ""; - logon.req.pdc2.mailslot_name = dgmslot->mailslot_name; - logon.req.pdc2.nt_version = 11; - logon.req.pdc2.lmnt_token = 0xFFFF; - logon.req.pdc2.lm20_token = 0xFFFF; + logon.command = LOGON_SAM_LOGON_REQUEST; + logon.req.logon.request_count = 0; + logon.req.logon.computer_name = TEST_NAME; + logon.req.logon.user_name = ""; + logon.req.logon.mailslot_name = dgmslot->mailslot_name; + logon.req.logon.nt_version = 11; + logon.req.logon.lmnt_token = 0xFFFF; + logon.req.logon.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); @@ -216,6 +215,7 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, + NBT_MAILSLOT_NETLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); @@ -227,32 +227,6 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) } -/* - reply handler for ntlogon request -*/ -static void ntlogon_handler(struct dgram_mailslot_handler *dgmslot, - struct nbt_dgram_packet *packet, - struct socket_address *src) -{ - NTSTATUS status; - struct nbt_ntlogon_packet ntlogon; - int *replies = (int *)dgmslot->private; - - printf("ntlogon reply from %s:%d\n", src->addr, src->port); - - status = dgram_mailslot_ntlogon_parse(dgmslot, dgmslot, packet, &ntlogon); - if (!NT_STATUS_IS_OK(status)) { - printf("Failed to parse ntlogon packet from %s:%d\n", - src->addr, src->port); - return; - } - - NDR_PRINT_DEBUG(nbt_ntlogon_packet, &ntlogon); - - (*replies)++; -} - - /* test UDP/138 ntlogon requests */ static bool nbt_test_ntlogon(struct torture_context *tctx) { @@ -265,7 +239,7 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) const struct dom_sid *dom_sid; const char *myaddress; - struct nbt_ntlogon_packet logon; + struct nbt_netlogon_packet logon; struct nbt_name myname; NTSTATUS status; struct timeval tv = timeval_current(); @@ -296,7 +270,7 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from - some windows versions won't be seen */ + most windows versions won't be seen */ status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { talloc_free(socket_address); @@ -317,17 +291,17 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, - ntlogon_handler, &replies); + netlogon_handler, &replies); ZERO_STRUCT(logon); - logon.command = NTLOGON_SAM_LOGON; + logon.command = LOGON_SAM_LOGON_REQUEST; logon.req.logon.request_count = 0; logon.req.logon.computer_name = TEST_NAME; logon.req.logon.user_name = TEST_NAME"$"; logon.req.logon.mailslot_name = dgmslot->mailslot_name; logon.req.logon.acct_control = ACB_WSTRUST; - logon.req.logon.sid = *dom_sid; + /* Leave sid as all zero */ logon.req.logon.nt_version = 1; logon.req.logon.lmnt_token = 0xFFFF; logon.req.logon.lm20_token = 0xFFFF; @@ -337,8 +311,10 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lp_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); - status = dgram_mailslot_ntlogon_send(dgmsock, DGRAM_DIRECT_UNIQUE, - &name, dest, &myname, &logon); + status = dgram_mailslot_netlogon_send(dgmsock, + &name, dest, + NBT_MAILSLOT_NTLOGON, + &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); while (timeval_elapsed(&tv) < 5 && replies == 0) { diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c index 00617f4072..989a1faf27 100644 --- a/source4/torture/rpc/dssync.c +++ b/source4/torture/rpc/dssync.c @@ -288,16 +288,17 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx) search.in.dest_address = ctx->drsuapi_binding->host; search.in.dest_port = lp_cldap_port(tctx->lp_ctx); search.in.acct_control = -1; - search.in.version = 6; + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; + search.in.map_response = true; status = cldap_netlogon(cldap, ctx, &search); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name"); printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr, ctx->site_name); } else { - ctx->site_name = talloc_steal(ctx, search.out.netlogon.logon5.client_site); + ctx->site_name = talloc_steal(ctx, search.out.netlogon.nt5_ex.client_site); printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx->site_name); - printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.logon5.server_site); + printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site); } return ret; -- cgit From 7c0eea48f35dfb4cbc06fbaabf767612b30121eb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:38:58 +1000 Subject: Put back the old netlogn parsing code - for the request only This gives us seperate parsing functions for requests and replies. Andrew Bartlett (This used to be commit d2d3d15a8edd58cda7543feebdeb52178400615b) --- source4/libcli/dgram/libdgram.h | 15 ++++++++++----- source4/libcli/dgram/netlogon.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 3eac78f5e8..e1209e7a54 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -128,11 +128,16 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply); -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_netlogon_response *netlogon); + struct nbt_netlogon_response *reply); +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon); + +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_response *netlogon); NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index c097127083..b37d4a2ee6 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -67,22 +67,18 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply) + struct nbt_netlogon_response *reply) { NTSTATUS status; - enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, - dgmsock->iconv_convenience, - reply, - (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); + status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience, + reply); + if (!NT_STATUS_IS_OK(status)) { + return status; } make_nbt_name_client(&myname, my_netbios_name); @@ -107,7 +103,32 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, /* parse a netlogon response. The packet must be a valid mailslot packet */ -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon) +{ + DATA_BLOB data = dgram_mailslot_data(dgram); + enum ndr_err_code ndr_err; + + ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data.length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data.data, data.length); + } + return status; + } + return NT_STATUS_OK; +} + +/* + parse a netlogon response. The packet must be a valid mailslot packet +*/ +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, TALLOC_CTX *mem_ctx, struct nbt_dgram_packet *dgram, struct nbt_netlogon_response *netlogon) -- cgit From ceb2e20f7de83207238347a9347f44fdab6dd253 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:39:38 +1000 Subject: Test the use of the domain SID on the NETLOGON mailslot Interestingly, despite these packets being very similar, this fails on NTLOGON - no reply is received. Andrew Bartlett (This used to be commit 25ab0ad0a0216ef18e0aaeec27c7833d8c68ca30) --- source4/torture/nbt/dgram.c | 65 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index e039aac509..38cc20b3b9 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -47,7 +47,7 @@ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, printf("netlogon reply from %s:%d\n", src->addr, src->port); - status = dgram_mailslot_netlogon_parse(dgmslot, dgmslot, packet, &netlogon); + status = dgram_mailslot_netlogon_parse_response(dgmslot, dgmslot, packet, &netlogon); if (!NT_STATUS_IS_OK(status)) { printf("Failed to parse netlogon packet from %s:%d\n", src->addr, src->port); @@ -162,6 +162,9 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) struct nbt_name name; struct interface *ifaces; + struct test_join *join_ctx; + struct cli_credentials *machine_credentials; + const struct dom_sid *dom_sid; name.name = lp_workgroup(tctx->lp_ctx); name.type = NBT_NAME_LOGON; @@ -223,6 +226,63 @@ static bool nbt_test_netlogon2(struct torture_context *tctx) event_loop_once(dgmsock->event_ctx); } + ZERO_STRUCT(logon); + logon.command = LOGON_SAM_LOGON_REQUEST; + logon.req.logon.request_count = 0; + logon.req.logon.computer_name = TEST_NAME; + logon.req.logon.user_name = TEST_NAME"$"; + logon.req.logon.mailslot_name = dgmslot->mailslot_name; + logon.req.logon.nt_version = 1; + logon.req.logon.lmnt_token = 0xFFFF; + logon.req.logon.lm20_token = 0xFFFF; + + make_nbt_name_client(&myname, TEST_NAME); + + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, lp_dgram_port(tctx->lp_ctx)); + + torture_assert(tctx, dest != NULL, "Error getting address"); + status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, + NBT_MAILSLOT_NETLOGON, + &myname, &logon); + torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); + + while (timeval_elapsed(&tv) < 5 && replies == 0) { + event_loop_once(dgmsock->event_ctx); + } + + join_ctx = torture_join_domain(tctx, TEST_NAME, + ACB_WSTRUST, &machine_credentials); + + dom_sid = torture_join_sid(join_ctx); + + ZERO_STRUCT(logon); + logon.command = LOGON_SAM_LOGON_REQUEST; + logon.req.logon.request_count = 0; + logon.req.logon.computer_name = TEST_NAME; + logon.req.logon.user_name = TEST_NAME"$"; + logon.req.logon.mailslot_name = dgmslot->mailslot_name; + logon.req.logon.sid = *dom_sid; + logon.req.logon.nt_version = 1; + logon.req.logon.lmnt_token = 0xFFFF; + logon.req.logon.lm20_token = 0xFFFF; + + make_nbt_name_client(&myname, TEST_NAME); + + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, lp_dgram_port(tctx->lp_ctx)); + + torture_assert(tctx, dest != NULL, "Error getting address"); + status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, + NBT_MAILSLOT_NETLOGON, + &myname, &logon); + torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); + + while (timeval_elapsed(&tv) < 5 && replies == 0) { + event_loop_once(dgmsock->event_ctx); + } + + torture_leave_domain(join_ctx); return true; } @@ -236,7 +296,6 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) struct socket_address *dest; struct test_join *join_ctx; struct cli_credentials *machine_credentials; - const struct dom_sid *dom_sid; const char *myaddress; struct nbt_netlogon_packet logon; @@ -287,8 +346,6 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) talloc_asprintf(tctx, "Failed to join domain %s as %s\n", lp_workgroup(tctx->lp_ctx), TEST_NAME)); - dom_sid = torture_join_sid(join_ctx); - /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, &replies); -- cgit From 326d591d57708a88ad30a8893ca9373f1d994b56 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:41:42 +1000 Subject: Convert the CLDAP server to use the new netlogon structures. This also makes the CLDAP server the place where we create the NETLOGON SAMLOGON replies, regardless of protocol (NBT mailslots or CLDAP). Andrew Bartlett (This used to be commit 8b00a9429470c9ad3646255c340e6a963bd226bd) --- source4/cldap_server/netlogon.c | 193 ++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index a524a6f8bd..b59a54ade7 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -4,6 +4,7 @@ CLDAP server - netlogon handling Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Bartlett 2008 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 @@ -28,25 +29,26 @@ #include "cldap_server/cldap_server.h" #include "librpc/gen_ndr/ndr_misc.h" #include "libcli/ldap/ldap_ndr.h" +#include "libcli/security/security.h" #include "dsdb/samdb/samdb.h" #include "auth/auth.h" #include "ldb_wrap.h" #include "system/network.h" #include "lib/socket/netif.h" #include "param/param.h" - /* fill in the cldap netlogon union for a given version */ -static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, - TALLOC_CTX *mem_ctx, - const char *domain, - const char *domain_guid, - const char *user, - const char *src_address, - uint32_t version, - struct loadparm_context *lp_ctx, - union nbt_cldap_netlogon *netlogon) +NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, + TALLOC_CTX *mem_ctx, + const char *domain, + struct dom_sid *domain_sid, + const char *domain_guid, + const char *user, + const char *src_address, + uint32_t version, + struct loadparm_context *lp_ctx, + struct netlogon_samlogon_response *netlogon) { const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL}; const char *dom_attrs[] = {"objectGUID", NULL}; @@ -66,7 +68,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, struct ldb_dn *partitions_basedn; struct interface *ifaces; - partitions_basedn = samdb_partitions_dn(cldapd->samctx, mem_ctx); + partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); /* the domain has an optional trailing . */ if (domain && domain[strlen(domain)-1] == '.') { @@ -77,7 +79,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, struct ldb_dn *dom_dn; /* try and find the domain */ - ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &ref_res, + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, partitions_basedn, LDB_SCOPE_ONELEVEL, ref_attrs, "(&(&(objectClass=crossRef)(dnsRoot=%s))(nETBIOSName=*))", @@ -86,19 +88,19 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", domain, - ldb_errstring(cldapd->samctx))); + ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (ref_res->count == 1) { talloc_steal(mem_ctx, dom_res); - dom_dn = ldb_msg_find_attr_as_dn(cldapd->samctx, mem_ctx, ref_res->msgs[0], "ncName"); + dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName"); if (!dom_dn) { return NT_STATUS_NO_SUCH_DOMAIN; } - ret = ldb_search(cldapd->samctx, dom_dn, + ret = ldb_search(sam_ctx, dom_dn, LDB_SCOPE_BASE, "objectClass=domain", dom_attrs, &dom_res); if (ret != LDB_SUCCESS) { - DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(cldapd->samctx))); + DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } talloc_steal(mem_ctx, dom_res); @@ -112,23 +114,31 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, } } - if ((dom_res == NULL || dom_res->count == 0) && domain_guid) { + if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) { ref_res = NULL; - ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &dom_res, - NULL, LDB_SCOPE_SUBTREE, - dom_attrs, - "(&(objectClass=domainDNS)(objectGUID=%s))", - domain_guid); + if (domain_guid) { + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res, + NULL, LDB_SCOPE_SUBTREE, + dom_attrs, + "(&(objectClass=domainDNS)(objectGUID=%s))", + domain_guid); + } else { /* domain_sid case */ + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &dom_res, + NULL, LDB_SCOPE_SUBTREE, + dom_attrs, + "(&(objectClass=domainDNS)(objectSID=%s))", + dom_sid_string(mem_ctx, domain_sid)); + } if (ret != LDB_SUCCESS) { - DEBUG(2,("Unable to find referece to GUID '%s' in sam: %s\n", - domain_guid, - ldb_errstring(cldapd->samctx))); + DEBUG(2,("Unable to find referece to GUID '%s' or SID %s in sam: %s\n", + domain_guid, dom_sid_string(mem_ctx, domain_sid), + ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (dom_res->count == 1) { /* try and find the domain */ - ret = ldb_search_exp_fmt(cldapd->samctx, mem_ctx, &ref_res, + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, partitions_basedn, LDB_SCOPE_ONELEVEL, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", @@ -137,7 +147,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", ldb_dn_get_linearized(dom_res->msgs[0]->dn), - ldb_errstring(cldapd->samctx))); + ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (ref_res->count != 1) { @@ -166,11 +176,11 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | NBT_SERVER_GOOD_TIMESERV; - if (samdb_is_pdc(cldapd->samctx)) { + if (samdb_is_pdc(sam_ctx)) { server_type |= NBT_SERVER_PDC; } - if (samdb_is_gc(cldapd->samctx)) { + if (samdb_is_gc(sam_ctx)) { server_type |= NBT_SERVER_GC; } @@ -200,68 +210,61 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, ZERO_STRUCTP(netlogon); - switch (version & 0xF) { - case 0: - case 1: - netlogon->logon1.type = (user?19+2:19); - netlogon->logon1.pdc_name = pdc_name; - netlogon->logon1.user_name = user; - netlogon->logon1.domain_name = flatname; - netlogon->logon1.nt_version = 1; - netlogon->logon1.lmnt_token = 0xFFFF; - netlogon->logon1.lm20_token = 0xFFFF; - break; - case 2: - case 3: - netlogon->logon3.type = (user?19+2:19); - netlogon->logon3.pdc_name = pdc_name; - netlogon->logon3.user_name = user; - netlogon->logon3.domain_name = flatname; - netlogon->logon3.domain_uuid = domain_uuid; - netlogon->logon3.forest = realm; - netlogon->logon3.dns_domain = dns_domain; - netlogon->logon3.pdc_dns_name = pdc_dns_name; - netlogon->logon3.pdc_ip = pdc_ip; - netlogon->logon3.server_type = server_type; - netlogon->logon3.lmnt_token = 0xFFFF; - netlogon->logon3.lm20_token = 0xFFFF; - break; - case 4: - case 5: - case 6: - case 7: - netlogon->logon5.type = (user?NETLOGON_RESPONSE_FROM_PDC_USER:NETLOGON_RESPONSE_FROM_PDC2); - netlogon->logon5.server_type = server_type; - netlogon->logon5.domain_uuid = domain_uuid; - netlogon->logon5.forest = realm; - netlogon->logon5.dns_domain = dns_domain; - netlogon->logon5.pdc_dns_name = pdc_dns_name; - netlogon->logon5.domain = flatname; - netlogon->logon5.pdc_name = lp_netbios_name(lp_ctx); - netlogon->logon5.user_name = user; - netlogon->logon5.server_site = server_site; - netlogon->logon5.client_site = client_site; - netlogon->logon5.lmnt_token = 0xFFFF; - netlogon->logon5.lm20_token = 0xFFFF; - break; - default: - netlogon->logon13.type = (user?NETLOGON_RESPONSE_FROM_PDC_USER:NETLOGON_RESPONSE_FROM_PDC2); - netlogon->logon13.server_type = server_type; - netlogon->logon13.domain_uuid = domain_uuid; - netlogon->logon13.forest = realm; - netlogon->logon13.dns_domain = dns_domain; - netlogon->logon13.pdc_dns_name = pdc_dns_name; - netlogon->logon13.domain = flatname; - netlogon->logon13.pdc_name = lp_netbios_name(lp_ctx); - netlogon->logon13.user_name = user; - netlogon->logon13.server_site = server_site; - netlogon->logon13.client_site = client_site; - netlogon->logon13.unknown = 10; - netlogon->logon13.unknown2 = 2; - netlogon->logon13.pdc_ip = pdc_ip; - netlogon->logon13.lmnt_token = 0xFFFF; - netlogon->logon13.lm20_token = 0xFFFF; - break; + if (version & NETLOGON_NT_VERSION_5EX) { + uint32_t extra_flags; + netlogon->ntver = NETLOGON_NT_VERSION_5EX; + + /* could check if the user exists */ + netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; + netlogon->nt5_ex.server_type = server_type; + netlogon->nt5_ex.domain_uuid = domain_uuid; + netlogon->nt5_ex.forest = realm; + netlogon->nt5_ex.dns_domain = dns_domain; + netlogon->nt5_ex.pdc_dns_name = pdc_dns_name; + netlogon->nt5_ex.domain = flatname; + netlogon->nt5_ex.pdc_name = lp_netbios_name(lp_ctx); + netlogon->nt5_ex.user_name = user; + netlogon->nt5_ex.server_site = server_site; + netlogon->nt5_ex.client_site = client_site; + + if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) { + /* Clearly this needs to be fixed up for IPv6 */ + extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; + netlogon->nt5_ex.sockaddr.sa_family = 2; + netlogon->nt5_ex.sockaddr.pdc_ip = pdc_ip; + } + netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5|extra_flags; + netlogon->nt5_ex.lmnt_token = 0xFFFF; + netlogon->nt5_ex.lm20_token = 0xFFFF; + + } else if (version & NETLOGON_NT_VERSION_5) { + netlogon->ntver = NETLOGON_NT_VERSION_5; + + /* could check if the user exists */ + netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; + netlogon->nt5.pdc_name = pdc_name; + netlogon->nt5.user_name = user; + netlogon->nt5.domain_name = flatname; + netlogon->nt5.domain_uuid = domain_uuid; + netlogon->nt5.forest = realm; + netlogon->nt5.dns_domain = dns_domain; + netlogon->nt5.pdc_dns_name = pdc_dns_name; + netlogon->nt5.pdc_ip = pdc_ip; + netlogon->nt5.server_type = server_type; + netlogon->nt5.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5; + netlogon->nt5.lmnt_token = 0xFFFF; + netlogon->nt5.lm20_token = 0xFFFF; + } else { + netlogon->ntver = NETLOGON_NT_VERSION_1; + /* could check if the user exists */ + netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; + netlogon->nt4.server = pdc_name; + netlogon->nt4.user_name = user; + netlogon->nt4.domain = flatname; + netlogon->nt4.nt_version = NETLOGON_NT_VERSION_1; + netlogon->nt4.lmnt_token = 0xFFFF; + netlogon->nt4.lm20_token = 0xFFFF; + } return NT_STATUS_OK; @@ -285,7 +288,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, const char *domain_sid = NULL; int acct_control = -1; int version = -1; - union nbt_cldap_netlogon netlogon; + struct netlogon_samlogon_response netlogon; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; TALLOC_CTX *tmp_ctx = talloc_new(cldap); @@ -346,9 +349,9 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, DEBUG(5,("cldap netlogon query domain=%s host=%s user=%s version=%d guid=%s\n", domain, host, user, version, domain_guid)); - status = cldapd_netlogon_fill(cldapd, tmp_ctx, domain, domain_guid, - user, src->addr, - version, cldapd->task->lp_ctx, &netlogon); + status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, domain_guid, + user, src->addr, + version, cldapd->task->lp_ctx, &netlogon); if (!NT_STATUS_IS_OK(status)) { goto failed; } -- cgit From b0f34415163e5b0be93540df5457e2f56d3845b3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:43:42 +1000 Subject: Make the IRPC GetDC request use SAM_LOGON packets. This also moves the request to the new netlogon structures. Andrew Bartlett (This used to be commit 7ed4ba8d1a2ced013feafc1f0ca95595ac66bcbc) --- source4/nbt_server/irpc.c | 77 +++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c index 8f2f7fc2c2..d184d05388 100644 --- a/source4/nbt_server/irpc.c +++ b/source4/nbt_server/irpc.c @@ -49,7 +49,7 @@ static NTSTATUS nbtd_information(struct irpc_message *msg, /* - winbind needs to be able to do a getdc request, but some windows + winbind needs to be able to do a getdc request, but most (all?) windows servers always send the reply to port 138, regardless of the request port. To cope with this we use a irpc request to the NBT server which has port 138 open, and thus can receive the replies @@ -59,55 +59,47 @@ struct getdc_state { struct nbtd_getdcname *req; }; -static void getdc_recv_ntlogon_reply(struct dgram_mailslot_handler *dgmslot, +static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, struct socket_address *src) { struct getdc_state *s = talloc_get_type(dgmslot->private, struct getdc_state); - - struct nbt_ntlogon_packet ntlogon; + const char *p; + struct nbt_netlogon_response netlogon; NTSTATUS status; - status = dgram_mailslot_ntlogon_parse(dgmslot, packet, packet, - &ntlogon); + status = dgram_mailslot_netlogon_parse(dgmslot, packet, packet, + &netlogon); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n", nt_errstr(status))); goto done; } + /* We asked for version 1 only */ + if (netlogon.response_type == NETLOGON_SAMLOGON + && netlogon.samlogon.ntver != NETLOGON_NT_VERSION_1) { + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + goto done; + } + status = NT_STATUS_NO_LOGON_SERVERS; - DEBUG(10, ("reply: command=%d\n", ntlogon.command)); + p = netlogon.samlogon.nt4.server; - switch (ntlogon.command) { - case NTLOGON_SAM_LOGON: - DEBUG(0, ("Huh -- got NTLOGON_SAM_LOGON as reply\n")); - break; - case NTLOGON_SAM_LOGON_REPLY: - case NTLOGON_SAM_LOGON_REPLY15: { - const char *p = ntlogon.req.reply.server; - - DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, " - "domain: %s\n", p, ntlogon.req.reply.user_name, - ntlogon.req.reply.domain)); - - if (*p == '\\') p += 1; - if (*p == '\\') p += 1; - - s->req->out.dcname = talloc_strdup(s->req, p); - if (s->req->out.dcname == NULL) { - DEBUG(0, ("talloc failed\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - status = NT_STATUS_OK; - break; - } - default: - DEBUG(0, ("Got unknown packet: %d\n", ntlogon.command)); - break; + DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, " + "domain: %s\n", p, netlogon.samlogon.nt4.user_name, + netlogon.samlogon.nt4.domain)); + + if (*p == '\\') p += 1; + if (*p == '\\') p += 1; + + s->req->out.dcname = talloc_strdup(s->req, p); + if (s->req->out.dcname == NULL) { + DEBUG(0, ("talloc failed\n")); + status = NT_STATUS_NO_MEMORY; + goto done; } done: @@ -121,8 +113,8 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, talloc_get_type(msg->private, struct nbtd_server); struct nbtd_interface *iface = nbtd_find_request_iface(server, req->in.ip_address, true); struct getdc_state *s; - struct nbt_ntlogon_packet p; - struct nbt_ntlogon_sam_logon *r; + struct nbt_netlogon_packet p; + struct NETLOGON_SAM_LOGON_REQUEST *r; struct nbt_name src, dst; struct socket_address *dest; struct dgram_mailslot_handler *handler; @@ -137,11 +129,11 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, s->req = req; handler = dgram_mailslot_temp(iface->dgmsock, NBT_MAILSLOT_GETDC, - getdc_recv_ntlogon_reply, s); + getdc_recv_netlogon_reply, s); NT_STATUS_HAVE_NO_MEMORY(handler); ZERO_STRUCT(p); - p.command = NTLOGON_SAM_LOGON; + p.command = LOGON_SAM_LOGON_REQUEST; r = &p.req.logon; r->request_count = 0; r->computer_name = req->in.my_computername; @@ -149,7 +141,7 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, r->mailslot_name = handler->mailslot_name; r->acct_control = req->in.account_control; r->sid = *req->in.domain_sid; - r->nt_version = 1; + r->nt_version = NETLOGON_NT_VERSION_1; r->lmnt_token = 0xffff; r->lm20_token = 0xffff; @@ -160,9 +152,10 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, req->in.ip_address, 138); NT_STATUS_HAVE_NO_MEMORY(dest); - status = dgram_mailslot_ntlogon_send(iface->dgmsock, DGRAM_DIRECT_GROUP, - &dst, dest, - &src, &p); + status = dgram_mailslot_netlogon_send(iface->dgmsock, + &dst, dest, + NBT_MAILSLOT_NETLOGON, + &src, &p); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n", nt_errstr(status))); -- cgit From 842040d18490d9f6d1fed621aa36946e2becc3e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 12:44:35 +1000 Subject: Explain that the sid must be absent on the NTLOGON mailslot. Andrew Bartlett (This used to be commit a7983387f7a624f6bf5c2fbfa41f849ac4471147) --- source4/librpc/idl/nbt.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl index 74e07210cd..e6af2cd035 100644 --- a/source4/librpc/idl/nbt.idl +++ b/source4/librpc/idl/nbt.idl @@ -398,6 +398,7 @@ interface nbt astring mailslot_name; samr_AcctFlags acct_control; [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; + /* Must not be present (ie, zero size, in request to \MAILSLOT\NET\NTLOGON */ [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; netlogon_nt_version_flags nt_version; uint16 lmnt_token; -- cgit From 4f557d7954eb80e566a91b2fe22f7b7e30e0b456 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 13:24:29 +1000 Subject: Show that the NTLOGON and NETLOGON mailslots are *very* similar. Rework the mailslot infrustructure to cope, passing down the mailslot name so that we can implement both in the same callback function. Andrew Bartlett (This used to be commit 89fdd77891529aa74bb920994b8b5959aae8ac2d) --- source4/libcli/dgram/dgramsocket.c | 2 +- source4/libcli/dgram/libdgram.h | 1 + source4/nbt_server/config.mk | 2 +- source4/nbt_server/dgram/browse.c | 1 + source4/nbt_server/dgram/netlogon.c | 148 +++++++++++------------------------- source4/nbt_server/dgram/request.c | 4 +- source4/nbt_server/irpc.c | 9 ++- source4/torture/nbt/dgram.c | 25 ++++++ 8 files changed, 81 insertions(+), 111 deletions(-) diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 06b7bd5771..2cdda654ef 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, src); + dgmslot->handler(dgmslot, packet, mailslot_name, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index e1209e7a54..51408d029e 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -70,6 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, + const char *mailslot_name, struct socket_address *src); struct dgram_mailslot_handler { diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk index 84e6b661bf..eb1aea65d7 100644 --- a/source4/nbt_server/config.mk +++ b/source4/nbt_server/config.mk @@ -44,7 +44,7 @@ PRIVATE_DEPENDENCIES = \ # End SUBSYSTEM NBTD_DGRAM ####################### -NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o ntlogon.o browse.o) +NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o browse.o) ####################### # Start SUBSYSTEM NBTD diff --git a/source4/nbt_server/dgram/browse.c b/source4/nbt_server/dgram/browse.c index 2e12fa114a..36f0160e1b 100644 --- a/source4/nbt_server/dgram/browse.c +++ b/source4/nbt_server/dgram/browse.c @@ -49,6 +49,7 @@ static const char *nbt_browse_opcode_string(enum nbt_browse_opcode r) */ void nbtd_mailslot_browse_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { struct nbt_browse_packet *browse = talloc(dgmslot, struct nbt_browse_packet); diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index 7fae6bc1f6..ae24a7cd2b 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -4,7 +4,8 @@ NBT datagram netlogon server Copyright (C) Andrew Tridgell 2005 - + Copyright (C) Andrew Bartlett 2008 + 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 @@ -26,9 +27,9 @@ #include "dsdb/samdb/samdb.h" #include "auth/auth.h" #include "util/util_ldb.h" -#include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" #include "smbd/service_task.h" +#include "cldap_server/cldap_server.h" /* reply to a GETDC request @@ -36,21 +37,22 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbtd_interface *iface, struct nbt_dgram_packet *packet, + const char *mailslot_name, const struct socket_address *src, struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false); - struct nbt_netlogon_packet reply; struct nbt_netlogon_response_from_pdc *pdc; const char *ref_attrs[] = {"nETBIOSName", NULL}; struct ldb_message **ref_res; struct ldb_context *samctx; struct ldb_dn *partitions_basedn; + struct nbt_netlogon_response netlogon_response; int ret; - /* only answer getdc requests on the PDC or LOGON names */ - if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { + /* only answer getdc requests on the PDC name */ + if (name->type != NBT_NAME_PDC) { return; } @@ -72,10 +74,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, } /* setup a GETDC reply */ - ZERO_STRUCT(reply); - reply.command = NETLOGON_RESPONSE_FROM_PDC; - pdc = &reply.req.response; + ZERO_STRUCT(netlogon_response); + netlogon_response.response_type = NETLOGON_GET_PDC; + pdc = &netlogon_response.get_pdc; + pdc->command = NETLOGON_RESPONSE_FROM_PDC; pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx); pdc->unicode_pdc_name = pdc->pdc_name; pdc->domain_name = samdb_result_string(ref_res[0], "nETBIOSName", name->name);; @@ -83,38 +86,32 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, pdc->lmnt_token = 0xFFFF; pdc->lm20_token = 0xFFFF; - - packet->data.msg.dest_name.type = 0; - dgram_mailslot_netlogon_reply(reply_iface->dgmsock, packet, lp_netbios_name(iface->nbtsrv->task->lp_ctx), netlogon->req.pdc.mailslot_name, - &reply); + &netlogon_response); } /* reply to a ADS style GETDC request */ -static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, - struct nbtd_interface *iface, - struct nbt_dgram_packet *packet, - const struct socket_address *src, - struct nbt_netlogon_packet *netlogon) +static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, + struct nbtd_interface *iface, + struct nbt_dgram_packet *packet, + const char *mailslot_name, + const struct socket_address *src, + struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false); - struct nbt_netlogon_packet reply; - struct nbt_netlogon_response_from_pdc2 *pdc; struct ldb_context *samctx; - const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL}; - const char *dom_attrs[] = {"objectGUID", NULL}; - struct ldb_message **ref_res, **dom_res; - int ret; - const char **services = lp_server_services(iface->nbtsrv->task->lp_ctx); const char *my_ip = reply_iface->ip_address; - struct ldb_dn *partitions_basedn; + struct dom_sid *sid; + struct nbt_netlogon_response netlogon_response; + NTSTATUS status; + if (!my_ip) { DEBUG(0, ("Could not obtain own IP address for datagram socket\n")); return; @@ -131,90 +128,30 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, return; } - partitions_basedn = samdb_partitions_dn(samctx, packet); - - ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs, - "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", - name->name); - - if (ret != 1) { - DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name)); - return; + if (netlogon->req.logon.sid_size) { + if (strcasecmp(mailslot_name, NBT_MAILSLOT_NTLOGON) == 0) { + /* SID not permitted on NTLOGON (for some reason...) */ + return; + } + sid = &netlogon->req.logon.sid; + } else { + sid = NULL; } - /* try and find the domain */ - ret = gendb_search_dn(samctx, packet, - samdb_result_dn(samctx, samctx, ref_res[0], "ncName", NULL), - &dom_res, dom_attrs); - if (ret != 1) { - DEBUG(2,("Unable to find domain from reference '%s' in sam\n", - ldb_dn_get_linearized(ref_res[0]->dn))); + status = fill_netlogon_samlogon_response(samctx, packet, name->name, sid, NULL, + netlogon->req.logon.user_name, src->addr, + netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon); + if (!NT_STATUS_IS_OK(status)) { return; } - /* setup a GETDC reply */ - ZERO_STRUCT(reply); - reply.command = NETLOGON_RESPONSE_FROM_PDC2; - -#if 0 - /* newer testing shows that the reply command type is not - changed based on whether a username is given in the - reply. This was what was causing the w2k join to be so - slow */ - if (netlogon->req.pdc2.user_name[0]) { - reply.command = NETLOGON_RESPONSE_FROM_PDC_USER; - } -#endif - - pdc = &reply.req.response2; - - /* TODO: accurately depict which services we are running */ - pdc->server_type = - NBT_SERVER_PDC | NBT_SERVER_GC | - NBT_SERVER_DS | NBT_SERVER_TIMESERV | - NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | - NBT_SERVER_GOOD_TIMESERV; - - /* hmm, probably a better way to do this */ - if (str_list_check(services, "ldap")) { - pdc->server_type |= NBT_SERVER_LDAP; - } - - if (str_list_check(services, "kdc")) { - pdc->server_type |= NBT_SERVER_KDC; - } - - pdc->domain_uuid = samdb_result_guid(dom_res[0], "objectGUID"); - pdc->forest = samdb_result_string(ref_res[0], "dnsRoot", - lp_realm(iface->nbtsrv->task->lp_ctx)); - pdc->dns_domain = samdb_result_string(ref_res[0], "dnsRoot", - lp_realm(iface->nbtsrv->task->lp_ctx)); - - /* TODO: get our full DNS name from somewhere else */ - pdc->pdc_dns_name = talloc_asprintf(packet, "%s.%s", - strlower_talloc(packet, - lp_netbios_name(iface->nbtsrv->task->lp_ctx)), - pdc->dns_domain); - pdc->domain = samdb_result_string(ref_res[0], "nETBIOSName", name->name);; - pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx); - pdc->user_name = netlogon->req.pdc2.user_name; - /* TODO: we need to make sure these are in our DNS zone */ - pdc->server_site = "Default-First-Site-Name"; - pdc->client_site = "Default-First-Site-Name"; - pdc->unknown = 0x10; /* what is this? */ - pdc->unknown2 = 2; /* and this ... */ - pdc->pdc_ip = my_ip; - pdc->nt_version = 13; - pdc->lmnt_token = 0xFFFF; - pdc->lm20_token = 0xFFFF; - packet->data.msg.dest_name.type = 0; dgram_mailslot_netlogon_reply(reply_iface->dgmsock, packet, lp_netbios_name(iface->nbtsrv->task->lp_ctx), - netlogon->req.pdc2.mailslot_name, - &reply); + netlogon->req.logon.mailslot_name, + &netlogon_response); } @@ -223,6 +160,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, */ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -246,15 +184,17 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, DEBUG(2,("netlogon request to %s from %s:%d\n", nbt_name_string(netlogon, name), src->addr, src->port)); - status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon); + status = dgram_mailslot_netlogon_parse_request(dgmslot, netlogon, packet, netlogon); if (!NT_STATUS_IS_OK(status)) goto failed; switch (netlogon->command) { - case NETLOGON_QUERY_FOR_PDC: - nbtd_netlogon_getdc(dgmslot, iface, packet, src, netlogon); + case LOGON_PRIMARY_QUERY: + nbtd_netlogon_getdc(dgmslot, iface, packet, mailslot_name, + src, netlogon); break; - case NETLOGON_QUERY_FOR_PDC2: - nbtd_netlogon_getdc2(dgmslot, iface, packet, src, netlogon); + case LOGON_SAM_LOGON_REQUEST: + nbtd_netlogon_samlogon(dgmslot, iface, packet, mailslot_name, + src, netlogon); break; default: DEBUG(2,("unknown netlogon op %d from %s:%d\n", diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c index 205a544209..277b64741d 100644 --- a/source4/nbt_server/dgram/request.c +++ b/source4/nbt_server/dgram/request.c @@ -35,8 +35,10 @@ static const struct { const char *mailslot_name; dgram_mailslot_handler_t handler; } mailslot_handlers[] = { + /* Handle both NTLOGON and NETLOGON in the same function, as + * they are very similar */ { NBT_MAILSLOT_NETLOGON, nbtd_mailslot_netlogon_handler }, - { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_ntlogon_handler }, + { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_netlogon_handler }, { NBT_MAILSLOT_BROWSE, nbtd_mailslot_browse_handler } }; diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c index d184d05388..3a70c98041 100644 --- a/source4/nbt_server/irpc.c +++ b/source4/nbt_server/irpc.c @@ -60,8 +60,9 @@ struct getdc_state { }; static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, - struct nbt_dgram_packet *packet, - struct socket_address *src) + struct nbt_dgram_packet *packet, + const char *mailslot_name, + struct socket_address *src) { struct getdc_state *s = talloc_get_type(dgmslot->private, struct getdc_state); @@ -69,8 +70,8 @@ static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_response netlogon; NTSTATUS status; - status = dgram_mailslot_netlogon_parse(dgmslot, packet, packet, - &netlogon); + status = dgram_mailslot_netlogon_parse_response(dgmslot, packet, packet, + &netlogon); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n", nt_errstr(status))); diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index 38cc20b3b9..ce5758977d 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -39,6 +39,7 @@ */ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { NTSTATUS status; @@ -378,6 +379,30 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) event_loop_once(dgmsock->event_ctx); } + ZERO_STRUCT(logon); + logon.command = LOGON_PRIMARY_QUERY; + logon.req.pdc.computer_name = TEST_NAME; + logon.req.pdc.mailslot_name = dgmslot->mailslot_name; + logon.req.pdc.unicode_name = TEST_NAME; + logon.req.pdc.nt_version = 1; + logon.req.pdc.lmnt_token = 0xFFFF; + logon.req.pdc.lm20_token = 0xFFFF; + + make_nbt_name_client(&myname, TEST_NAME); + + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, lp_dgram_port(tctx->lp_ctx)); + torture_assert(tctx, dest != NULL, "Error getting address"); + status = dgram_mailslot_netlogon_send(dgmsock, + &name, dest, + NBT_MAILSLOT_NTLOGON, + &myname, &logon); + torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); + + while (timeval_elapsed(&tv) < 5 && replies == 0) { + event_loop_once(dgmsock->event_ctx); + } + torture_leave_domain(join_ctx); return true; } -- cgit From 24264e9acb12938f666bcdfc92ee4f9ed6409112 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 20:52:23 +1000 Subject: Modify the LDAP-CLDAP test for better coverage. This fixes up some compiled in constants and checks a couple more NT versions. Andrew Bartlett (This used to be commit ca1b3fe3add06dc22361d5a5fe7e63a6abb1697c) --- source4/torture/ldap/cldap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index bb77acd2d0..a77920d4e6 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -83,7 +83,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_OK); } - search.in.version = 0x20000006; + search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP; + status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); @@ -104,7 +105,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); - search.in.version = 6; + search.in.version = NETLOGON_NT_VERSION_5; status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); @@ -114,7 +115,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) status = cldap_netlogon(cldap, tctx, &search); CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.nt5_ex.user_name, ""); - CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE); printf("Trying with User=Administrator\n"); @@ -123,7 +124,9 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); - CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN); + + search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; printf("Trying with a GUID\n"); search.in.realm = NULL; @@ -168,6 +171,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_OK); CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user); CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain); + CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX); printf("Trying with just a bad domain\n"); search = empty_search; -- cgit From fd0d47b746be322b60fca29c1daa13e72b360e62 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 20:53:29 +1000 Subject: Handle netbios domains in the CLDAP server too. This commit also fixes a number of issues found by the NBT-DGRAM and LDAP-CLDAP tests. Andrew Bartlett (This used to be commit 8f99a4b94e95f8bde0f80f92d4e57020c62cfaab) --- source4/cldap_server/netlogon.c | 72 ++++++++++++++++++++++++++++++++----- source4/nbt_server/dgram/netlogon.c | 17 +++++++-- 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index b59a54ade7..b2a034d5a4 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -42,6 +42,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *domain, + const char *netbios_domain, struct dom_sid *domain_sid, const char *domain_guid, const char *user, @@ -114,6 +115,45 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, } } + if (netbios_domain) { + struct ldb_dn *dom_dn; + /* try and find the domain */ + + ret = ldb_search_exp_fmt(sam_ctx, mem_ctx, &ref_res, + partitions_basedn, LDB_SCOPE_ONELEVEL, + ref_attrs, + "(&(objectClass=crossRef)(ncName=*)(nETBIOSName=%s))", + netbios_domain); + + if (ret != LDB_SUCCESS) { + DEBUG(2,("Unable to find referece to '%s' in sam: %s\n", + netbios_domain, + ldb_errstring(sam_ctx))); + return NT_STATUS_NO_SUCH_DOMAIN; + } else if (ref_res->count == 1) { + talloc_steal(mem_ctx, dom_res); + dom_dn = ldb_msg_find_attr_as_dn(sam_ctx, mem_ctx, ref_res->msgs[0], "ncName"); + if (!dom_dn) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + ret = ldb_search(sam_ctx, dom_dn, + LDB_SCOPE_BASE, "objectClass=domain", + dom_attrs, &dom_res); + if (ret != LDB_SUCCESS) { + DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain, ldb_dn_get_linearized(dom_dn), ldb_errstring(sam_ctx))); + return NT_STATUS_NO_SUCH_DOMAIN; + } + talloc_steal(mem_ctx, dom_res); + if (dom_res->count != 1) { + DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain, ldb_dn_get_linearized(dom_dn))); + return NT_STATUS_NO_SUCH_DOMAIN; + } + } else if (ref_res->count > 1) { + talloc_free(ref_res); + return NT_STATUS_NO_SUCH_DOMAIN; + } + } + if ((dom_res == NULL || dom_res->count == 0) && (domain_guid || domain_sid)) { ref_res = NULL; @@ -211,11 +251,16 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, ZERO_STRUCTP(netlogon); if (version & NETLOGON_NT_VERSION_5EX) { - uint32_t extra_flags; + uint32_t extra_flags = 0; netlogon->ntver = NETLOGON_NT_VERSION_5EX; /* could check if the user exists */ - netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; + if (!user) { + user = ""; + netlogon->nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; + } else { + netlogon->nt5_ex.command = LOGON_SAM_LOGON_USER_UNKNOWN_EX; + } netlogon->nt5_ex.server_type = server_type; netlogon->nt5_ex.domain_uuid = domain_uuid; netlogon->nt5_ex.forest = realm; @@ -232,8 +277,9 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; netlogon->nt5_ex.sockaddr.sa_family = 2; netlogon->nt5_ex.sockaddr.pdc_ip = pdc_ip; + netlogon->nt5_ex.sockaddr.remaining = data_blob(NULL, 4); } - netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5|extra_flags; + netlogon->nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags; netlogon->nt5_ex.lmnt_token = 0xFFFF; netlogon->nt5_ex.lm20_token = 0xFFFF; @@ -241,7 +287,12 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, netlogon->ntver = NETLOGON_NT_VERSION_5; /* could check if the user exists */ - netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; + if (!user) { + user = ""; + netlogon->nt5.command = LOGON_SAM_LOGON_RESPONSE; + } else { + netlogon->nt5.command = LOGON_SAM_LOGON_USER_UNKNOWN; + } netlogon->nt5.pdc_name = pdc_name; netlogon->nt5.user_name = user; netlogon->nt5.domain_name = flatname; @@ -254,17 +305,22 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, netlogon->nt5.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5; netlogon->nt5.lmnt_token = 0xFFFF; netlogon->nt5.lm20_token = 0xFFFF; - } else { + + } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ { netlogon->ntver = NETLOGON_NT_VERSION_1; /* could check if the user exists */ - netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; + if (!user) { + user = ""; + netlogon->nt4.command = LOGON_SAM_LOGON_RESPONSE; + } else { + netlogon->nt4.command = LOGON_SAM_LOGON_USER_UNKNOWN; + } netlogon->nt4.server = pdc_name; netlogon->nt4.user_name = user; netlogon->nt4.domain = flatname; netlogon->nt4.nt_version = NETLOGON_NT_VERSION_1; netlogon->nt4.lmnt_token = 0xFFFF; netlogon->nt4.lm20_token = 0xFFFF; - } return NT_STATUS_OK; @@ -349,7 +405,7 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, DEBUG(5,("cldap netlogon query domain=%s host=%s user=%s version=%d guid=%s\n", domain, host, user, version, domain_guid)); - status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, domain_guid, + status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid, user, src->addr, version, cldapd->task->lp_ctx, &netlogon); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index ae24a7cd2b..c66089523b 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -30,6 +30,7 @@ #include "param/param.h" #include "smbd/service_task.h" #include "cldap_server/cldap_server.h" +#include "libcli/security/security.h" /* reply to a GETDC request @@ -51,8 +52,8 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_response netlogon_response; int ret; - /* only answer getdc requests on the PDC name */ - if (name->type != NBT_NAME_PDC) { + /* only answer getdc requests on the PDC or LOGON names */ + if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { return; } @@ -62,6 +63,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, return; } + if (!samdb_is_pdc(samctx)) { + DEBUG(2, ("Not a PDC, so not processing LOGON_PRIMARY_QUERY\n")); + return; + } + partitions_basedn = samdb_partitions_dn(samctx, packet); ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs, @@ -130,6 +136,7 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, if (netlogon->req.logon.sid_size) { if (strcasecmp(mailslot_name, NBT_MAILSLOT_NTLOGON) == 0) { + DEBUG(2,("NBT netlogon query failed because SID specified in request to NTLOGON\n")); /* SID not permitted on NTLOGON (for some reason...) */ return; } @@ -138,13 +145,17 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, sid = NULL; } - status = fill_netlogon_samlogon_response(samctx, packet, name->name, sid, NULL, + status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, netlogon->req.logon.user_name, src->addr, netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon); if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n", + name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status))); return; } + netlogon_response.response_type = NETLOGON_SAMLOGON; + packet->data.msg.dest_name.type = 0; dgram_mailslot_netlogon_reply(reply_iface->dgmsock, -- cgit From 38c68f1d5bf972f2473a41bf15c4a54efdc38b7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 May 2008 21:30:36 +1000 Subject: Ensure we don't send a reply if we couldn't push the CLDAP blob Andrew Bartlett (This used to be commit a8ec36eba79f96940f314520f97d23181bc9cfc5) --- source4/libcli/cldap/cldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 3867f3d3fd..860bd358d5 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -712,7 +712,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience, netlogon); if (!NT_STATUS_IS_OK(status)) { - + return status; } reply.messageid = message_id; reply.dest = src; -- cgit From eb1b76d200ea38fd1cea367016b782776004964c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 May 2008 14:15:15 +0200 Subject: build: only add enabled subsystems and modules to ALL_OBJS metze (This used to be commit cc07bd86e270c8016acd0f685d699e4a3e63cfb1) --- source4/build/smb_build/main.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/build/smb_build/main.pl b/source4/build/smb_build/main.pl index 3ff34eedcf..b31bfaa1f2 100644 --- a/source4/build/smb_build/main.pl +++ b/source4/build/smb_build/main.pl @@ -55,6 +55,7 @@ my $mkenv = new smb_build::makefile(\%config::config, $mkfile); my $shared_libs_used = 0; foreach my $key (values %$OUTPUT) { + next if ($key->{ENABLE} ne "YES"); push(@{$mkenv->{all_objs}}, "\$($key->{NAME}_OBJ_FILES)"); } -- cgit From d817b435342956295f0a31b91203d1a63ae12063 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 May 2008 15:53:09 +0200 Subject: Fix a memleak in irpc_remove_name First, even when length==0 tdb_fetch might return something. Second, for some weird reason there might be less data than necessary for a single server id. (This used to be commit 49b04ca7aadf264e500d83bc8d3cb5173a86184e) --- source4/lib/messaging/messaging.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index 19284461ee..e7b654894f 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -1085,8 +1085,14 @@ void irpc_remove_name(struct messaging_context *msg_ctx, const char *name) return; } rec = tdb_fetch_bystring(t->tdb, name); + if (rec.dptr == NULL) { + tdb_unlock_bystring(t->tdb, name); + talloc_free(t); + return; + } count = rec.dsize / sizeof(struct server_id); if (count == 0) { + free(rec.dptr); tdb_unlock_bystring(t->tdb, name); talloc_free(t); return; -- cgit From ae4611909609b8a0466938171812f10974dc054a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 May 2008 23:07:04 +0200 Subject: Add __repr__ implementations for ldb.Message, ldb.MessageElement and ldb.Dn. (This used to be commit b9119c0f0f524d43ff09825dffb24a5e77a240f4) --- source4/lib/ldb/ldb.i | 50 ++++++++++++++++++++++++++++++---- source4/lib/ldb/ldb.py | 30 +++++++++++++++++++-- source4/lib/ldb/ldb_wrap.c | 54 ++++++++++++++++++++++++++++++------- source4/lib/ldb/tests/python/api.py | 38 +++++++++++++++++++++++++- 4 files changed, 155 insertions(+), 17 deletions(-) diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 6b94f19cb5..75482011fb 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -229,6 +229,14 @@ fail: return ldb_dn_canonical_ex_string($self, $self); } #ifdef SWIGPYTHON + char *__repr__(void) + { + char *dn = ldb_dn_get_linearized($self), *ret; + asprintf(&ret, "Dn('%s')", dn); + talloc_free(dn); + return ret; + } + ldb_dn *__add__(ldb_dn *other) { ldb_dn *ret = ldb_dn_copy(NULL, $self); @@ -376,6 +384,9 @@ typedef struct ldb_message_element { raise KeyError("no such value") return ret + def __repr__(self): + return "MessageElement([%s])" % (",".join(repr(x) for x in self.__set__())) + def __eq__(self, other): if (len(self) == 1 and self.get(0) == other): return True @@ -400,17 +411,22 @@ typedef struct ldb_message_element { else $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0); } -%rename(__getitem__) ldb_message::find_element; //%typemap(out) ldb_msg_element *; %inline { PyObject *ldb_msg_list_elements(ldb_msg *msg) { - int i; - PyObject *obj = PyList_New(msg->num_elements); - for (i = 0; i < msg->num_elements; i++) - PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name)); + int i, j = 0; + PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); + if (msg->dn != NULL) { + PyList_SetItem(obj, j, PyString_FromString("dn")); + j++; + } + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name)); + j++; + } return obj; } } @@ -466,6 +482,28 @@ typedef struct ldb_message { } #endif void remove_attr(const char *name); +%pythoncode { + def get(self, key, default=None): + if key == "dn": + return self.dn + return self.find_element(key) + + def __getitem__(self, key): + ret = self.get(key, None) + if ret is None: + raise KeyError("No such element") + return ret + + def iteritems(self): + for k in self.keys(): + yield k, self[k] + + def items(self): + return list(self.iteritems()) + + def __repr__(self): + return "Message(%s)" % repr(dict(self.iteritems())) +} } } ldb_msg; @@ -753,6 +791,8 @@ typedef struct ldb_context { def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, attrs=None, controls=None): + if not (attrs is None or isinstance(attrs, list)): + raise TypeError("attributes not a list") parsed_controls = None if controls is not None: parsed_controls = self.parse_control_strings(controls) diff --git a/source4/lib/ldb/ldb.py b/source4/lib/ldb/ldb.py index b148782c63..60644d352c 100644 --- a/source4/lib/ldb/ldb.py +++ b/source4/lib/ldb/ldb.py @@ -68,7 +68,6 @@ CHANGETYPE_MODIFY = _ldb.CHANGETYPE_MODIFY ldb_val_to_py_object = _ldb.ldb_val_to_py_object class Dn(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr def __init__(self, *args, **kwargs): _ldb.Dn_swiginit(self,_ldb.new_Dn(*args, **kwargs)) __swig_destroy__ = _ldb.delete_Dn @@ -93,6 +92,7 @@ Dn.add_child = new_instancemethod(_ldb.Dn_add_child,None,Dn) Dn.add_base = new_instancemethod(_ldb.Dn_add_base,None,Dn) Dn.canonical_str = new_instancemethod(_ldb.Dn_canonical_str,None,Dn) Dn.canonical_ex_str = new_instancemethod(_ldb.Dn_canonical_ex_str,None,Dn) +Dn.__repr__ = new_instancemethod(_ldb.Dn___repr__,None,Dn) Dn.__add__ = new_instancemethod(_ldb.Dn___add__,None,Dn) Dn_swigregister = _ldb.Dn_swigregister Dn_swigregister(Dn) @@ -108,6 +108,9 @@ class ldb_msg_element(object): raise KeyError("no such value") return ret + def __repr__(self): + return "MessageElement([%s])" % (",".join(repr(x) for x in self.__set__())) + def __eq__(self, other): if (len(self) == 1 and self.get(0) == other): return True @@ -139,7 +142,28 @@ class Message(object): def __init__(self, *args, **kwargs): _ldb.Message_swiginit(self,_ldb.new_Message(*args, **kwargs)) __swig_destroy__ = _ldb.delete_Message -Message.__getitem__ = new_instancemethod(_ldb.Message___getitem__,None,Message) + def get(self, key, default=None): + if key == "dn": + return self.dn + return self.find_element(key) + + def __getitem__(self, key): + ret = self.get(key, None) + if ret is None: + raise KeyError("No such element") + return ret + + def iteritems(self): + for k in self.keys(): + yield k, self[k] + + def items(self): + return list(self.iteritems()) + + def __repr__(self): + return "Message(%s)" % repr(dict(self.iteritems())) + +Message.find_element = new_instancemethod(_ldb.Message_find_element,None,Message) Message.__setitem__ = new_instancemethod(_ldb.Message___setitem__,None,Message) Message.__len__ = new_instancemethod(_ldb.Message___len__,None,Message) Message.keys = new_instancemethod(_ldb.Message_keys,None,Message) @@ -202,6 +226,8 @@ class Ldb(object): def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, attrs=None, controls=None): + if not (attrs is None or isinstance(attrs, list)): + raise TypeError("attributes not a list") parsed_controls = None if controls is not None: parsed_controls = self.parse_control_strings(controls) diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c index 390652eebe..f13ed4dc3b 100644 --- a/source4/lib/ldb/ldb_wrap.c +++ b/source4/lib/ldb/ldb_wrap.c @@ -2719,6 +2719,12 @@ SWIGINTERN char const *ldb_dn_canonical_str(ldb_dn *self){ SWIGINTERN char const *ldb_dn_canonical_ex_str(ldb_dn *self){ return ldb_dn_canonical_ex_string(self, self); } +SWIGINTERN char *ldb_dn___repr__(ldb_dn *self){ + char *dn = ldb_dn_get_linearized(self), *ret; + asprintf(&ret, "Dn('%s')", dn); + talloc_free(dn); + return ret; + } SWIGINTERN ldb_dn *ldb_dn___add__(ldb_dn *self,ldb_dn *other){ ldb_dn *ret = ldb_dn_copy(NULL, self); ldb_dn_add_child(ret, other); @@ -2970,10 +2976,16 @@ SWIGINTERN void delete_ldb_msg_element(ldb_msg_element *self){ talloc_free(self) PyObject *ldb_msg_list_elements(ldb_msg *msg) { - int i; - PyObject *obj = PyList_New(msg->num_elements); - for (i = 0; i < msg->num_elements; i++) - PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name)); + int i, j = 0; + PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); + if (msg->dn != NULL) { + PyList_SetItem(obj, j, PyString_FromString("dn")); + j++; + } + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name)); + j++; + } return obj; } @@ -3678,6 +3690,29 @@ fail: } +SWIGINTERN PyObject *_wrap_Dn___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + ldb_dn *arg1 = (ldb_dn *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_dn, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Dn___repr__" "', argument " "1"" of type '" "ldb_dn *""'"); + } + arg1 = (ldb_dn *)(argp1); + result = (char *)ldb_dn___repr__(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Dn___add__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; ldb_dn *arg1 = (ldb_dn *) 0 ; @@ -4074,7 +4109,7 @@ fail: } -SWIGINTERN PyObject *_wrap_Message___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_Message_find_element(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; ldb_msg *arg1 = (ldb_msg *) 0 ; char *arg2 = (char *) 0 ; @@ -4090,15 +4125,15 @@ SWIGINTERN PyObject *_wrap_Message___getitem__(PyObject *SWIGUNUSEDPARM(self), P (char *) "self",(char *) "name", NULL }; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Message___getitem__",kwnames,&obj0,&obj1)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Message_find_element",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message___getitem__" "', argument " "1"" of type '" "ldb_msg *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_find_element" "', argument " "1"" of type '" "ldb_msg *""'"); } arg1 = (ldb_msg *)(argp1); res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message___getitem__" "', argument " "2"" of type '" "char const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_find_element" "', argument " "2"" of type '" "char const *""'"); } arg2 = (char *)(buf2); if (arg1 == NULL) @@ -5673,6 +5708,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Dn_add_base", (PyCFunction) _wrap_Dn_add_base, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Dn_canonical_str", (PyCFunction)_wrap_Dn_canonical_str, METH_O, NULL}, { (char *)"Dn_canonical_ex_str", (PyCFunction)_wrap_Dn_canonical_ex_str, METH_O, NULL}, + { (char *)"Dn___repr__", (PyCFunction)_wrap_Dn___repr__, METH_O, NULL}, { (char *)"Dn___add__", (PyCFunction) _wrap_Dn___add__, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Dn_swigregister", Dn_swigregister, METH_VARARGS, NULL}, { (char *)"Dn_swiginit", Dn_swiginit, METH_VARARGS, NULL}, @@ -5689,7 +5725,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Message_dn_get", (PyCFunction)_wrap_Message_dn_get, METH_O, NULL}, { (char *)"new_Message", (PyCFunction) _wrap_new_Message, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"delete_Message", (PyCFunction)_wrap_delete_Message, METH_O, NULL}, - { (char *)"Message___getitem__", (PyCFunction) _wrap_Message___getitem__, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Message_find_element", (PyCFunction) _wrap_Message_find_element, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Message___setitem__", _wrap_Message___setitem__, METH_VARARGS, NULL}, { (char *)"Message___len__", (PyCFunction)_wrap_Message___len__, METH_O, NULL}, { (char *)"Message_keys", (PyCFunction)_wrap_Message_keys, METH_O, NULL}, diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index 5f3f727b5d..6f073f79a8 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -60,6 +60,10 @@ class SimpleLdb(unittest.TestCase): l = ldb.Ldb("foo.tdb") self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) + def test_search_attr_string(self): + l = ldb.Ldb("foo.tdb") + self.assertRaises(TypeError, l.search, attrs="dc") + def test_opaque(self): l = ldb.Ldb("foo.tdb") l.set_opaque("my_opaque", l) @@ -257,6 +261,10 @@ class DnTests(unittest.TestCase): x = ldb.Dn(self.ldb, "dc=foo,bar=bloe") self.assertEquals(x.__str__(), "dc=foo,bar=bloe") + def test_repr(self): + x = ldb.Dn(self.ldb, "dc=foo,bla=blie") + self.assertEquals(x.__repr__(), "Dn('dc=foo,bla=blie')") + def test_get_casefold(self): x = ldb.Dn(self.ldb, "dc=foo,bar=bloe") self.assertEquals(x.get_casefold(), "DC=FOO,BAR=bloe") @@ -347,6 +355,16 @@ class LdbMsgTests(unittest.TestCase): self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo")) self.assertEquals("dc=foo", str(self.msg.dn)) + def test_iter_items(self): + self.assertEquals(0, len(self.msg.items())) + self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo") + self.assertEquals(1, len(self.msg.items())) + + def test_repr(self): + self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo") + self.msg["dc"] = "foo" + self.assertEquals("Message({'dn': Dn('dc=foo'), 'dc': MessageElement(['foo'])})", repr(self.msg)) + def test_len(self): self.assertEquals(0, len(self.msg)) @@ -374,14 +392,26 @@ class LdbMsgTests(unittest.TestCase): self.assertEquals(["bar"], list(self.msg["foo"])) def test_keys(self): + self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO") self.msg["foo"] = ["bla"] self.msg["bar"] = ["bla"] - self.assertEquals(["foo", "bar"], self.msg.keys()) + self.assertEquals(["dn", "foo", "bar"], self.msg.keys()) def test_dn(self): self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO") self.assertEquals("@BASEINFO", self.msg.dn.__str__()) + def test_get_dn(self): + self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO") + self.assertEquals("@BASEINFO", self.msg.get("dn").__str__()) + + def test_get_other(self): + self.msg["foo"] = ["bar"] + self.assertEquals("bar", self.msg.get("foo")[0]) + + def test_get_unknown(self): + self.assertRaises(KeyError, self.msg.get, "lalalala") + class MessageElementTests(unittest.TestCase): def test_cmp_element(self): @@ -395,6 +425,12 @@ class MessageElementTests(unittest.TestCase): x = ldb.MessageElement(["foo"]) self.assertEquals(["foo"], list(x)) + def test_repr(self): + x = ldb.MessageElement(["foo"]) + self.assertEquals("MessageElement(['foo'])", repr(x)) + x = ldb.MessageElement(["foo", "bla"]) + self.assertEquals("MessageElement(['foo','bla'])", repr(x)) + def test_get_item(self): x = ldb.MessageElement(["foo", "bar"]) self.assertEquals("foo", x[0]) -- cgit From 43a22c9b4a7868a740e2de417f50702209d2aced Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 May 2008 23:12:13 +0200 Subject: Add __repr__ implementation for Ldb. (This used to be commit 5607aea07f66f09fd5b33842d07d2fbbf44d13e7) --- source4/lib/ldb/ldb.i | 6 ++++++ source4/lib/ldb/ldb.py | 2 +- source4/lib/ldb/ldb_wrap.c | 32 ++++++++++++++++++++++++++++++++ source4/lib/ldb/tests/python/api.py | 4 ++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 75482011fb..18e981f7be 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -781,6 +781,12 @@ typedef struct ldb_context { return PyObject_GetIter(list); } + char *__repr__(void) + { + char *ret; + asprintf(&ret, "", ret); + return ret; + } #endif } %pythoncode { diff --git a/source4/lib/ldb/ldb.py b/source4/lib/ldb/ldb.py index 60644d352c..e9f4055fbf 100644 --- a/source4/lib/ldb/ldb.py +++ b/source4/lib/ldb/ldb.py @@ -215,7 +215,6 @@ LDB_ERR_AFFECTS_MULTIPLE_DSAS = _ldb.LDB_ERR_AFFECTS_MULTIPLE_DSAS LDB_ERR_OTHER = _ldb.LDB_ERR_OTHER class Ldb(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr def __init__(self, *args, **kwargs): _ldb.Ldb_swiginit(self,_ldb.new_Ldb(*args, **kwargs)) __swig_destroy__ = _ldb.delete_Ldb @@ -260,6 +259,7 @@ Ldb.schema_attribute_add = new_instancemethod(_ldb.Ldb_schema_attribute_add,None Ldb.setup_wellknown_attributes = new_instancemethod(_ldb.Ldb_setup_wellknown_attributes,None,Ldb) Ldb.__contains__ = new_instancemethod(_ldb.Ldb___contains__,None,Ldb) Ldb.parse_ldif = new_instancemethod(_ldb.Ldb_parse_ldif,None,Ldb) +Ldb.__repr__ = new_instancemethod(_ldb.Ldb___repr__,None,Ldb) Ldb_swigregister = _ldb.Ldb_swigregister Ldb_swigregister(Ldb) diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c index f13ed4dc3b..d787266416 100644 --- a/source4/lib/ldb/ldb_wrap.c +++ b/source4/lib/ldb/ldb_wrap.c @@ -3200,6 +3200,11 @@ SWIGINTERN PyObject *ldb_parse_ldif(ldb *self,char const *s){ } return PyObject_GetIter(list); } +SWIGINTERN char *ldb___repr__(ldb *self){ + char *ret; + asprintf(&ret, "", ret); + return ret; + } static char *timestring(time_t t) { @@ -5573,6 +5578,32 @@ fail: } +SWIGINTERN PyObject *_wrap_Ldb___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + ldb *arg1 = (ldb *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb___repr__" "', argument " "1"" of type '" "ldb *""'"); + } + arg1 = (ldb *)(argp1); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = (char *)ldb___repr__(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *Ldb_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *obj; if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; @@ -5762,6 +5793,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Ldb_setup_wellknown_attributes", (PyCFunction)_wrap_Ldb_setup_wellknown_attributes, METH_O, NULL}, { (char *)"Ldb___contains__", (PyCFunction) _wrap_Ldb___contains__, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Ldb_parse_ldif", (PyCFunction) _wrap_Ldb_parse_ldif, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Ldb___repr__", (PyCFunction)_wrap_Ldb___repr__, METH_O, NULL}, { (char *)"Ldb_swigregister", Ldb_swigregister, METH_VARARGS, NULL}, { (char *)"Ldb_swiginit", Ldb_swiginit, METH_VARARGS, NULL}, { (char *)"valid_attr_name", (PyCFunction) _wrap_valid_attr_name, METH_VARARGS | METH_KEYWORDS, NULL}, diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index 6f073f79a8..1ae3fde744 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -36,6 +36,10 @@ class SimpleLdb(unittest.TestCase): x = ldb.Ldb() x.connect("foo.tdb") + def test_repr(self): + x = ldb.Ldb() + self.assertTrue(repr(x).startswith(" Date: Mon, 19 May 2008 23:36:11 +0200 Subject: Fix dependency. (This used to be commit d8fe782dc200907e0364c623e187c51f4d44edb2) --- source4/lib/tdb/tdb.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/tdb/tdb.mk b/source4/lib/tdb/tdb.mk index c91b1289cb..fa8db6d34c 100644 --- a/source4/lib/tdb/tdb.mk +++ b/source4/lib/tdb/tdb.mk @@ -50,7 +50,7 @@ install-python:: build-python cp $(tdbdir)/tdb.py $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` cp _tdb.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` -check-python:: build-python +check-python:: build-python $(TDB_SONAME) $(LIB_PATH_VAR)=. PYTHONPATH=".:$(tdbdir)" $(PYTHON) $(tdbdir)/python/tests/simple.py install-swig:: -- cgit From 1b4b8d5e78e553c759c16c1605b610498fddf77b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 19 May 2008 23:36:33 +0200 Subject: Add __repr__ implementation for Tdb. (This used to be commit 205699ed663a3c6d27695dee25bf26978615b475) --- source4/lib/tdb/python/tests/simple.py | 7 ++-- source4/lib/tdb/tdb.i | 4 +-- source4/lib/tdb/tdb.py | 8 ++--- source4/lib/tdb/tdb_wrap.c | 65 ++++++++++++++++++++++++---------- 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/source4/lib/tdb/python/tests/simple.py b/source4/lib/tdb/python/tests/simple.py index 94407b6398..7147718c91 100644 --- a/source4/lib/tdb/python/tests/simple.py +++ b/source4/lib/tdb/python/tests/simple.py @@ -3,8 +3,8 @@ # Note that this tests the interface of the Python bindings # It does not test tdb itself. # -# Copyright (C) 2007 Jelmer Vernooij -# Published under the GNU LGPL +# Copyright (C) 2007-2008 Jelmer Vernooij +# Published under the GNU LGPLv3 or later import tdb from unittest import TestCase @@ -25,6 +25,9 @@ class SimpleTdbTests(TestCase): def tearDown(self): del self.tdb + def test_repr(self): + self.assertTrue(repr(self.tdb).startswith("Tdb('")) + def test_lockall(self): self.tdb.lock_all() diff --git a/source4/lib/tdb/tdb.i b/source4/lib/tdb/tdb.i index c82d2d0a6d..704f0facc6 100644 --- a/source4/lib/tdb/tdb.i +++ b/source4/lib/tdb/tdb.i @@ -182,8 +182,8 @@ typedef struct tdb_context { } %pythoncode { - def __str__(self): - return self.name() + def __repr__(self): + return "Tdb('%s')" % self.name() # Random access to keys, values def __getitem__(self, key): diff --git a/source4/lib/tdb/tdb.py b/source4/lib/tdb/tdb.py index 0effa3ff98..eb76ca6459 100644 --- a/source4/lib/tdb/tdb.py +++ b/source4/lib/tdb/tdb.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. @@ -80,11 +80,11 @@ TDB_ERR_EINVAL = _tdb.TDB_ERR_EINVAL TDB_ERR_RDONLY = _tdb.TDB_ERR_RDONLY class tdb(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - def __init__(self): raise AttributeError, "No constructor defined" + def __init__(self, *args, **kwargs): raise AttributeError, "No constructor defined" __repr__ = _swig_repr __swig_destroy__ = _tdb.delete_tdb - def __str__(self): - return self.name() + def __repr__(self): + return "Tdb('%s')" % self.name() def __getitem__(self, key): diff --git a/source4/lib/tdb/tdb_wrap.c b/source4/lib/tdb/tdb_wrap.c index 6a5b7feffc..f36d569937 100644 --- a/source4/lib/tdb/tdb_wrap.c +++ b/source4/lib/tdb/tdb_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2500,7 +2518,7 @@ static swig_module_info swig_module = {swig_types, 11, 0, 0, 0, 0}; #define SWIG_name "_tdb" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -3753,7 +3771,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -3763,6 +3781,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -3791,6 +3812,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); -- cgit From 868c45102d98f4207e614d79af2f37dbb0418203 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 08:06:50 +1000 Subject: Don't regenerate pam_errors.h any more. Due to the new rules on prototypes, it must be a static header file. Andrew Bartlett (This used to be commit cf60a9b34ec2419b2bc03a37190cb17ad4cf3d5f) --- .gitignore | 1 - source4/auth/ntlm/config.mk | 2 -- 2 files changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 1ad2e2501f..5ed4eeda44 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ source/heimdal/lib/des/hcrypto source/build/smb_build/config.pm source/auth/auth_proto.h source/auth/auth_sam.h -source/auth/pam_errors.h source/auth/credentials/credentials_proto.h source/auth/gensec/gensec_proto.h source/auth/gensec/schannel_proto.h diff --git a/source4/auth/ntlm/config.mk b/source4/auth/ntlm/config.mk index d812816a91..f31c2b7279 100644 --- a/source4/auth/ntlm/config.mk +++ b/source4/auth/ntlm/config.mk @@ -70,8 +70,6 @@ auth_unix_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, auth_unix.o) [SUBSYSTEM::PAM_ERRORS] -$(eval $(call proto_header_template,$(authsrcdir)/ntlm/pam_errors.h,$(auth_unix_OBJ_FILES:.o=.c))) - #VERSION = 0.0.1 #SO_VERSION = 0 PAM_ERRORS_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, pam_errors.o) -- cgit From 1323e3e736803885c9ab2ce496a5a4dc429a753a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 May 2008 01:02:05 +0200 Subject: Fix proto generation. (This used to be commit 7385d9641d49b94c83fd2c75e57c9623d21fcdb0) --- source4/auth/ntlmssp/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/auth/ntlmssp/config.mk b/source4/auth/ntlmssp/config.mk index ca58e28a24..129f58de83 100644 --- a/source4/auth/ntlmssp/config.mk +++ b/source4/auth/ntlmssp/config.mk @@ -2,7 +2,7 @@ MSRPC_PARSE_OBJ_FILES = $(addprefix $(authsrcdir)/ntlmssp/, ntlmssp_parse.o) -$(eval $(call proto_header_template,$(authsrcdir)/ntlmssp/msrpc_parse.h,$(MSRPC_PARSE_OBJ_FILES))) +$(eval $(call proto_header_template,$(authsrcdir)/ntlmssp/msrpc_parse.h,$(MSRPC_PARSE_OBJ_FILES:.o=.c))) ################################################ # Start MODULE gensec_ntlmssp -- cgit From 7015b7840c0e8bc85c77de2442b46a8c71449163 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 May 2008 01:52:11 +0200 Subject: Update tdb version number. (This used to be commit eae17ae8ecdcb83fdb756189a9d5609a192371a4) --- source4/lib/tdb/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/tdb/configure.ac b/source4/lib/tdb/configure.ac index 9b16a82c33..eaf70d30b4 100644 --- a/source4/lib/tdb/configure.ac +++ b/source4/lib/tdb/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.1.1) +AC_INIT(tdb, 1.1.2) AC_CONFIG_SRCDIR([common/tdb.c]) AC_CONFIG_HEADER(include/config.h) AC_LIBREPLACE_ALL_CHECKS -- cgit From 8052309d5a4d0d4b7c63806cfdba5e6dcc161461 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 10:58:43 +1000 Subject: Add the core of the new CLDAP/NBT 'netlogon' parsing library. This uses some hand-adjusted PIDL output to cope with some 'oddities' in the parsing of the _EX varient of the netlogon packet. Andrew Bartlett (This used to be commit 6e357d00474de65395ca51524d3b85d00691baf2) --- source4/libcli/netlogon.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++ source4/libcli/netlogon.h | 53 ++++++++ 2 files changed, 364 insertions(+) create mode 100644 source4/libcli/netlogon.c create mode 100644 source4/libcli/netlogon.h diff --git a/source4/libcli/netlogon.c b/source4/libcli/netlogon.c new file mode 100644 index 0000000000..3ef7cf6335 --- /dev/null +++ b/source4/libcli/netlogon.c @@ -0,0 +1,311 @@ +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +#include "includes.h" +#include "libcli/netlogon.h" + +_PUBLIC_ enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz)); + NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site)); + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site)); + if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + { + struct ndr_push *_ndr_sockaddr; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags))); + } + } + if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site)); + } + NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r, + uint32_t nt_version_flags) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ZERO_STRUCTP(r); + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz)); + NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site)); + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site)); + if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) { + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size)); + { + struct ndr_pull *_ndr_sockaddr; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size)); + NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size)); + } + } + if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) { + NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site)); + } + NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version)); + if (r->nt_version != nt_version_flags) { + return NDR_ERR_VALIDATE; + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid)); + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + enum ndr_err_code ndr_err; + if (response->ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40); + } else if (response->ntver & NETLOGON_NT_VERSION_5EX) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5_ex, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags); + } else if (response->ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE); + } else { + DEBUG(0, ("Asked to push unknown netlogon response type 0x%02x\n", response->ntver)); + return NT_STATUS_INVALID_PARAMETER; + } + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to push netlogon response of type 0x%02x\n", + response->ntver)); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + uint32_t ntver; + enum ndr_err_code ndr_err; + + if (data->length < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* lmnttoken */ + if (SVAL(data->data, data->length - 4) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + /* lm20token */ + if (SVAL(data->data, data->length - 2) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + ntver = IVAL(data->data, data->length - 8); + + if (ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40); + response->ntver = NETLOGON_NT_VERSION_1; + } else if (ntver & NETLOGON_NT_VERSION_5EX) { + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(data, mem_ctx, iconv_convenience); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(ndr, NDR_SCALARS|NDR_BUFFERS, &response->nt5_ex, ntver); + if (ndr->offset < ndr->data_size) { + ndr_err = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES, + "not all bytes consumed ofs[%u] size[%u]", + ndr->offset, ndr->data_size); + } + response->ntver = NETLOGON_NT_VERSION_5EX; + + } else if (ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE); + response->ntver = NETLOGON_NT_VERSION_5; + } else { + DEBUG(2,("failed to parse netlogon response of type 0x%02x - unknown response type\n", + ntver)); + dump_data(10, data->data, data->length); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to parse netlogon response of type 0x%02x\n", + ntver)); + dump_data(10, data->data, data->length); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response) +{ + struct NETLOGON_SAM_LOGON_RESPONSE_EX response_5_ex; + switch (response->ntver) { + case NETLOGON_NT_VERSION_5EX: + break; + case NETLOGON_NT_VERSION_5: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt5.command; + response_5_ex.pdc_name = response->nt5.pdc_name; + response_5_ex.user_name = response->nt5.user_name; + response_5_ex.domain = response->nt5.domain_name; + response_5_ex.domain_uuid = response->nt5.domain_uuid; + response_5_ex.forest = response->nt5.forest; + response_5_ex.dns_domain = response->nt5.dns_domain; + response_5_ex.pdc_dns_name = response->nt5.pdc_dns_name; + response_5_ex.sockaddr.pdc_ip = response->nt5.pdc_ip; + response_5_ex.server_type = response->nt5.server_type; + response_5_ex.nt_version = response->nt5.nt_version; + response_5_ex.lmnt_token = response->nt5.lmnt_token; + response_5_ex.lm20_token = response->nt5.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + + case NETLOGON_NT_VERSION_1: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt4.command; + response_5_ex.pdc_name = response->nt4.server; + response_5_ex.user_name = response->nt4.user_name; + response_5_ex.domain = response->nt4.domain; + response_5_ex.nt_version = response->nt4.nt_version; + response_5_ex.lmnt_token = response->nt4.lmnt_token; + response_5_ex.lm20_token = response->nt4.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + } + return; +} + +NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum ndr_err_code ndr_err; + switch (response->response_type) { + case NETLOGON_GET_PDC: + ndr_err = ndr_push_struct_blob(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + break; + case NETLOGON_SAMLOGON: + status = push_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + break; + } + return status; +} + + +NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum netlogon_command command; + enum ndr_err_code ndr_err; + if (data->length < 4) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + command = SVAL(data->data, 0); + + switch (command) { + case NETLOGON_RESPONSE_FROM_PDC: + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + response->response_type = NETLOGON_GET_PDC; + break; + case LOGON_SAM_LOGON_RESPONSE: + case LOGON_SAM_LOGON_PAUSE_RESPONSE: + case LOGON_SAM_LOGON_USER_UNKNOWN: + case LOGON_SAM_LOGON_RESPONSE_EX: + case LOGON_SAM_LOGON_PAUSE_RESPONSE_EX: + case LOGON_SAM_LOGON_USER_UNKNOWN_EX: + status = pull_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + response->response_type = NETLOGON_SAMLOGON; + break; + + /* These levels are queries, not responses */ + case LOGON_PRIMARY_QUERY: + case NETLOGON_ANNOUNCE_UAS: + case LOGON_SAM_LOGON_REQUEST: + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + return status; + +} diff --git a/source4/libcli/netlogon.h b/source4/libcli/netlogon.h new file mode 100644 index 0000000000..b8615b55a5 --- /dev/null +++ b/source4/libcli/netlogon.h @@ -0,0 +1,53 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 2008 + + 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 . +*/ + +#ifndef __LIBCLI_NETLOGON_H__ +#define __LIBCLI_NETLOGON_H__ + +#include "librpc/gen_ndr/ndr_nbt.h" + +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_svcctl.h" +#include "librpc/gen_ndr/ndr_samr.h" + +struct netlogon_samlogon_response +{ + uint32_t ntver; + union { + struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4; + struct NETLOGON_SAM_LOGON_RESPONSE nt5; + struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex; + }; + +}; + +struct nbt_netlogon_response +{ + enum {NETLOGON_GET_PDC, NETLOGON_SAMLOGON} response_type; + union { + struct nbt_netlogon_response_from_pdc get_pdc; + struct netlogon_samlogon_response samlogon; + }; +}; + +#include "libcli/netlogon_proto.h" +#endif /* __CLDAP_SERVER_PROTO_H__ */ -- cgit From e533e7a7ebc8b3029cf604e63cdc6d1cf8570ccd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 20 May 2008 11:24:38 +1000 Subject: Fix prototype generation in new syntax for netlogon.c Andrew Bartlett (This used to be commit b6f91ce75ae401bed515012fa3019a6241e7ff6d) --- source4/libcli/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index c8056dbe63..0cc97c058a 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -63,7 +63,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ netlogon.o) -$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i -- cgit