From f22f04f76beba755ed5fcc7385de7b366b71032c Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 29 Sep 2008 22:47:07 +0200 Subject: Stop creating symlinks to libraries without sonames. (caused recursive symlinks overwriting the original file). --- source4/script/installlib.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/script/installlib.sh b/source4/script/installlib.sh index 962c9562b1..cc9ff0b9ea 100755 --- a/source4/script/installlib.sh +++ b/source4/script/installlib.sh @@ -15,7 +15,9 @@ for p in $*; do mv $LIBDIR/$p2 $LIBDIR/$p2.old fi cp $p $LIBDIR/ - ln -sf $p2 $LIBDIR/$lnname + if [ $p2 != $lnname ]; then + ln -sf $p2 $LIBDIR/$lnname + fi done cat << EOF -- cgit From 744667b3a9bc9d4d48e842378612b40b3539840a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 29 Sep 2008 22:57:16 +0200 Subject: Consistently use lower case variable names for path variables. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Matthias Dieter Wallnöfer and me. --- source4/Makefile | 32 ++++++++++++++++---------------- source4/dynconfig/config.mk | 12 ++++++------ 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'source4') diff --git a/source4/Makefile b/source4/Makefile index 813f0cedd4..cb4aa0e916 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -10,11 +10,11 @@ include mkconfig.mk pidldir := $(srcdir)/../pidl -BASEDIR = $(prefix) -TORTUREDIR = $(libdir)/torture -SWATDIR = $(datadir)/swat -SETUPDIR = $(datadir)/setup -NCALRPCDIR = $(localstatedir)/ncalrpc +basedir = $(prefix) +torturedir = $(libdir)/torture +swatdir = $(datadir)/swat +setupdir = $(datadir)/setup +ncalrpcdir = $(localstatedir)/ncalrpc BNLD = $(LD) BNLD_FLAGS = $(LDFLAGS) $(SYS_LDFLAGS) @@ -133,7 +133,7 @@ include $(srcdir)/static_deps.mk endif clean:: - @find ../lib ../libcli -name '*.o' -o -name '*.hd' | xargs rm -f + @find ../lib ../libcli -name '*.o' -o -name '*.hd' | xargs rm -f DEFAULT_HEADERS = $(srcdir)/lib/util/dlinklist.h \ $(srcdir)/version.h @@ -155,7 +155,7 @@ testsuite:: bin/smbclient bin/cifsdd bin/smbtorture bin/nmblookup showlayout:: @echo 'Samba will be installed into:' - @echo ' basedir: $(BASEDIR)' + @echo ' basedir: $(basedir)' @echo ' bindir: $(bindir)' @echo ' sbindir: $(sbindir)' @echo ' libdir: $(libdir)' @@ -166,10 +166,10 @@ showlayout:: @echo ' piddir: $(piddir)' @echo ' lockdir: $(lockdir)' @echo ' logfilebase: $(logfilebase)' - @echo ' setupdir: $(SETUPDIR)' - @echo ' swatdir: $(SWATDIR)' + @echo ' setupdir: $(setupdir)' + @echo ' swatdir: $(swatdir)' @echo ' mandir: $(mandir)' - @echo ' torturedir: $(TORTUREDIR)' + @echo ' torturedir: $(torturedir)' @echo ' datadir: $(datadir)' @echo ' winbindd_socket_dir: $(winbindd_socket_dir)' @echo ' ntp_signd_socket_dir: $(ntp_signd_socket_dir)' @@ -194,10 +194,10 @@ install:: showlayout everything installbin installsbin installdat installswat in installdirs:: @$(SHELL) $(srcdir)/script/installdirs.sh \ - $(DESTDIR)$(BASEDIR) \ + $(DESTDIR)$(basedir) \ $(DESTDIR)$(bindir) \ $(DESTDIR)$(sbindir) \ - $(DESTDIR)$(TORTUREDIR) \ + $(DESTDIR)$(torturedir) \ $(DESTDIR)$(libdir) \ $(DESTDIR)$(modulesdir) \ $(DESTDIR)$(mandir) \ @@ -211,7 +211,7 @@ installdirs:: $(DESTDIR)$(logfilebase) \ $(DESTDIR)$(privatedir)/tls \ $(DESTDIR)$(includedir) \ - $(DESTDIR)$(PKGCONFIGDIR) \ + $(DESTDIR)$(pkgconfigdir) \ $(DESTDIR)$(sysconfdir) installbin:: installdirs @@ -230,16 +230,16 @@ installdat:: installdirs installswat:: installdirs #SWAT has been disabled until further notice -# @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(SWATDIR) $(srcdir) +# @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(swatdir) $(srcdir) installman:: manpages installdirs @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(mandir) $(MANPAGES) installmisc:: installdirs - @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(SETUPDIR) $(DESTDIR)$(bindir) + @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(setupdir) $(DESTDIR)$(bindir) installpc:: installdirs - @$(SHELL) $(srcdir)/script/installpc.sh $(builddir) $(DESTDIR)$(PKGCONFIGDIR) $(PC_FILES) + @$(SHELL) $(srcdir)/script/installpc.sh $(builddir) $(DESTDIR)$(pkgconfigdir) $(PC_FILES) uninstall:: uninstallbin uninstallman uninstallmisc uninstalllib uninstallheader \ uninstallplugins diff --git a/source4/dynconfig/config.mk b/source4/dynconfig/config.mk index 699c30e764..f79cdb8e75 100644 --- a/source4/dynconfig/config.mk +++ b/source4/dynconfig/config.mk @@ -6,19 +6,19 @@ DYNCONFIG_OBJ_FILES = $(dynconfigsrcdir)/dynconfig.o # These can be overridden by command line switches (see samba(8)) # or in smb.conf (see smb.conf(5)) CONFIG4FILE = $(sysconfdir)/smb.conf -PKGCONFIGDIR = $(libdir)/pkgconfig +pkgconfigdir = $(libdir)/pkgconfig LMHOSTSFILE4 = $(sysconfdir)/lmhosts $(dynconfigsrcdir)/dynconfig.o: CFLAGS+=-DCONFIGFILE=\"$(CONFIG4FILE)\" -DBINDIR=\"$(bindir)\" \ -DLMHOSTSFILE=\"$(LMHOSTSFILE4)\" \ -DLOCKDIR=\"$(lockdir)\" -DPIDDIR=\"$(piddir)\" -DDATADIR=\"$(datadir)\" \ -DLOGFILEBASE=\"$(logfilebase)\" \ - -DCONFIGDIR=\"$(sysconfdir)\" -DNCALRPCDIR=\"$(NCALRPCDIR)\" \ - -DSWATDIR=\"$(SWATDIR)\" \ + -DCONFIGDIR=\"$(sysconfdir)\" -DNCALRPCDIR=\"$(ncalrpcdir)\" \ + -DSWATDIR=\"$(swatdir)\" \ -DPRIVATE_DIR=\"$(privatedir)\" \ - -DMODULESDIR=\"$(modulesdir)\" -DJSDIR=\"$(JSDIR)\" \ - -DTORTUREDIR=\"$(TORTUREDIR)\" \ - -DSETUPDIR=\"$(SETUPDIR)\" \ + -DMODULESDIR=\"$(modulesdir)\" \ + -DTORTUREDIR=\"$(torturedir)\" \ + -DSETUPDIR=\"$(setupdir)\" \ -DWINBINDD_PRIVILEGED_SOCKET_DIR=\"$(winbindd_privileged_socket_dir)\" \ -DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\" \ -DNTP_SIGND_SOCKET_DIR=\"$(ntp_signd_socket_dir)\" -- cgit From dd4d309cac42c353c118d50e2f47ed0d27f429fb Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 29 Sep 2008 23:34:05 +0200 Subject: Patch by Matthias that removes old SWAT support and fixes uninstall. --- source4/Makefile | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'source4') diff --git a/source4/Makefile b/source4/Makefile index cb4aa0e916..8f31979f21 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -181,7 +181,7 @@ showflags:: # The permissions to give the executables INSTALLPERMS = 0755 -install:: showlayout everything installbin installsbin installdat installswat installmisc \ +install:: showlayout everything installbin installsbin installdat installmisc \ installlib installheader installpc installplugins # DESTDIR is used here to prevent packagers wasting their time @@ -228,10 +228,6 @@ installheader:: headers installdirs installdat:: installdirs @$(SHELL) $(srcdir)/script/installdat.sh $(DESTDIR)$(datadir) $(srcdir) -installswat:: installdirs -#SWAT has been disabled until further notice -# @$(SHELL) $(srcdir)/script/installswat.sh $(DESTDIR)$(swatdir) $(srcdir) - installman:: manpages installdirs @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(mandir) $(MANPAGES) @@ -241,11 +237,12 @@ installmisc:: installdirs installpc:: installdirs @$(SHELL) $(srcdir)/script/installpc.sh $(builddir) $(DESTDIR)$(pkgconfigdir) $(PC_FILES) -uninstall:: uninstallbin uninstallman uninstallmisc uninstalllib uninstallheader \ - uninstallplugins +uninstall:: uninstallbin uninstallsbin uninstalldat uninstallmisc uninstalllib uninstallheader \ + uninstallman uninstallpc uninstallplugins uninstallmisc:: - #FIXME + @echo "Removing MISC files" + @cd $(DESTDIR)$(bindir); rm -f $(notdir $(miscbinfiles)) $(DESTDIR)$(bindir)/%: bin/% installdirs @mkdir -p $(@D) @@ -261,19 +258,27 @@ $(DESTDIR)$(sbindir)/%: bin/% installdirs @cp $< $@ @chmod $(INSTALLPERMS) $@ +uninstalldat:: + @echo "Removing DAT files" + @rm -fr $(DESTDIR)$(datadir)/* + uninstallbin:: uninstalllib:: + @echo "Removing libraries" @$(SHELL) $(srcdir)/script/uninstalllib.sh $(DESTDIR)$(libdir) $(SHARED_LIBS) - #@$(SHELL) $(srcdir)/script/uninstalllib.sh $(DESTDIR)$(libdir) $(STATIC_LIBS) uninstallheader:: - @$(SHELL) $(srcdir)/script/uninstallheader.sh $(DESTDIR)$(includedir) $(PUBLIC_HEADERS) + @echo "Removing headers" + @rm -fr $(DESTDIR)$(includedir)/* uninstallman:: + @echo "Removing manpages" @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(mandir) $(MANPAGES) -uninstallplugins:: +uninstallpc:: + @echo "Removing package configurations" + @cd $(DESTDIR)$(pkgconfigdir); rm -f $(notdir $(PC_FILES)) config.status: @echo "config.status does not exist. Please run ./configure." -- cgit From 2ed71ce6bc97cbb9b854bb24ab49001910eda36d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 00:28:06 +0200 Subject: Remove ldb_module_wait implementation - ldb_module.wait() is gone. --- source4/lib/ldb/ldb.i | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 1e3a3169c8..024ba1959a 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -1219,22 +1219,6 @@ int py_module_del_transaction(struct ldb_module *mod) return LDB_SUCCESS; } -int py_module_wait(struct ldb_handle *mod, enum ldb_wait_type wait_type) -{ - PyObject *py_ldb = mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, "wait", "i", wait_type); - - if (py_result == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - int py_module_sequence_number(struct ldb_module *mod, struct ldb_request *req) { PyObject *py_ldb = mod->private_data; @@ -1308,7 +1292,6 @@ int py_module_init (struct ldb_module *mod) $1->start_transaction = py_module_start_transaction; $1->end_transaction = py_module_end_transaction; $1->del_transaction = py_module_del_transaction; - $1->wait = py_module_wait; $1->sequence_number = py_module_sequence_number; } -- cgit From f379f67dd287292e3bb7b606f1bdc3fe7a8db59c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 00:29:03 +0200 Subject: Fix installation of misc files. --- source4/Makefile | 13 +++++++++++-- source4/dynconfig/dynconfig.c | 3 --- source4/script/installmisc.sh | 6 ------ 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4') diff --git a/source4/Makefile b/source4/Makefile index 8f31979f21..71529305b4 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -107,6 +107,15 @@ comsrcdir := $(srcdir)/lib/com include data.mk +$(foreach SCRIPT,$(wildcard scripting/bin/*),$(eval $(call binary_install_template,$(SCRIPT)))) + +$(DESTDIR)$(bindir)/%: scripting/bin/% installdirs + @mkdir -p $(@D) + @echo Installing $(@F) as $@ + @if test -f $@; then echo -n ""; rm -f $@.old; mv $@ $@.old; fi + @cp $< $@ + @chmod $(INSTALLPERMS) $@ + pythonmods:: $(PYTHON_PYS) $(PYTHON_SO) DEP_FILES = $(patsubst %.ho,%.hd,$(patsubst %.o,%.d,$(ALL_OBJS))) \ @@ -232,7 +241,7 @@ installman:: manpages installdirs @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(mandir) $(MANPAGES) installmisc:: installdirs - @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(setupdir) $(DESTDIR)$(bindir) + @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(setupdir) installpc:: installdirs @$(SHELL) $(srcdir)/script/installpc.sh $(builddir) $(DESTDIR)$(pkgconfigdir) $(PC_FILES) @@ -242,7 +251,7 @@ uninstall:: uninstallbin uninstallsbin uninstalldat uninstallmisc uninstalllib u uninstallmisc:: @echo "Removing MISC files" - @cd $(DESTDIR)$(bindir); rm -f $(notdir $(miscbinfiles)) + @rm -rf $(DESTDIR)$(setupdir)/* $(DESTDIR)$(bindir)/%: bin/% installdirs @mkdir -p $(@D) diff --git a/source4/dynconfig/dynconfig.c b/source4/dynconfig/dynconfig.c index 507570318d..e0cabef317 100644 --- a/source4/dynconfig/dynconfig.c +++ b/source4/dynconfig/dynconfig.c @@ -79,9 +79,6 @@ _PUBLIC_ const char *dyn_SWATDIR = SWATDIR; /** SETUP files (source files used by the provision) */ _PUBLIC_ const char *dyn_SETUPDIR = SETUPDIR; -/** EJS Javascript library includes */ -_PUBLIC_ const char *dyn_JSDIR = JSDIR; - /** Where to find the winbindd socket */ _PUBLIC_ const char *dyn_WINBINDD_SOCKET_DIR = WINBINDD_SOCKET_DIR; diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh index eb347307ba..2bd34b119f 100755 --- a/source4/script/installmisc.sh +++ b/source4/script/installmisc.sh @@ -3,7 +3,6 @@ SRCDIR="$1" SETUPDIR="$2" -BINDIR="$3" cd $SRCDIR || exit 1 @@ -25,9 +24,4 @@ cp setup/provision.smb.conf.dc $SETUPDIR || exit 1 cp setup/provision.smb.conf.member $SETUPDIR || exit 1 cp setup/provision.smb.conf.standalone $SETUPDIR || exit 1 -echo "Installing script tools" -mkdir -p "$BINDIR" -rm -f scripting/bin/*~ -cp scripting/bin/* $BINDIR/ || exit 1 - exit 0 -- cgit From 257fe87efd079ccc085e67d04c7797dbf2e84c51 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 00:32:20 +0200 Subject: Re-add uninstallplugins, there has to be at least one instance of this. --- source4/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4') diff --git a/source4/Makefile b/source4/Makefile index 71529305b4..74383b1a59 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -285,6 +285,8 @@ uninstallman:: @echo "Removing manpages" @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(mandir) $(MANPAGES) +uninstallplugins:: + uninstallpc:: @echo "Removing package configurations" @cd $(DESTDIR)$(pkgconfigdir); rm -f $(notdir $(PC_FILES)) -- cgit From 21df9532f54ad15c308630672f3b8a6dc4ce6294 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 00:48:13 +0200 Subject: Remove unused uninstallheader script. --- source4/script/uninstallheader.sh | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100755 source4/script/uninstallheader.sh (limited to 'source4') diff --git a/source4/script/uninstallheader.sh b/source4/script/uninstallheader.sh deleted file mode 100755 index cb491f071a..0000000000 --- a/source4/script/uninstallheader.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# based on uninstallbin.sh: -# 4 July 96 Dan.Shearer@UniSA.edu.au - -INCLUDEDIR=$1 -shift - -if [ ! -d $INCLUDEDIR ]; then - echo Directory $INCLUDEDIR does not exist! - echo Do a "make installbin" or "make install" first. - exit 1 -fi - -for p in $*; do - p2=`basename $p` - if [ -f $INCLUDEDIR/$p2 ]; then - echo Removing $INCLUDEDIR/$p2 - rm -f $INCLUDEDIR/$p2 - if [ -f $INCLUDEDIR/$p2 ]; then - echo Cannot remove $INCLUDEDIR/$p2 ... does $USER have privileges? - fi - fi -done - - -cat << EOF -====================================================================== -The headers have been uninstalled. You may restore the headers using -the command "make installheader" or "make install" to install binaries, -man pages, modules and shell scripts. You can restore a previous -version of the headers (if there were any) using "make revert". -====================================================================== -EOF - -exit 0 -- cgit From c8a19f0b8373bec27f4d3638bb731963896f3ff5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 01:29:53 +0200 Subject: Pass options struct into session initialization functions rather than using global_loadparm. --- source4/libcli/cliconnect.c | 6 +++++- source4/libcli/raw/clisession.c | 7 +++---- source4/libcli/smb_composite/connect.c | 5 ++++- source4/param/loadparm.c | 8 ++++++++ source4/param/param.h | 3 +++ source4/torture/basic/secleak.c | 5 ++++- source4/torture/raw/context.c | 26 ++++++++++++++++++-------- source4/torture/raw/lock.c | 5 ++++- source4/torture/rpc/samba3rpc.c | 8 ++++++-- 9 files changed, 55 insertions(+), 18 deletions(-) (limited to 'source4') diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c20a7fd935..6fb9f130a9 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -73,8 +73,12 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, { struct smb_composite_sesssetup setup; NTSTATUS status; + struct smbcli_session_options options; - cli->session = smbcli_session_init(cli->transport, cli, true); + lp_smbcli_session_options(global_loadparm, &options); + + cli->session = smbcli_session_init(cli->transport, cli, true, + options); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; setup.in.sesskey = cli->transport->negotiate.sesskey; diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c index ad4ca7b471..38d8f700f2 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -35,7 +35,8 @@ Initialize the session context ****************************************************************************/ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, - TALLOC_CTX *parent_ctx, bool primary) + TALLOC_CTX *parent_ctx, bool primary, + struct smbcli_session_options options) { struct smbcli_session *session; uint16_t flags2; @@ -53,9 +54,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, } session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; - session->options.lanman_auth = lp_client_lanman_auth(global_loadparm); - session->options.ntlmv2_auth = lp_client_ntlmv2_auth(global_loadparm); - session->options.plaintext_auth = lp_client_plaintext_auth(global_loadparm); + session->options = options; capabilities = transport->negotiate.capabilities; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index e56339f96b..5f651f4865 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -229,12 +229,15 @@ static NTSTATUS connect_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); NTSTATUS status; + struct smbcli_session_options options; + + lp_smbcli_session_options(global_loadparm, &options); status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, true); + state->session = smbcli_session_init(state->transport, state, true, options); NT_STATUS_HAVE_NO_MEMORY(state->session); /* setup for a tconx (or at least have the structure ready to diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 15edbd1f89..0042dbd876 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -2629,3 +2629,11 @@ void lp_smbcli_options(struct loadparm_context *lp_ctx, options->use_oplocks = true; options->use_level2_oplocks = true; } + +void lp_smbcli_session_options(struct loadparm_context *lp_ctx, + struct smbcli_session_options *options) +{ + options->lanman_auth = lp_client_lanman_auth(lp_ctx); + options->ntlmv2_auth = lp_client_ntlmv2_auth(lp_ctx); + options->plaintext_auth = lp_client_plaintext_auth(lp_ctx); +} diff --git a/source4/param/param.h b/source4/param/param.h index 4ed2654692..4c6e8b79a2 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -60,6 +60,7 @@ enum announce_as {/* Types of machine we can announce as. */ struct loadparm_context; struct loadparm_service; struct smbcli_options; +struct smbcli_session_options; void reload_charcnv(struct loadparm_context *lp_ctx); @@ -318,6 +319,8 @@ int lp_maxprintjobs(struct loadparm_service *service, struct loadparm_service *s struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_ctx); void lp_smbcli_options(struct loadparm_context *lp_ctx, struct smbcli_options *options); +void lp_smbcli_session_options(struct loadparm_context *lp_ctx, + struct smbcli_session_options *options); /* The following definitions come from param/generic.c */ diff --git a/source4/torture/basic/secleak.c b/source4/torture/basic/secleak.c index 4caeee72a4..ca1fd444d9 100644 --- a/source4/torture/basic/secleak.c +++ b/source4/torture/basic/secleak.c @@ -36,8 +36,11 @@ static bool try_failed_login(struct torture_context *tctx, struct smbcli_state * NTSTATUS status; struct smb_composite_sesssetup setup; struct smbcli_session *session; + struct smbcli_session_options options; - session = smbcli_session_init(cli->transport, cli, false); + lp_smbcli_session_options(tctx->lp_ctx, &options); + + session = smbcli_session_init(cli->transport, cli, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); diff --git a/source4/torture/raw/context.c b/source4/torture/raw/context.c index 15e736fff5..450ad0f260 100644 --- a/source4/torture/raw/context.c +++ b/source4/torture/raw/context.c @@ -81,6 +81,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) const char *fname = BASEDIR "\\test.txt"; uint8_t c = 1; int i; + struct smbcli_session_options options; printf("TESTING SESSION HANDLING\n"); @@ -89,7 +90,10 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) } printf("create a second security context on the same transport\n"); - session = smbcli_session_init(cli->transport, tctx, false); + + lp_smbcli_session_options(tctx->lp_ctx, &options); + + session = smbcli_session_init(cli->transport, tctx, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */ @@ -103,7 +107,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) session->vuid = setup.out.vuid; printf("create a third security context on the same transport, with vuid set\n"); - session2 = smbcli_session_init(cli->transport, tctx, false); + session2 = smbcli_session_init(cli->transport, tctx, false, options); session2->vuid = session->vuid; setup.in.sesskey = cli->transport->negotiate.sesskey; @@ -130,7 +134,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) { printf("create a fourth security context on the same transport, without extended security\n"); - session3 = smbcli_session_init(cli->transport, tctx, false); + session3 = smbcli_session_init(cli->transport, tctx, false, options); session3->vuid = session->vuid; setup.in.sesskey = cli->transport->negotiate.sesskey; @@ -144,7 +148,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE); printf("create a fouth anonymous security context on the same transport, without extended security\n"); - session4 = smbcli_session_init(cli->transport, tctx, false); + session4 = smbcli_session_init(cli->transport, tctx, false, options); session4->vuid = session->vuid; setup.in.sesskey = cli->transport->negotiate.sesskey; @@ -230,7 +234,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) setups[i].in.credentials = cmdline_credentials; - sessions[i] = smbcli_session_init(cli->transport, tctx, false); + sessions[i] = smbcli_session_init(cli->transport, tctx, false, options); composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]); } @@ -379,6 +383,7 @@ static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context * const char *fname1 = BASEDIR "\\test1.txt"; const char *fname2 = BASEDIR "\\test2.txt"; uint8_t c = 1; + struct smbcli_session_options options; printf("TESTING TREE with ulogoff\n"); @@ -389,8 +394,10 @@ static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context * share = torture_setting_string(tctx, "share", NULL); host = torture_setting_string(tctx, "host", NULL); + lp_smbcli_session_options(tctx->lp_ctx, &options); + printf("create the first new sessions\n"); - session1 = smbcli_session_init(cli->transport, tctx, false); + session1 = smbcli_session_init(cli->transport, tctx, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); @@ -446,7 +453,7 @@ static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context * CHECK_STATUS(status, NT_STATUS_OK); printf("create the second new sessions\n"); - session2 = smbcli_session_init(cli->transport, tctx, false); + session2 = smbcli_session_init(cli->transport, tctx, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); @@ -634,6 +641,7 @@ static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tct const char *fname = BASEDIR "\\test.txt"; uint8_t c = 1; uint16_t vuid1, vuid2; + struct smbcli_session_options options; printf("TESTING PID HANDLING WITH 2 SESSIONS\n"); @@ -641,8 +649,10 @@ static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tct return false; } + lp_smbcli_session_options(tctx->lp_ctx, &options); + printf("create a second security context on the same transport\n"); - session = smbcli_session_init(cli->transport, tctx, false); + session = smbcli_session_init(cli->transport, tctx, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */ diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c index cd8d606795..dbe071c9ad 100644 --- a/source4/torture/raw/lock.c +++ b/source4/torture/raw/lock.c @@ -456,11 +456,14 @@ static bool test_async(struct torture_context *tctx, const char *fname = BASEDIR "\\test.txt"; time_t t; struct smbcli_request *req; + struct smbcli_session_options options; if (!torture_setup_dir(cli, BASEDIR)) { return false; } + lp_smbcli_session_options(tctx->lp_ctx, &options); + printf("Testing LOCKING_ANDX_CANCEL_LOCK\n"); io.generic.level = RAW_LOCK_LOCKX; @@ -590,7 +593,7 @@ static bool test_async(struct torture_context *tctx, } printf("create a new sessions\n"); - session = smbcli_session_init(cli->transport, tctx, false); + session = smbcli_session_init(cli->transport, tctx, false, options); setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 3bbf6cf223..e030b972f8 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -74,6 +74,7 @@ bool torture_bind_authcontext(struct torture_context *torture) struct cli_credentials *anon_creds; struct smb_composite_sesssetup setup; struct smbcli_options options; + struct smbcli_session_options session_options; mem_ctx = talloc_init("torture_bind_authcontext"); @@ -83,6 +84,7 @@ bool torture_bind_authcontext(struct torture_context *torture) } lp_smbcli_options(torture->lp_ctx, &options); + lp_smbcli_session_options(torture->lp_ctx, &session_options); status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), @@ -142,7 +144,7 @@ bool torture_bind_authcontext(struct torture_context *torture) goto done; } - session2 = smbcli_session_init(cli->transport, mem_ctx, false); + session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options); if (session2 == NULL) { d_printf("smbcli_session_init failed\n"); goto done; @@ -1670,12 +1672,14 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) struct cli_credentials *user_creds; char *domain_name; struct smbcli_options options; + struct smbcli_session_options session_options; if (!(mem_ctx = talloc_new(torture))) { return false; } lp_smbcli_options(torture->lp_ctx, &options); + lp_smbcli_session_options(torture->lp_ctx, &session_options); status = smbcli_full_connection( mem_ctx, &cli, torture_setting_string(torture, "host", NULL), @@ -1762,7 +1766,7 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) struct smb_composite_sesssetup setup; struct smbcli_tree *tree; - session2 = smbcli_session_init(cli->transport, mem_ctx, false); + session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options); if (session2 == NULL) { d_printf("(%s) smbcli_session_init failed\n", __location__); -- cgit From 83183bf38190b867ca4bb7ebda1136803e36f777 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 01:38:51 +0200 Subject: Explicitly pass on session options to session setup function. --- source4/client/smbmount.c | 19 ++++++++++++++----- source4/libcli/cliconnect.c | 6 ++---- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'source4') diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c index 9ab6c375f2..37c9eaadc4 100644 --- a/source4/client/smbmount.c +++ b/source4/client/smbmount.c @@ -111,7 +111,8 @@ static void usr1_handler(int x) /***************************************************** return a connection to a server *******************************************************/ -static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol) +static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol, + struct smbcli_session_options session_options) { struct smbcli_state *c; struct nmb_name called, calling; @@ -210,11 +211,12 @@ static struct smbcli_state *do_connection(const char *the_service, bool unicode, if (!smbcli_session_setup(c, username, password, strlen(password), password, strlen(password), - workgroup)) { + workgroup, session_options)) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || - !smbcli_session_setup(c, "", "", 0, "", 0, workgroup)) { + !smbcli_session_setup(c, "", "", 0, "", 0, workgroup, + session_options)) { DEBUG(0,("%d: session setup failed: %s\n", sys_getpid(), smbcli_errstr(c))); talloc_free(c); @@ -329,6 +331,9 @@ static void send_fs_socket(struct loadparm_context *lp_ctx, int fd, closed = 0, res = 1; pid_t parentpid = getppid(); struct smb_conn_opt conn_options; + struct smbcli_session_options session_options; + + lp_smbcli_session_options(lp_ctx, &session_options); memset(&conn_options, 0, sizeof(conn_options)); @@ -409,7 +414,8 @@ static void send_fs_socket(struct loadparm_context *lp_ctx, DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid())); c = do_connection(the_service, lp_unicode(lp_ctx), - lp_cli_maxprotocol(lp_ctx)); + lp_cli_maxprotocol(lp_ctx), + session_options); } } @@ -430,14 +436,17 @@ static void init_mount(struct loadparm_context *lp_ctx) struct smbcli_state *c; char *args[20]; int i, status; + struct smbcli_session_options session_options; if (realpath(mpoint, mount_point) == NULL) { fprintf(stderr, "Could not resolve mount point %s\n", mpoint); return; } + lp_smbcli_session_options(lp_ctx, &session_options); - c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx)); + c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx), + session_options); if (!c) { fprintf(stderr,"SMB connection failed\n"); exit(1); diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 6fb9f130a9..3b1c3c5314 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -69,13 +69,11 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) /* wrapper around smb_raw_sesssetup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, struct cli_credentials *credentials, - const char *workgroup) + const char *workgroup, + struct smbcli_session_options options) { struct smb_composite_sesssetup setup; NTSTATUS status; - struct smbcli_session_options options; - - lp_smbcli_session_options(global_loadparm, &options); cli->session = smbcli_session_init(cli->transport, cli, true, options); -- cgit From 9de1472bd1848363dfce1644ce7b971486551ec3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 01:58:06 +0200 Subject: Remove redundant call. --- source4/librpc/rpc/dcerpc_connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 318b8fe36d..7bdca2d986 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -137,7 +137,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT /* send smb connect request */ conn_req = smb_composite_connect_send(conn, s->io.pipe->conn, - lp_resolve_context(lp_ctx), + s->io.resolve_ctx, s->io.pipe->conn->event_ctx); if (composite_nomem(conn_req, c)) return c; -- cgit From 43d944e6d6b66cf67ee857a62a439296738d3a59 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 01:59:10 +0200 Subject: Remove global_loadparm instance. --- source4/libnet/libnet_site.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c index bb65de1f54..5647a93b8d 100644 --- a/source4/libnet/libnet_site.c +++ b/source4/libnet/libnet_site.c @@ -56,7 +56,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li 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)); + cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(lctx->lp_ctx)); status = cldap_netlogon(cldap, tmp_ctx, &search); if (!NT_STATUS_IS_OK(status) || !search.out.netlogon.nt5_ex.client_site) { /* -- cgit From 755ad80e2932f2114941adeb13f8879010484ff8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 02:07:14 +0200 Subject: Remove uses of global_loadparm. --- source4/torture/rpc/samlogon.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 4fbffee41e..b7028e6609 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -53,7 +53,9 @@ struct samlogon_state { const char *comment; const char *account_name; const char *account_domain; + const char *netbios_name; const char *password; + const char *workgroup; struct dcerpc_pipe *p; int function_level; uint32_t parameter_control; @@ -593,7 +595,7 @@ static bool test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_session_key = data_blob(NULL, 0); DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, TEST_MACHINE_NAME, lp_workgroup(global_loadparm)); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, TEST_MACHINE_NAME, samlogon_state->workgroup); uint8_t lm_session_key[8]; uint8_t user_session_key[16]; @@ -741,7 +743,7 @@ static bool test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_session_key = data_blob(NULL, 0); DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0); - DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, lp_netbios_name(global_loadparm), lp_workgroup(global_loadparm)); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, samlogon_state->iconv_convenience, samlogon_state->netbios_name, samlogon_state->workgroup); DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24); DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16); @@ -1337,6 +1339,8 @@ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, samlogon_state.account_name = account_name; samlogon_state.account_domain = account_domain; samlogon_state.password = plain_pass; + samlogon_state.workgroup = lp_workgroup(tctx->lp_ctx); + samlogon_state.netbios_name = lp_netbios_name(tctx->lp_ctx); samlogon_state.p = p; samlogon_state.creds = creds; samlogon_state.expected_error = expected_error; -- cgit From 4e8cb60222ea13295eaff477625164dfd61e288f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 02:11:55 +0200 Subject: Remove global_loadparm instance. --- source4/libcli/smb_composite/fsinfo.c | 10 ++++++---- source4/torture/raw/composite.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 270d71f518..cd6e98547b 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -127,7 +127,8 @@ static void fsinfo_composite_handler(struct composite_context *creq) composite fsinfo call - connects to a tree and queries a file system information */ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, - struct smb_composite_fsinfo *io) + struct smb_composite_fsinfo *io, + struct resolve_context *resolve_ctx) { struct composite_context *c; struct fsinfo_state *state; @@ -160,7 +161,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, c->private_data = state; state->creq = smb_composite_connect_send(state->connect, state, - lp_resolve_context(global_loadparm), c->event_ctx); + resolve_ctx, c->event_ctx); if (state->creq == NULL) goto failed; @@ -197,9 +198,10 @@ NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ */ NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - struct smb_composite_fsinfo *io) + struct smb_composite_fsinfo *io, + struct resolve_context *resolve_ctx) { - struct composite_context *c = smb_composite_fsinfo_send(tree, io); + struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx); return smb_composite_fsinfo_recv(c, mem_ctx); } diff --git a/source4/torture/raw/composite.c b/source4/torture/raw/composite.c index d73ac1327e..a151854e59 100644 --- a/source4/torture/raw/composite.c +++ b/source4/torture/raw/composite.c @@ -358,7 +358,7 @@ static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx) c = talloc_array(tctx, struct composite_context *, torture_numops); for (i=0; itree,&io1); + c[i] = smb_composite_fsinfo_send(cli->tree, &io1, lp_resolve_context(tctx->lp_ctx)); c[i]->async.fn = loadfile_complete; c[i]->async.private_data = count; } -- cgit From cef80957c49c972e82a634724590b5fd5d6ca78f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 02:19:15 +0200 Subject: Remove global_loadparm instance, discard_const_p. --- source4/libnet/libnet_samdump_keytab.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/libnet/libnet_samdump_keytab.c b/source4/libnet/libnet_samdump_keytab.c index 0c4d3e5c59..4b71b0c24d 100644 --- a/source4/libnet/libnet_samdump_keytab.c +++ b/source4/libnet/libnet_samdump_keytab.c @@ -68,6 +68,11 @@ static NTSTATUS samdump_keytab_handle_user(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +struct libnet_samdump_keytab_data { + const char *keytab_name; + struct loadparm_context *lp_ctx; +}; + static NTSTATUS libnet_samdump_keytab_fn(TALLOC_CTX *mem_ctx, void *private, enum netr_SamDatabaseID database, @@ -75,8 +80,7 @@ static NTSTATUS libnet_samdump_keytab_fn(TALLOC_CTX *mem_ctx, char **error_string) { NTSTATUS nt_status = NT_STATUS_OK; - const char *keytab_name = private; - + struct libnet_samdump_keytab_data *data = private; *error_string = NULL; switch (delta->delta_type) { case NETR_DELTA_USER: @@ -85,8 +89,8 @@ static NTSTATUS libnet_samdump_keytab_fn(TALLOC_CTX *mem_ctx, if (database == SAM_DATABASE_DOMAIN) { nt_status = samdump_keytab_handle_user(mem_ctx, event_context_find(mem_ctx), - global_loadparm, - keytab_name, + data->lp_ctx, + data->keytab_name, delta); break; } @@ -101,14 +105,18 @@ static NTSTATUS libnet_samdump_keytab_fn(TALLOC_CTX *mem_ctx, NTSTATUS libnet_SamDump_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamDump_keytab *r) { NTSTATUS nt_status; + struct libnet_samdump_keytab_data data; struct libnet_SamSync r2; + data.keytab_name = r->in.keytab_name; + data.lp_ctx = ctx->lp_ctx; + r2.out.error_string = NULL; r2.in.binding_string = r->in.binding_string; r2.in.rid_crypt = true; r2.in.init_fn = NULL; r2.in.delta_fn = libnet_samdump_keytab_fn; - r2.in.fn_ctx = discard_const(r->in.keytab_name); + r2.in.fn_ctx = &data; r2.in.machine_account = r->in.machine_account; nt_status = libnet_SamSync_netlogon(ctx, mem_ctx, &r2); r->out.error_string = r2.out.error_string; -- cgit From 181ee01da67985f5db684500247d655ce72fe611 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 02:47:19 +0200 Subject: Pass session options around; saves another use of global_loadparm. --- source4/auth/ntlm/auth_server.c | 1 + source4/libcli/raw/clitree.c | 4 +++- source4/libcli/smb_composite/connect.c | 5 +---- source4/libcli/smb_composite/fetchfile.c | 1 + source4/libcli/smb_composite/fsinfo.c | 1 + source4/libcli/smb_composite/smb_composite.h | 2 ++ source4/librpc/rpc/dcerpc_connect.c | 1 + source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/torture/basic/misc.c | 1 + source4/torture/raw/composite.c | 1 + source4/torture/raw/lockbench.c | 1 + source4/torture/raw/openbench.c | 1 + 12 files changed, 15 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index bb8773e75e..539ae6aa80 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -80,6 +80,7 @@ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX io.in.workgroup = ""; /* only used with SPNEGO, disabled above */ io.in.options = smb_options; + lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options); status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx), ctx->auth_ctx->event_ctx); diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 15cd70833c..4b5d2dc397 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -177,7 +177,8 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { struct smb_composite_connect io; NTSTATUS status; @@ -200,6 +201,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, * is complete -- abartlet 2008-04-28 */ io.in.workgroup = lp_workgroup(global_loadparm); io.in.options = *options; + io.in.session_options = *session_options; status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 5f651f4865..a4137290bb 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -229,15 +229,12 @@ static NTSTATUS connect_negprot(struct composite_context *c, { struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); NTSTATUS status; - struct smbcli_session_options options; - - lp_smbcli_session_options(global_loadparm, &options); status = smb_raw_negotiate_recv(state->req); NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, true, options); + state->session = smbcli_session_init(state->transport, state, true, io->in.session_options); NT_STATUS_HAVE_NO_MEMORY(state->session); /* setup for a tconx (or at least have the structure ready to diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 9cd02a51f4..ff4f0e7930 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -147,6 +147,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.workgroup = io->in.workgroup; state->connect->in.options = io->in.options; + state->connect->in.session_options = io->in.session_options; state->creq = smb_composite_connect_send(state->connect, state, io->in.resolve_ctx, event_ctx); diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index cd6e98547b..dc5327a29c 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -155,6 +155,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.workgroup = io->in.workgroup; state->connect->in.options = tree->session->transport->options; + state->connect->in.session_options = tree->session->options; c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 7f4b9d73e4..08ca40c833 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -57,6 +57,7 @@ struct smb_composite_fetchfile { const char *workgroup; const char *filename; struct smbcli_options options; + struct smbcli_session_options session_options; struct resolve_context *resolve_ctx; } in; struct { @@ -98,6 +99,7 @@ struct smb_composite_connect { bool fallback_to_anonymous; const char *workgroup; struct smbcli_options options; + struct smbcli_session_options session_options; } in; struct { struct smbcli_tree *tree; diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 7bdca2d986..b117a98270 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -121,6 +121,7 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT conn->in.workgroup = lp_workgroup(lp_ctx); lp_smbcli_options(lp_ctx, &conn->in.options); + lp_smbcli_session_options(lp_ctx, &conn->in.session_options); /* * provide proper credentials - user supplied, but allow a diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 844fa11cc5..9bc36a1762 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -206,6 +206,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); + lp_smbcli_session_options(ntvfs->ctx->lp_ctx, &io.in.session_options); if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { io.in.options.use_level2_oplocks = false; diff --git a/source4/torture/basic/misc.c b/source4/torture/basic/misc.c index 24e0324bc3..c129fd586b 100644 --- a/source4/torture/basic/misc.c +++ b/source4/torture/basic/misc.c @@ -823,6 +823,7 @@ static struct composite_context *torture_connect_async( smb->in.fallback_to_anonymous=false; smb->in.workgroup=workgroup; lp_smbcli_options(tctx->lp_ctx, &smb->in.options); + lp_smbcli_session_options(tctx->lp_ctx, &smb->in.session_options); return smb_composite_connect_send(smb,mem_ctx, lp_resolve_context(tctx->lp_ctx),ev); diff --git a/source4/torture/raw/composite.c b/source4/torture/raw/composite.c index a151854e59..7f1f5943e1 100644 --- a/source4/torture/raw/composite.c +++ b/source4/torture/raw/composite.c @@ -164,6 +164,7 @@ static bool test_fetchfile(struct smbcli_state *cli, struct torture_context *tct io2.in.filename = fname; io2.in.resolve_ctx = lp_resolve_context(tctx->lp_ctx); lp_smbcli_options(tctx->lp_ctx, &io2.in.options); + lp_smbcli_session_options(tctx->lp_ctx, &io2.in.session_options); printf("testing parallel fetchfile with %d ops\n", torture_numops); diff --git a/source4/torture/raw/lockbench.c b/source4/torture/raw/lockbench.c index 21541d003b..26fad4235e 100644 --- a/source4/torture/raw/lockbench.c +++ b/source4/torture/raw/lockbench.c @@ -195,6 +195,7 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te, io->in.fallback_to_anonymous = false; io->in.workgroup = lp_workgroup(state->tctx->lp_ctx); lp_smbcli_options(state->tctx->lp_ctx, &io->in.options); + lp_smbcli_session_options(state->tctx->lp_ctx, &io->in.session_options); /* kill off the remnants of the old connection */ talloc_free(state->tree); diff --git a/source4/torture/raw/openbench.c b/source4/torture/raw/openbench.c index 26b862c33f..ec94637445 100644 --- a/source4/torture/raw/openbench.c +++ b/source4/torture/raw/openbench.c @@ -137,6 +137,7 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te, io->in.fallback_to_anonymous = false; io->in.workgroup = lp_workgroup(state->tctx->lp_ctx); lp_smbcli_options(state->tctx->lp_ctx, &io->in.options); + lp_smbcli_session_options(state->tctx->lp_ctx, &io->in.session_options); /* kill off the remnants of the old connection */ talloc_free(state->tree); -- cgit From 235b729309a17fa44fecf743db5fe6552f67f577 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 03:07:08 +0200 Subject: Cope with API changes. --- source4/client/cifsdd.c | 15 ++++++++++----- source4/client/cifsdd.h | 4 +++- source4/client/cifsddio.c | 17 +++++++++++------ source4/client/client.c | 9 ++++++--- source4/libcli/cliconnect.c | 6 ++++-- source4/torture/gentest.c | 5 ++++- source4/torture/locktest.c | 4 +++- source4/torture/locktest2.c | 19 ++++++++++++------- source4/torture/masktest.c | 9 ++++++--- source4/torture/raw/oplock.c | 5 +++-- source4/torture/raw/tconrate.c | 4 +++- source4/torture/rpc/join.c | 6 ++++-- source4/torture/rpc/samba3rpc.c | 18 ++++++++++++------ source4/torture/unix/unix_info2.c | 4 +++- source4/torture/unix/whoami.c | 4 +++- source4/torture/util_smb.c | 4 +++- 16 files changed, 90 insertions(+), 43 deletions(-) (limited to 'source4') diff --git a/source4/client/cifsdd.c b/source4/client/cifsdd.c index 141b165ad4..5f07826d06 100644 --- a/source4/client/cifsdd.c +++ b/source4/client/cifsdd.c @@ -357,7 +357,8 @@ static void print_transfer_stats(void) static struct dd_iohandle * open_file(struct resolve_context *resolve_ctx, struct event_context *ev, const char * which, const char **ports, - struct smbcli_options *smb_options) + struct smbcli_options *smb_options, + struct smbcli_session_options *smb_session_options) { int options = 0; const char * path = NULL; @@ -379,13 +380,13 @@ static struct dd_iohandle * open_file(struct resolve_context *resolve_ctx, path = check_arg_pathname("if"); handle = dd_open_path(resolve_ctx, ev, path, ports, check_arg_numeric("ibs"), options, - smb_options); + smb_options, smb_session_options); } else if (strcmp(which, "of") == 0) { options |= DD_WRITE; path = check_arg_pathname("of"); handle = dd_open_path(resolve_ctx, ev, path, ports, check_arg_numeric("obs"), options, - smb_options); + smb_options, smb_session_options); } else { SMB_ASSERT(0); return(NULL); @@ -412,12 +413,14 @@ static int copy_files(struct event_context *ev, struct loadparm_context *lp_ctx) struct dd_iohandle * ofile; struct smbcli_options options; + struct smbcli_session_options session_options; ibs = check_arg_numeric("ibs"); obs = check_arg_numeric("obs"); count = check_arg_numeric("count"); lp_smbcli_options(lp_ctx, &options); + lp_smbcli_session_options(lp_ctx, &session_options); /* Allocate IO buffer. We need more than the max IO size because we * could accumulate a remainder if ibs and obs don't match. @@ -436,12 +439,14 @@ static int copy_files(struct event_context *ev, struct loadparm_context *lp_ctx) (unsigned long long)iomax, options.max_xmit)); if (!(ifile = open_file(lp_resolve_context(lp_ctx), ev, "if", - lp_smb_ports(lp_ctx), &options))) { + lp_smb_ports(lp_ctx), &options, + &session_options))) { return(FILESYS_EXIT_CODE); } if (!(ofile = open_file(lp_resolve_context(lp_ctx), ev, "of", - lp_smb_ports(lp_ctx), &options))) { + lp_smb_ports(lp_ctx), &options, + &session_options))) { return(FILESYS_EXIT_CODE); } diff --git a/source4/client/cifsdd.h b/source4/client/cifsdd.h index 21a4ad4882..3195e4334f 100644 --- a/source4/client/cifsdd.h +++ b/source4/client/cifsdd.h @@ -89,6 +89,7 @@ struct dd_iohandle #define DD_OPLOCK 0x00000008 struct smbcli_options; +struct smbcli_session_options; struct event_context; struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, @@ -96,7 +97,8 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, const char * path, const char **ports, uint64_t io_size, int options, - struct smbcli_options *smb_options); + struct smbcli_options *smb_options, + struct smbcli_session_options *smb_session_options); bool dd_fill_block(struct dd_iohandle * h, uint8_t * buf, uint64_t * buf_size, uint64_t need_size, uint64_t block_size); bool dd_flush_block(struct dd_iohandle * h, uint8_t * buf, diff --git a/source4/client/cifsddio.c b/source4/client/cifsddio.c index 4297c30012..25194a621a 100644 --- a/source4/client/cifsddio.c +++ b/source4/client/cifsddio.c @@ -225,7 +225,8 @@ static struct smbcli_state * init_smb_session(struct resolve_context *resolve_ct const char * host, const char **ports, const char * share, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { NTSTATUS ret; struct smbcli_state * cli = NULL; @@ -236,7 +237,8 @@ static struct smbcli_state * init_smb_session(struct resolve_context *resolve_ct ret = smbcli_full_connection(NULL, &cli, host, ports, share, NULL /* devtype */, cmdline_credentials, resolve_ctx, - ev, options); + ev, options, + session_options); if (!NT_STATUS_IS_OK(ret)) { fprintf(stderr, "%s: connecting to //%s/%s: %s\n", @@ -302,7 +304,8 @@ static struct dd_iohandle * open_cifs_handle(struct resolve_context *resolve_ctx const char * path, uint64_t io_size, int options, - struct smbcli_options *smb_options) + struct smbcli_options *smb_options, + struct smbcli_session_options *smb_session_options) { struct cifs_handle * smbh; @@ -323,7 +326,7 @@ static struct dd_iohandle * open_cifs_handle(struct resolve_context *resolve_ctx smbh->h.io_seek = smb_seek_func; if ((smbh->cli = init_smb_session(resolve_ctx, ev, host, ports, share, - smb_options)) == NULL) { + smb_options, smb_session_options)) == NULL) { return(NULL); } @@ -344,7 +347,8 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, const char **ports, uint64_t io_size, int options, - struct smbcli_options *smb_options) + struct smbcli_options *smb_options, + struct smbcli_session_options *smb_session_options) { if (file_exist(path)) { return(open_fd_handle(path, io_size, options)); @@ -361,7 +365,8 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, return(open_cifs_handle(resolve_ctx, ev, host, ports, share, remain, - io_size, options, smb_options)); + io_size, options, smb_options, + smb_session_options)); } return(open_fd_handle(path, io_size, options)); diff --git a/source4/client/client.c b/source4/client/client.c index e05e195372..266bd67025 100644 --- a/source4/client/client.c +++ b/source4/client/client.c @@ -3032,7 +3032,8 @@ static bool do_connect(struct smbclient_context *ctx, const char *specified_server, const char **ports, const char *specified_share, struct cli_credentials *cred, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { NTSTATUS status; char *server, *share; @@ -3051,7 +3052,7 @@ static bool do_connect(struct smbclient_context *ctx, status = smbcli_full_connection(ctx, &ctx->cli, server, ports, share, NULL, cred, resolve_ctx, - ev_ctx, options); + ev_ctx, options, session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("Connection to \\\\%s\\%s failed - %s\n", server, share, nt_errstr(status)); @@ -3138,6 +3139,7 @@ static int do_message_op(const char *netbios_name, const char *desthost, struct smbclient_context *ctx; const char *cmdstr = NULL; struct smbcli_options smb_options; + struct smbcli_session_options smb_session_options; struct poptOption long_options[] = { POPT_AUTOHELP @@ -3227,6 +3229,7 @@ static int do_message_op(const char *netbios_name, const char *desthost, poptFreeContext(pc); lp_smbcli_options(cmdline_lp_ctx, &smb_options); + lp_smbcli_session_options(cmdline_lp_ctx, &smb_session_options); ev_ctx = s4_event_context_init(talloc_autofree_context()); @@ -3255,7 +3258,7 @@ static int do_message_op(const char *netbios_name, const char *desthost, if (!do_connect(ctx, ev_ctx, lp_resolve_context(cmdline_lp_ctx), desthost, lp_smb_ports(cmdline_lp_ctx), service, - cmdline_credentials, &smb_options)) + cmdline_credentials, &smb_options, &smb_session_options)) return 1; if (base_directory) diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 3b1c3c5314..e42b04cdc5 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -146,7 +146,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { struct smbcli_tree *tree; NTSTATUS status; @@ -157,7 +158,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, &tree, host, ports, sharename, devtype, credentials, resolve_ctx, ev, - options); + options, + session_options); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index fecdfda56e..3bf3ad8b1b 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -214,7 +214,9 @@ static bool connect_servers(struct event_context *ev, for (j=0;jlp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); options.use_level2_oplocks = false; @@ -188,7 +189,7 @@ static bool open_connection_no_level2_oplocks(struct torture_context *tctx, torture_setting_string(tctx, "share", NULL), NULL, cmdline_credentials, lp_resolve_context(tctx->lp_ctx), - tctx->ev, &options); + tctx->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { printf("Failed to open connection - %s\n", nt_errstr(status)); return false; diff --git a/source4/torture/raw/tconrate.c b/source4/torture/raw/tconrate.c index 6f0ba0d617..66ef2ae2dd 100644 --- a/source4/torture/raw/tconrate.c +++ b/source4/torture/raw/tconrate.c @@ -69,8 +69,10 @@ static int fork_tcon_client(struct torture_context *tctx, struct timeval end; struct timeval now; struct smbcli_options options; + struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); child = fork(); if (child == -1) { @@ -100,7 +102,7 @@ static int fork_tcon_client(struct torture_context *tctx, host, lp_smb_ports(tctx->lp_ctx), share, NULL, cmdline_credentials, lp_resolve_context(tctx->lp_ctx), - tctx->ev, &options); + tctx->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/rpc/join.c b/source4/torture/rpc/join.c index 77da32d572..ee0c05360f 100644 --- a/source4/torture/rpc/join.c +++ b/source4/torture/rpc/join.c @@ -19,6 +19,7 @@ bool torture_rpc_join(struct torture_context *torture) struct smbcli_state *cli; const char *host = torture_setting_string(torture, "host", NULL); struct smbcli_options options; + struct smbcli_session_options session_options; /* Join domain as a member server. */ tj = torture_join_domain(torture, @@ -33,13 +34,14 @@ bool torture_rpc_join(struct torture_context *torture) } lp_smbcli_options(torture->lp_ctx, &options); + lp_smbcli_session_options(torture->lp_ctx, &session_options); status = smbcli_full_connection(tj, &cli, host, lp_smb_ports(torture->lp_ctx), "IPC$", NULL, machine_account, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("%s failed to connect to IPC$ with workstation credentials\n", TORTURE_NETBIOS_NAME)); @@ -65,7 +67,7 @@ bool torture_rpc_join(struct torture_context *torture) "IPC$", NULL, machine_account, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("%s failed to connect to IPC$ with workstation credentials\n", TORTURE_NETBIOS_NAME)); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index e030b972f8..260c1cc149 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -91,7 +91,7 @@ bool torture_bind_authcontext(struct torture_context *torture) lp_smb_ports(torture->lp_ctx), "IPC$", NULL, cmdline_credentials, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -290,6 +290,7 @@ bool torture_bind_samba3(struct torture_context *torture) bool ret = false; struct smbcli_state *cli; struct smbcli_options options; + struct smbcli_session_options session_options; mem_ctx = talloc_init("torture_bind_authcontext"); @@ -299,13 +300,14 @@ bool torture_bind_samba3(struct torture_context *torture) } lp_smbcli_options(torture->lp_ctx, &options); + lp_smbcli_session_options(torture->lp_ctx, &session_options); status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), "IPC$", NULL, cmdline_credentials, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -1197,6 +1199,7 @@ bool torture_netlogon_samba3(struct torture_context *torture) const char *wks_name; int i; struct smbcli_options options; + struct smbcli_session_options session_options; wks_name = torture_setting_string(torture, "wksname", NULL); if (wks_name == NULL) { @@ -1216,13 +1219,14 @@ bool torture_netlogon_samba3(struct torture_context *torture) } lp_smbcli_options(torture->lp_ctx, &options); + lp_smbcli_session_options(torture->lp_ctx, &session_options); status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), "IPC$", NULL, anon_creds, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -1301,15 +1305,17 @@ static bool test_join3(struct torture_context *tctx, struct smbcli_state *cli; struct cli_credentials *wks_creds; struct smbcli_options options; + struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); status = smbcli_full_connection(tctx, &cli, torture_setting_string(tctx, "host", NULL), lp_smb_ports(tctx->lp_ctx), "IPC$", NULL, smb_creds, lp_resolve_context(tctx->lp_ctx), - tctx->ev, &options); + tctx->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -1686,7 +1692,7 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) lp_smb_ports(torture->lp_ctx), "IPC$", NULL, cmdline_credentials, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) smbcli_full_connection failed: %s\n", __location__, nt_errstr(status)); @@ -1713,7 +1719,7 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) lp_smb_ports(torture->lp_ctx), "IPC$", NULL, anon_creds, lp_resolve_context(torture->lp_ctx), - torture->ev, &options); + torture->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) anon smbcli_full_connection failed: %s\n", __location__, nt_errstr(status)); diff --git a/source4/torture/unix/unix_info2.c b/source4/torture/unix/unix_info2.c index d7482ddcf1..3bddde2a97 100644 --- a/source4/torture/unix/unix_info2.c +++ b/source4/torture/unix/unix_info2.c @@ -56,15 +56,17 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx) const char *host = torture_setting_string(tctx, "host", NULL); const char *share = torture_setting_string(tctx, "share", NULL); struct smbcli_options options; + struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); status = smbcli_full_connection(tctx, &cli, host, lp_smb_ports(tctx->lp_ctx), share, NULL, cmdline_credentials, lp_resolve_context(tctx->lp_ctx), - tctx->ev, &options); + tctx->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/unix/whoami.c b/source4/torture/unix/whoami.c index 39d0a12ab1..d742e23e82 100644 --- a/source4/torture/unix/whoami.c +++ b/source4/torture/unix/whoami.c @@ -77,14 +77,16 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx, const char *host = torture_setting_string(tctx, "host", NULL); const char *share = torture_setting_string(tctx, "share", NULL); struct smbcli_options options; + struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); status = smbcli_full_connection(tctx, &cli, host, lp_smb_ports(tctx->lp_ctx), share, NULL, creds, lp_resolve_context(tctx->lp_ctx), - tctx->ev, &options); + tctx->ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c index 938e7d6c03..32e4453aca 100644 --- a/source4/torture/util_smb.c +++ b/source4/torture/util_smb.c @@ -475,8 +475,10 @@ _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx, NTSTATUS status; struct smbcli_options options; + struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); + lp_smbcli_session_options(tctx->lp_ctx, &session_options); options.use_oplocks = torture_setting_bool(tctx, "use_oplocks", true); options.use_level2_oplocks = torture_setting_bool(tctx, "use_level2_oplocks", true); @@ -486,7 +488,7 @@ _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx, sharename, NULL, cmdline_credentials, lp_resolve_context(tctx->lp_ctx), - ev, &options); + ev, &options, &session_options); if (!NT_STATUS_IS_OK(status)) { printf("Failed to open connection - %s\n", nt_errstr(status)); return false; -- cgit From 2ba4a79210f35df526a72c740ada5de34d6f45f4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 03:20:46 +0200 Subject: Eliminate another global_loadparm. --- source4/smbd/process_model.h | 3 ++- source4/smbd/process_prefork.c | 2 +- source4/smbd/process_single.c | 2 +- source4/smbd/process_standard.c | 5 +++-- source4/smbd/process_thread.c | 2 +- source4/smbd/service_stream.c | 2 +- source4/smbd/service_task.c | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) (limited to 'source4') diff --git a/source4/smbd/process_model.h b/source4/smbd/process_model.h index a9b33a4725..6afb66ff20 100644 --- a/source4/smbd/process_model.h +++ b/source4/smbd/process_model.h @@ -63,7 +63,8 @@ struct model_ops { void *); /* function to terminate a connection or task */ - void (*terminate)(struct event_context *, const char *reason); + void (*terminate)(struct event_context *, struct loadparm_context *lp_ctx, + const char *reason); /* function to set a title for the connection or task */ void (*set_title)(struct event_context *, const char *title); diff --git a/source4/smbd/process_prefork.c b/source4/smbd/process_prefork.c index 0d17e5301d..1b369613ff 100644 --- a/source4/smbd/process_prefork.c +++ b/source4/smbd/process_prefork.c @@ -189,7 +189,7 @@ static void prefork_new_task(struct event_context *ev, /* called when a task goes down */ -_NORETURN_ static void prefork_terminate(struct event_context *ev, const char *reason) +_NORETURN_ static void prefork_terminate(struct event_context *ev, struct loadparm_context *lp_ctx, const char *reason) { DEBUG(2,("prefork_terminate: reason[%s]\n",reason)); } diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c index a7a27ef9e0..26afff9930 100644 --- a/source4/smbd/process_single.c +++ b/source4/smbd/process_single.c @@ -95,7 +95,7 @@ static void single_new_task(struct event_context *ev, /* called when a task goes down */ -static void single_terminate(struct event_context *ev, const char *reason) +static void single_terminate(struct event_context *ev, struct loadparm_context *lp_ctx, const char *reason) { DEBUG(2,("single_terminate: reason[%s]\n",reason)); } diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c index c8f90209b6..0a864dabb2 100644 --- a/source4/smbd/process_standard.c +++ b/source4/smbd/process_standard.c @@ -196,13 +196,14 @@ static void standard_new_task(struct event_context *ev, /* called when a task goes down */ -_NORETURN_ static void standard_terminate(struct event_context *ev, const char *reason) +_NORETURN_ static void standard_terminate(struct event_context *ev, struct loadparm_context *lp_ctx, + const char *reason) { DEBUG(2,("standard_terminate: reason[%s]\n",reason)); /* this reload_charcnv() has the effect of freeing the iconv context memory, which makes leak checking easier */ - reload_charcnv(global_loadparm); + reload_charcnv(lp_ctx); talloc_free(ev); diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c index 540d956420..597cf587f1 100644 --- a/source4/smbd/process_thread.c +++ b/source4/smbd/process_thread.c @@ -188,7 +188,7 @@ static void thread_new_task(struct event_context *ev, } /* called when a task goes down */ -static void thread_terminate(struct event_context *event_ctx, const char *reason) +static void thread_terminate(struct event_context *event_ctx, struct loadparm_context *lp_ctx, const char *reason) { DEBUG(10,("thread_terminate: reason[%s]\n",reason)); diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c index 48eda46dc7..1240382944 100644 --- a/source4/smbd/service_stream.c +++ b/source4/smbd/service_stream.c @@ -79,7 +79,7 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char talloc_free(srv_conn->event.fde); srv_conn->event.fde = NULL; talloc_free(srv_conn); - model_ops->terminate(event_ctx, reason); + model_ops->terminate(event_ctx, srv_conn->lp_ctx, reason); } /** diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c index 2274685059..9a2903e281 100644 --- a/source4/smbd/service_task.c +++ b/source4/smbd/service_task.c @@ -35,7 +35,7 @@ void task_server_terminate(struct task_server *task, const char *reason) struct event_context *event_ctx = task->event_ctx; const struct model_ops *model_ops = task->model_ops; DEBUG(0,("task_server_terminate: [%s]\n", reason)); - model_ops->terminate(event_ctx, reason); + model_ops->terminate(event_ctx, task->lp_ctx, reason); /* don't free this above, it might contain the 'reason' being printed */ talloc_free(task); -- cgit From 5bbd73c0ff64ec5da337d327d4f6ed1de2132ed4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 04:01:47 +0200 Subject: Remove two more uses of global loadparm by remember required details for secondary DCE/RPC connections. --- source4/librpc/rpc/dcerpc_secondary.c | 7 +++--- source4/librpc/rpc/dcerpc_sock.c | 40 +++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'source4') diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c index abc67ad38b..b4d5d05b61 100644 --- a/source4/librpc/rpc/dcerpc_secondary.c +++ b/source4/librpc/rpc/dcerpc_secondary.c @@ -95,13 +95,14 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp s->binding->host, s->binding->target_hostname, atoi(s->binding->endpoint), - lp_resolve_context(global_loadparm)); + dcerpc_resolve_ctx(s->pipe->conn)); composite_continue(c, pipe_tcp_req, continue_open_tcp, c); return c; case NCALRPC: - pipe_ncalrpc_req = dcerpc_pipe_open_pipe_send(s->pipe2->conn, lp_ncalrpc_dir(global_loadparm), - s->binding->endpoint); + case NCACN_UNIX_STREAM: + pipe_ncalrpc_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn, + dcerpc_unix_socket_path(s->pipe->conn)); composite_continue(c, pipe_ncalrpc_req, continue_open_pipe, c); return c; diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index 7480beae33..1e2b4cde48 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -39,6 +39,9 @@ struct sock_private { struct packet_context *packet; uint32_t pending_reads; + + struct resolve_context *resolve_ctx; + const char *path; /* For ncacn_unix_sock and ncalrpc */ }; @@ -307,6 +310,7 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct struct resolve_context *resolve_context, struct socket_address *server, const char *target_hostname, + const char *full_path, enum dcerpc_transport_t transport) { struct composite_context *c; @@ -334,6 +338,9 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct talloc_steal(s->sock, s->socket_ctx); + s->sock->resolve_ctx = resolve_context; + s->sock->path = talloc_reference(s->sock, full_path); + conn_req = socket_connect_send(s->socket_ctx, NULL, s->server, 0, resolve_context, c->event_ctx); @@ -386,6 +393,7 @@ static void continue_ip_resolve_name(struct composite_context *ctx) sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->resolve_ctx, s->srvaddr, s->target_hostname, + NULL, NCACN_IP_TCP); composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c); } @@ -561,6 +569,7 @@ struct composite_context *dcerpc_pipe_open_unix_stream_send(struct dcerpc_connec sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, + s->path, NCALRPC); composite_continue(c, sock_unix_req, continue_unix_open_socket, c); return c; @@ -579,13 +588,6 @@ NTSTATUS dcerpc_pipe_open_unix_stream_recv(struct composite_context *c) } -struct pipe_np_state { - char *full_path; - struct socket_address *srvaddr; - struct dcerpc_connection *conn; -}; - - /* Stage 2 of dcerpc_pipe_open_pipe_send: receive socket open request */ @@ -612,13 +614,13 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c struct composite_context *c; struct composite_context *sock_np_req; - struct pipe_np_state *s; + struct pipe_unix_state *s; /* composite context allocation and setup */ c = composite_create(conn, conn->event_ctx); if (c == NULL) return NULL; - s = talloc_zero(c, struct pipe_np_state); + s = talloc_zero(c, struct pipe_unix_state); if (composite_nomem(s, c)) return c; c->private_data = s; @@ -628,15 +630,15 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c s->conn = conn; string_replace(canon, '/', '\\'); - s->full_path = talloc_asprintf(canon, "%s/%s", ncalrpc_dir, canon); - if (composite_nomem(s->full_path, c)) return c; + s->path = talloc_asprintf(canon, "%s/%s", ncalrpc_dir, canon); + if (composite_nomem(s->path, c)) return c; /* prepare server address using path and transport name */ - s->srvaddr = socket_address_from_strings(conn, "unix", s->full_path, 0); + s->srvaddr = socket_address_from_strings(conn, "unix", s->path, 0); if (composite_nomem(s->srvaddr, c)) return c; /* send socket open request */ - sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, NCALRPC); + sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, s->path, NCALRPC); composite_continue(c, sock_np_req, continue_np_open_socket, c); return c; } @@ -662,3 +664,15 @@ NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_connection *conn, const char *ncalr struct composite_context *c = dcerpc_pipe_open_pipe_send(conn, ncalrpc_dir, identifier); return dcerpc_pipe_open_pipe_recv(c); } + +const char *dcerpc_unix_socket_path(struct dcerpc_connection *p) +{ + struct sock_private *sock = (struct sock_private *)p->transport.private_data; + return sock->path; +} + +struct resolve_context *dcerpc_resolve_ctx(struct dcerpc_connection *p) +{ + struct sock_private *sock = (struct sock_private *)p->transport.private_data; + return sock->resolve_ctx; +} -- cgit From 4a1dabd8361c8480261d89b4ea39236ff0431897 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 04:22:24 +0200 Subject: wmi: Use cli_credentials. --- source4/lib/wmi/wmi.h | 2 +- source4/lib/wmi/wmicore.c | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) (limited to 'source4') diff --git a/source4/lib/wmi/wmi.h b/source4/lib/wmi/wmi.h index 32543a8ca7..46c9b70cdb 100644 --- a/source4/lib/wmi/wmi.h +++ b/source4/lib/wmi/wmi.h @@ -27,7 +27,7 @@ /** FIXME: Use credentials struct rather than user/password here */ WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const char *nspace, - const char *user, const char *password, + struct cli_credentials *credentials, const char *locale, uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx, struct IWbemServices** services); const char *wmi_errstr(WERROR werror); diff --git a/source4/lib/wmi/wmicore.c b/source4/lib/wmi/wmicore.c index 49c1e03312..3ac6c89292 100644 --- a/source4/lib/wmi/wmicore.c +++ b/source4/lib/wmi/wmicore.c @@ -51,7 +51,7 @@ void wmi_init(struct com_context **ctx, struct cli_credentials *credentials) /** FIXME: Use credentials struct rather than user/password here */ WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const uint16_t *nspace, - const char *user, const char *password, + struct cli_credentials *credentials, const char *locale, uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx, struct IWbemServices** services) { @@ -61,18 +61,6 @@ WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const uin struct IUnknown **mqi; struct IWbemLevel1Login *pL; - if (user) { - char *cred; - struct cli_credentials *cc; - - cred = talloc_asprintf(NULL, "%s%%%s", user, password); - cc = cli_credentials_init(cred); - cli_credentials_set_conf(cc, global_loadparm); - cli_credentials_parse_string(cc, cred, CRED_SPECIFIED); - dcom_add_server_credentials(ctx, server, cc); - talloc_free(cred); - } - GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid); GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid); result = dcom_create_object(ctx, &clsid, server, 1, &iid, &mqi, &coresult); -- cgit From 2400b1fea2a07ad3972ee8133e37eaf2f91499d0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 04:22:54 +0200 Subject: Fix segfault. --- source4/smbd/service_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c index 1240382944..ce5b6519a1 100644 --- a/source4/smbd/service_stream.c +++ b/source4/smbd/service_stream.c @@ -78,8 +78,8 @@ void stream_terminate_connection(struct stream_connection *srv_conn, const char talloc_free(srv_conn->event.fde); srv_conn->event.fde = NULL; - talloc_free(srv_conn); model_ops->terminate(event_ctx, srv_conn->lp_ctx, reason); + talloc_free(srv_conn); } /** -- cgit From 454122ab091715edf02c26e0a408141c7374b693 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 06:05:05 +0200 Subject: make sure dcerpc is always initialized. --- source4/librpc/rpc/dcerpc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 5bbcc5e91c..5cee9f27ad 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -33,9 +33,7 @@ _PUBLIC_ NTSTATUS dcerpc_init(void) { - gensec_init(global_loadparm); - - return NT_STATUS_OK; + return gensec_init(global_loadparm); } static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status); -- cgit From ac5e69a999c4dcd337c5b8467aba3018df50126b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 06:10:32 +0200 Subject: dcesrv: Remove use of global_loadparm. --- source4/rpc_server/service_rpc.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source4') diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c index b68cec4c7d..2ef8591c32 100644 --- a/source4/rpc_server/service_rpc.c +++ b/source4/rpc_server/service_rpc.c @@ -436,6 +436,25 @@ static void dcesrv_task_init(struct task_server *task) NTSTATUS status; struct dcesrv_context *dce_ctx; struct dcesrv_endpoint *e; + extern NTSTATUS dcerpc_server_wkssvc_init(void); + extern NTSTATUS dcerpc_server_drsuapi_init(void); + extern NTSTATUS dcerpc_server_winreg_init(void); + extern NTSTATUS dcerpc_server_spoolss_init(void); + extern NTSTATUS dcerpc_server_epmapper_init(void); + extern NTSTATUS dcerpc_server_srvsvc_init(void); + extern NTSTATUS dcerpc_server_netlogon_init(void); + extern NTSTATUS dcerpc_server_rpcecho_init(void); + extern NTSTATUS dcerpc_server_unixinfo_init(void); + extern NTSTATUS dcerpc_server_samr_init(void); + extern NTSTATUS dcerpc_server_remote_init(void); + extern NTSTATUS dcerpc_server_lsa_init(void); + init_module_fn static_init[] = { STATIC_DCESRV_MODULES }; + init_module_fn *shared_init = load_samba_modules(NULL, task->lp_ctx, "dcerpc_server"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); task_server_set_title(task, "task[dcesrv]"); @@ -462,25 +481,6 @@ failed: NTSTATUS server_service_rpc_init(void) { - extern NTSTATUS dcerpc_server_wkssvc_init(void); - extern NTSTATUS dcerpc_server_drsuapi_init(void); - extern NTSTATUS dcerpc_server_winreg_init(void); - extern NTSTATUS dcerpc_server_spoolss_init(void); - extern NTSTATUS dcerpc_server_epmapper_init(void); - extern NTSTATUS dcerpc_server_srvsvc_init(void); - extern NTSTATUS dcerpc_server_netlogon_init(void); - extern NTSTATUS dcerpc_server_rpcecho_init(void); - extern NTSTATUS dcerpc_server_unixinfo_init(void); - extern NTSTATUS dcerpc_server_samr_init(void); - extern NTSTATUS dcerpc_server_remote_init(void); - extern NTSTATUS dcerpc_server_lsa_init(void); - init_module_fn static_init[] = { STATIC_DCESRV_MODULES }; - init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "dcerpc_server"); - run_init_functions(static_init); - run_init_functions(shared_init); - - talloc_free(shared_init); - return register_server_service("rpc", dcesrv_task_init); } -- cgit From 3ff298c37be5daa015006fe5cede3980b26e570e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 06:43:32 +0200 Subject: s4:selftest: add "smb.signing" to anon signing tests metze --- source4/selftest/samba4_tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index 667b21975f..af8c3e94c1 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -328,9 +328,9 @@ for mech in \ name="smb.signing on with $signoptions" plantest "$name local-creds" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$NETBIOSNAME/\$USERNAME"%"\$PASSWORD" BASE-XCOPY "$*" done -plantest "--signing=yes anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=yes -U% BASE-XCOPY "$*" -plantest "--signing=required anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=required -U% BASE-XCOPY "$*" -plantest "--signing=no anon" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=no -U% BASE-XCOPY "$*" +plantest "smb.signing --signing=yes anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=yes -U% BASE-XCOPY "$*" +plantest "smb.signing --signing=required anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=required -U% BASE-XCOPY "$*" +plantest "smb.signing --signing=no anon" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=no -U% BASE-XCOPY "$*" NBT_TESTS=`$smb4torture --list | grep "^NBT-" | xargs` -- cgit From abe0af4ab417086d413f02cadf7315a8f801a0f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 04:59:24 +0200 Subject: dcerpc.idl: add DCERPC_PFC_OFFSET metze --- source4/librpc/idl/dcerpc.idl | 1 + 1 file changed, 1 insertion(+) (limited to 'source4') diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl index 1c6574b11b..a78329d990 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/source4/librpc/idl/dcerpc.idl @@ -261,6 +261,7 @@ interface dcerpc const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */ /* these offsets are needed by the signing code */ + const uint8 DCERPC_PFC_OFFSET = 3; const uint8 DCERPC_DREP_OFFSET = 4; const uint8 DCERPC_FRAG_LEN_OFFSET = 8; const uint8 DCERPC_AUTH_LEN_OFFSET = 10; -- cgit From eb1de4f0ed149dd2b348d756f091809d934309a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 04:59:56 +0200 Subject: s4:librpc/rpc: correctly sign or seal rpc request with an object guid metze --- source4/librpc/rpc/dcerpc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 5bbcc5e91c..c1e3e26ee9 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -334,6 +334,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, DATA_BLOB creds2; size_t payload_length; enum ndr_err_code ndr_err; + size_t hdr_size = DCERPC_REQUEST_LENGTH; /* non-signed packets are simpler */ if (sig_size == 0) { @@ -367,6 +368,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; + hdr_size += 16; } ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); @@ -415,7 +417,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_seal_packet(c->security_state.generic_state, mem_ctx, - blob->data + DCERPC_REQUEST_LENGTH, + blob->data + hdr_size, payload_length, blob->data, blob->length, @@ -428,7 +430,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c, case DCERPC_AUTH_LEVEL_INTEGRITY: status = gensec_sign_packet(c->security_state.generic_state, mem_ctx, - blob->data + DCERPC_REQUEST_LENGTH, + blob->data + hdr_size, payload_length, blob->data, blob->length, -- cgit From 844b331d257b02c073cc0dc4a6e229e6b9645949 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 05:01:19 +0200 Subject: s4:rpc_server: correctly handle dcerpc requests with object uuids metze --- source4/rpc_server/dcerpc_server.c | 8 ++++---- source4/rpc_server/dcesrv_auth.c | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'source4') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e5f59d0cf9..893055d3b1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -870,10 +870,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->context = context; call->ndr_pull = pull; - if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { - pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; - } - if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } @@ -1112,6 +1108,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } + if (CVAL(blob.data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) { + ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; + } + ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(dce_conn->partial_input.data); diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 16bf4eb7ed..52d5631cfd 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -287,6 +287,7 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) struct ndr_pull *ndr; NTSTATUS status; enum ndr_err_code ndr_err; + size_t hdr_size = DCERPC_REQUEST_LENGTH; if (!dce_conn->auth_state.auth_info || !dce_conn->auth_state.gensec_security) { @@ -335,6 +336,11 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } + if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { + ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; + hdr_size += 16; + } + ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); @@ -346,13 +352,13 @@ bool dcesrv_auth_request(struct dcesrv_call_state *call, DATA_BLOB *full_packet) case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(dce_conn->auth_state.gensec_security, call, - full_packet->data + DCERPC_REQUEST_LENGTH, + full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length, full_packet->data, full_packet->length-auth.credentials.length, &auth.credentials); memcpy(pkt->u.request.stub_and_verifier.data, - full_packet->data + DCERPC_REQUEST_LENGTH, + full_packet->data + hdr_size, pkt->u.request.stub_and_verifier.length); break; -- cgit From 40e7769959e29eccf1f0f14142828c9d0b7880b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 06:40:15 +0200 Subject: s4:torture/rpc: add RPC-OBJECTUUID This test shows that object uuids should be ignored if they're present in a dcerpc request. metze --- source4/torture/config.mk | 2 +- source4/torture/rpc/object_uuid.c | 87 +++++++++++++++++++++++++++++++++++++++ source4/torture/rpc/rpc.c | 1 + 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 source4/torture/rpc/object_uuid.c (limited to 'source4') diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 96da10b5df..211d09756d 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -116,7 +116,7 @@ torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \ eventlog.o epmapper.o winreg.o initshutdown.o oxidresolve.o remact.o mgmt.o \ scanner.o autoidl.o countcalls.o testjoin.o schannel.o netlogon.o remote_pac.o samlogon.o \ samsync.o bind.o dssetup.o alter_context.o bench.o samba3rpc.o rpc.o async_bind.o \ - handles.o frsapi.o) + handles.o frsapi.o object_uuid.o) $(eval $(call proto_header_template,$(torturesrcdir)/rpc/proto.h,$(torture_rpc_OBJ_FILES:.o=.c))) diff --git a/source4/torture/rpc/object_uuid.c b/source4/torture/rpc/object_uuid.c new file mode 100644 index 0000000000..5a77bd1c29 --- /dev/null +++ b/source4/torture/rpc/object_uuid.c @@ -0,0 +1,87 @@ +/* + Unix SMB/CIFS implementation. + + test suite for behaviour of object uuids in rpc requests + + Copyright (C) Stefan Metzmacher 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 . +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "librpc/gen_ndr/ndr_dssetup.h" +#include "librpc/gen_ndr/ndr_dssetup_c.h" +#include "librpc/gen_ndr/ndr_lsa.h" +#include "librpc/gen_ndr/ndr_lsa_c.h" +#include "torture/rpc/rpc.h" + +/* + this tests the send object uuids in the dcerpc request +*/ + +static bool test_random_uuid(struct torture_context *torture) +{ + NTSTATUS status; + struct dcerpc_pipe *p1, *p2; + struct rpc_request *req; + struct GUID uuid; + struct dssetup_DsRoleGetPrimaryDomainInformation r1; + struct lsa_GetUserName r2; + struct lsa_StringPointer authority_name_p; + + torture_comment(torture, "RPC-OBJECTUUID-RANDOM\n"); + + status = torture_rpc_connection(torture, &p1, &ndr_table_dssetup); + torture_assert_ntstatus_ok(torture, status, "opening dsetup pipe1"); + + status = torture_rpc_connection(torture, &p2, &ndr_table_lsarpc); + torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); + + uuid = GUID_random(); + + r1.in.level = DS_ROLE_BASIC_INFORMATION; + req = dcerpc_ndr_request_send(p1, &uuid, + &ndr_table_dssetup, + NDR_DSSETUP_DSROLEGETPRIMARYDOMAININFORMATION, + torture, &r1); + status = dcerpc_ndr_request_recv(req); + torture_assert_ntstatus_ok(torture, status, "DsRoleGetPrimaryDomainInformation failed"); + torture_assert_werr_ok(torture, r1.out.result, "DsRoleGetPrimaryDomainInformation failed"); + + uuid = GUID_random(); + + r2.in.system_name = "\\"; + r2.in.account_name = NULL; + r2.in.authority_name = &authority_name_p; + authority_name_p.string = NULL; + + req = dcerpc_ndr_request_send(p2, &uuid, + &ndr_table_lsarpc, + NDR_LSA_GETUSERNAME, + torture, &r2); + status = dcerpc_ndr_request_recv(req); + torture_assert_ntstatus_ok(torture, status, "lsaClose failed"); + torture_assert_ntstatus_ok(torture, r2.out.result, "lsaClose failed"); + + return true; +} + +struct torture_suite *torture_rpc_object_uuid(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite; + suite = torture_suite_create(mem_ctx, "OBJECTUUID"); + torture_suite_add_simple_test(suite, "random-uuid", test_random_uuid); + return suite; +} diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 85f7bde16c..c35f93e3f9 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -387,6 +387,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_suite(suite, torture_rpc_atsvc(suite)); torture_suite_add_suite(suite, torture_rpc_wkssvc(suite)); torture_suite_add_suite(suite, torture_rpc_handles(suite)); + torture_suite_add_suite(suite, torture_rpc_object_uuid(suite)); torture_suite_add_suite(suite, torture_rpc_winreg(suite)); torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss); torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite)); -- cgit From 45645426c2ae541fc2c3a112cde5a7f1d857938b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 06:42:53 +0200 Subject: s4:selftest: make sure we test RPC-OBJECTUUID with seal metze --- source4/selftest/samba4_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh index af8c3e94c1..bfe386af69 100755 --- a/source4/selftest/samba4_tests.sh +++ b/source4/selftest/samba4_tests.sh @@ -91,7 +91,7 @@ plantest "ldb" none TEST_DATA_PREFIX=\$PREFIX $LDBDIR/tests/test-tdb.sh # that they stay passing ncacn_np_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-SAMSYNC RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME RPC-SAMBA3-LSA RPC-BINDSAMBA3 RPC-NETLOGSAMBA3 RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" ncalrpc_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-DRSUAPI RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" -ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-DSSYNC RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" +ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-DSSYNC RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT RPC-OBJECTUUID" slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" slow_ncalrpc_tests="RPC-SAMR RPC-SAMR-PASSWORDS" slow_ncacn_ip_tcp_tests="RPC-SAMR RPC-SAMR-PASSWORDS RPC-CRACKNAMES" -- cgit From 8dd35fabbb4732cf601a93abbe0373fd53e661a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Sep 2008 11:20:45 -0700 Subject: NetApp found that we never set the smb signing flags2. This was found during testing at the CIFS plugfest. No other client seems to honour or use this bit, but it is quite ligitimately required by the spec. Andrew Bartlett --- source4/smb_server/smb/request.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4') diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index c7fa2d7d8a..eb3e100b96 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -140,6 +140,10 @@ void smbsrv_setup_reply(struct smbsrv_request *req, uint_t wct, size_t buflen) flags2 |= FLAGS2_32_BIT_ERROR_CODES; } + if (req->smb_conn->signing.allow_smb_signing || req->smb_conn->signing.mandatory_signing) { + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + } + req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.vwv = req->out.hdr + HDR_VWV; req->out.wct = wct; -- cgit From 6ad78f01a5982666c83025a94ce4ff3729d5db6f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Sep 2008 12:53:10 -0700 Subject: Rename hdb_ldb to hdb_samba4 and load as a plugin into the kdc. This avoids one more custom patch to the Heimdal code, and provides a more standard way to produce hdb plugins in future. I've renamed from hdb_ldb to hdb_samba4 as it really is not generic ldb. Andrew Bartlett --- source4/heimdal/lib/hdb/hdb.c | 42 +- source4/heimdal/lib/hdb/hdb.h | 6 + source4/kdc/config.mk | 8 +- source4/kdc/hdb-ldb.c | 1550 ----------------------------------------- source4/kdc/hdb-samba4.c | 1550 +++++++++++++++++++++++++++++++++++++++++ source4/kdc/kdc.c | 17 +- 6 files changed, 1604 insertions(+), 1569 deletions(-) delete mode 100644 source4/kdc/hdb-ldb.c create mode 100644 source4/kdc/hdb-samba4.c (limited to 'source4') diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index 3fddabb2d0..19c170767d 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -31,34 +31,27 @@ * SUCH DAMAGE. */ +#include "krb5.h" +#include "krb5_locl.h" #include "hdb_locl.h" - RCSID("$Id$"); #ifdef HAVE_DLFCN_H #include #endif -struct hdb_method { - const char *prefix; - krb5_error_code (*create)(krb5_context, HDB **, const char *filename); -}; - static struct hdb_method methods[] = { #if HAVE_DB1 || HAVE_DB3 - {"db:", hdb_db_create}, + {HDB_INTERFACE_VERSION, "db:", hdb_db_create}, #endif #if HAVE_NDBM - {"ndbm:", hdb_ndbm_create}, + {HDB_INTERFACE_VERSION, "ndbm:", hdb_ndbm_create}, #endif #if defined(OPENLDAP) && !defined(OPENLDAP_MODULE) - {"ldap:", hdb_ldap_create}, - {"ldapi:", hdb_ldapi_create}, -#endif -#ifdef HAVE_LDB /* Used for integrated samba build */ - {"ldb:", hdb_ldb_create}, + {HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create}, + {HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create}, #endif - {NULL, NULL} + {0, NULL, NULL} }; #if HAVE_DB1 || HAVE_DB3 @@ -398,11 +391,32 @@ hdb_create(krb5_context context, HDB **db, const char *filename) { const struct hdb_method *h; const char *residual; + krb5_error_code ret; + struct krb5_plugin *list = NULL, *e; if(filename == NULL) filename = HDB_DEFAULT_DB; krb5_add_et_list(context, initialize_hdb_error_table_r); h = find_method (filename, &residual); + + if (h == NULL) { + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "hdb", &list); + if(ret == 0 && list != NULL) { + for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) { + h = _krb5_plugin_get_symbol(e); + if (strncmp (filename, h->prefix, strlen(h->prefix)) == 0 + && h->interface_version == HDB_INTERFACE_VERSION) { + residual = filename + strlen(h->prefix); + break; + } + } + if (e == NULL) { + h = NULL; + _krb5_plugin_free(list); + } + } + } + #ifdef HAVE_DLOPEN if (h == NULL) h = find_dynamic_method (context, filename, &residual); diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index bc1b744015..5c2097ea59 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -139,6 +139,12 @@ typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*, hdb_entry_ex*, void*); extern krb5_kt_ops hdb_kt_ops; +struct hdb_method { + int interface_version; + const char *prefix; + krb5_error_code (*create)(krb5_context, HDB **, const char *filename); +}; + #include #endif /* __HDB_H__ */ diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk index b3e5bfdb92..dfd2879bd6 100644 --- a/source4/kdc/config.mk +++ b/source4/kdc/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION = server_service_kdc_init SUBSYSTEM = samba PRIVATE_DEPENDENCIES = \ - HEIMDAL_KDC HDB_LDB + HEIMDAL_KDC HDB_SAMBA4 # End SUBSYSTEM KDC ####################### @@ -14,7 +14,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o) ####################### # Start SUBSYSTEM KDC -[SUBSYSTEM::HDB_LDB] +[SUBSYSTEM::HDB_SAMBA4] CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb PRIVATE_DEPENDENCIES = \ LIBLDB auth_sam auth_sam_reply CREDENTIALS \ @@ -22,5 +22,5 @@ PRIVATE_DEPENDENCIES = \ # End SUBSYSTEM KDC ####################### -HDB_LDB_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-ldb.o pac-glue.o) -$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_LDB_OBJ_FILES:.o=.c))) +HDB_SAMBA4_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-samba4.o pac-glue.o) +$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_SAMBA4_OBJ_FILES:.o=.c))) diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c deleted file mode 100644 index 4fde75cf70..0000000000 --- a/source4/kdc/hdb-ldb.c +++ /dev/null @@ -1,1550 +0,0 @@ -/* - * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd. - * Copyright (c) 2004, Andrew Bartlett . - * Copyright (c) 2004, Stefan Metzmacher - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of PADL Software nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "includes.h" -#include "system/time.h" -#include "dsdb/common/flags.h" -#include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_errors.h" -#include "librpc/gen_ndr/netlogon.h" -#include "auth/auth.h" -#include "auth/credentials/credentials.h" -#include "auth/auth_sam.h" -#include "util/util_ldb.h" -#include "dsdb/samdb/samdb.h" -#include "librpc/ndr/libndr.h" -#include "librpc/gen_ndr/ndr_drsblobs.h" -#include "librpc/gen_ndr/lsa.h" -#include "libcli/auth/libcli_auth.h" -#include "param/param.h" -#include "events/events.h" -#include "kdc/kdc.h" -#include "../lib/crypto/md4.h" - -enum hdb_ldb_ent_type -{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, - HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY }; - -enum trust_direction { - UNKNOWN = 0, - INBOUND = LSA_TRUST_DIRECTION_INBOUND, - OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND -}; - -static const char *realm_ref_attrs[] = { - "nCName", - "dnsRoot", - NULL -}; - -static const char *trust_attrs[] = { - "trustPartner", - "trustAuthIncoming", - "trustAuthOutgoing", - "whenCreated", - "msDS-SupportedEncryptionTypes", - "trustAttributes", - "trustDirection", - "trustType", - NULL -}; - -static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val) -{ - const char *tmp; - const char *gentime; - struct tm tm; - - gentime = ldb_msg_find_attr_as_string(msg, attr, NULL); - if (!gentime) - return default_val; - - tmp = strptime(gentime, "%Y%m%d%H%M%SZ", &tm); - if (tmp == NULL) { - return default_val; - } - - return timegm(&tm); -} - -static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum hdb_ldb_ent_type ent_type) -{ - HDBFlags flags = int2HDBFlags(0); - - /* we don't allow kadmin deletes */ - flags.immutable = 1; - - /* mark the principal as invalid to start with */ - flags.invalid = 1; - - flags.renewable = 1; - - /* All accounts are servers, but this may be disabled again in the caller */ - flags.server = 1; - - /* Account types - clear the invalid bit if it turns out to be valid */ - if (userAccountControl & UF_NORMAL_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { - flags.client = 1; - } - flags.invalid = 0; - } - - if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { - flags.client = 1; - } - flags.invalid = 0; - } - if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { - flags.client = 1; - } - flags.invalid = 0; - } - if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) { - if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) { - flags.client = 1; - } - flags.invalid = 0; - } - - /* Not permitted to act as a client if disabled */ - if (userAccountControl & UF_ACCOUNTDISABLE) { - flags.client = 0; - } - if (userAccountControl & UF_LOCKOUT) { - flags.invalid = 1; - } -/* - if (userAccountControl & UF_PASSWORD_NOTREQD) { - flags.invalid = 1; - } -*/ -/* - UF_PASSWORD_CANT_CHANGE and UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED are irrelevent -*/ - if (userAccountControl & UF_TEMP_DUPLICATE_ACCOUNT) { - flags.invalid = 1; - } - -/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */ - -/* - if (userAccountControl & UF_MNS_LOGON_ACCOUNT) { - flags.invalid = 1; - } -*/ - if (userAccountControl & UF_SMARTCARD_REQUIRED) { - flags.require_hwauth = 1; - } - if (userAccountControl & UF_TRUSTED_FOR_DELEGATION) { - flags.ok_as_delegate = 1; - } - if (!(userAccountControl & UF_NOT_DELEGATED)) { - flags.forwardable = 1; - flags.proxiable = 1; - } - - if (userAccountControl & UF_DONT_REQUIRE_PREAUTH) { - flags.require_preauth = 0; - } else { - flags.require_preauth = 1; - - } - return flags; -} - -static int hdb_ldb_destructor(struct hdb_ldb_private *private) -{ - hdb_entry_ex *entry_ex = private->entry_ex; - free_hdb_entry(&entry_ex->entry); - return 0; -} - -static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex) -{ - talloc_free(entry_ex->ctx); -} - -static krb5_error_code LDB_message2entry_keys(krb5_context context, - struct smb_iconv_convenience *iconv_convenience, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg, - unsigned int userAccountControl, - hdb_entry_ex *entry_ex) -{ - krb5_error_code ret = 0; - enum ndr_err_code ndr_err; - struct samr_Password *hash; - const struct ldb_val *sc_val; - struct supplementalCredentialsBlob scb; - struct supplementalCredentialsPackage *scpk = NULL; - bool newer_keys = false; - struct package_PrimaryKerberosBlob _pkb; - struct package_PrimaryKerberosCtr3 *pkb3 = NULL; - struct package_PrimaryKerberosCtr4 *pkb4 = NULL; - uint32_t i; - uint32_t allocated_keys = 0; - - entry_ex->entry.keys.val = NULL; - entry_ex->entry.keys.len = 0; - - entry_ex->entry.kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0); - - /* Get keys from the db */ - - hash = samdb_result_hash(mem_ctx, msg, "unicodePwd"); - sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials"); - - /* unicodePwd for enctype 0x17 (23) if present */ - if (hash) { - allocated_keys++; - } - - /* supplementalCredentials if present */ - if (sc_val) { - ndr_err = ndr_pull_struct_blob_all(sc_val, mem_ctx, iconv_convenience, &scb, - (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - dump_data(0, sc_val->data, sc_val->length); - ret = EINVAL; - goto out; - } - - if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) { - NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb); - ret = EINVAL; - goto out; - } - - for (i=0; i < scb.sub.num_packages; i++) { - if (strcmp("Primary:Kerberos-Newer-Keys", scb.sub.packages[i].name) == 0) { - scpk = &scb.sub.packages[i]; - if (!scpk->data || !scpk->data[0]) { - scpk = NULL; - continue; - } - newer_keys = true; - break; - } else if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) == 0) { - scpk = &scb.sub.packages[i]; - if (!scpk->data || !scpk->data[0]) { - scpk = NULL; - } - /* - * we don't break here in hope to find - * a Kerberos-Newer-Keys package - */ - } - } - } - /* - * Primary:Kerberos-Newer-Keys or Primary:Kerberos element - * of supplementalCredentials - */ - if (scpk) { - DATA_BLOB blob; - - blob = strhex_to_data_blob(scpk->data); - if (!blob.data) { - ret = ENOMEM; - goto out; - } - talloc_steal(mem_ctx, blob.data); - - /* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */ - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb, - (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); - krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); - ret = EINVAL; - goto out; - } - - if (newer_keys && _pkb.version != 4) { - krb5_set_error_string(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); - krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); - ret = EINVAL; - goto out; - } - - if (!newer_keys && _pkb.version != 3) { - krb5_set_error_string(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); - krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); - ret = EINVAL; - goto out; - } - - if (_pkb.version == 4) { - pkb4 = &_pkb.ctr.ctr4; - allocated_keys += pkb4->num_keys; - } else if (_pkb.version == 3) { - pkb3 = &_pkb.ctr.ctr3; - allocated_keys += pkb3->num_keys; - } - } - - if (allocated_keys == 0) { - /* oh, no password. Apparently (comment in - * hdb-ldap.c) this violates the ASN.1, but this - * allows an entry with no keys (yet). */ - return 0; - } - - /* allocate space to decode into */ - entry_ex->entry.keys.len = 0; - entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key)); - if (entry_ex->entry.keys.val == NULL) { - ret = ENOMEM; - goto out; - } - - if (hash && !(userAccountControl & UF_USE_DES_KEY_ONLY)) { - Key key; - - key.mkvno = 0; - key.salt = NULL; /* No salt for this enc type */ - - ret = krb5_keyblock_init(context, - ENCTYPE_ARCFOUR_HMAC_MD5, - hash->hash, sizeof(hash->hash), - &key.key); - if (ret) { - goto out; - } - - entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; - entry_ex->entry.keys.len++; - } - - if (pkb4) { - for (i=0; i < pkb4->num_keys; i++) { - bool use = true; - Key key; - - if (!pkb4->keys[i].value) continue; - - if (userAccountControl & UF_USE_DES_KEY_ONLY) { - switch (pkb4->keys[i].keytype) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - break; - default: - use = false; - break; - } - } - - if (!use) continue; - - key.mkvno = 0; - key.salt = NULL; - - if (pkb4->salt.string) { - DATA_BLOB salt; - - salt = data_blob_string_const(pkb4->salt.string); - - key.salt = calloc(1, sizeof(*key.salt)); - if (key.salt == NULL) { - ret = ENOMEM; - goto out; - } - - key.salt->type = hdb_pw_salt; - - ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length); - if (ret) { - free(key.salt); - key.salt = NULL; - goto out; - } - } - - /* TODO: maybe pass the iteration_count somehow... */ - - ret = krb5_keyblock_init(context, - pkb4->keys[i].keytype, - pkb4->keys[i].value->data, - pkb4->keys[i].value->length, - &key.key); - if (ret) { - if (key.salt) { - free_Salt(key.salt); - free(key.salt); - key.salt = NULL; - } - goto out; - } - - entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; - entry_ex->entry.keys.len++; - } - } else if (pkb3) { - for (i=0; i < pkb3->num_keys; i++) { - bool use = true; - Key key; - - if (!pkb3->keys[i].value) continue; - - if (userAccountControl & UF_USE_DES_KEY_ONLY) { - switch (pkb3->keys[i].keytype) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - break; - default: - use = false; - break; - } - } - - if (!use) continue; - - key.mkvno = 0; - key.salt = NULL; - - if (pkb3->salt.string) { - DATA_BLOB salt; - - salt = data_blob_string_const(pkb3->salt.string); - - key.salt = calloc(1, sizeof(*key.salt)); - if (key.salt == NULL) { - ret = ENOMEM; - goto out; - } - - key.salt->type = hdb_pw_salt; - - ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length); - if (ret) { - free(key.salt); - key.salt = NULL; - goto out; - } - } - - ret = krb5_keyblock_init(context, - pkb3->keys[i].keytype, - pkb3->keys[i].value->data, - pkb3->keys[i].value->length, - &key.key); - if (ret) { - if (key.salt) { - free_Salt(key.salt); - free(key.salt); - key.salt = NULL; - } - goto out; - } - - entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; - entry_ex->entry.keys.len++; - } - } - -out: - if (ret != 0) { - entry_ex->entry.keys.len = 0; - } - if (entry_ex->entry.keys.len == 0 && entry_ex->entry.keys.val) { - free(entry_ex->entry.keys.val); - entry_ex->entry.keys.val = NULL; - } - return ret; -} - -/* - * Construct an hdb_entry from a directory entry. - */ -static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, - TALLOC_CTX *mem_ctx, krb5_const_principal principal, - enum hdb_ldb_ent_type ent_type, - struct ldb_message *msg, - struct ldb_message *realm_ref_msg, - hdb_entry_ex *entry_ex) -{ - unsigned int userAccountControl; - int i; - krb5_error_code ret = 0; - krb5_boolean is_computer = FALSE; - const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL); - char *realm = strupper_talloc(mem_ctx, dnsdomain); - struct loadparm_context *lp_ctx = ldb_get_opaque((struct ldb_context *)db->hdb_db, "loadparm"); - struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, - mem_ctx, - realm_ref_msg, - "nCName", - ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL)); - - struct hdb_ldb_private *private; - NTTIME acct_expiry; - - struct ldb_message_element *objectclasses; - struct ldb_val computer_val; - computer_val.data = discard_const_p(uint8_t,"computer"); - computer_val.length = strlen((const char *)computer_val.data); - - objectclasses = ldb_msg_find_element(msg, "objectClass"); - - if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) { - is_computer = TRUE; - } - - memset(entry_ex, 0, sizeof(*entry_ex)); - - if (!realm) { - krb5_set_error_string(context, "talloc_strdup: out of memory"); - ret = ENOMEM; - goto out; - } - - private = talloc(mem_ctx, struct hdb_ldb_private); - if (!private) { - ret = ENOMEM; - goto out; - } - - private->entry_ex = entry_ex; - private->iconv_convenience = lp_iconv_convenience(lp_ctx); - private->netbios_name = lp_netbios_name(lp_ctx); - - talloc_set_destructor(private, hdb_ldb_destructor); - - entry_ex->ctx = private; - entry_ex->free_entry = hdb_ldb_free_entry; - - userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); - - - entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); - if (ent_type == HDB_LDB_ENT_TYPE_ANY && principal == NULL) { - const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); - if (!samAccountName) { - krb5_set_error_string(context, "LDB_message2entry: no samAccountName present"); - ret = ENOENT; - goto out; - } - samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); - krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL); - } else { - char *strdup_realm; - ret = copy_Principal(principal, entry_ex->entry.principal); - if (ret) { - krb5_clear_error_string(context); - goto out; - } - - /* While we have copied the client principal, tests - * show that Win2k3 returns the 'corrected' realm, not - * the client-specified realm. This code attempts to - * replace the client principal's realm with the one - * we determine from our records */ - - /* this has to be with malloc() */ - strdup_realm = strdup(realm); - if (!strdup_realm) { - ret = ENOMEM; - krb5_clear_error_string(context); - goto out; - } - free(*krb5_princ_realm(context, entry_ex->entry.principal)); - krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm); - } - - entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type); - - if (ent_type == HDB_LDB_ENT_TYPE_KRBTGT) { - entry_ex->entry.flags.invalid = 0; - entry_ex->entry.flags.server = 1; - entry_ex->entry.flags.forwardable = 1; - entry_ex->entry.flags.ok_as_delegate = 1; - } - - if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { - if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) { - entry_ex->entry.flags.server = 0; - } - } - - /* use 'whenCreated' */ - entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); - /* use '???' */ - entry_ex->entry.created_by.principal = NULL; - - entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); - if (entry_ex->entry.modified_by == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; - } - - /* use 'whenChanged' */ - entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); - /* use '???' */ - entry_ex->entry.modified_by->principal = NULL; - - entry_ex->entry.valid_start = NULL; - - acct_expiry = samdb_result_account_expires(msg); - if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) { - entry_ex->entry.valid_end = NULL; - } else { - entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end)); - if (entry_ex->entry.valid_end == NULL) { - ret = ENOMEM; - goto out; - } - *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry); - } - - if (ent_type != HDB_LDB_ENT_TYPE_KRBTGT) { - NTTIME must_change_time - = samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, - domain_dn, msg); - if (must_change_time == 0x7FFFFFFFFFFFFFFFULL) { - entry_ex->entry.pw_end = NULL; - } else { - entry_ex->entry.pw_end = malloc(sizeof(*entry_ex->entry.pw_end)); - if (entry_ex->entry.pw_end == NULL) { - ret = ENOMEM; - goto out; - } - *entry_ex->entry.pw_end = nt_time_to_unix(must_change_time); - } - } else { - entry_ex->entry.pw_end = NULL; - } - - entry_ex->entry.max_life = NULL; - - entry_ex->entry.max_renew = NULL; - - entry_ex->entry.generation = NULL; - - /* Get keys from the db */ - ret = LDB_message2entry_keys(context, private->iconv_convenience, private, msg, userAccountControl, entry_ex); - if (ret) { - /* Could be bougus data in the entry, or out of memory */ - goto out; - } - - entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); - if (entry_ex->entry.etypes == NULL) { - krb5_clear_error_string(context); - ret = ENOMEM; - goto out; - } - entry_ex->entry.etypes->len = entry_ex->entry.keys.len; - entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); - if (entry_ex->entry.etypes->val == NULL) { - krb5_clear_error_string(context); - ret = ENOMEM; - goto out; - } - for (i=0; i < entry_ex->entry.etypes->len; i++) { - entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype; - } - - - private->msg = talloc_steal(private, msg); - private->realm_ref_msg = talloc_steal(private, realm_ref_msg); - private->samdb = (struct ldb_context *)db->hdb_db; - -out: - if (ret != 0) { - /* This doesn't free ent itself, that is for the eventual caller to do */ - hdb_free_entry(context, entry_ex); - } else { - talloc_steal(db, entry_ex->ctx); - } - - return ret; -} - -/* - * Construct an hdb_entry from a directory entry. - */ -static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, - struct loadparm_context *lp_ctx, - TALLOC_CTX *mem_ctx, krb5_const_principal principal, - enum trust_direction direction, - struct ldb_message *msg, - hdb_entry_ex *entry_ex) -{ - - const char *dnsdomain; - char *realm; - char *strdup_realm; - DATA_BLOB password_utf16; - struct samr_Password password_hash; - const struct ldb_val *password_val; - struct trustAuthInOutBlob password_blob; - struct hdb_ldb_private *private; - - enum ndr_err_code ndr_err; - int i, ret, trust_direction_flags; - - private = talloc(mem_ctx, struct hdb_ldb_private); - if (!private) { - ret = ENOMEM; - goto out; - } - - private->entry_ex = entry_ex; - private->iconv_convenience = lp_iconv_convenience(lp_ctx); - private->netbios_name = lp_netbios_name(lp_ctx); - - talloc_set_destructor(private, hdb_ldb_destructor); - - entry_ex->ctx = private; - entry_ex->free_entry = hdb_ldb_free_entry; - - /* use 'whenCreated' */ - entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); - /* use '???' */ - entry_ex->entry.created_by.principal = NULL; - - entry_ex->entry.valid_start = NULL; - - trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0); - - if (direction == INBOUND) { - realm = strupper_talloc(mem_ctx, lp_realm(lp_ctx)); - password_val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming"); - - } else { /* OUTBOUND */ - dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL); - realm = strupper_talloc(mem_ctx, dnsdomain); - password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing"); - } - - if (!password_val || !(trust_direction_flags & direction)) { - ret = ENOENT; - goto out; - } - - ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, - (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - ret = EINVAL; - goto out; - } - - for (i=0; i < password_blob.count; i++) { - if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { - password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, - password_blob.current->array[i].AuthInfo.clear.size); - /* In the future, generate all sorts of - * hashes, but for now we can't safely convert - * the random strings windows uses into - * utf8 */ - - /* but as it is utf16 already, we can get the NT password/arcfour-hmac-md5 key */ - mdfour(password_hash.hash, password_utf16.data, password_utf16.length); - break; - } else if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { - password_hash = password_blob.current->array[i].AuthInfo.nt4owf.password; - break; - } - } - entry_ex->entry.keys.len = 0; - entry_ex->entry.keys.val = NULL; - - if (i < password_blob.count) { - Key key; - /* Must have found a cleartext or MD4 password */ - entry_ex->entry.keys.val = calloc(1, sizeof(Key)); - - key.mkvno = 0; - key.salt = NULL; /* No salt for this enc type */ - - if (entry_ex->entry.keys.val == NULL) { - ret = ENOMEM; - goto out; - } - - ret = krb5_keyblock_init(context, - ENCTYPE_ARCFOUR_HMAC_MD5, - password_hash.hash, sizeof(password_hash.hash), - &key.key); - - entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; - entry_ex->entry.keys.len++; - } - - ret = copy_Principal(principal, entry_ex->entry.principal); - if (ret) { - krb5_clear_error_string(context); - goto out; - } - - /* While we have copied the client principal, tests - * show that Win2k3 returns the 'corrected' realm, not - * the client-specified realm. This code attempts to - * replace the client principal's realm with the one - * we determine from our records */ - - /* this has to be with malloc() */ - strdup_realm = strdup(realm); - if (!strdup_realm) { - ret = ENOMEM; - krb5_clear_error_string(context); - goto out; - } - free(*krb5_princ_realm(context, entry_ex->entry.principal)); - krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm); - - entry_ex->entry.flags = int2HDBFlags(0); - entry_ex->entry.flags.immutable = 1; - entry_ex->entry.flags.invalid = 0; - entry_ex->entry.flags.server = 1; - entry_ex->entry.flags.require_preauth = 1; - - entry_ex->entry.pw_end = NULL; - - entry_ex->entry.max_life = NULL; - - entry_ex->entry.max_renew = NULL; - - entry_ex->entry.generation = NULL; - - entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); - if (entry_ex->entry.etypes == NULL) { - krb5_clear_error_string(context); - ret = ENOMEM; - goto out; - } - entry_ex->entry.etypes->len = entry_ex->entry.keys.len; - entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); - if (entry_ex->entry.etypes->val == NULL) { - krb5_clear_error_string(context); - ret = ENOMEM; - goto out; - } - for (i=0; i < entry_ex->entry.etypes->len; i++) { - entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype; - } - - - private->msg = talloc_steal(private, msg); - private->realm_ref_msg = NULL; - private->samdb = (struct ldb_context *)db->hdb_db; - -out: - if (ret != 0) { - /* This doesn't free ent itself, that is for the eventual caller to do */ - hdb_free_entry(context, entry_ex); - } else { - talloc_steal(db, entry_ex->ctx); - } - - return ret; - -} - -static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_context *ldb_ctx, - TALLOC_CTX *mem_ctx, - krb5_const_principal principal, - enum hdb_ldb_ent_type ent_type, - struct ldb_dn *realm_dn, - struct ldb_message ***pmsg) -{ - krb5_error_code ret; - int lret; - char *filter = NULL; - const char * const *princ_attrs = user_attrs; - - char *short_princ; - char *short_princ_talloc; - - struct ldb_result *res = NULL; - - ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ); - - if (ret != 0) { - krb5_set_error_string(context, "LDB_lookup_principal: could not parse principal"); - krb5_warnx(context, "LDB_lookup_principal: could not parse principal"); - return ret; - } - - short_princ_talloc = talloc_strdup(mem_ctx, short_princ); - free(short_princ); - if (!short_princ_talloc) { - krb5_set_error_string(context, "LDB_lookup_principal: talloc_strdup() failed!"); - return ENOMEM; - } - - switch (ent_type) { - case HDB_LDB_ENT_TYPE_CLIENT: - case HDB_LDB_ENT_TYPE_TRUST: - case HDB_LDB_ENT_TYPE_ANY: - /* Can't happen */ - return EINVAL; - case HDB_LDB_ENT_TYPE_KRBTGT: - filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", - KRB5_TGS_NAME); - break; - case HDB_LDB_ENT_TYPE_SERVER: - filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", - short_princ_talloc); - break; - } - - if (!filter) { - krb5_set_error_string(context, "talloc_asprintf: out of memory"); - return ENOMEM; - } - - lret = ldb_search(ldb_ctx, mem_ctx, &res, realm_dn, - LDB_SCOPE_SUBTREE, princ_attrs, "%s", filter); - if (lret != LDB_SUCCESS) { - DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); - return HDB_ERR_NOENTRY; - } else if (res->count == 0 || res->count > 1) { - DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); - talloc_free(res); - return HDB_ERR_NOENTRY; - } - talloc_steal(mem_ctx, res->msgs); - *pmsg = res->msgs; - talloc_free(res); - return 0; -} - -static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, - TALLOC_CTX *mem_ctx, - const char *realm, - struct ldb_dn *realm_dn, - struct ldb_message ***pmsg) -{ - int lret; - char *filter = NULL; - const char * const *attrs = trust_attrs; - - struct ldb_result *res = NULL; - filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm); - - if (!filter) { - krb5_set_error_string(context, "talloc_asprintf: out of memory"); - return ENOMEM; - } - - lret = ldb_search(ldb_ctx, mem_ctx, &res, - ldb_get_default_basedn(ldb_ctx), - LDB_SCOPE_SUBTREE, attrs, "%s", filter); - if (lret != LDB_SUCCESS) { - DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); - return HDB_ERR_NOENTRY; - } else if (res->count == 0 || res->count > 1) { - DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); - talloc_free(res); - return HDB_ERR_NOENTRY; - } - talloc_steal(mem_ctx, res->msgs); - *pmsg = res->msgs; - talloc_free(res); - return 0; -} - -static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx, - TALLOC_CTX *mem_ctx, - const char *realm, - struct ldb_message ***pmsg) -{ - int ret; - struct ldb_result *cross_ref_res; - struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx); - - ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res, - partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs, - "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))", - realm, realm); - - if (ret != LDB_SUCCESS) { - DEBUG(3, ("Failed to search to lookup realm(%s): %s\n", realm, ldb_errstring(ldb_ctx))); - talloc_free(cross_ref_res); - return HDB_ERR_NOENTRY; - } else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) { - DEBUG(3, ("Failed find a single entry for realm %s: got %d\n", realm, cross_ref_res->count)); - talloc_free(cross_ref_res); - return HDB_ERR_NOENTRY; - } - - if (pmsg) { - *pmsg = cross_ref_res->msgs; - talloc_steal(mem_ctx, cross_ref_res->msgs); - } - talloc_free(cross_ref_res); - - return 0; -} - - -static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode) -{ - if (db->hdb_master_key_set) { - krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n"); - krb5_set_error_string(context, "LDB_open: use of a master key incompatible with LDB\n"); - return HDB_ERR_NOENTRY; - } - - return 0; -} - -static krb5_error_code LDB_close(krb5_context context, HDB *db) -{ - return 0; -} - -static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation) -{ - return 0; -} - -static krb5_error_code LDB_unlock(krb5_context context, HDB *db) -{ - return 0; -} - -static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name) -{ - return HDB_ERR_DB_INUSE; -} - -static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, - TALLOC_CTX *mem_ctx, - krb5_const_principal principal, - unsigned flags, - hdb_entry_ex *entry_ex) { - NTSTATUS nt_status; - char *principal_string; - krb5_error_code ret; - struct ldb_message **msg = NULL; - struct ldb_message **realm_ref_msg = NULL; - - ret = krb5_unparse_name(context, principal, &principal_string); - - if (ret != 0) { - return ret; - } - - nt_status = sam_get_results_principal((struct ldb_context *)db->hdb_db, - mem_ctx, principal_string, - &msg, &realm_ref_msg); - free(principal_string); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) { - return HDB_ERR_NOENTRY; - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) { - return ENOMEM; - } else if (!NT_STATUS_IS_OK(nt_status)) { - return EINVAL; - } - - ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_CLIENT, - msg[0], realm_ref_msg[0], entry_ex); - return ret; -} - -static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, - TALLOC_CTX *mem_ctx, - krb5_const_principal principal, - unsigned flags, - hdb_entry_ex *entry_ex) -{ - krb5_error_code ret; - struct ldb_message **msg = NULL; - struct ldb_message **realm_ref_msg_1 = NULL; - struct ldb_message **realm_ref_msg_2 = NULL; - struct ldb_dn *realm_dn; - const char *realm; - - krb5_principal alloc_principal = NULL; - if (principal->name.name_string.len != 2 - || (strcmp(principal->name.name_string.val[0], KRB5_TGS_NAME) != 0)) { - /* Not a krbtgt */ - return HDB_ERR_NOENTRY; - } - - /* krbtgt case. Either us or a trusted realm */ - - if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, - mem_ctx, principal->realm, &realm_ref_msg_1) == 0) - && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, - mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0) - && (ldb_dn_compare(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) { - /* us */ - /* Cludge, cludge cludge. If the realm part of krbtgt/realm, - * is in our db, then direct the caller at our primary - * krbtgt */ - - const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg_1[0], "dnsRoot", NULL); - char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain); - if (!realm_fixed) { - krb5_set_error_string(context, "strupper_talloc: out of memory"); - return ENOMEM; - } - - ret = krb5_copy_principal(context, principal, &alloc_principal); - if (ret) { - return ret; - } - - free(alloc_principal->name.name_string.val[1]); - alloc_principal->name.name_string.val[1] = strdup(realm_fixed); - talloc_free(realm_fixed); - if (!alloc_principal->name.name_string.val[1]) { - krb5_set_error_string(context, "LDB_fetch: strdup() failed!"); - return ENOMEM; - } - principal = alloc_principal; - realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL); - - ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, - mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg); - - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: could not find principal in DB"); - krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); - return ret; - } - - ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_KRBTGT, - msg[0], realm_ref_msg_1[0], entry_ex); - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); - } - return ret; - - } else { - enum trust_direction direction = UNKNOWN; - - struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context); - /* Either an inbound or outbound trust */ - - if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) { - /* look for inbound trust */ - direction = INBOUND; - realm = principal->name.name_string.val[1]; - } - - if (strcasecmp(lp_realm(lp_ctx), principal->name.name_string.val[1]) == 0) { - /* look for outbound trust */ - direction = OUTBOUND; - realm = principal->realm; - } - - /* Trusted domains are under CN=system */ - - ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, - mem_ctx, - realm, realm_dn, &msg); - - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: could not find principal in DB"); - krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); - return ret; - } - - ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, - principal, direction, - msg[0], entry_ex); - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); - } - return ret; - - - /* we should lookup trusted domains */ - return HDB_ERR_NOENTRY; - } - -} - -static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, - TALLOC_CTX *mem_ctx, - krb5_const_principal principal, - unsigned flags, - hdb_entry_ex *entry_ex) -{ - krb5_error_code ret; - const char *realm; - struct ldb_message **msg = NULL; - struct ldb_message **realm_ref_msg = NULL; - struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx); - if (principal->name.name_string.len >= 2) { - /* 'normal server' case */ - int ldb_ret; - NTSTATUS nt_status; - struct ldb_dn *user_dn, *domain_dn; - char *principal_string; - - ret = krb5_unparse_name_flags(context, principal, - KRB5_PRINCIPAL_UNPARSE_NO_REALM, - &principal_string); - if (ret != 0) { - return ret; - } - - /* At this point we may find the host is known to be - * in a different realm, so we should generate a - * referral instead */ - nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db, - mem_ctx, principal_string, - &user_dn, &domain_dn); - free(principal_string); - - if (!NT_STATUS_IS_OK(nt_status)) { - return HDB_ERR_NOENTRY; - } - - ldb_ret = gendb_search_dn((struct ldb_context *)db->hdb_db, - mem_ctx, user_dn, &msg, user_attrs); - - if (ldb_ret != 1) { - return HDB_ERR_NOENTRY; - } - - ldb_ret = gendb_search((struct ldb_context *)db->hdb_db, - mem_ctx, partitions_basedn, &realm_ref_msg, realm_ref_attrs, - "ncName=%s", ldb_dn_get_linearized(domain_dn)); - - if (ldb_ret != 1) { - return HDB_ERR_NOENTRY; - } - - } else { - struct ldb_dn *realm_dn; - /* server as client principal case, but we must not lookup userPrincipalNames */ - - realm = krb5_principal_get_realm(context, principal); - - ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, - mem_ctx, realm, &realm_ref_msg); - if (ret != 0) { - return HDB_ERR_NOENTRY; - } - - realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL); - - ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, - mem_ctx, - principal, HDB_LDB_ENT_TYPE_SERVER, realm_dn, &msg); - - if (ret != 0) { - return ret; - } - } - - ret = LDB_message2entry(context, db, mem_ctx, - principal, HDB_LDB_ENT_TYPE_SERVER, - msg[0], realm_ref_msg[0], entry_ex); - if (ret != 0) { - krb5_warnx(context, "LDB_fetch: message2entry failed"); - } - - return ret; -} - -static krb5_error_code LDB_fetch(krb5_context context, HDB *db, - krb5_const_principal principal, - unsigned flags, - hdb_entry_ex *entry_ex) -{ - krb5_error_code ret = HDB_ERR_NOENTRY; - - TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context"); - - if (!mem_ctx) { - krb5_set_error_string(context, "LDB_fetch: talloc_named() failed!"); - return ENOMEM; - } - - if (flags & HDB_F_GET_CLIENT) { - ret = LDB_fetch_client(context, db, mem_ctx, principal, flags, entry_ex); - if (ret != HDB_ERR_NOENTRY) goto done; - } - if (flags & HDB_F_GET_SERVER) { - /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */ - ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); - if (ret != HDB_ERR_NOENTRY) goto done; - - /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */ - ret = LDB_fetch_server(context, db, mem_ctx, principal, flags, entry_ex); - if (ret != HDB_ERR_NOENTRY) goto done; - } - if (flags & HDB_F_GET_KRBTGT) { - ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); - if (ret != HDB_ERR_NOENTRY) goto done; - } - -done: - talloc_free(mem_ctx); - return ret; -} - -static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) -{ - return HDB_ERR_DB_INUSE; -} - -static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal) -{ - return HDB_ERR_DB_INUSE; -} - -struct hdb_ldb_seq { - struct ldb_context *ctx; - int index; - int count; - struct ldb_message **msgs; - struct ldb_message **realm_ref_msgs; -}; - -static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) -{ - krb5_error_code ret; - struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc; - TALLOC_CTX *mem_ctx; - hdb_entry_ex entry_ex; - memset(&entry_ex, '\0', sizeof(entry_ex)); - - if (!priv) { - return HDB_ERR_NOENTRY; - } - - mem_ctx = talloc_named(priv, 0, "LDB_seq context"); - - if (!mem_ctx) { - krb5_set_error_string(context, "LDB_seq: talloc_named() failed!"); - return ENOMEM; - } - - if (priv->index < priv->count) { - ret = LDB_message2entry(context, db, mem_ctx, - NULL, HDB_LDB_ENT_TYPE_ANY, - priv->msgs[priv->index++], - priv->realm_ref_msgs[0], entry); - } else { - ret = HDB_ERR_NOENTRY; - } - - if (ret != 0) { - talloc_free(priv); - db->hdb_dbc = NULL; - } else { - talloc_free(mem_ctx); - } - - return ret; -} - -static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) -{ - struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db; - struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc; - char *realm; - struct ldb_dn *realm_dn = NULL; - struct ldb_result *res = NULL; - struct ldb_message **realm_ref_msgs = NULL; - krb5_error_code ret; - TALLOC_CTX *mem_ctx; - int lret; - - if (priv) { - talloc_free(priv); - db->hdb_dbc = NULL; - } - - priv = (struct hdb_ldb_seq *) talloc(db, struct hdb_ldb_seq); - if (!priv) { - krb5_set_error_string(context, "talloc: out of memory"); - return ENOMEM; - } - - priv->ctx = ldb_ctx; - priv->index = 0; - priv->msgs = NULL; - priv->realm_ref_msgs = NULL; - priv->count = 0; - - mem_ctx = talloc_named(priv, 0, "LDB_firstkey context"); - - if (!mem_ctx) { - krb5_set_error_string(context, "LDB_firstkey: talloc_named() failed!"); - return ENOMEM; - } - - ret = krb5_get_default_realm(context, &realm); - if (ret != 0) { - talloc_free(priv); - return ret; - } - - ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, - mem_ctx, realm, &realm_ref_msgs); - - free(realm); - - if (ret != 0) { - talloc_free(priv); - krb5_warnx(context, "LDB_firstkey: could not find realm\n"); - return HDB_ERR_NOENTRY; - } - - realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL); - - priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs); - - lret = ldb_search(ldb_ctx, priv, &res, - realm_dn, LDB_SCOPE_SUBTREE, user_attrs, - "(objectClass=user)"); - - if (lret != LDB_SUCCESS) { - talloc_free(priv); - return HDB_ERR_NOENTRY; - } - - priv->count = res->count; - priv->msgs = talloc_steal(priv, res->msgs); - talloc_free(res); - - db->hdb_dbc = priv; - - ret = LDB_seq(context, db, flags, entry); - - if (ret != 0) { - talloc_free(priv); - db->hdb_dbc = NULL; - } else { - talloc_free(mem_ctx); - } - return ret; -} - -static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags, - hdb_entry_ex *entry) -{ - return LDB_seq(context, db, flags, entry); -} - -static krb5_error_code LDB_destroy(krb5_context context, HDB *db) -{ - talloc_free(db); - return 0; -} - -/* This interface is to be called by the KDC, which is expecting Samba - * calling conventions. It is also called by a wrapper - * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb - * code */ - -NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx, - struct event_context *ev_ctx, - struct loadparm_context *lp_ctx, - krb5_context context, struct HDB **db, const char *arg) -{ - NTSTATUS nt_status; - struct auth_session_info *session_info; - *db = talloc(mem_ctx, HDB); - if (!*db) { - krb5_set_error_string(context, "malloc: out of memory"); - return NT_STATUS_NO_MEMORY; - } - - (*db)->hdb_master_key_set = 0; - (*db)->hdb_db = NULL; - - nt_status = auth_system_session_info(*db, lp_ctx, &session_info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - /* The idea here is very simple. Using Kerberos to - * authenticate the KDC to the LDAP server is higly likely to - * be circular. - * - * In future we may set this up to use EXERNAL and SSL - * certificates, for now it will almost certainly be NTLMSSP - */ - - cli_credentials_set_kerberos_state(session_info->credentials, - CRED_DONT_USE_KERBEROS); - - /* Setup the link to LDB */ - (*db)->hdb_db = samdb_connect(*db, ev_ctx, lp_ctx, session_info); - if ((*db)->hdb_db == NULL) { - DEBUG(1, ("hdb_ldb_create: Cannot open samdb for KDC backend!")); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - - (*db)->hdb_dbc = NULL; - (*db)->hdb_open = LDB_open; - (*db)->hdb_close = LDB_close; - (*db)->hdb_fetch = LDB_fetch; - (*db)->hdb_store = LDB_store; - (*db)->hdb_remove = LDB_remove; - (*db)->hdb_firstkey = LDB_firstkey; - (*db)->hdb_nextkey = LDB_nextkey; - (*db)->hdb_lock = LDB_lock; - (*db)->hdb_unlock = LDB_unlock; - (*db)->hdb_rename = LDB_rename; - /* we don't implement these, as we are not a lockable database */ - (*db)->hdb__get = NULL; - (*db)->hdb__put = NULL; - /* kadmin should not be used for deletes - use other tools instead */ - (*db)->hdb__del = NULL; - (*db)->hdb_destroy = LDB_destroy; - - return NT_STATUS_OK; -} - -krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg) -{ - NTSTATUS nt_status; - /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */ - nt_status = kdc_hdb_ldb_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, - context, db, arg); - - if (NT_STATUS_IS_OK(nt_status)) { - return 0; - } - return EINVAL; -} diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c new file mode 100644 index 0000000000..d7317f17d4 --- /dev/null +++ b/source4/kdc/hdb-samba4.c @@ -0,0 +1,1550 @@ +/* + * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd. + * Copyright (c) 2004, Andrew Bartlett . + * Copyright (c) 2004, Stefan Metzmacher + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" +#include "system/time.h" +#include "dsdb/common/flags.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "librpc/gen_ndr/netlogon.h" +#include "auth/auth.h" +#include "auth/credentials/credentials.h" +#include "auth/auth_sam.h" +#include "util/util_ldb.h" +#include "dsdb/samdb/samdb.h" +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" +#include "librpc/gen_ndr/lsa.h" +#include "libcli/auth/libcli_auth.h" +#include "param/param.h" +#include "events/events.h" +#include "kdc/kdc.h" +#include "../lib/crypto/md4.h" + +enum hdb_ldb_ent_type +{ HDB_SAMBA4_ENT_TYPE_CLIENT, HDB_SAMBA4_ENT_TYPE_SERVER, + HDB_SAMBA4_ENT_TYPE_KRBTGT, HDB_SAMBA4_ENT_TYPE_TRUST, HDB_SAMBA4_ENT_TYPE_ANY }; + +enum trust_direction { + UNKNOWN = 0, + INBOUND = LSA_TRUST_DIRECTION_INBOUND, + OUTBOUND = LSA_TRUST_DIRECTION_OUTBOUND +}; + +static const char *realm_ref_attrs[] = { + "nCName", + "dnsRoot", + NULL +}; + +static const char *trust_attrs[] = { + "trustPartner", + "trustAuthIncoming", + "trustAuthOutgoing", + "whenCreated", + "msDS-SupportedEncryptionTypes", + "trustAttributes", + "trustDirection", + "trustType", + NULL +}; + +static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val) +{ + const char *tmp; + const char *gentime; + struct tm tm; + + gentime = ldb_msg_find_attr_as_string(msg, attr, NULL); + if (!gentime) + return default_val; + + tmp = strptime(gentime, "%Y%m%d%H%M%SZ", &tm); + if (tmp == NULL) { + return default_val; + } + + return timegm(&tm); +} + +static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum hdb_ldb_ent_type ent_type) +{ + HDBFlags flags = int2HDBFlags(0); + + /* we don't allow kadmin deletes */ + flags.immutable = 1; + + /* mark the principal as invalid to start with */ + flags.invalid = 1; + + flags.renewable = 1; + + /* All accounts are servers, but this may be disabled again in the caller */ + flags.server = 1; + + /* Account types - clear the invalid bit if it turns out to be valid */ + if (userAccountControl & UF_NORMAL_ACCOUNT) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { + flags.client = 1; + } + flags.invalid = 0; + } + + if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { + flags.client = 1; + } + flags.invalid = 0; + } + if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { + flags.client = 1; + } + flags.invalid = 0; + } + if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) { + if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) { + flags.client = 1; + } + flags.invalid = 0; + } + + /* Not permitted to act as a client if disabled */ + if (userAccountControl & UF_ACCOUNTDISABLE) { + flags.client = 0; + } + if (userAccountControl & UF_LOCKOUT) { + flags.invalid = 1; + } +/* + if (userAccountControl & UF_PASSWORD_NOTREQD) { + flags.invalid = 1; + } +*/ +/* + UF_PASSWORD_CANT_CHANGE and UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED are irrelevent +*/ + if (userAccountControl & UF_TEMP_DUPLICATE_ACCOUNT) { + flags.invalid = 1; + } + +/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */ + +/* + if (userAccountControl & UF_MNS_LOGON_ACCOUNT) { + flags.invalid = 1; + } +*/ + if (userAccountControl & UF_SMARTCARD_REQUIRED) { + flags.require_hwauth = 1; + } + if (userAccountControl & UF_TRUSTED_FOR_DELEGATION) { + flags.ok_as_delegate = 1; + } + if (!(userAccountControl & UF_NOT_DELEGATED)) { + flags.forwardable = 1; + flags.proxiable = 1; + } + + if (userAccountControl & UF_DONT_REQUIRE_PREAUTH) { + flags.require_preauth = 0; + } else { + flags.require_preauth = 1; + + } + return flags; +} + +static int hdb_ldb_destructor(struct hdb_ldb_private *private) +{ + hdb_entry_ex *entry_ex = private->entry_ex; + free_hdb_entry(&entry_ex->entry); + return 0; +} + +static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex) +{ + talloc_free(entry_ex->ctx); +} + +static krb5_error_code LDB_message2entry_keys(krb5_context context, + struct smb_iconv_convenience *iconv_convenience, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + unsigned int userAccountControl, + hdb_entry_ex *entry_ex) +{ + krb5_error_code ret = 0; + enum ndr_err_code ndr_err; + struct samr_Password *hash; + const struct ldb_val *sc_val; + struct supplementalCredentialsBlob scb; + struct supplementalCredentialsPackage *scpk = NULL; + bool newer_keys = false; + struct package_PrimaryKerberosBlob _pkb; + struct package_PrimaryKerberosCtr3 *pkb3 = NULL; + struct package_PrimaryKerberosCtr4 *pkb4 = NULL; + uint32_t i; + uint32_t allocated_keys = 0; + + entry_ex->entry.keys.val = NULL; + entry_ex->entry.keys.len = 0; + + entry_ex->entry.kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0); + + /* Get keys from the db */ + + hash = samdb_result_hash(mem_ctx, msg, "unicodePwd"); + sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials"); + + /* unicodePwd for enctype 0x17 (23) if present */ + if (hash) { + allocated_keys++; + } + + /* supplementalCredentials if present */ + if (sc_val) { + ndr_err = ndr_pull_struct_blob_all(sc_val, mem_ctx, iconv_convenience, &scb, + (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + dump_data(0, sc_val->data, sc_val->length); + ret = EINVAL; + goto out; + } + + if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) { + NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb); + ret = EINVAL; + goto out; + } + + for (i=0; i < scb.sub.num_packages; i++) { + if (strcmp("Primary:Kerberos-Newer-Keys", scb.sub.packages[i].name) == 0) { + scpk = &scb.sub.packages[i]; + if (!scpk->data || !scpk->data[0]) { + scpk = NULL; + continue; + } + newer_keys = true; + break; + } else if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) == 0) { + scpk = &scb.sub.packages[i]; + if (!scpk->data || !scpk->data[0]) { + scpk = NULL; + } + /* + * we don't break here in hope to find + * a Kerberos-Newer-Keys package + */ + } + } + } + /* + * Primary:Kerberos-Newer-Keys or Primary:Kerberos element + * of supplementalCredentials + */ + if (scpk) { + DATA_BLOB blob; + + blob = strhex_to_data_blob(scpk->data); + if (!blob.data) { + ret = ENOMEM; + goto out; + } + talloc_steal(mem_ctx, blob.data); + + /* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */ + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb, + (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + krb5_set_error_string(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); + krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob"); + ret = EINVAL; + goto out; + } + + if (newer_keys && _pkb.version != 4) { + krb5_set_error_string(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); + krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4"); + ret = EINVAL; + goto out; + } + + if (!newer_keys && _pkb.version != 3) { + krb5_set_error_string(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); + krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3"); + ret = EINVAL; + goto out; + } + + if (_pkb.version == 4) { + pkb4 = &_pkb.ctr.ctr4; + allocated_keys += pkb4->num_keys; + } else if (_pkb.version == 3) { + pkb3 = &_pkb.ctr.ctr3; + allocated_keys += pkb3->num_keys; + } + } + + if (allocated_keys == 0) { + /* oh, no password. Apparently (comment in + * hdb-ldap.c) this violates the ASN.1, but this + * allows an entry with no keys (yet). */ + return 0; + } + + /* allocate space to decode into */ + entry_ex->entry.keys.len = 0; + entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key)); + if (entry_ex->entry.keys.val == NULL) { + ret = ENOMEM; + goto out; + } + + if (hash && !(userAccountControl & UF_USE_DES_KEY_ONLY)) { + Key key; + + key.mkvno = 0; + key.salt = NULL; /* No salt for this enc type */ + + ret = krb5_keyblock_init(context, + ENCTYPE_ARCFOUR_HMAC_MD5, + hash->hash, sizeof(hash->hash), + &key.key); + if (ret) { + goto out; + } + + entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; + entry_ex->entry.keys.len++; + } + + if (pkb4) { + for (i=0; i < pkb4->num_keys; i++) { + bool use = true; + Key key; + + if (!pkb4->keys[i].value) continue; + + if (userAccountControl & UF_USE_DES_KEY_ONLY) { + switch (pkb4->keys[i].keytype) { + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD5: + break; + default: + use = false; + break; + } + } + + if (!use) continue; + + key.mkvno = 0; + key.salt = NULL; + + if (pkb4->salt.string) { + DATA_BLOB salt; + + salt = data_blob_string_const(pkb4->salt.string); + + key.salt = calloc(1, sizeof(*key.salt)); + if (key.salt == NULL) { + ret = ENOMEM; + goto out; + } + + key.salt->type = hdb_pw_salt; + + ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length); + if (ret) { + free(key.salt); + key.salt = NULL; + goto out; + } + } + + /* TODO: maybe pass the iteration_count somehow... */ + + ret = krb5_keyblock_init(context, + pkb4->keys[i].keytype, + pkb4->keys[i].value->data, + pkb4->keys[i].value->length, + &key.key); + if (ret) { + if (key.salt) { + free_Salt(key.salt); + free(key.salt); + key.salt = NULL; + } + goto out; + } + + entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; + entry_ex->entry.keys.len++; + } + } else if (pkb3) { + for (i=0; i < pkb3->num_keys; i++) { + bool use = true; + Key key; + + if (!pkb3->keys[i].value) continue; + + if (userAccountControl & UF_USE_DES_KEY_ONLY) { + switch (pkb3->keys[i].keytype) { + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD5: + break; + default: + use = false; + break; + } + } + + if (!use) continue; + + key.mkvno = 0; + key.salt = NULL; + + if (pkb3->salt.string) { + DATA_BLOB salt; + + salt = data_blob_string_const(pkb3->salt.string); + + key.salt = calloc(1, sizeof(*key.salt)); + if (key.salt == NULL) { + ret = ENOMEM; + goto out; + } + + key.salt->type = hdb_pw_salt; + + ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length); + if (ret) { + free(key.salt); + key.salt = NULL; + goto out; + } + } + + ret = krb5_keyblock_init(context, + pkb3->keys[i].keytype, + pkb3->keys[i].value->data, + pkb3->keys[i].value->length, + &key.key); + if (ret) { + if (key.salt) { + free_Salt(key.salt); + free(key.salt); + key.salt = NULL; + } + goto out; + } + + entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; + entry_ex->entry.keys.len++; + } + } + +out: + if (ret != 0) { + entry_ex->entry.keys.len = 0; + } + if (entry_ex->entry.keys.len == 0 && entry_ex->entry.keys.val) { + free(entry_ex->entry.keys.val); + entry_ex->entry.keys.val = NULL; + } + return ret; +} + +/* + * Construct an hdb_entry from a directory entry. + */ +static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, + TALLOC_CTX *mem_ctx, krb5_const_principal principal, + enum hdb_ldb_ent_type ent_type, + struct ldb_message *msg, + struct ldb_message *realm_ref_msg, + hdb_entry_ex *entry_ex) +{ + unsigned int userAccountControl; + int i; + krb5_error_code ret = 0; + krb5_boolean is_computer = FALSE; + const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg, "dnsRoot", NULL); + char *realm = strupper_talloc(mem_ctx, dnsdomain); + struct loadparm_context *lp_ctx = ldb_get_opaque((struct ldb_context *)db->hdb_db, "loadparm"); + struct ldb_dn *domain_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, + mem_ctx, + realm_ref_msg, + "nCName", + ldb_dn_new(mem_ctx, (struct ldb_context *)db->hdb_db, NULL)); + + struct hdb_ldb_private *private; + NTTIME acct_expiry; + + struct ldb_message_element *objectclasses; + struct ldb_val computer_val; + computer_val.data = discard_const_p(uint8_t,"computer"); + computer_val.length = strlen((const char *)computer_val.data); + + objectclasses = ldb_msg_find_element(msg, "objectClass"); + + if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) { + is_computer = TRUE; + } + + memset(entry_ex, 0, sizeof(*entry_ex)); + + if (!realm) { + krb5_set_error_string(context, "talloc_strdup: out of memory"); + ret = ENOMEM; + goto out; + } + + private = talloc(mem_ctx, struct hdb_ldb_private); + if (!private) { + ret = ENOMEM; + goto out; + } + + private->entry_ex = entry_ex; + private->iconv_convenience = lp_iconv_convenience(lp_ctx); + private->netbios_name = lp_netbios_name(lp_ctx); + + talloc_set_destructor(private, hdb_ldb_destructor); + + entry_ex->ctx = private; + entry_ex->free_entry = hdb_ldb_free_entry; + + userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); + + + entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal))); + if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) { + const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); + if (!samAccountName) { + krb5_set_error_string(context, "LDB_message2entry: no samAccountName present"); + ret = ENOENT; + goto out; + } + samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); + krb5_make_principal(context, &entry_ex->entry.principal, realm, samAccountName, NULL); + } else { + char *strdup_realm; + ret = copy_Principal(principal, entry_ex->entry.principal); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + + /* While we have copied the client principal, tests + * show that Win2k3 returns the 'corrected' realm, not + * the client-specified realm. This code attempts to + * replace the client principal's realm with the one + * we determine from our records */ + + /* this has to be with malloc() */ + strdup_realm = strdup(realm); + if (!strdup_realm) { + ret = ENOMEM; + krb5_clear_error_string(context); + goto out; + } + free(*krb5_princ_realm(context, entry_ex->entry.principal)); + krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm); + } + + entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type); + + if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) { + entry_ex->entry.flags.invalid = 0; + entry_ex->entry.flags.server = 1; + entry_ex->entry.flags.forwardable = 1; + entry_ex->entry.flags.ok_as_delegate = 1; + } + + if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { + if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) { + entry_ex->entry.flags.server = 0; + } + } + + /* use 'whenCreated' */ + entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); + /* use '???' */ + entry_ex->entry.created_by.principal = NULL; + + entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); + if (entry_ex->entry.modified_by == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + goto out; + } + + /* use 'whenChanged' */ + entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); + /* use '???' */ + entry_ex->entry.modified_by->principal = NULL; + + entry_ex->entry.valid_start = NULL; + + acct_expiry = samdb_result_account_expires(msg); + if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) { + entry_ex->entry.valid_end = NULL; + } else { + entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end)); + if (entry_ex->entry.valid_end == NULL) { + ret = ENOMEM; + goto out; + } + *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry); + } + + if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) { + NTTIME must_change_time + = samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx, + domain_dn, msg); + if (must_change_time == 0x7FFFFFFFFFFFFFFFULL) { + entry_ex->entry.pw_end = NULL; + } else { + entry_ex->entry.pw_end = malloc(sizeof(*entry_ex->entry.pw_end)); + if (entry_ex->entry.pw_end == NULL) { + ret = ENOMEM; + goto out; + } + *entry_ex->entry.pw_end = nt_time_to_unix(must_change_time); + } + } else { + entry_ex->entry.pw_end = NULL; + } + + entry_ex->entry.max_life = NULL; + + entry_ex->entry.max_renew = NULL; + + entry_ex->entry.generation = NULL; + + /* Get keys from the db */ + ret = LDB_message2entry_keys(context, private->iconv_convenience, private, msg, userAccountControl, entry_ex); + if (ret) { + /* Could be bougus data in the entry, or out of memory */ + goto out; + } + + entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); + if (entry_ex->entry.etypes == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + entry_ex->entry.etypes->len = entry_ex->entry.keys.len; + entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); + if (entry_ex->entry.etypes->val == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + for (i=0; i < entry_ex->entry.etypes->len; i++) { + entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype; + } + + + private->msg = talloc_steal(private, msg); + private->realm_ref_msg = talloc_steal(private, realm_ref_msg); + private->samdb = (struct ldb_context *)db->hdb_db; + +out: + if (ret != 0) { + /* This doesn't free ent itself, that is for the eventual caller to do */ + hdb_free_entry(context, entry_ex); + } else { + talloc_steal(db, entry_ex->ctx); + } + + return ret; +} + +/* + * Construct an hdb_entry from a directory entry. + */ +static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, + struct loadparm_context *lp_ctx, + TALLOC_CTX *mem_ctx, krb5_const_principal principal, + enum trust_direction direction, + struct ldb_message *msg, + hdb_entry_ex *entry_ex) +{ + + const char *dnsdomain; + char *realm; + char *strdup_realm; + DATA_BLOB password_utf16; + struct samr_Password password_hash; + const struct ldb_val *password_val; + struct trustAuthInOutBlob password_blob; + struct hdb_ldb_private *private; + + enum ndr_err_code ndr_err; + int i, ret, trust_direction_flags; + + private = talloc(mem_ctx, struct hdb_ldb_private); + if (!private) { + ret = ENOMEM; + goto out; + } + + private->entry_ex = entry_ex; + private->iconv_convenience = lp_iconv_convenience(lp_ctx); + private->netbios_name = lp_netbios_name(lp_ctx); + + talloc_set_destructor(private, hdb_ldb_destructor); + + entry_ex->ctx = private; + entry_ex->free_entry = hdb_ldb_free_entry; + + /* use 'whenCreated' */ + entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); + /* use '???' */ + entry_ex->entry.created_by.principal = NULL; + + entry_ex->entry.valid_start = NULL; + + trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0); + + if (direction == INBOUND) { + realm = strupper_talloc(mem_ctx, lp_realm(lp_ctx)); + password_val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming"); + + } else { /* OUTBOUND */ + dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL); + realm = strupper_talloc(mem_ctx, dnsdomain); + password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing"); + } + + if (!password_val || !(trust_direction_flags & direction)) { + ret = ENOENT; + goto out; + } + + ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob, + (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + ret = EINVAL; + goto out; + } + + for (i=0; i < password_blob.count; i++) { + if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { + password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, + password_blob.current->array[i].AuthInfo.clear.size); + /* In the future, generate all sorts of + * hashes, but for now we can't safely convert + * the random strings windows uses into + * utf8 */ + + /* but as it is utf16 already, we can get the NT password/arcfour-hmac-md5 key */ + mdfour(password_hash.hash, password_utf16.data, password_utf16.length); + break; + } else if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { + password_hash = password_blob.current->array[i].AuthInfo.nt4owf.password; + break; + } + } + entry_ex->entry.keys.len = 0; + entry_ex->entry.keys.val = NULL; + + if (i < password_blob.count) { + Key key; + /* Must have found a cleartext or MD4 password */ + entry_ex->entry.keys.val = calloc(1, sizeof(Key)); + + key.mkvno = 0; + key.salt = NULL; /* No salt for this enc type */ + + if (entry_ex->entry.keys.val == NULL) { + ret = ENOMEM; + goto out; + } + + ret = krb5_keyblock_init(context, + ENCTYPE_ARCFOUR_HMAC_MD5, + password_hash.hash, sizeof(password_hash.hash), + &key.key); + + entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key; + entry_ex->entry.keys.len++; + } + + ret = copy_Principal(principal, entry_ex->entry.principal); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + + /* While we have copied the client principal, tests + * show that Win2k3 returns the 'corrected' realm, not + * the client-specified realm. This code attempts to + * replace the client principal's realm with the one + * we determine from our records */ + + /* this has to be with malloc() */ + strdup_realm = strdup(realm); + if (!strdup_realm) { + ret = ENOMEM; + krb5_clear_error_string(context); + goto out; + } + free(*krb5_princ_realm(context, entry_ex->entry.principal)); + krb5_princ_set_realm(context, entry_ex->entry.principal, &strdup_realm); + + entry_ex->entry.flags = int2HDBFlags(0); + entry_ex->entry.flags.immutable = 1; + entry_ex->entry.flags.invalid = 0; + entry_ex->entry.flags.server = 1; + entry_ex->entry.flags.require_preauth = 1; + + entry_ex->entry.pw_end = NULL; + + entry_ex->entry.max_life = NULL; + + entry_ex->entry.max_renew = NULL; + + entry_ex->entry.generation = NULL; + + entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); + if (entry_ex->entry.etypes == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + entry_ex->entry.etypes->len = entry_ex->entry.keys.len; + entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); + if (entry_ex->entry.etypes->val == NULL) { + krb5_clear_error_string(context); + ret = ENOMEM; + goto out; + } + for (i=0; i < entry_ex->entry.etypes->len; i++) { + entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype; + } + + + private->msg = talloc_steal(private, msg); + private->realm_ref_msg = NULL; + private->samdb = (struct ldb_context *)db->hdb_db; + +out: + if (ret != 0) { + /* This doesn't free ent itself, that is for the eventual caller to do */ + hdb_free_entry(context, entry_ex); + } else { + talloc_steal(db, entry_ex->ctx); + } + + return ret; + +} + +static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_context *ldb_ctx, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + enum hdb_ldb_ent_type ent_type, + struct ldb_dn *realm_dn, + struct ldb_message ***pmsg) +{ + krb5_error_code ret; + int lret; + char *filter = NULL; + const char * const *princ_attrs = user_attrs; + + char *short_princ; + char *short_princ_talloc; + + struct ldb_result *res = NULL; + + ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ); + + if (ret != 0) { + krb5_set_error_string(context, "LDB_lookup_principal: could not parse principal"); + krb5_warnx(context, "LDB_lookup_principal: could not parse principal"); + return ret; + } + + short_princ_talloc = talloc_strdup(mem_ctx, short_princ); + free(short_princ); + if (!short_princ_talloc) { + krb5_set_error_string(context, "LDB_lookup_principal: talloc_strdup() failed!"); + return ENOMEM; + } + + switch (ent_type) { + case HDB_SAMBA4_ENT_TYPE_CLIENT: + case HDB_SAMBA4_ENT_TYPE_TRUST: + case HDB_SAMBA4_ENT_TYPE_ANY: + /* Can't happen */ + return EINVAL; + case HDB_SAMBA4_ENT_TYPE_KRBTGT: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", + KRB5_TGS_NAME); + break; + case HDB_SAMBA4_ENT_TYPE_SERVER: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))", + short_princ_talloc); + break; + } + + if (!filter) { + krb5_set_error_string(context, "talloc_asprintf: out of memory"); + return ENOMEM; + } + + lret = ldb_search(ldb_ctx, mem_ctx, &res, realm_dn, + LDB_SCOPE_SUBTREE, princ_attrs, "%s", filter); + if (lret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); + return HDB_ERR_NOENTRY; + } else if (res->count == 0 || res->count > 1) { + DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); + talloc_free(res); + return HDB_ERR_NOENTRY; + } + talloc_steal(mem_ctx, res->msgs); + *pmsg = res->msgs; + talloc_free(res); + return 0; +} + +static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx, + TALLOC_CTX *mem_ctx, + const char *realm, + struct ldb_dn *realm_dn, + struct ldb_message ***pmsg) +{ + int lret; + char *filter = NULL; + const char * const *attrs = trust_attrs; + + struct ldb_result *res = NULL; + filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm); + + if (!filter) { + krb5_set_error_string(context, "talloc_asprintf: out of memory"); + return ENOMEM; + } + + lret = ldb_search(ldb_ctx, mem_ctx, &res, + ldb_get_default_basedn(ldb_ctx), + LDB_SCOPE_SUBTREE, attrs, "%s", filter); + if (lret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx))); + return HDB_ERR_NOENTRY; + } else if (res->count == 0 || res->count > 1) { + DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count)); + talloc_free(res); + return HDB_ERR_NOENTRY; + } + talloc_steal(mem_ctx, res->msgs); + *pmsg = res->msgs; + talloc_free(res); + return 0; +} + +static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context *ldb_ctx, + TALLOC_CTX *mem_ctx, + const char *realm, + struct ldb_message ***pmsg) +{ + int ret; + struct ldb_result *cross_ref_res; + struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx); + + ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res, + partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs, + "(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))", + realm, realm); + + if (ret != LDB_SUCCESS) { + DEBUG(3, ("Failed to search to lookup realm(%s): %s\n", realm, ldb_errstring(ldb_ctx))); + talloc_free(cross_ref_res); + return HDB_ERR_NOENTRY; + } else if (cross_ref_res->count == 0 || cross_ref_res->count > 1) { + DEBUG(3, ("Failed find a single entry for realm %s: got %d\n", realm, cross_ref_res->count)); + talloc_free(cross_ref_res); + return HDB_ERR_NOENTRY; + } + + if (pmsg) { + *pmsg = cross_ref_res->msgs; + talloc_steal(mem_ctx, cross_ref_res->msgs); + } + talloc_free(cross_ref_res); + + return 0; +} + + +static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode) +{ + if (db->hdb_master_key_set) { + krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n"); + krb5_set_error_string(context, "LDB_open: use of a master key incompatible with LDB\n"); + return HDB_ERR_NOENTRY; + } + + return 0; +} + +static krb5_error_code LDB_close(krb5_context context, HDB *db) +{ + return 0; +} + +static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation) +{ + return 0; +} + +static krb5_error_code LDB_unlock(krb5_context context, HDB *db) +{ + return 0; +} + +static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name) +{ + return HDB_ERR_DB_INUSE; +} + +static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + unsigned flags, + hdb_entry_ex *entry_ex) { + NTSTATUS nt_status; + char *principal_string; + krb5_error_code ret; + struct ldb_message **msg = NULL; + struct ldb_message **realm_ref_msg = NULL; + + ret = krb5_unparse_name(context, principal, &principal_string); + + if (ret != 0) { + return ret; + } + + nt_status = sam_get_results_principal((struct ldb_context *)db->hdb_db, + mem_ctx, principal_string, + &msg, &realm_ref_msg); + free(principal_string); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) { + return HDB_ERR_NOENTRY; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) { + return ENOMEM; + } else if (!NT_STATUS_IS_OK(nt_status)) { + return EINVAL; + } + + ret = LDB_message2entry(context, db, mem_ctx, + principal, HDB_SAMBA4_ENT_TYPE_CLIENT, + msg[0], realm_ref_msg[0], entry_ex); + return ret; +} + +static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + unsigned flags, + hdb_entry_ex *entry_ex) +{ + krb5_error_code ret; + struct ldb_message **msg = NULL; + struct ldb_message **realm_ref_msg_1 = NULL; + struct ldb_message **realm_ref_msg_2 = NULL; + struct ldb_dn *realm_dn; + const char *realm; + + krb5_principal alloc_principal = NULL; + if (principal->name.name_string.len != 2 + || (strcmp(principal->name.name_string.val[0], KRB5_TGS_NAME) != 0)) { + /* Not a krbtgt */ + return HDB_ERR_NOENTRY; + } + + /* krbtgt case. Either us or a trusted realm */ + + if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, + mem_ctx, principal->realm, &realm_ref_msg_1) == 0) + && (LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, + mem_ctx, principal->name.name_string.val[1], &realm_ref_msg_2) == 0) + && (ldb_dn_compare(realm_ref_msg_1[0]->dn, realm_ref_msg_1[0]->dn) == 0)) { + /* us */ + /* Cludge, cludge cludge. If the realm part of krbtgt/realm, + * is in our db, then direct the caller at our primary + * krbtgt */ + + const char *dnsdomain = ldb_msg_find_attr_as_string(realm_ref_msg_1[0], "dnsRoot", NULL); + char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain); + if (!realm_fixed) { + krb5_set_error_string(context, "strupper_talloc: out of memory"); + return ENOMEM; + } + + ret = krb5_copy_principal(context, principal, &alloc_principal); + if (ret) { + return ret; + } + + free(alloc_principal->name.name_string.val[1]); + alloc_principal->name.name_string.val[1] = strdup(realm_fixed); + talloc_free(realm_fixed); + if (!alloc_principal->name.name_string.val[1]) { + krb5_set_error_string(context, "LDB_fetch: strdup() failed!"); + return ENOMEM; + } + principal = alloc_principal; + realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg_1[0], "nCName", NULL); + + ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, + mem_ctx, + principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg); + + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: could not find principal in DB"); + krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); + return ret; + } + + ret = LDB_message2entry(context, db, mem_ctx, + principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, + msg[0], realm_ref_msg_1[0], entry_ex); + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: message2entry failed"); + } + return ret; + + } else { + enum trust_direction direction = UNKNOWN; + + struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context); + /* Either an inbound or outbound trust */ + + if (strcasecmp(lp_realm(lp_ctx), principal->realm) == 0) { + /* look for inbound trust */ + direction = INBOUND; + realm = principal->name.name_string.val[1]; + } + + if (strcasecmp(lp_realm(lp_ctx), principal->name.name_string.val[1]) == 0) { + /* look for outbound trust */ + direction = OUTBOUND; + realm = principal->realm; + } + + /* Trusted domains are under CN=system */ + + ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, + mem_ctx, + realm, realm_dn, &msg); + + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: could not find principal in DB"); + krb5_set_error_string(context, "LDB_fetch: could not find principal in DB"); + return ret; + } + + ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, + principal, direction, + msg[0], entry_ex); + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: message2entry failed"); + } + return ret; + + + /* we should lookup trusted domains */ + return HDB_ERR_NOENTRY; + } + +} + +static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, + TALLOC_CTX *mem_ctx, + krb5_const_principal principal, + unsigned flags, + hdb_entry_ex *entry_ex) +{ + krb5_error_code ret; + const char *realm; + struct ldb_message **msg = NULL; + struct ldb_message **realm_ref_msg = NULL; + struct ldb_dn *partitions_basedn = samdb_partitions_dn(db->hdb_db, mem_ctx); + if (principal->name.name_string.len >= 2) { + /* 'normal server' case */ + int ldb_ret; + NTSTATUS nt_status; + struct ldb_dn *user_dn, *domain_dn; + char *principal_string; + + ret = krb5_unparse_name_flags(context, principal, + KRB5_PRINCIPAL_UNPARSE_NO_REALM, + &principal_string); + if (ret != 0) { + return ret; + } + + /* At this point we may find the host is known to be + * in a different realm, so we should generate a + * referral instead */ + nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db, + mem_ctx, principal_string, + &user_dn, &domain_dn); + free(principal_string); + + if (!NT_STATUS_IS_OK(nt_status)) { + return HDB_ERR_NOENTRY; + } + + ldb_ret = gendb_search_dn((struct ldb_context *)db->hdb_db, + mem_ctx, user_dn, &msg, user_attrs); + + if (ldb_ret != 1) { + return HDB_ERR_NOENTRY; + } + + ldb_ret = gendb_search((struct ldb_context *)db->hdb_db, + mem_ctx, partitions_basedn, &realm_ref_msg, realm_ref_attrs, + "ncName=%s", ldb_dn_get_linearized(domain_dn)); + + if (ldb_ret != 1) { + return HDB_ERR_NOENTRY; + } + + } else { + struct ldb_dn *realm_dn; + /* server as client principal case, but we must not lookup userPrincipalNames */ + + realm = krb5_principal_get_realm(context, principal); + + ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, + mem_ctx, realm, &realm_ref_msg); + if (ret != 0) { + return HDB_ERR_NOENTRY; + } + + realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msg[0], "nCName", NULL); + + ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db, + mem_ctx, + principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg); + + if (ret != 0) { + return ret; + } + } + + ret = LDB_message2entry(context, db, mem_ctx, + principal, HDB_SAMBA4_ENT_TYPE_SERVER, + msg[0], realm_ref_msg[0], entry_ex); + if (ret != 0) { + krb5_warnx(context, "LDB_fetch: message2entry failed"); + } + + return ret; +} + +static krb5_error_code LDB_fetch(krb5_context context, HDB *db, + krb5_const_principal principal, + unsigned flags, + hdb_entry_ex *entry_ex) +{ + krb5_error_code ret = HDB_ERR_NOENTRY; + + TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context"); + + if (!mem_ctx) { + krb5_set_error_string(context, "LDB_fetch: talloc_named() failed!"); + return ENOMEM; + } + + if (flags & HDB_F_GET_CLIENT) { + ret = LDB_fetch_client(context, db, mem_ctx, principal, flags, entry_ex); + if (ret != HDB_ERR_NOENTRY) goto done; + } + if (flags & HDB_F_GET_SERVER) { + /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */ + ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); + if (ret != HDB_ERR_NOENTRY) goto done; + + /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */ + ret = LDB_fetch_server(context, db, mem_ctx, principal, flags, entry_ex); + if (ret != HDB_ERR_NOENTRY) goto done; + } + if (flags & HDB_F_GET_KRBTGT) { + ret = LDB_fetch_krbtgt(context, db, mem_ctx, principal, flags, entry_ex); + if (ret != HDB_ERR_NOENTRY) goto done; + } + +done: + talloc_free(mem_ctx); + return ret; +} + +static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +{ + return HDB_ERR_DB_INUSE; +} + +static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal) +{ + return HDB_ERR_DB_INUSE; +} + +struct hdb_ldb_seq { + struct ldb_context *ctx; + int index; + int count; + struct ldb_message **msgs; + struct ldb_message **realm_ref_msgs; +}; + +static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +{ + krb5_error_code ret; + struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc; + TALLOC_CTX *mem_ctx; + hdb_entry_ex entry_ex; + memset(&entry_ex, '\0', sizeof(entry_ex)); + + if (!priv) { + return HDB_ERR_NOENTRY; + } + + mem_ctx = talloc_named(priv, 0, "LDB_seq context"); + + if (!mem_ctx) { + krb5_set_error_string(context, "LDB_seq: talloc_named() failed!"); + return ENOMEM; + } + + if (priv->index < priv->count) { + ret = LDB_message2entry(context, db, mem_ctx, + NULL, HDB_SAMBA4_ENT_TYPE_ANY, + priv->msgs[priv->index++], + priv->realm_ref_msgs[0], entry); + } else { + ret = HDB_ERR_NOENTRY; + } + + if (ret != 0) { + talloc_free(priv); + db->hdb_dbc = NULL; + } else { + talloc_free(mem_ctx); + } + + return ret; +} + +static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) +{ + struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db; + struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc; + char *realm; + struct ldb_dn *realm_dn = NULL; + struct ldb_result *res = NULL; + struct ldb_message **realm_ref_msgs = NULL; + krb5_error_code ret; + TALLOC_CTX *mem_ctx; + int lret; + + if (priv) { + talloc_free(priv); + db->hdb_dbc = NULL; + } + + priv = (struct hdb_ldb_seq *) talloc(db, struct hdb_ldb_seq); + if (!priv) { + krb5_set_error_string(context, "talloc: out of memory"); + return ENOMEM; + } + + priv->ctx = ldb_ctx; + priv->index = 0; + priv->msgs = NULL; + priv->realm_ref_msgs = NULL; + priv->count = 0; + + mem_ctx = talloc_named(priv, 0, "LDB_firstkey context"); + + if (!mem_ctx) { + krb5_set_error_string(context, "LDB_firstkey: talloc_named() failed!"); + return ENOMEM; + } + + ret = krb5_get_default_realm(context, &realm); + if (ret != 0) { + talloc_free(priv); + return ret; + } + + ret = LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db, + mem_ctx, realm, &realm_ref_msgs); + + free(realm); + + if (ret != 0) { + talloc_free(priv); + krb5_warnx(context, "LDB_firstkey: could not find realm\n"); + return HDB_ERR_NOENTRY; + } + + realm_dn = samdb_result_dn((struct ldb_context *)db->hdb_db, mem_ctx, realm_ref_msgs[0], "nCName", NULL); + + priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs); + + lret = ldb_search(ldb_ctx, priv, &res, + realm_dn, LDB_SCOPE_SUBTREE, user_attrs, + "(objectClass=user)"); + + if (lret != LDB_SUCCESS) { + talloc_free(priv); + return HDB_ERR_NOENTRY; + } + + priv->count = res->count; + priv->msgs = talloc_steal(priv, res->msgs); + talloc_free(res); + + db->hdb_dbc = priv; + + ret = LDB_seq(context, db, flags, entry); + + if (ret != 0) { + talloc_free(priv); + db->hdb_dbc = NULL; + } else { + talloc_free(mem_ctx); + } + return ret; +} + +static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) +{ + return LDB_seq(context, db, flags, entry); +} + +static krb5_error_code LDB_destroy(krb5_context context, HDB *db) +{ + talloc_free(db); + return 0; +} + +/* This interface is to be called by the KDC, which is expecting Samba + * calling conventions. It is also called by a wrapper + * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb + * code */ + +NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, + struct event_context *ev_ctx, + struct loadparm_context *lp_ctx, + krb5_context context, struct HDB **db, const char *arg) +{ + NTSTATUS nt_status; + struct auth_session_info *session_info; + *db = talloc(mem_ctx, HDB); + if (!*db) { + krb5_set_error_string(context, "malloc: out of memory"); + return NT_STATUS_NO_MEMORY; + } + + (*db)->hdb_master_key_set = 0; + (*db)->hdb_db = NULL; + + nt_status = auth_system_session_info(*db, lp_ctx, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + /* The idea here is very simple. Using Kerberos to + * authenticate the KDC to the LDAP server is higly likely to + * be circular. + * + * In future we may set this up to use EXERNAL and SSL + * certificates, for now it will almost certainly be NTLMSSP + */ + + cli_credentials_set_kerberos_state(session_info->credentials, + CRED_DONT_USE_KERBEROS); + + /* Setup the link to LDB */ + (*db)->hdb_db = samdb_connect(*db, ev_ctx, lp_ctx, session_info); + if ((*db)->hdb_db == NULL) { + DEBUG(1, ("hdb_ldb_create: Cannot open samdb for KDC backend!")); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + (*db)->hdb_dbc = NULL; + (*db)->hdb_open = LDB_open; + (*db)->hdb_close = LDB_close; + (*db)->hdb_fetch = LDB_fetch; + (*db)->hdb_store = LDB_store; + (*db)->hdb_remove = LDB_remove; + (*db)->hdb_firstkey = LDB_firstkey; + (*db)->hdb_nextkey = LDB_nextkey; + (*db)->hdb_lock = LDB_lock; + (*db)->hdb_unlock = LDB_unlock; + (*db)->hdb_rename = LDB_rename; + /* we don't implement these, as we are not a lockable database */ + (*db)->hdb__get = NULL; + (*db)->hdb__put = NULL; + /* kadmin should not be used for deletes - use other tools instead */ + (*db)->hdb__del = NULL; + (*db)->hdb_destroy = LDB_destroy; + + return NT_STATUS_OK; +} + +krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg) +{ + NTSTATUS nt_status; + /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */ + nt_status = kdc_hdb_samba4_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx, + context, db, arg); + + if (NT_STATUS_IS_OK(nt_status)) { + return 0; + } + return EINVAL; +} diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 030eb23c10..83c6f1c2ee 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -667,6 +667,11 @@ static void kdc_task_init(struct task_server *task) NTSTATUS status; krb5_error_code ret; struct interface *ifaces; + struct hdb_method hdb_samba4 = { + .interface_version = HDB_INTERFACE_VERSION, + .prefix = "samba4:", + .create = hdb_samba4_create + }; switch (lp_server_role(task->lp_ctx)) { case ROLE_STANDALONE: @@ -724,7 +729,7 @@ static void kdc_task_init(struct task_server *task) } kdc->config->num_db = 1; - status = kdc_hdb_ldb_create(kdc, task->event_ctx, task->lp_ctx, + status = kdc_hdb_samba4_create(kdc, task->event_ctx, task->lp_ctx, kdc->smb_krb5_context->krb5_context, &kdc->config->db[0], NULL); if (!NT_STATUS_IS_OK(status)) { @@ -732,6 +737,16 @@ static void kdc_task_init(struct task_server *task) return; } + + /* Register hdb-samba4 hooks */ + ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, + PLUGIN_TYPE_DATA, "hdb", + &hdb_samba4); + if(ret) { + task_server_terminate(task, "kdc: failed to register hdb keytab"); + return; + } + ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); if(ret) { task_server_terminate(task, "kdc: failed to register hdb keytab"); -- cgit From 15b686198120cca0aaa305edc0a5e3242b4fa869 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Sep 2008 12:53:40 -0700 Subject: Use the new 'samba4' name for our internal hdb plugin. --- source4/setup/secrets_dc.ldif | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/setup/secrets_dc.ldif b/source4/setup/secrets_dc.ldif index abc5860cf7..8ae5578e6b 100644 --- a/source4/setup/secrets_dc.ldif +++ b/source4/setup/secrets_dc.ldif @@ -22,7 +22,7 @@ realm: ${REALM} sAMAccountName: krbtgt objectSid: ${DOMAINSID} servicePrincipalName: kadmin/changepw -krb5Keytab: HDB:ldb:${SAM_LDB}: +krb5Keytab: HDB:samba4:${SAM_LDB}: #The trailing : here is a HACK, but it matches the Heimdal format. # A hook from our credentials system into HDB, as we must be on a KDC, -- cgit From 64195b72be6c251412500984c2a5c103e376d3c6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Sep 2008 21:36:21 -0700 Subject: Fix parsing of the trust passwords in LSA CreateTrustedDomainEx* --- source4/libcli/config.mk | 8 -- source4/libcli/drsblobs.c | 179 ------------------------------ source4/librpc/config.mk | 4 +- source4/librpc/idl/drsblobs.idl | 25 +++-- source4/librpc/ndr/ndr_drsblobs.c | 213 ++++++++++++++++++++++++++++++++++++ source4/rpc_server/lsa/dcesrv_lsa.c | 8 +- source4/torture/rpc/lsa.c | 6 +- 7 files changed, 239 insertions(+), 204 deletions(-) delete mode 100644 source4/libcli/drsblobs.c create mode 100644 source4/librpc/ndr/ndr_drsblobs.c (limited to 'source4') diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 2f81d7cff0..d68a2a2ce3 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -67,14 +67,6 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclinbtsrcdir)/, \ netlogon.o) -[SUBSYSTEM::LIBCLI_DRSBLOBS] -PUBLIC_DEPENDENCIES = LIBNDR - -LIBCLI_DRSBLOBS_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ - drsblobs.o) - -$(eval $(call proto_header_template,$(libclisrcdir)/drsblobs_proto.h,$(LIBCLI_DRSBLOBS_OBJ_FILES:.o=.c))) - [PYTHON::python_netbios] LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG diff --git a/source4/libcli/drsblobs.c b/source4/libcli/drsblobs.c deleted file mode 100644 index 126f2ccc40..0000000000 --- a/source4/libcli/drsblobs.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Manually parsed structures found in the DRS protocol - - 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 . -*/ - -#include "includes.h" -#include "libcli/drsblobs.h" - -/* parser auto-generated by pidl, then hand-modified by abartlet */ - -/* Modified to have 'count' specified */ -static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, - const struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); - } - } - if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } - } - return NDR_ERR_SUCCESS; -} - -/* Modified to have 'count' specified, and to allocate the array */ -static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - TALLOC_CTX *_mem_save_array_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_PULL_ALLOC_N(ndr, r->array, count); - _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); - } - if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } - } - return NDR_ERR_SUCCESS; -} - -/* Modified to have 'count' specified */ -_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - ndr_print_struct(ndr, name, "AuthenticationInformationArray"); - ndr->depth++; - ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); - ndr->depth++; - for (cntr_array_0=0;cntr_array_0array[cntr_array_0]); - free(idx_0); - } - } - ndr->depth--; - ndr->depth--; -} - -/* Modified to call AuthenticationInformationArray with 'count' specified */ -_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); - } - if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - NDR_CHECK(ndr_push_relative_ptr2(ndr, r->current)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - } - if (r->previous) { - NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) -{ - uint32_t _ptr_current; - TALLOC_CTX *_mem_save_current_0; - uint32_t _ptr_previous; - TALLOC_CTX *_mem_save_previous_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); - if (_ptr_current) { - NDR_PULL_ALLOC(ndr, r->current); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); - } else { - r->current = NULL; - } - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); - if (_ptr_previous) { - NDR_PULL_ALLOC(ndr, r->previous); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); - } else { - r->previous = NULL; - } - } - if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); - _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); - ndr->offset = _relative_save_offset; - } - if (r->previous) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); - _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); - ndr->offset = _relative_save_offset; - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) -{ - ndr_print_struct(ndr, name, "trustAuthInOutBlob"); - ndr->depth++; - ndr_print_uint32(ndr, "count", r->count); - ndr_print_ptr(ndr, "current", r->current); - ndr->depth++; - if (r->current) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); - } - ndr->depth--; - ndr_print_ptr(ndr, "previous", r->previous); - ndr->depth++; - if (r->previous) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); - } - ndr->depth--; - ndr->depth--; -} - - diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index cf41f9884a..41dd17e428 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -144,9 +144,9 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL NDR_DRSUAPI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsuapi.o $(ndrsrcdir)/ndr_drsuapi.o [SUBSYSTEM::NDR_DRSBLOBS] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI LIBCLI_DRSBLOBS +PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI -NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o +NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o $(ndrsrcdir)/ndr_drsblobs.o [SUBSYSTEM::NDR_SASL_HELPERS] PUBLIC_DEPENDENCIES = LIBNDR diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl index 6b1f649ff5..31fe8a359e 100644 --- a/source4/librpc/idl/drsblobs.idl +++ b/source4/librpc/idl/drsblobs.idl @@ -415,18 +415,27 @@ interface drsblobs { [relative] AuthenticationInformationArray *previous; } trustAuthInOutBlob; - typedef [public] struct { - uint8 confounder[512]; - trustAuthInOutBlob outgoing; - trustAuthInOutBlob incoming; - [value(ndr_size_trustAuthInOutBlob(&outgoing, ndr->flags))] uint32 outgoing_size; - [value(ndr_size_trustAuthInOutBlob(&incoming, ndr->flags))] uint32 incoming_size; - } trustAuthInAndOutBlob; - + typedef [public,gensize] struct { + uint32 count; + [relative] AuthenticationInformation *current[count]; + } trustCurrentPasswords; + void decode_trustAuthInOut( [in] trustAuthInOutBlob blob ); + typedef [public,nopull] struct { + uint8 confounder[512]; + [subcontext(0),subcontext_size(outgoing_size)] trustCurrentPasswords outgoing; + [subcontext(0),subcontext_size(incoming_size)] trustCurrentPasswords incoming; + [value(ndr_size_trustCurrentPasswords(&outgoing, ndr->flags))] uint32 outgoing_size; + [value(ndr_size_trustCurrentPasswords(&incoming, ndr->flags))] uint32 incoming_size; + } trustDomainPasswords; + + void decode_trustDomainPasswords( + [in] trustDomainPasswords blob + ); + typedef [public] struct { uint32 marker; DATA_BLOB data; diff --git a/source4/librpc/ndr/ndr_drsblobs.c b/source4/librpc/ndr/ndr_drsblobs.c new file mode 100644 index 0000000000..47a6bb60c9 --- /dev/null +++ b/source4/librpc/ndr/ndr_drsblobs.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + + Manually parsed structures found in the DRS protocol + + 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 . +*/ + +#include "includes.h" +#include "libcli/drsblobs.h" + +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +/* Modified to have 'count' specified */ +static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, + const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified, and to allocate the array */ +static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + TALLOC_CTX *_mem_save_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_PULL_ALLOC_N(ndr, r->array, count); + _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified */ +_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + ndr_print_struct(ndr, name, "AuthenticationInformationArray"); + ndr->depth++; + ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); + ndr->depth++; + for (cntr_array_0=0;cntr_array_0array[cntr_array_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +/* Modified to call AuthenticationInformationArray with 'count' specified */ +_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->current)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + } + if (r->previous) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) +{ + uint32_t _ptr_current; + TALLOC_CTX *_mem_save_current_0; + uint32_t _ptr_previous; + TALLOC_CTX *_mem_save_previous_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); + if (_ptr_current) { + NDR_PULL_ALLOC(ndr, r->current); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); + } else { + r->current = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); + if (_ptr_previous) { + NDR_PULL_ALLOC(ndr, r->previous); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); + } else { + r->previous = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); + _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); + ndr->offset = _relative_save_offset; + } + if (r->previous) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); + _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); + ndr->offset = _relative_save_offset; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) +{ + ndr_print_struct(ndr, name, "trustAuthInOutBlob"); + ndr->depth++; + ndr_print_uint32(ndr, "count", r->count); + ndr_print_ptr(ndr, "current", r->current); + ndr->depth++; + if (r->current) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); + } + ndr->depth--; + ndr_print_ptr(ndr, "previous", r->previous); + ndr->depth++; + if (r->previous) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_trustDomainPasswords(struct ndr_pull *ndr, int ndr_flags, struct trustDomainPasswords *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t offset; + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 8); + + offset = ndr->offset; + ndr->offset = ndr->data_size - 8; + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->outgoing_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->incoming_size)); + + ndr->offset = offset; + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->confounder, 512)); + { + struct ndr_pull *_ndr_outgoing; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_outgoing, 0, r->outgoing_size)); + NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_outgoing, NDR_SCALARS|NDR_BUFFERS, &r->outgoing)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_outgoing, 0, r->outgoing_size)); + } + { + struct ndr_pull *_ndr_incoming; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_incoming, 0, r->incoming_size)); + NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_incoming, NDR_SCALARS|NDR_BUFFERS, &r->incoming)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_incoming, 0, r->incoming_size)); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->outgoing_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->incoming_size)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 3b70f3e934..4c3c708d4a 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -626,7 +626,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc const char *name; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; - struct trustAuthInAndOutBlob auth_struct; + struct trustDomainPasswords auth_struct; int ret; NTSTATUS nt_status; enum ndr_err_code ndr_err; @@ -679,7 +679,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc ndr_err = ndr_pull_struct_blob(&auth_blob, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), &auth_struct, - (ndr_pull_flags_fn_t)ndr_pull_trustAuthInAndOutBlob); + (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } @@ -689,7 +689,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc ndr_err = ndr_push_struct_blob(&trustAuthIncoming, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), &auth_struct.incoming, - (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); + (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } @@ -701,7 +701,7 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc ndr_err = ndr_push_struct_blob(&trustAuthOutgoing, mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), &auth_struct.outgoing, - (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); + (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; } diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 69bf33352b..af5ee4f6e1 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -2077,7 +2077,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, struct lsa_CreateTrustedDomainEx2 r; struct lsa_TrustDomainInfoInfoEx trustinfo; struct lsa_TrustDomainInfoAuthInfoInternal authinfo; - struct trustAuthInAndOutBlob auth_struct; + struct trustDomainPasswords auth_struct; DATA_BLOB auth_blob; struct dom_sid *domsid[12]; struct policy_handle trustdom_handle[12]; @@ -2125,9 +2125,9 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p, auth_struct.incoming.count = 0; ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct, - (ndr_push_flags_fn_t)ndr_push_trustAuthInAndOutBlob); + (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - printf("ndr_push_struct_blob of trustAuthInAndOutBlob structure failed"); + printf("ndr_push_struct_blob of trustDomainPasswords structure failed"); ret = false; } -- cgit From 04edf11bee9f248241c46ce809870163a16d3ba0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Sep 2008 22:34:30 -0700 Subject: Rework to match new trustDomainPasswords IDL --- source4/rpc_server/lsa/dcesrv_lsa.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 4c3c708d4a..7b15241b96 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -859,11 +859,11 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc if (auth_struct.incoming.count) { int i; for (i=0; i < auth_struct.incoming.count; i++ ) { - if (auth_struct.incoming.current->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { + if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_NT4OWF) { samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user, "unicodePwd", - &auth_struct.incoming.current->array[i].AuthInfo.nt4owf.password); - } else if (auth_struct.incoming.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { + &auth_struct.incoming.current[i]->AuthInfo.nt4owf.password); + } else if (auth_struct.incoming.current[i]->AuthType == TRUST_AUTH_TYPE_CLEAR) { struct samr_Password hash; /* . We cannot do this, as windows chooses to send in random passwords here, that won't convert to UTF8 @@ -871,8 +871,8 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc mem_ctx, msg_user, "userPassword", auth_struct.incoming.current->array[i].AuthInfo.clear.password); */ - mdfour(hash.hash, auth_struct.incoming.current->array[i].AuthInfo.clear.password, - auth_struct.incoming.current->array[i].AuthInfo.clear.size); + mdfour(hash.hash, auth_struct.incoming.current[i]->AuthInfo.clear.password, + auth_struct.incoming.current[i]->AuthInfo.clear.size); samdb_msg_add_hash(trusted_domain_state->policy->sam_ldb, mem_ctx, msg_user, "unicodePwd", &hash); -- cgit From e622325155a13fd9f6f85a767d345344f18eca41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 08:41:16 +0200 Subject: s4:smb_server/smb: FLAGS2_SMB_SECURITY_SIGNATURES should only be echoed, not set always metze --- source4/smb_server/smb/request.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index eb3e100b96..241c262857 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -135,15 +135,16 @@ void smbsrv_setup_reply(struct smbsrv_request *req, uint_t wct, size_t buflen) flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES | FLAGS2_IS_LONG_NAME; - flags2 |= (req->flags2 & (FLAGS2_UNICODE_STRINGS|FLAGS2_EXTENDED_SECURITY)); +#define _SMB_FLAGS2_ECHOED_FLAGS ( \ + FLAGS2_UNICODE_STRINGS | \ + FLAGS2_EXTENDED_SECURITY | \ + FLAGS2_SMB_SECURITY_SIGNATURES \ +) + flags2 |= (req->flags2 & _SMB_FLAGS2_ECHOED_FLAGS); if (req->smb_conn->negotiate.client_caps & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - if (req->smb_conn->signing.allow_smb_signing || req->smb_conn->signing.mandatory_signing) { - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - } - req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.vwv = req->out.hdr + HDR_VWV; req->out.wct = wct; -- cgit From 394f24b374e1fda8dc8222b71ce164a1a79efde6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 09:04:52 +0200 Subject: s4:drsblob: fix the build metze --- source4/libcli/drsblobs.h | 28 ---------------------------- source4/librpc/ndr/ndr_drsblobs.c | 2 +- 2 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 source4/libcli/drsblobs.h (limited to 'source4') diff --git a/source4/libcli/drsblobs.h b/source4/libcli/drsblobs.h deleted file mode 100644 index 8fee4114be..0000000000 --- a/source4/libcli/drsblobs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Manually parsed structures found in the DRS protocol - - 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_DRSBLOBS_H__ -#define __LIBCLI_DRSBLOBS_H__ - -#include "librpc/gen_ndr/ndr_drsblobs.h" - -#include "libcli/drsblobs_proto.h" -#endif /* __CLDAP_SERVER_PROTO_H__ */ diff --git a/source4/librpc/ndr/ndr_drsblobs.c b/source4/librpc/ndr/ndr_drsblobs.c index 47a6bb60c9..aecb0c3b16 100644 --- a/source4/librpc/ndr/ndr_drsblobs.c +++ b/source4/librpc/ndr/ndr_drsblobs.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/drsblobs.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" /* parser auto-generated by pidl, then hand-modified by abartlet */ -- cgit From 7f1c02cd7a8f4238041406acab061f34c587c69a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 15:24:46 +0200 Subject: Enable winreg Python tests - authentication works now. --- source4/samba4-skip | 1 - source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/samba4-skip b/source4/samba4-skip index 5fa40ee706..e3e2d2d525 100644 --- a/source4/samba4-skip +++ b/source4/samba4-skip @@ -59,4 +59,3 @@ samba4.ntvfs.cifs.raw. ^samba4.net.api.become.dc.*$ # Fails nss.test # Fails raw.offline # Samba 4 doesn't have much offline support yet -winreg* #Does not authenticate against the target server diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 12638e2397..06790736b8 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -25,7 +25,8 @@ from samba.tests import RpcInterfaceTestCase class RpcEchoTests(RpcInterfaceTestCase): def setUp(self): - self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) + self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm(), + self.get_credentials()) def test_two_contexts(self): self.conn2 = echo.rpcecho("ncalrpc:", self.get_loadparm(), basis_connection=self.conn) -- cgit From a36b6c5a42212e175ece8e9f5aa74f2741ec8868 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 16:02:09 +0200 Subject: Make Sid member variables accessible from Python. --- source4/libcli/security/security.i | 6 ++ source4/libcli/security/security.py | 4 ++ source4/libcli/security/security_wrap.c | 118 ++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) (limited to 'source4') diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index 6ba106bb5f..420439d147 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -105,6 +105,12 @@ typedef struct security_descriptor { %talloctype(dom_sid); typedef struct dom_sid { + %immutable; + uint8_t sid_rev_num; + int8_t num_auths;/* [range(0,15)] */ + uint8_t id_auth[6]; + uint32_t *sub_auths; + %mutable; %extend { dom_sid(TALLOC_CTX *mem_ctx, const char *text) { return dom_sid_parse_talloc(mem_ctx, text); diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py index c310dde56b..8afb3eda61 100644 --- a/source4/libcli/security/security.py +++ b/source4/libcli/security/security.py @@ -147,6 +147,10 @@ security_descriptor_swigregister(security_descriptor) class Sid(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr + sid_rev_num = _swig_property(_security.Sid_sid_rev_num_get) + num_auths = _swig_property(_security.Sid_num_auths_get) + id_auth = _swig_property(_security.Sid_id_auth_get) + sub_auths = _swig_property(_security.Sid_sub_auths_get) def __init__(self, *args, **kwargs): _security.Sid_swiginit(self,_security.new_Sid(*args, **kwargs)) def __repr__(self): diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index b7d66b5aec..f7e3c2fb21 100644 --- a/source4/libcli/security/security_wrap.c +++ b/source4/libcli/security/security_wrap.c @@ -2712,6 +2712,28 @@ SWIGINTERN void delete_security_token(security_token *self){ talloc_free(self); SWIGINTERN security_descriptor *new_security_descriptor(TALLOC_CTX *mem_ctx){ return security_descriptor_initialise(mem_ctx); } SWIGINTERN void delete_security_descriptor(security_descriptor *self){ talloc_free(self); } +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_char (unsigned char value) +{ + return SWIG_From_unsigned_SS_long (value); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_signed_SS_char (signed char value) +{ + return SWIG_From_long (value); +} + + SWIGINTERN swig_type_info* SWIG_pchar_descriptor(void) { @@ -3337,6 +3359,98 @@ SWIGINTERN PyObject *security_descriptor_swiginit(PyObject *SWIGUNUSEDPARM(self) return SWIG_Python_InitShadowInstance(args); } +SWIGINTERN PyObject *_wrap_Sid_sid_rev_num_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t result; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_sid_rev_num_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint8_t) ((arg1)->sid_rev_num); + resultobj = SWIG_From_unsigned_SS_char((unsigned char)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_num_auths_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + int8_t result; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_num_auths_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (int8_t) ((arg1)->num_auths); + resultobj = SWIG_From_signed_SS_char((signed char)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_id_auth_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t *result = 0 ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_id_auth_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint8_t *)(uint8_t *) ((arg1)->id_auth); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_sub_auths_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint32_t *result = 0 ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_sub_auths_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint32_t *) ((arg1)->sub_auths); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_int, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; @@ -3561,6 +3675,10 @@ static PyMethodDef SwigMethods[] = { { (char *)"delete_security_descriptor", (PyCFunction)_wrap_delete_security_descriptor, METH_O, NULL}, { (char *)"security_descriptor_swigregister", security_descriptor_swigregister, METH_VARARGS, NULL}, { (char *)"security_descriptor_swiginit", security_descriptor_swiginit, METH_VARARGS, NULL}, + { (char *)"Sid_sid_rev_num_get", (PyCFunction)_wrap_Sid_sid_rev_num_get, METH_O, NULL}, + { (char *)"Sid_num_auths_get", (PyCFunction)_wrap_Sid_num_auths_get, METH_O, NULL}, + { (char *)"Sid_id_auth_get", (PyCFunction)_wrap_Sid_id_auth_get, METH_O, NULL}, + { (char *)"Sid_sub_auths_get", (PyCFunction)_wrap_Sid_sub_auths_get, METH_O, NULL}, { (char *)"new_Sid", (PyCFunction) _wrap_new_Sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Sid___str__", (PyCFunction)_wrap_Sid___str__, METH_O, NULL}, { (char *)"Sid___eq__", (PyCFunction) _wrap_Sid___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, -- cgit From 3d8323fbff85709ab64ea039044a555975821b7f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 16:02:21 +0200 Subject: Compare sids in samba3sam tests. --- source4/dsdb/samdb/ldb_modules/tests/samba3sam.py | 32 +++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'source4') diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 882376cb09..1fc531902d 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -27,6 +27,9 @@ import ldb from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE from samba import Ldb, substitute_var from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm +import samba.dcerpc.security +import samba.security +import samba.ndr datadir = os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -112,6 +115,18 @@ class MapBaseTestCase(TestCaseInTempDir): os.unlink(self.samba4.file) super(MapBaseTestCase, self).tearDown() + def assertSidEquals(self, text, ndr_sid): + sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid, + str(ndr_sid[0])) + sid_obj2 = samba.security.Sid(text) + # For now, this is the only way we can compare these since the + # classes are in different places. Should reconcile that at some point. + self.assertEquals(sid_obj1.sid_rev_num, sid_obj2.sid_rev_num) + self.assertEquals(sid_obj1.num_auths, sid_obj2.num_auths) + # FIXME: self.assertEquals(sid_obj1.id_auth, sid_obj2.id_auth) + # FIXME: self.assertEquals(sid_obj1.sub_auths[:sid_obj1.num_auths], + # sid_obj2.sub_auths[:sid_obj2.num_auths]) + class Samba3SamTestCase(MapBaseTestCase): @@ -150,10 +165,8 @@ class Samba3SamTestCase(MapBaseTestCase): self.assertEquals(str(msg[0].dn), "cn=Replicator,ou=Groups,dc=vernstok,dc=nl") self.assertTrue("objectSid" in msg[0]) - # FIXME: NDR unpack msg[0]["objectSid"] before comparing: - # self.assertEquals(msg[0]["objectSid"], - # "S-1-5-21-4231626423-2410014848-2360679739-552") - # Check mapping of objectClass + self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", + msg[0]["objectSid"]) oc = set(msg[0]["objectClass"]) self.assertEquals(oc, set(["group"])) @@ -459,17 +472,14 @@ primaryGroupID: 1-5-21-4231626423-2410014848-2360679739-512 self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X")) self.assertEquals(res[0]["dnsHostName"], "x") self.assertEquals(res[0]["lastLogon"], "x") - # FIXME:Properly compare sid,requires converting between NDR encoding - # and string - #self.assertEquals(res[0]["objectSid"], - # "S-1-5-21-4231626423-2410014848-2360679739-552") + self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", + res[0]["objectSid"]) self.assertTrue("objectSid" in res[0]) self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A")) self.assertTrue(not "dnsHostName" in res[1]) self.assertEquals(res[1]["lastLogon"], "x") - # FIXME: Properly compare sid,see above - #self.assertEquals(res[1]["objectSid"], - # "S-1-5-21-4231626423-2410014848-2360679739-552") + self.assertSidEquals("S-1-5-21-4231626423-2410014848-2360679739-552", + res[1]["objectSid"]) self.assertTrue("objectSid" in res[1]) # Search by generated attribute -- cgit From e0af9601e1535b847e3c82e334d6a9de2ff3580d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 16:41:21 +0200 Subject: Fix FHS flag, rename to --enable-fhs since it's a feature flag and doesn't take any arguments. --- source4/build/m4/check_path.m4 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'source4') diff --git a/source4/build/m4/check_path.m4 b/source4/build/m4/check_path.m4 index 51d5daa913..666dd3b0ae 100644 --- a/source4/build/m4/check_path.m4 +++ b/source4/build/m4/check_path.m4 @@ -23,13 +23,13 @@ winbindd_socket_dir="${localstatedir}/run/winbindd" winbindd_privileged_socket_dir="${localstatedir}/lib/winbindd_privileged" ntp_signd_socket_dir="${localstatedir}/run/ntp_signd" -# Check to prevent installing directly under /usr without the FHS -AS_IF([test ${prefix} == /usr],[ - AC_MSG_ERROR([Don't install directly under "/usr" without using the FHS option (--with-fhs). This could lead to file loss!]) -]) +AC_ARG_ENABLE(fhs, +[AS_HELP_STRING([--enable-fhs],[Use FHS-compliant paths (default=no)])], +[fhs=$enableval], +[fhs=no] +) -AC_ARG_WITH(fhs, -[AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])], +if test x$fhs = xyes; then lockdir="${localstatedir}/lib/samba" piddir="${localstatedir}/run/samba" logfilebase="${localstatedir}/log/samba" @@ -41,7 +41,12 @@ AC_ARG_WITH(fhs, ntp_signd_socket_dir="${localstatedir}/run/samba/ntp_signd" winbindd_socket_dir="${localstatedir}/run/samba/winbindd" winbindd_privileged_socket_dir="${localstatedir}/lib/samba/winbindd_privileged" -) +else + # Check to prevent installing directly under /usr without the FHS + AS_IF([test $prefix == /usr || $prefix == /usr/local],[ + AC_MSG_ERROR([Don't install directly under "/usr" or "/usr/local" without using the FHS option (--enable-fhs). This could lead to file loss!]) + ]) +fi ################################################# # set private directory location -- cgit From 40a6a28170881e567d130c10bec700441423d1e8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Sep 2008 17:11:39 +0200 Subject: Move Samba4-specific files into source4/ --- source4/BUGS | 24 +++ source4/NEWS | 508 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ source4/TODO | 278 ++++++++++++++++++++++++++++++++ 3 files changed, 810 insertions(+) create mode 100644 source4/BUGS create mode 100644 source4/NEWS create mode 100644 source4/TODO (limited to 'source4') diff --git a/source4/BUGS b/source4/BUGS new file mode 100644 index 0000000000..1a9790ddd9 --- /dev/null +++ b/source4/BUGS @@ -0,0 +1,24 @@ +Samba4 alpha4 is not a final Samba release. That is more a reference +to Samba4's lack of the features we expect you will need than a +statement of code quality, but clearly it hasn't seen a broad +deployment yet. If you were to upgrade Samba3 (or indeed Windows) to +Samba4, you would find many things work, but that other key features +you may have relied on simply are not there yet. + +For example, while Samba 3.0 is an excellent member of a Active +Directory domain, Samba4 is happier as a domain controller, and it is +in this role where it has seen deployment into production. + +Samba4 is subjected to an awesome battery of tests on an +automated basis, we have found Samba4 to be very stable in it's +behaviour. We have to recommend against upgrading production servers +from Samba 3 to Samba 4 at this stage, because there may be the features on +which you may rely that are not present, or the mapping of +your configuration and user database may not be complete. + +If you are upgrading, or looking to develop, test or deploy Samba4, you should +backup all configuration and data. + +We welcome your testing, please file bug reports at +https://bugzilla.samba.org/, product: Samba4. Please include as much +information as possible, such as GIT revision number and backtraces. diff --git a/source4/NEWS b/source4/NEWS new file mode 100644 index 0000000000..8a63719a0e --- /dev/null +++ b/source4/NEWS @@ -0,0 +1,508 @@ +This file aims to document the major changes since the latest released version +of Samba, 3.0. Samba 4.0 contains rewrites of several subsystems +and uses a different internal format for most data. Since this +file is an initial draft, please update missing items. + +One of the main goals of Samba 4 was Active Directory Domain Controller +support. This means Samba now implements several protocols that are required +by AD such as Kerberos and DNS. + +An (experimental) upgrade script that performs a one-way upgrade +from Samba 3 is available in source/setup/upgrade. + +Removal of nmbd and introduction of process models +================================================== +smbd now implements several network protocols other than just CIFS and +DCE/RPC. nmbd's functionality has been merged into smbd. smbd supports +various 'process models' that specify how concurrent connections are +handled (when to fork, use threads, etc). + +Introduction of LDB +=================== +Samba now stores most of its persistent data in a LDAP-like database +called LDB (see ldb(7) for more info). + +Removed SWAT +================== +Unlike previous versions, Samba4 does not provide a web interface at this time. + +Built-in KDC +============ +Samba4 ships with an integrated KDC (Kerberos Key Distribution +Center). Backed directly onto our main internal database, and +integrated with custom code to handle the PAC, Samba4's KDC is an +integral part of our support for AD logon protocols. + +Built-in LDAP Server +==================== +Like the situation with the KDC, Samba4 ships with it's own LDAP +server, included to provide simple, built-in LDAP services in an AD +(rather than distinctly standards) matching manner. The database is +LDB, and it shares that in common with the rest of Samba. + +Changed configuration options +============================= +Several configuration options have been removed in Samba4 while others have +been introduced. This section contains a summary of changes to smb.conf and +where these settings moved. Configuration options that have disappeared may be +re-added later when the functionality that uses them gets reimplemented in +Samba 4. + +The 'security' parameter has been split up. It is now only used to choose +between the 'user' and 'share' security levels (the latter is not supported +in Samba 4 yet). The other values of this option and the 'domain master' and +'domain logons' parameters have been merged into a 'server role' parameter +that can be either 'domain controller', 'member server' or 'standalone'. Note that +member server support does not work yet. + +The following parameters have been removed: +- passdb backend: accounts are now stored in a LDB-based SAM database, + see 'sam database' below. +- update encrypted +- public +- guest ok +- client schannel +- server schannel +- allow trusted domains +- hosts equiv +- map to guest +- smb passwd file +- algorithmic rid base +- root directory +- root dir +- root +- guest account +- enable privileges +- pam password change +- passwd program +- passwd chat debug +- passwd chat timeout +- check password script +- username map +- username level +- unix password sync +- restrict anonymous +- username +- user +- users +- invalid users +- valid users +- admin users +- read list +- write list +- printer admin +- force user +- force group +- group +- write ok +- writeable +- writable +- acl check permissions +- acl group control +- acl map full control +- create mask +- create mode +- force create mode +- security mask +- force security mode +- directory mask +- directory mode +- force directory mode +- directory security mask +- force directory security mode +- force unknown acl user +- inherit permissions +- inherit acls +- inherit owner +- guest only +- only guest +- only user +- allow hosts +- deny hosts +- preload modules +- use kerberos keytab +- syslog +- syslog only +- max log size +- debug timestamp +- timestamp logs +- debug hires timestamp +- debug pid +- debug uid +- allocation roundup size +- aio read size +- aio write size +- aio write behind +- large readwrite +- protocol +- read bmpx +- reset on zero vc +- acl compatibility +- defer sharing violations +- ea support +- nt acl support +- nt pipe support +- profile acls +- map acl inherit +- afs share +- max ttl +- client use spnego +- enable asu support +- svcctl list +- block size +- change notify timeout +- deadtime +- getwd cache +- keepalive +- kernel change notify +- lpq cache time +- max smbd processes +- max disk size +- max open files +- min print space +- strict allocate +- sync always +- use mmap +- use sendfile +- hostname lookups +- write cache size +- name cache timeout +- max reported print jobs +- load printers +- printcap cache time +- printcap name +- printcap +- printing +- cups options +- cups server +- iprint server +- print command +- disable spoolss +- enable spoolss +- lpq command +- lprm command +- lppause command +- lpresume command +- queuepause command +- queueresume command +- enumports command +- addprinter command +- deleteprinter command +- show add printer wizard +- os2 driver map +- use client driver +- default devmode +- force printername +- mangling method +- mangle prefix +- default case +- case sensitive +- casesignames +- preserve case +- short preserve case +- mangling char +- hide dot files +- hide special files +- hide unreadable +- hide unwriteable files +- delete veto files +- veto files +- hide files +- veto oplock files +- map readonly +- mangled names +- mangled map +- max stat cache size +- stat cache +- store dos attributes +- machine password timeout +- add user script +- rename user script +- delete user script +- add group script +- delete group script +- add user to group script +- delete user from group script +- set primary group script +- add machine script +- shutdown script +- abort shutdown script +- username map script +- logon script +- logon path +- logon drive +- logon home +- domain logons +- os level +- lm announce +- lm interval +- domain master +- browse list +- enhanced browsing +- wins proxy +- wins hook +- wins partners +- blocking locks +- fake oplocks +- kernel oplocks +- locking +- lock spin count +- lock spin time +- level2 oplocks +- oplock break wait time +- oplock contention limit +- posix locking +- share modes +- ldap server +- ldap port +- ldap admin dn +- ldap delete dn +- ldap group suffix +- ldap idmap suffix +- ldap machine suffix +- ldap passwd sync +- ldap password sync +- ldap replication sleep +- ldap suffix +- ldap ssl +- ldap timeout +- ldap page size +- ldap user suffix +- add share command +- change share command +- delete share command +- eventlog list +- utmp directory +- wtmp directory +- utmp +- default service +- default +- message command +- dfree cache time +- dfree command +- get quota command +- set quota command +- remote announce +- remote browse sync +- homedir map +- afs username map +- afs token lifetime +- log nt token command +- time offset +- NIS homedir +- preexec +- exec +- preexec close +- postexec +- root preexec +- root preexec close +- root postexec +- set directory +- wide links +- follow symlinks +- dont descend +- magic script +- magic output +- delete readonly +- dos filemode +- dos filetimes +- dos filetime resolution +- fake directory create times +- panic action +- vfs objects +- vfs object +- msdfs root +- msdfs proxy +- host msdfs +- enable rid algorithm +- passdb expand explicit +- idmap backend +- idmap uid +- winbind uid +- idmap gid +- winbind gid +- template homedir +- template shell +- winbind separator +- winbind cache time +- winbind enum users +- winbind enum groups +- winbind use default domain +- winbind trusted domains only +- winbind nested groups +- winbind max idle children +- winbind nss info + +The following parameters have been added: ++ rpc big endian (G) + Make Samba fake it is running on a bigendian machine when using DCE/RPC. + Useful for debugging. + + Default: no + ++ case insensitive filesystem (S) + Set to true if this share is located on a case-insensitive filesystem. + This disables looking for a filename by trying all possible combinations of + uppercase/lowercase characters and thus speeds up operations when a + file cannot be found. + + Default: no + ++ js include (G) + Path to JavaScript library. + + Default: Set at compile-time + ++ setup directory + Path to data used by provisioning script. + + Default: Set at compile-time + ++ ncalrpc dir + Directory to use for UNIX sockets used by the 'ncalrpc' DCE/RPC transport. + + Default: Set at compile-time + ++ ntvfs handler + Backend to the NT VFS to use (more than one can be specified). Available + backends include: + + - posix: + Maps POSIX FS semantics to NT semantics + + - simple: + Very simple backend (original testing backend). + + - unixuid: + Sets up user credentials based on POSIX gid/uid. + + - cifs: + Proxies a remote CIFS FS. Mainly useful for testing. + + - nbench: + Filter module that saves data useful to the nbench benchmark suite. + + - ipc: + Allows using SMB for inter process communication. Only used for + the IPC$ share. + + - print: + Allows printing over SMB. This is LANMAN-style printing (?), not + the be confused with the spoolss DCE/RPC interface used by later + versions of Windows. + + Default: unixuid default + ++ ntptr providor + FIXME + ++ dcerpc endpoint servers + What DCE/RPC servers to start. + + Default: epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup + ++ server services + Services Samba should provide. + + Default: smb rpc nbt wrepl ldap cldap web kdc + ++ sam database + Location of the SAM (account database) database. This should be a + LDB URL. + + Default: set at compile-time + ++ spoolss database + Spoolss (printer) DCE/RPC server database. This should be a LDB URL. + + Default: set at compile-time + ++ wins config database + WINS configuration database location. This should be a LDB URL. + + Default: set at compile-time + ++ wins database + WINS database location. This should be a LDB URL. + + Default: set at compile-time + ++ client use spnego principal + Tells the client to use the Kerberos service principal specified by the + server during the security protocol negotation rather than + looking up the principal itself (cifs/hostname). + + Default: false + ++ nbt port + TCP/IP Port used by the NetBIOS over TCP/IP (NBT) implementation. + + Default: 137 + ++ dgram port + UDP/IP port used by the NetBIOS over TCP/IP (NBT) implementation. + + Default: 138 + ++ cldap port + UDP/IP port used by the CLDAP protocol. + + Default: 389 + ++ krb5 port + IP port used by the kerberos KDC. + + Default: 88 + ++ kpasswd port + IP port used by the kerberos password change protocol. + + Default: 464 + ++ web port + TCP/IP port SWAT should listen on. + + Default: 901 + ++ tls enabled + Enable TLS support for SWAT + + Default: true + ++ tls keyfile + Path to TLS key file (PEM format) to be used by SWAT. If no + path is specified, Samba will create a key. + + Default: none + ++ tls certfile + Path to TLS certificate file (PEM format) to be used by SWAT. If no + path is specified, Samba will create a certificate. + + Default: none + ++ tls cafile + Path to CA authority file Samba will use to sign TLS keys it generates. If + no path is specified, Samba will create a self-signed CA certificate. + + Default: none + ++ tls crlfile + Path to TLS certificate revocation lists file. + + Default: none + ++ swat directory + SWAT data directory. + + Default: set at compile-time + ++ large readwrite + Indicate the CIFS server is able to do large reads/writes. + + Default: true + ++ unicode + Enable/disable unicode support in the protocol. + + Default: true diff --git a/source4/TODO b/source4/TODO new file mode 100644 index 0000000000..5efebed1b3 --- /dev/null +++ b/source4/TODO @@ -0,0 +1,278 @@ +build/smb_build/TODO +lib/registry/TODO +lib/tdr/TODO +pidl/TODO + +- seperate adminlog mechanism (as opposed to the current DEBUG log, + which is not really aimed at administrators but more at developers) + Perhaps similar to eventlog so we can also use eventlog to retrieve the data? + +- testsuite for the 'net' tool + +- and a lot of other stuff + +Configuration options +===================== + +The following options don't exist in Samba4 yet +or are not converted by the upgrade script +or will be removed: + +- update encrypted +- public +- guest ok +- client schannel +- server schannel +- allow trusted domains +- hosts equiv +- map to guest +- algorithmic rid base +- root directory +- root dir +- root +- guest account +- enable privileges +- pam password change +- passwd program +- passwd chat debug +- passwd chat timeout +- check password script +- username map +- username level +- unix password sync +- restrict anonymous +- username +- user +- users +- invalid users +- valid users +- admin users +- read list +- write list +- printer admin +- force user +- force group +- group +- write ok +- writeable +- writable +- acl check permissions +- acl group control +- acl map full control +- create mask +- create mode +- force create mode +- security mask +- force security mode +- directory mask +- directory mode +- force directory mode +- directory security mask +- force directory security mode +- force unknown acl user +- inherit permissions +- inherit acls +- inherit owner +- guest only +- only guest +- only user +- allow hosts +- deny hosts +- preload modules +- use kerberos keytab +- syslog +- syslog only +- max log size +- debug timestamp +- timestamp logs +- debug hires timestamp +- debug pid +- debug uid +- allocation roundup size +- aio read size +- aio write size +- aio write behind +- large readwrite +- protocol +- read bmpx +- reset on zero vc +- acl compatibility +- defer sharing violations +- ea support +- nt acl support +- nt pipe support +- profile acls +- map acl inherit +- afs share +- max ttl +- client use spnego +- enable asu support +- svcctl list +- block size +- change notify timeout +- deadtime +- getwd cache +- keepalive +- kernel change notify +- lpq cache time +- max smbd processes +- max disk size +- max open files +- min print space +- strict allocate +- sync always +- use mmap +- use sendfile +- hostname lookups +- write cache size +- name cache timeout +- max reported print jobs +- load printers +- printcap cache time +- printcap name +- printcap +- printing +- cups options +- cups server +- iprint server +- print command +- disable spoolss +- enable spoolss +- lpq command +- lprm command +- lppause command +- lpresume command +- queuepause command +- queueresume command +- enumports command +- addprinter command +- deleteprinter command +- show add printer wizard +- os2 driver map +- use client driver +- default devmode +- force printername +- mangling method +- mangle prefix +- default case +- case sensitive +- casesignames +- preserve case +- short preserve case +- mangling char +- hide dot files +- hide special files +- hide unreadable +- hide unwriteable files +- delete veto files +- veto files +- hide files +- veto oplock files +- map readonly +- mangled names +- mangled map +- max stat cache size +- stat cache +- store dos attributes +- machine password timeout +- add user script +- rename user script +- delete user script +- add group script +- delete group script +- add user to group script +- delete user from group script +- set primary group script +- add machine script +- shutdown script +- abort shutdown script +- username map script +- logon script +- logon path +- logon drive +- logon home +- domain logons +- os level +- lm announce +- lm interval +- domain master +- browse list +- enhanced browsing +- wins proxy +- blocking locks +- fake oplocks +- kernel oplocks +- locking +- lock spin count +- lock spin time +- oplocks +- level2 oplocks +- oplock break wait time +- oplock contention limit +- posix locking +- share modes +- add share command +- change share command +- delete share command +- eventlog list +- utmp directory +- wtmp directory +- utmp +- default service +- default +- message command +- dfree cache time +- dfree command +- get quota command +- set quota command +- remote announce +- remote browse sync +- homedir map +- afs username map +- afs token lifetime +- log nt token command +- time offset +- NIS homedir +- preexec +- exec +- preexec close +- postexec +- root preexec +- root preexec close +- root postexec +- set directory +- wide links +- follow symlinks +- dont descend +- magic script +- magic output +- delete readonly +- dos filemode +- dos filetimes +- dos filetime resolution +- fake directory create times +- panic action +- vfs objects +- vfs object +- msdfs root +- msdfs proxy +- host msdfs +- enable rid algorithm +- passdb expand explicit +- idmap backend +- idmap uid +- winbind uid +- idmap gid +- winbind gid +- template homedir +- template shell +- winbind separator +- winbind cache time +- winbind enum users +- winbind enum groups +- winbind use default domain +- winbind trusted domains only +- winbind nested groups +- winbind max idle children +- winbind nss info + -- cgit From ee97097783aa146b0b2f88c15f3764a420797e1a Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 30 Sep 2008 18:10:04 +0200 Subject: Use UTF8 rather than the possibly different UNIX charset. --- source4/lib/registry/tests/generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/lib/registry/tests/generic.c b/source4/lib/registry/tests/generic.c index 6eae26bc46..2b7eb838ba 100644 --- a/source4/lib/registry/tests/generic.c +++ b/source4/lib/registry/tests/generic.c @@ -53,7 +53,7 @@ static bool test_reg_val_data_string_dword(struct torture_context *ctx) static bool test_reg_val_data_string_sz(struct torture_context *ctx) { DATA_BLOB db; - db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + db.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "bla", 3, (void **)&db.data); torture_assert_str_equal(ctx, "bla", reg_val_data_string(ctx, lp_iconv_convenience(ctx->lp_ctx), REG_SZ, db), @@ -88,7 +88,7 @@ static bool test_reg_val_data_string_empty(struct torture_context *ctx) static bool test_reg_val_description(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "stationary traveller", strlen("stationary traveller"), (void **)&data.data); @@ -102,7 +102,7 @@ static bool test_reg_val_description(struct torture_context *ctx) static bool test_reg_val_description_nullname(struct torture_context *ctx) { DATA_BLOB data; - data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UNIX, CH_UTF16, + data.length = convert_string_talloc(ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF8, CH_UTF16, "west berlin", strlen("west berlin"), (void **)&data.data); -- cgit From a238f17e2785da4f11411c6a4dd20fdcb3c349b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 12:33:00 -0700 Subject: Add in test name visible on the wire or in debug logs so you can see when particular tests start. Jeremy. --- source4/torture/raw/notify.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'source4') diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 25c91eb88b..14ee23158a 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -583,7 +583,8 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t notify.nttrans.in.buffer_size = 1000; notify.nttrans.in.recursive = true; -#define NOTIFY_MASK_TEST(setup, op, cleanup, Action, expected, nchanges) \ +#define NOTIFY_MASK_TEST(test_name, setup, op, cleanup, Action, expected, nchanges) \ + smbcli_unlink(cli->tree, test_name); \ do { for (mask=i=0;i<32;i++) { \ struct smbcli_request *req; \ status = smb_raw_open(cli->tree, tctx, &io); \ @@ -643,21 +644,21 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t } while (0) printf("testing mkdir\n"); - NOTIFY_MASK_TEST(;, + NOTIFY_MASK_TEST("testing mkdir",;, smbcli_mkdir(cli->tree, BASEDIR "\\tname1");, smbcli_rmdir(cli->tree, BASEDIR "\\tname1");, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME, 1); printf("testing create file\n"); - NOTIFY_MASK_TEST(;, + NOTIFY_MASK_TEST("testing create file",;, smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", O_CREAT, 0));, smbcli_unlink(cli->tree, BASEDIR "\\tname1");, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, 1); printf("testing unlink\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing unlink", smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", O_CREAT, 0));, smbcli_unlink(cli->tree, BASEDIR "\\tname1");, ;, @@ -665,7 +666,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_FILE_NAME, 1); printf("testing rmdir\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing rmdir", smbcli_mkdir(cli->tree, BASEDIR "\\tname1");, smbcli_rmdir(cli->tree, BASEDIR "\\tname1");, ;, @@ -673,7 +674,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_DIR_NAME, 1); printf("testing rename file\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing rename file", smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", O_CREAT, 0));, smbcli_rename(cli->tree, BASEDIR "\\tname1", BASEDIR "\\tname2");, smbcli_unlink(cli->tree, BASEDIR "\\tname2");, @@ -681,7 +682,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_CREATION, 2); printf("testing rename dir\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing rename dir", smbcli_mkdir(cli->tree, BASEDIR "\\tname1");, smbcli_rename(cli->tree, BASEDIR "\\tname1", BASEDIR "\\tname2");, smbcli_rmdir(cli->tree, BASEDIR "\\tname2");, @@ -689,7 +690,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_DIR_NAME, 2); printf("testing set path attribute\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set path attribute", smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", O_CREAT, 0));, smbcli_setatr(cli->tree, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN, 0);, smbcli_unlink(cli->tree, BASEDIR "\\tname1");, @@ -697,7 +698,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_ATTRIBUTES, 1); printf("testing set path write time\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set path write time", smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", O_CREAT, 0));, smbcli_setatr(cli->tree, BASEDIR "\\tname1", FILE_ATTRIBUTE_NORMAL, 1000);, smbcli_unlink(cli->tree, BASEDIR "\\tname1");, @@ -705,7 +706,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_LAST_WRITE, 1); printf("testing set file attribute\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set file attribute", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_fsetatr(cli->tree, fnum2, FILE_ATTRIBUTE_HIDDEN, 0, 0, 0, 0);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, @@ -718,7 +719,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t } else { printf("testing set file create time\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set file create time", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_fsetatr(cli->tree, fnum2, 0, t, 0, 0, 0);, @@ -729,7 +730,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t } printf("testing set file access time\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set file access time", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_fsetatr(cli->tree, fnum2, 0, 0, t, 0, 0);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, @@ -737,7 +738,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_LAST_ACCESS, 1); printf("testing set file write time\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set file write time", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_fsetatr(cli->tree, fnum2, 0, 0, 0, t, 0);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, @@ -745,7 +746,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t FILE_NOTIFY_CHANGE_LAST_WRITE, 1); printf("testing set file change time\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing set file change time", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_fsetatr(cli->tree, fnum2, 0, 0, 0, 0, t);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, @@ -754,7 +755,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t printf("testing write\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing write", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_write(cli->tree, fnum2, 1, &c, 10000, 1);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, @@ -762,7 +763,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t 0, 1); printf("testing truncate\n"); - NOTIFY_MASK_TEST( + NOTIFY_MASK_TEST("testing truncate", fnum2 = create_complex_file(cli, tctx, BASEDIR "\\tname1");, smbcli_ftruncate(cli->tree, fnum2, 10000);, (smbcli_close(cli->tree, fnum2), smbcli_unlink(cli->tree, BASEDIR "\\tname1"));, -- cgit From 687ce0b60a3913b0f2eca2365a5ab56e78523ab5 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 30 Sep 2008 12:44:24 -0700 Subject: Use a getatr instead to make things cleaner. Jeremy. --- source4/torture/raw/notify.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 14ee23158a..d7541b7c71 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -584,7 +584,8 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t notify.nttrans.in.recursive = true; #define NOTIFY_MASK_TEST(test_name, setup, op, cleanup, Action, expected, nchanges) \ - smbcli_unlink(cli->tree, test_name); \ + do { \ + smbcli_getatr(cli->tree, test_name, NULL, NULL, NULL); \ do { for (mask=i=0;i<32;i++) { \ struct smbcli_request *req; \ status = smb_raw_open(cli->tree, tctx, &io); \ @@ -641,7 +642,8 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t mask, expected); \ } \ } \ - } while (0) + } while (0); \ + } while (0); printf("testing mkdir\n"); NOTIFY_MASK_TEST("testing mkdir",;, -- cgit