diff options
author | Simo Sorce <idra@samba.org> | 2008-08-26 18:56:49 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2008-08-26 18:56:49 -0400 |
commit | a1de4e988d7780f687bb7ed2288faf3dfbb9da71 (patch) | |
tree | abc569f52f33efdf48135faf7f0c790601eef229 | |
parent | 5e7655fa27f7b2c9c54edfc25f86974dbdb23ea4 (diff) | |
parent | 95cc5ee395ab9d7f6f79d341ad20bc486c292a8d (diff) | |
download | samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.tar.gz samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.tar.bz2 samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.zip |
Merge branch 'v3-devel' of ssh://git.samba.org/data/git/samba into v3-devel
(This used to be commit e038f1cf9fb305fc1e7a4189208e451d30aaa1f0)
66 files changed, 1246 insertions, 597 deletions
diff --git a/.gitignore b/.gitignore index 5e779f1463..edb1b3d6d8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ source/include/stamp-h source/include/version.h source/Makefile source/lib/netapi/examples/Makefile +source/lib/netapi/tests/Makefile source/config.log source/config.status source/configure @@ -32,6 +33,8 @@ source/cscope.out source/torture.tdb source/pkgconfig/*.pc source/st +source/exports/libsmbclient.syms +source/exports/libsmbsharemodes.syms source/exports/libnetapi.syms source/exports/libtalloc.syms source/exports/libtdb.syms @@ -61,6 +64,8 @@ examples/libsmbclient/teststat3 examples/libsmbclient/testutime examples/libsmbclient/testwrite examples/libsmbclient/testtruncate +examples/libsmbclient/tree +examples/libsmbclient/Makefile.internal source/librpc/gen_ndr/cli_krb5pac.* source/librpc/gen_ndr/cli_messaging.* source/librpc/gen_ndr/cli_misc.* diff --git a/docs-xml/manpages-3/net.8.xml b/docs-xml/manpages-3/net.8.xml index cdf0fbbf60..31fe69d8d3 100644 --- a/docs-xml/manpages-3/net.8.xml +++ b/docs-xml/manpages-3/net.8.xml @@ -850,7 +850,20 @@ to run this against the PDC, from a Samba machine joined as a BDC. </para> <para>Export users, aliases and groups from remote server to local server. You need to run this against the PDC, from a Samba machine joined as a BDC. </para> +</refsect2> + +<refsect2> +<title>RPC VAMPIRE KEYTAB</title> +<para>Dump remote SAM database to local Kerberos keytab file. +</para> +</refsect2> + +<refsect2> +<title>RPC VAMPIRE LDIF</title> + +<para>Dump remote SAM database to local LDIF file or standard output. +</para> </refsect2> <refsect2> diff --git a/docs-xml/manpages-3/smbcontrol.1.xml b/docs-xml/manpages-3/smbcontrol.1.xml index d7c7751cbe..f8c31bb1b9 100644 --- a/docs-xml/manpages-3/smbcontrol.1.xml +++ b/docs-xml/manpages-3/smbcontrol.1.xml @@ -58,23 +58,32 @@ on STDIN. An empty command line or a "q" will quit the program.</para></listitem> </varlistentry> - + <varlistentry> <term>destination</term> <listitem><para>One of <parameter>nmbd</parameter>, <parameter>smbd</parameter> or a process ID.</para> + <para>The <parameter>all</parameter> destination causes the + message to "broadcast" to all running daemons including nmbd and + winbind. This is a change for Samba 3.3, prior to this the + paramter smbd used to do this.</para> + <para>The <parameter>smbd</parameter> destination causes the - message to "broadcast" to all smbd daemons.</para> + message to be sent to the smbd daemon specified in the + <filename>smbd.pid</filename> file.</para> <para>The <parameter>nmbd</parameter> destination causes the message to be sent to the nmbd daemon specified in the <filename>nmbd.pid</filename> file.</para> + <para>The <parameter>winbindd</parameter> destination causes the + message to be sent to the winbind daemon specified in the + <filename>winbindd.pid</filename> file.</para> + <para>If a single process ID is given, the message is sent to only that process.</para></listitem> </varlistentry> - - + <varlistentry> <term>message-type</term> <listitem><para>Type of message to send. See diff --git a/docs-xml/smbdotconf/logon/initlogondelay.xml b/docs-xml/smbdotconf/logon/initlogondelay.xml new file mode 100644 index 0000000000..de8b19ecf5 --- /dev/null +++ b/docs-xml/smbdotconf/logon/initlogondelay.xml @@ -0,0 +1,15 @@ +<samba:parameter name="init logon delay" + context="G" + type="integer" + advanced="1" developer="1" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> +<description> + <para> + This parameter specifies a delay in milliseconds for the hosts configured + for delayed initial samlogon with + <smbconfoption name="init logon delayed hosts"/>. + </para> +</description> + +<value type="default">100</value> +</samba:parameter> diff --git a/docs-xml/smbdotconf/logon/initlogondelayedhosts.xml b/docs-xml/smbdotconf/logon/initlogondelayedhosts.xml new file mode 100644 index 0000000000..2756a63ef9 --- /dev/null +++ b/docs-xml/smbdotconf/logon/initlogondelayedhosts.xml @@ -0,0 +1,21 @@ +<samba:parameter name="init logon delayed hosts" + context="G" + type="list" + advanced="1" developer="1" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> +<description> + <para> + This parameter takes a list of host names, addresses or networks for + which the initial samlogon reply should be delayed (so other DCs get + preferred by XP workstations if there are any). + </para> + + <para> + The length of the delay can be specified with the + <smbconfoption name="init logon delay"/> parameter. + </para> +</description> + +<value type="default"></value> +<value type="example">150.203.5. myhost.mynet.de</value> +</samba:parameter> diff --git a/docs-xml/smbdotconf/winbind/idmapcachetime.xml b/docs-xml/smbdotconf/winbind/idmapcachetime.xml index 1636cdfa58..ba526100fc 100644 --- a/docs-xml/smbdotconf/winbind/idmapcachetime.xml +++ b/docs-xml/smbdotconf/winbind/idmapcachetime.xml @@ -9,5 +9,5 @@ </para> </description> -<value type="default">900</value> +<value type="default">604800 (one week)</value> </samba:parameter> diff --git a/docs-xml/smbdotconf/winbind/winbindreconnectdelay.xml b/docs-xml/smbdotconf/winbind/winbindreconnectdelay.xml new file mode 100644 index 0000000000..2da263e5ce --- /dev/null +++ b/docs-xml/smbdotconf/winbind/winbindreconnectdelay.xml @@ -0,0 +1,15 @@ +<samba:parameter name="winbind reconnect delay" + context="G" + type="integer" + advanced="1" developer="1" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> +<description> + <para>This parameter specifies the number of + seconds the <citerefentry><refentrytitle>winbindd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> daemon will wait between + attempts to contact a Domain controller for a domain that is + determined to be down or not contactable.</para> +</description> + +<value type="default">30</value> +</samba:parameter> diff --git a/examples/libsmbclient/Makefile.internal.in b/examples/libsmbclient/Makefile.internal.in new file mode 100644 index 0000000000..dd4518f212 --- /dev/null +++ b/examples/libsmbclient/Makefile.internal.in @@ -0,0 +1,138 @@ +# Makefile.internal.in for building the libsmbclient examples +# from within a samba build. +# +# Use Makfile for building the examples with a libsmbclient +# installed to /usr/local/samba + +CC = @CC@ + +SAMBA_DIR = ../../source +SAMBA_INCLUDES = -I$(SAMBA_DIR)/include +SAMBA_LIBPATH = -L$(SAMBA_DIR)/bin + +GTK_CFLAGS = `gtk-config --cflags` +GTK_LIBS = `gtk-config --libs` + +#GTK_CFLAGS = `pkg-config gtk+-2.0 --cflags` +#GTK_LIBS = `pkg-config gtk+-2.0 --libs` + +FLAGS = @CPPFLAGS@ @CFLAGS@ $(GTK_CFLAGS) $(SAMBA_INCLUDES) + +PICFLAG=@PICFLAG@ +LDFLAGS= $(SAMBA_LIBPATH) @PIE_LDFLAGS@ @LDFLAGS@ + +EXTERNAL_LIBS = @LIBS@ @LDAP_LIBS@ @KRB5_LIBS@ @NSCD_LIBS@ +LIBSMBCLIENT_LIBS = -lwbclient -lsmbclient -ltalloc -ltdb -ldl -lresolv +CMDLINE_LIBS = @POPTLIBS@ +LIBS = $(EXTERNAL_LIBS) $(LIBSMBCLIENT_LIBS) + +# Compile a source file. (.c --> .o) +COMPILE_CC = $(CC) -I. $(FLAGS) $(PICFLAG) -c $< -o $@ +COMPILE = $(COMPILE_CC) + +MAKEDIR = || exec false; \ + if test -d "$$dir"; then :; else \ + echo mkdir "$$dir"; \ + mkdir -p "$$dir" >/dev/null 2>&1 || \ + test -d "$$dir" || \ + mkdir "$$dir" || \ + exec false; fi || exec false + +TESTS= testsmbc \ + testacl \ + testacl2 \ + testacl3 \ + testbrowse \ + testbrowse2 \ + teststat \ + teststat2 \ + teststat3 \ + testtruncate \ + testchmod \ + testutime \ + testread \ + testwrite + +# tree \ + +all: $(TESTS) smbsh + +.c.o: + @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ + dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi + @echo Compiling $*.c + @$(COMPILE) && exit 0;\ + echo "The following command failed:" 1>&2;\ + echo "$(COMPILE_CC)" 1>&2;\ + $(COMPILE_CC) >/dev/null 2>&1 + +testsmbc: testsmbc.o + @echo Linking testsmbc + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) + +tree: tree.o + @echo Linking tree + @$(CC) $(GTK_CFLAGS) $(FLAGS) $(LDFLAGS) -o $@ $< $(GTK_LIBS) $(LIBS) + +testacl: testacl.o + @echo Linking testacl + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testacl2: testacl2.o + @echo Linking testacl2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testacl3: testacl3.o + @echo Linking testacl3 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testbrowse: testbrowse.o + @echo Linking testbrowse + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testbrowse2: testbrowse2.o + @echo Linking testbrowse2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat: teststat.o + @echo Linking teststat + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat2: teststat2.o + @echo Linking teststat2 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +teststat3: teststat3.o + @echo Linking teststat3 + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testtruncate: testtruncate.o + @echo Linking testtruncate + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testchmod: testchmod.o + @echo Linking testchmod + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testutime: testutime.o + @echo Linking testutime + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testread: testread.o + @echo Linking testread + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testwrite: testwrite.o + @echo Linking testwrite + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +testctx: testctx.o + @echo Linking testctx + @$(CC) $(FLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(CMDLINE_LIBS) + +smbsh: + make -C smbwrapper + +clean: + @rm -f *.o *~ $(TESTS) + @make -C smbwrapper clean diff --git a/examples/libsmbclient/smbwrapper/Makefile b/examples/libsmbclient/smbwrapper/Makefile index 7f5c17c79f..eb470056e1 100644 --- a/examples/libsmbclient/smbwrapper/Makefile +++ b/examples/libsmbclient/smbwrapper/Makefile @@ -3,7 +3,7 @@ DEFS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL) -LDFLAGS = -L/usr/local/samba/lib +LDFLAGS = -L/usr/local/samba/lib -L../../../source/bin SMBINCLUDE = -I../../../source/include CFLAGS= -fpic -g -O0 $(DEFS) $(SMBINCLUDE) diff --git a/examples/libsmbclient/smbwrapper/wrapper.c b/examples/libsmbclient/smbwrapper/wrapper.c index 958e00636e..3811b04356 100644 --- a/examples/libsmbclient/smbwrapper/wrapper.c +++ b/examples/libsmbclient/smbwrapper/wrapper.c @@ -1109,7 +1109,7 @@ int utimes(const char *name, const struct timeval *tvp) return (* smbw_libc.utimes)((char *) name, (struct timeval *) tvp); } -int readlink(const char *path, char *buf, size_t bufsize) +ssize_t readlink(const char *path, char *buf, size_t bufsize) { check_init("readlink"); diff --git a/source3/Doxyfile b/source3/Doxyfile index c1040781d8..9ade25c9a6 100644 --- a/source3/Doxyfile +++ b/source3/Doxyfile @@ -1,7 +1,7 @@ -# Doxyfile 0.1 +# Doxyfile 1.5.3 #--------------------------------------------------------------------------- -# General configuration options +# Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = Samba PROJECT_NUMBER = HEAD @@ -13,68 +13,84 @@ PROJECT_NUMBER = HEAD # doesn't mind variables being redefined. OUTPUT_DIRECTORY = dox - OUTPUT_LANGUAGE = English -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO +DOXYFILE_ENCODING = UTF-8 BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ALWAYS_DETAILED_SEC = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = $(PWD)/ +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +INHERIT_DOCS = YES +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +DISTRIBUTE_GROUP_DOC = NO +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO INTERNAL_DOCS = YES -CLASS_DIAGRAMS = YES -SOURCE_BROWSER = YES -INLINE_SOURCES = YES -STRIP_CODE_COMMENTS = NO CASE_SENSE_NAMES = YES -SHORT_NAMES = NO HIDE_SCOPE_NAMES = YES -VERBATIM_HEADERS = YES SHOW_INCLUDE_FILES = YES -JAVADOC_AUTOBRIEF = YES -INHERIT_DOCS = YES INLINE_INFO = YES SORT_MEMBER_DOCS = NO -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 8 +SORT_BRIEF_DOCS = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES -ALIASES = +GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 -OPTIMIZE_OUTPUT_FOR_C = YES SHOW_USED_FILES = YES -REFERENCED_BY_RELATION = YES +SHOW_DIRECTORIES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = YES WARNINGS = NO WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = NO +WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = . +INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.h \ *.idl RECURSIVE = YES EXCLUDE = include/includes.h \ include/proto.h +EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXAMPLE_PATH = EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES @@ -85,13 +101,12 @@ IGNORE_PREFIX = #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO -GENERATE_CHI = NO -BINARY_TOC = NO TOC_EXPAND = NO DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 3 @@ -152,25 +167,26 @@ PERL_PATH = /usr/bin/perl # configuration options related to the dot tool #--------------------------------------------------------------------------- HAVE_DOT = NO +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES TEMPLATE_RELATIONS = YES INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png DOT_PATH = DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 GENERATE_LEGEND = YES DOT_CLEANUP = YES #--------------------------------------------------------------------------- # configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO -CGI_NAME = search.cgi -CGI_URL = -DOC_URL = -DOC_ABSPATH = -BIN_ABSPATH = /usr/local/bin/ -EXT_DOC_PATHS = diff --git a/source3/Makefile.in b/source3/Makefile.in index d92ececbbf..486d47f5f8 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -178,9 +178,9 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ # Note that all executable programs now provide for an optional executable suffix. -SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ @SWAT_SBIN_TARGETS@ @EXTRA_SBIN_PROGS@ +SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ @SWAT_SBIN_TARGETS@ @EXTRA_SBIN_PROGS@ @CIFSUPCALL_PROGS@ -ROOT_SBIN_PROGS = @CIFSMOUNT_PROGS@ @CIFSUPCALL_PROGS@ +ROOT_SBIN_PROGS = @CIFSMOUNT_PROGS@ BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \ bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ bin/smbget@EXEEXT@ @@ -339,7 +339,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) \ lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \ lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \ libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \ - lib/file_id.o + lib/file_id.o lib/idmap_cache.o LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ) @@ -980,7 +980,7 @@ PAM_SMBPASS_OBJ = $(PAM_SMBPASS_OBJ_0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_ $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ) \ $(LDB_OBJ) -IDMAP_OBJ = winbindd/idmap.o winbindd/idmap_cache.o winbindd/idmap_util.o @IDMAP_STATIC@ +IDMAP_OBJ = winbindd/idmap.o winbindd/idmap_util.o @IDMAP_STATIC@ NSS_INFO_OBJ = winbindd/nss_info.o @NSS_INFO_STATIC@ @@ -1350,7 +1350,7 @@ bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ @$(CC) $(FLAGS) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \ -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \ $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \ - $(LIBTDB_LIBS) + $(LIBTDB_LIBS) $(NSCD_LIBS) bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ @@ -1824,7 +1824,7 @@ shlibs test_shlibs: @LIBADDNS_SHARED@ # #------------------------------------------------------------------- -LIBNETAPI_OBJ1 = lib/netapi/netapi.o \ +LIBNETAPI_OBJ0 = lib/netapi/netapi.o \ lib/netapi/cm.o \ librpc/gen_ndr/ndr_libnetapi.o \ lib/netapi/libnetapi.o \ @@ -1837,7 +1837,7 @@ LIBNETAPI_OBJ1 = lib/netapi/netapi.o \ lib/netapi/samr.o \ lib/netapi/sid.o -LIBNETAPI_OBJ = $(LIBNETAPI_OBJ1) $(LIBNET_OBJ) \ +LIBNETAPI_OBJ = $(LIBNETAPI_OBJ0) $(LIBNET_OBJ) \ $(LIBSMBCONF_OBJ) \ $(REG_SMBCONF_OBJ) \ $(PARAM_WITHOUT_REG_OBJ) $(LIB_NONSMBD_OBJ) \ @@ -1869,9 +1869,9 @@ $(LIBNETAPI_SHARED_TARGET): $(LIBNETAPI_SHARED_TARGET_SONAME) @rm -f $@ @ln -s -f `basename $(LIBNETAPI_SHARED_TARGET_SONAME)` $@ -$(LIBNETAPI_STATIC_TARGET): $(BINARY_PREREQS) $(LIBNETAPI_OBJ1) +$(LIBNETAPI_STATIC_TARGET): $(BINARY_PREREQS) $(LIBNETAPI_OBJ0) @echo Linking non-shared library $@ - @-$(AR) -rc $@ $(LIBNETAPI_OBJ1) + @-$(AR) -rc $@ $(LIBNETAPI_OBJ0) libnetapi: $(LIBNETAPI) @@ -1917,10 +1917,13 @@ LIBSMBCLIENT_SOVER=@LIBSMBCLIENT_SOVER@ LIBSMBCLIENT_SHARED_TARGET_SONAME=$(LIBSMBCLIENT_SHARED_TARGET).$(LIBSMBCLIENT_SOVER) LIBSMBCLIENT_STATIC_TARGET=@LIBSMBCLIENT_STATIC_TARGET@ LIBSMBCLIENT=$(LIBSMBCLIENT_STATIC_TARGET) @LIBSMBCLIENT_SHARED@ -#LIBSMBCLIENT_SYMS=$(srcdir)/exports/libsmbclient.@SYMSEXT@ +LIBSMBCLIENT_SYMS=$(srcdir)/exports/libsmbclient.@SYMSEXT@ LIBSMBCLIENT_HEADERS=$(srcdir)/include/libsmbclient.h -$(LIBSMBCLIENT_SHARED_TARGET_SONAME): $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ +$(LIBSMBCLIENT_SYMS): $(LIBSMBCLIENT_HEADERS) + @$(MKSYMS_SH) $(AWK) $@ $(LIBSMBCLIENT_HEADERS) + +$(LIBSMBCLIENT_SHARED_TARGET_SONAME): $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) $(LIBSMBCLIENT_SYMS) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking shared library $@ @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(LIBS) \ @@ -1986,12 +1989,13 @@ LIBSMBSHAREMODES_SOVER=@LIBSMBSHAREMODES_SOVER@ LIBSMBSHAREMODES_SHARED_TARGET_SONAME=$(LIBSMBSHAREMODES_SHARED_TARGET).$(LIBSMBSHAREMODES_SOVER) LIBSMBSHAREMODES_STATIC_TARGET=@LIBSMBSHAREMODES_STATIC_TARGET@ LIBSMBSHAREMODES=$(LIBSMBSHAREMODES_STATIC_TARGET) @LIBSMBSHAREMODES_SHARED@ -#LIBSMBSHAREMODES_SYMS=$(srcdir)/exports/libsmbsharemodes.@SYMSEXT@ +LIBSMBSHAREMODES_SYMS=$(srcdir)/exports/libsmbsharemodes.@SYMSEXT@ LIBSMBSHAREMODES_HEADERS=$(srcdir)/include/smb_share_modes.h -LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@ +$(LIBSMBSHAREMODES_SYMS): $(LIBSMBSHAREMODES_HEADERS) + @$(MKSYMS_SH) $(AWK) $@ $(LIBSMBSHAREMODES_HEADERS) -$(LIBSMBSHAREMODES_SHARED_TARGET_SONAME): $(BINARY_PREREQS) $(LIBSMBSHAREMODES_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ +$(LIBSMBSHAREMODES_SHARED_TARGET_SONAME): $(BINARY_PREREQS) $(LIBSMBSHAREMODES_OBJ) $(LIBSMBSHAREMODES_SYMS) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking shared library $@ @$(SHLD_DSO) $(LIBSMBSHAREMODES_OBJ) \ $(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ @@ -2471,7 +2475,7 @@ install-everything:: install installmodules # is not used installdirs:: - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) installservers:: all installdirs @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) $(SBIN_PROGS) @@ -2484,8 +2488,8 @@ installcifsmount:: @CIFSMOUNT_PROGS@ @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSMOUNT_PROGS@ installcifsupcall:: @CIFSUPCALL_PROGS@ - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(ROOTSBINDIR) - @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(ROOTSBINDIR) @CIFSUPCALL_PROGS@ + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(SBINDIR) + @$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) @CIFSUPCALL_PROGS@ # Some symlinks are required for the 'probing' of modules. # This mechanism should go at some point.. @@ -2716,3 +2720,14 @@ valgrindtest:: all torture timelimit SMBD_VALGRIND="xterm -n smbd -e valgrind -q --db-attach=yes --num-callers=30" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" + + +## +## Examples: +## + +libsmbclient_examples: + $(MAKE) -C ../examples/libsmbclient -f Makefile.internal + +clean_libsmbclient_examples: + $(MAKE) -C ../examples/libsmbclient -f Makefile.internal clean diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c index 58921bdf15..9345eed27a 100644 --- a/source3/auth/pampass.c +++ b/source3/auth/pampass.c @@ -63,6 +63,7 @@ typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_resp * Macros to help make life easy */ #define COPY_STRING(s) (s) ? SMB_STRDUP(s) : NULL +#define COPY_FSTRING(s) (s[0]) ? SMB_STRDUP(s) : NULL /******************************************************************* PAM error handler. @@ -327,7 +328,7 @@ static int smb_pam_passchange_conv(int num_msg, DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actualy sent: %s\n", current_reply)); #endif reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(current_reply); + reply[replies].resp = COPY_FSTRING(current_reply); found = True; break; } @@ -355,7 +356,7 @@ static int smb_pam_passchange_conv(int num_msg, DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply)); pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(current_reply); + reply[replies].resp = COPY_FSTRING(current_reply); #ifdef DEBUG_PASSWORD DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actualy sent: %s\n", current_reply)); #endif diff --git a/source3/client/cifs.upcall.c b/source3/client/cifs.upcall.c index aa5eb57310..7cb51660d7 100644 --- a/source3/client/cifs.upcall.c +++ b/source3/client/cifs.upcall.c @@ -29,7 +29,7 @@ create dns_resolver * * /usr/local/sbin/cifs.upcall %k #include "cifs_spnego.h" -const char *CIFSSPNEGO_VERSION = "1.1"; +const char *CIFSSPNEGO_VERSION = "1.2"; static const char *prog = "cifs.upcall"; typedef enum _secType { KRB5, @@ -73,7 +73,7 @@ int handle_krb5_mech(const char *oid, const char *principal, tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - *secblob = gen_negTokenInit(OID_KERBEROS5, tkt_wrapped); + *secblob = gen_negTokenInit(oid, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); @@ -118,6 +118,9 @@ int decode_key_description(const char *desc, int *ver, secType_t * sec, if (strncmp(tkn + 4, "krb5", 4) == 0) { retval |= DKD_HAVE_SEC; *sec = KRB5; + } else if (strncmp(tkn + 4, "mskrb5", 6) == 0) { + retval |= DKD_HAVE_SEC; + *sec = MS_KRB5; } } else if (strncmp(tkn, "uid=", 4) == 0) { errno = 0; @@ -220,6 +223,7 @@ int main(const int argc, char *const argv[]) int kernel_upcall_version; int c, use_cifs_service_prefix = 0; char *buf, *hostname = NULL; + const char *oid; openlog(prog, 0, LOG_DAEMON); @@ -280,7 +284,7 @@ int main(const int argc, char *const argv[]) } SAFE_FREE(buf); - if (kernel_upcall_version != CIFS_SPNEGO_UPCALL_VERSION) { + if (kernel_upcall_version > CIFS_SPNEGO_UPCALL_VERSION) { syslog(LOG_WARNING, "incompatible kernel upcall version: 0x%x", kernel_upcall_version); @@ -301,6 +305,7 @@ int main(const int argc, char *const argv[]) // do mech specific authorization switch (sectype) { + case MS_KRB5: case KRB5:{ char *princ; size_t len; @@ -319,8 +324,12 @@ int main(const int argc, char *const argv[]) } strlcpy(princ + 5, hostname, len - 5); - rc = handle_krb5_mech(OID_KERBEROS5, princ, - &secblob, &sess_key); + if (sectype == MS_KRB5) + oid = OID_KERBEROS5_OLD; + else + oid = OID_KERBEROS5; + + rc = handle_krb5_mech(oid, princ, &secblob, &sess_key); SAFE_FREE(princ); break; } @@ -344,7 +353,7 @@ int main(const int argc, char *const argv[]) rc = 1; goto out; } - keydata->version = CIFS_SPNEGO_UPCALL_VERSION; + keydata->version = kernel_upcall_version; keydata->flags = 0; keydata->sesskey_len = sess_key.length; keydata->secblob_len = secblob.length; diff --git a/source3/client/cifs_spnego.h b/source3/client/cifs_spnego.h index 13909dd505..f8753a7d59 100644 --- a/source3/client/cifs_spnego.h +++ b/source3/client/cifs_spnego.h @@ -23,7 +23,7 @@ #ifndef _CIFS_SPNEGO_H #define _CIFS_SPNEGO_H -#define CIFS_SPNEGO_UPCALL_VERSION 1 +#define CIFS_SPNEGO_UPCALL_VERSION 2 /* * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION. diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index c7009e306c..dd878aa07b 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -473,7 +473,8 @@ static int parse_options(char ** optionsp, int * filesys_flags) } } else if (strncmp(data, "sec", 3) == 0) { if (value) { - if (!strcmp(value, "none")) + if (!strncmp(value, "none", 4) || + !strncmp(value, "krb5", 4)) got_password = 1; } } else if (strncmp(data, "ip", 2) == 0) { diff --git a/source3/configure.in b/source3/configure.in index c7698590a9..9436fed1ff 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2627,30 +2627,32 @@ AC_CHECK_FUNCS(getpagesize) ################################################ # look for a method of setting the effective uid seteuid=no; + if test $seteuid = no; then -AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ +AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ AC_TRY_RUN([ #define AUTOCONF_TEST 1 -#define USE_SETRESUID 1 +#define USE_SETREUID 1 #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) -if test x"$samba_cv_USE_SETRESUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) + samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) +if test x"$samba_cv_USE_SETREUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) fi fi - +# we check for setresuid second as it conflicts with AIO on Linux. +# see http://samba.org/~tridge/junkcode/aio_uid.c if test $seteuid = no; then -AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ +AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ AC_TRY_RUN([ #define AUTOCONF_TEST 1 -#define USE_SETREUID 1 +#define USE_SETRESUID 1 #include "confdefs.h" #include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) -if test x"$samba_cv_USE_SETREUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) + samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) +if test x"$samba_cv_USE_SETRESUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) fi fi @@ -4048,7 +4050,7 @@ INSTALL_CIFSUPCALL="" UNINSTALL_CIFSUPCALL="" AC_MSG_CHECKING(whether to build cifs.upcall) AC_ARG_WITH(cifsupcall, -[AS_HELP_STRING([--with-cifsupcall], [Include cifs.upcall (Linux only) support (default=no)])], +[AS_HELP_STRING([--with-cifsupcall], [Include cifs.upcall (Linux only) support (default=yes)])], [ case "$withval" in no) AC_MSG_RESULT(no) @@ -4074,9 +4076,24 @@ AC_ARG_WITH(cifsupcall, esac ;; esac ], -[ - AC_MSG_RESULT(no) - ] +[ case "$host_os" in + *linux*) + if test x"$use_ads" != x"yes"; then + AC_MSG_WARN(ADS support should be enabled for building cifs.upcall) + elif test x"$HAVE_KEYUTILS_H" != "x1"; then + AC_MSG_WARN(keyutils package is required for cifs.upcall) + else + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_CIFSUPCALL,1,[whether to build cifs.upcall]) + CIFSUPCALL_PROGS="bin/cifs.upcall" + INSTALL_CIFSUPCALL="installcifsupcall" + UNINSTALL_CIFSUPCALL="uninstallcifsupcall" + fi + ;; + *) + AC_MSG_RESULT(no) + ;; + esac ] ) @@ -6149,6 +6166,7 @@ AC_OUTPUT(Makefile pkgconfig/wbclient.pc pkgconfig/netapi.pc pkgconfig/smbsharemodes.pc + ../examples/libsmbclient/Makefile.internal ) ################################################# diff --git a/source3/exports/libsmbclient.syms b/source3/exports/libsmbclient.syms deleted file mode 100644 index 3062e34bfd..0000000000 --- a/source3/exports/libsmbclient.syms +++ /dev/null @@ -1,4 +0,0 @@ -{ - global: smbc_*; - local: *; -}; diff --git a/source3/exports/libsmbsharemodes.syms b/source3/exports/libsmbsharemodes.syms deleted file mode 100644 index eb34bfc012..0000000000 --- a/source3/exports/libsmbsharemodes.syms +++ /dev/null @@ -1,3 +0,0 @@ -{ - global: *; -}; diff --git a/source3/include/proto.h b/source3/include/proto.h index 2d9734873e..d757b2db80 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -623,7 +623,7 @@ bool is_local_net(const struct sockaddr_storage *from); void setup_linklocal_scope_id(struct sockaddr_storage *pss); bool is_local_net_v4(struct in_addr from); int iface_count(void); -int iface_count_v4(void); +int iface_count_v4_nl(void); const struct in_addr *first_ipv4_iface(void); struct interface *get_interface(int n); const struct sockaddr_storage *iface_n_sockaddr_storage(int n); @@ -6049,6 +6049,7 @@ int lp_directory_name_cache_size(int ); int lp_smb_encrypt(int ); char lp_magicchar(const struct share_params *p ); int lp_winbind_cache_time(void); +int lp_winbind_reconnect_delay(void); const char **lp_winbind_nss_info(void); int lp_algorithmic_rid_base(void); int lp_name_cache_timeout(void); diff --git a/source3/include/smb.h b/source3/include/smb.h index b8ff34f831..c8c4f8c3cc 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1330,12 +1330,19 @@ struct bitmap { #define FILE_DELETE_ON_CLOSE 0x1000 #define FILE_OPEN_BY_FILE_ID 0x2000 -/* Private create options used by the ntcreatex processing code. From Samba4. */ -#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000 -#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000 +#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK (0x008F0480) + +#define NTCREATEX_OPTIONS_INVALID_PARAM_MASK (0xFF100030) + +/* + * Private create options used by the ntcreatex processing code. From Samba4. + * We reuse some ignored flags for private use. + */ +#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x00010000 +#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x00020000 /* Private options for streams support */ -#define NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE 0x04000000 +#define NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE 0x00040000 /* Responses when opening a file. */ #define FILE_WAS_SUPERSEDED 0 diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 7c1ef8fed8..63a5ce4de6 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. Database interface wrapper around ctdbd Copyright (C) Volker Lendecke 2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -76,7 +76,7 @@ static NTSTATUS tdb_error_to_ntstatus(struct tdb_context *tdb) /* form a ctdb_rec_data record from a key/data pair - + note that header may be NULL. If not NULL then it is included in the data portion of the record */ @@ -130,7 +130,8 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, } if (m == NULL) { - m = talloc_zero_size(mem_ctx, offsetof(struct ctdb_marshall_buffer, data)); + m = (struct ctdb_marshall_buffer *)talloc_zero_size( + mem_ctx, offsetof(struct ctdb_marshall_buffer, data)); if (m == NULL) { return NULL; } @@ -140,7 +141,8 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, m_size = talloc_get_size(m); r_size = talloc_get_size(r); - m2 = talloc_realloc_size(mem_ctx, m, m_size + r_size); + m2 = (struct ctdb_marshall_buffer *)talloc_realloc_size( + mem_ctx, m, m_size + r_size); if (m2 == NULL) { talloc_free(m); return NULL; @@ -166,7 +168,7 @@ static TDB_DATA db_ctdb_marshall_finish(struct ctdb_marshall_buffer *m) /* loop over a marshalling buffer - + - pass r==NULL to start - loop the number of times indicated by m->count */ @@ -184,7 +186,7 @@ static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buf if (reqid != NULL) { *reqid = r->reqid; } - + if (key != NULL) { key->dptr = &r->data[0]; key->dsize = r->keylen; @@ -228,7 +230,7 @@ static int db_ctdb_transaction_fetch_start(struct db_ctdb_transaction_handle *h) struct db_ctdb_ctx *ctx = h->ctx; TDB_DATA data; - key.dptr = discard_const(keyname); + key.dptr = (uint8_t *)discard_const(keyname); key.dsize = strlen(keyname); again: @@ -483,16 +485,16 @@ static int db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h, return -1; } } - + h->m_write = db_ctdb_marshall_add(h, h->m_write, h->ctx->db_id, 0, key, &header, data); if (h->m_write == NULL) { DEBUG(0,(__location__ " Failed to add to marshalling record\n")); talloc_free(tmp_ctx); return -1; } - + rec.dsize = data.dsize + sizeof(struct ctdb_ltdb_header); - rec.dptr = talloc_size(tmp_ctx, rec.dsize); + rec.dptr = (uint8_t *)talloc_size(tmp_ctx, rec.dsize); if (rec.dptr == NULL) { DEBUG(0,(__location__ " Failed to alloc record\n")); talloc_free(tmp_ctx); @@ -504,7 +506,7 @@ static int db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h, ret = tdb_store(h->ctx->wtdb->tdb, key, rec, TDB_REPLACE); talloc_free(tmp_ctx); - + return ret; } @@ -590,7 +592,7 @@ static int ctdb_replay_transaction(struct db_ctdb_transaction_handle *h) talloc_free(tmp_ctx); } } - + return 0; failed: @@ -868,7 +870,7 @@ again: (int)crec->ctdb_ctx->db_id, keystr)); TALLOC_FREE(keystr); } - + if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { DEBUG(3, ("tdb_chainlock failed\n")); TALLOC_FREE(result); diff --git a/source3/winbindd/idmap_cache.c b/source3/lib/idmap_cache.c index 496f70ab45..6377635a65 100644 --- a/source3/winbindd/idmap_cache.c +++ b/source3/lib/idmap_cache.c @@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.*/ #include "includes.h" -#include "winbindd.h" /** * Find a sid2uid mapping diff --git a/source3/lib/interface.c b/source3/lib/interface.c index eb0af9ef34..2e7c2706a0 100644 --- a/source3/lib/interface.c +++ b/source3/lib/interface.c @@ -131,15 +131,18 @@ int iface_count(void) } /**************************************************************************** - How many interfaces do we have (v4 only) ? + How many non-loopback IPv4 interfaces do we have ? **************************************************************************/ -int iface_count_v4(void) +int iface_count_v4_nl(void) { int ret = 0; struct interface *i; for (i=local_interfaces;i;i=i->next) { + if (is_loopback_addr(&i->ip)) { + continue; + } if (i->ip.ss_family == AF_INET) { ret++; } diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 5f26cc80f8..9f952abf10 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2008,6 +2008,7 @@ bool str_list_sub_basic( char **list, const char *smb_name, bool str_list_substitute(char **list, const char *pattern, const char *insert) { + TALLOC_CTX *ctx = list; char *p, *s, *t; ssize_t ls, lp, li, ld, i, d; @@ -2030,7 +2031,7 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert) t = *list; d = p -t; if (ld) { - t = (char *) SMB_MALLOC(ls +ld +1); + t = TALLOC_ARRAY(ctx, char, ls +ld +1); if (!t) { DEBUG(0,("str_list_substitute: " "Unable to allocate memory")); @@ -2038,7 +2039,7 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert) } memcpy(t, *list, d); memcpy(t +d +li, p +lp, ls -d -lp +1); - SAFE_FREE(*list); + TALLOC_FREE(*list); *list = t; ls += ld; s = t +d +li; diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b59dab1f13..eb45e3a0dd 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -393,9 +393,6 @@ static NTSTATUS ads_lookup_site(void) ADS_STRUCT *ads = NULL; ADS_STATUS ads_status; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct nbt_cldap_netlogon_5 cldap_reply; - - ZERO_STRUCT(cldap_reply); ads = ads_init(lp_realm(), NULL, NULL); if (!ads) { diff --git a/source3/librpc/gen_ndr/cli_netlogon.c b/source3/librpc/gen_ndr/cli_netlogon.c index 2ddb165bec..d6ac8b9ede 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.c +++ b/source3/librpc/gen_ndr/cli_netlogon.c @@ -1504,9 +1504,9 @@ NTSTATUS rpccli_netr_ServerPasswordSet2(struct rpc_pipe_client *cli, const char *account_name /* [in] [charset(UTF16)] */, enum netr_SchannelType secure_channel_type /* [in] */, const char *computer_name /* [in] [charset(UTF16)] */, - struct netr_Authenticator credential /* [in] */, - struct netr_CryptPassword new_password /* [in] */, - struct netr_Authenticator *return_authenticator /* [out] [ref] */) + struct netr_Authenticator *credential /* [in] [ref] */, + struct netr_Authenticator *return_authenticator /* [out] [ref] */, + struct netr_CryptPassword *new_password /* [in] [ref] */) { struct netr_ServerPasswordSet2 r; NTSTATUS status; diff --git a/source3/librpc/gen_ndr/cli_netlogon.h b/source3/librpc/gen_ndr/cli_netlogon.h index 296873274e..2033315a5d 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.h +++ b/source3/librpc/gen_ndr/cli_netlogon.h @@ -239,9 +239,9 @@ NTSTATUS rpccli_netr_ServerPasswordSet2(struct rpc_pipe_client *cli, const char *account_name /* [in] [charset(UTF16)] */, enum netr_SchannelType secure_channel_type /* [in] */, const char *computer_name /* [in] [charset(UTF16)] */, - struct netr_Authenticator credential /* [in] */, - struct netr_CryptPassword new_password /* [in] */, - struct netr_Authenticator *return_authenticator /* [out] [ref] */); + struct netr_Authenticator *credential /* [in] [ref] */, + struct netr_Authenticator *return_authenticator /* [out] [ref] */, + struct netr_CryptPassword *new_password /* [in] [ref] */); NTSTATUS rpccli_netr_ServerPasswordGet(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_name /* [in] [unique,charset(UTF16)] */, diff --git a/source3/librpc/gen_ndr/krb5pac.h b/source3/librpc/gen_ndr/krb5pac.h index 2d799ea7c7..b3b29e5b2f 100644 --- a/source3/librpc/gen_ndr/krb5pac.h +++ b/source3/librpc/gen_ndr/krb5pac.h @@ -76,7 +76,7 @@ union PAC_INFO { struct PAC_SIGNATURE_DATA srv_cksum;/* [case(PAC_TYPE_SRV_CHECKSUM)] */ struct PAC_SIGNATURE_DATA kdc_cksum;/* [case(PAC_TYPE_KDC_CHECKSUM)] */ struct PAC_LOGON_NAME logon_name;/* [case(PAC_TYPE_LOGON_NAME)] */ - struct DATA_BLOB_REM unknown;/* [subcontext(0),case(PAC_TYPE_UNKNOWN_12)] */ + struct DATA_BLOB_REM unknown;/* [subcontext(0),default] */ }/* [gensize,nodiscriminant,public] */; struct PAC_BUFFER { diff --git a/source3/librpc/gen_ndr/ndr_krb5pac.c b/source3/librpc/gen_ndr/ndr_krb5pac.c index 70d63aee91..6e06f90a68 100644 --- a/source3/librpc/gen_ndr/ndr_krb5pac.c +++ b/source3/librpc/gen_ndr/ndr_krb5pac.c @@ -319,7 +319,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_PAC_INFO(struct ndr_push *ndr, int ndr_flags NDR_CHECK(ndr_push_PAC_LOGON_NAME(ndr, NDR_SCALARS, &r->logon_name)); break; } - case PAC_TYPE_UNKNOWN_12: { + default: { { struct ndr_push *_ndr_unknown; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_unknown, 0, -1)); @@ -328,8 +328,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_PAC_INFO(struct ndr_push *ndr, int ndr_flags } break; } - default: - return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } if (ndr_flags & NDR_BUFFERS) { @@ -348,11 +346,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_PAC_INFO(struct ndr_push *ndr, int ndr_flags case PAC_TYPE_LOGON_NAME: break; - case PAC_TYPE_UNKNOWN_12: + default: break; - default: - return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } return NDR_ERR_SUCCESS; @@ -380,7 +376,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_PAC_INFO(struct ndr_pull *ndr, int ndr_flags NDR_CHECK(ndr_pull_PAC_LOGON_NAME(ndr, NDR_SCALARS, &r->logon_name)); break; } - case PAC_TYPE_UNKNOWN_12: { + default: { { struct ndr_pull *_ndr_unknown; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_unknown, 0, -1)); @@ -389,8 +385,6 @@ _PUBLIC_ enum ndr_err_code ndr_pull_PAC_INFO(struct ndr_pull *ndr, int ndr_flags } break; } - default: - return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } if (ndr_flags & NDR_BUFFERS) { @@ -408,11 +402,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_PAC_INFO(struct ndr_pull *ndr, int ndr_flags case PAC_TYPE_LOGON_NAME: break; - case PAC_TYPE_UNKNOWN_12: + default: break; - default: - return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } return NDR_ERR_SUCCESS; @@ -440,12 +432,10 @@ _PUBLIC_ void ndr_print_PAC_INFO(struct ndr_print *ndr, const char *name, const ndr_print_PAC_LOGON_NAME(ndr, "logon_name", &r->logon_name); break; - case PAC_TYPE_UNKNOWN_12: + default: ndr_print_DATA_BLOB_REM(ndr, "unknown", &r->unknown); break; - default: - ndr_print_bad_level(ndr, name, level); } } diff --git a/source3/librpc/gen_ndr/ndr_netlogon.c b/source3/librpc/gen_ndr/ndr_netlogon.c index ba05ebc03f..b43a157997 100644 --- a/source3/librpc/gen_ndr/ndr_netlogon.c +++ b/source3/librpc/gen_ndr/ndr_netlogon.c @@ -12310,8 +12310,14 @@ static enum ndr_err_code ndr_push_netr_ServerPasswordSet2(struct ndr_push *ndr, NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.computer_name, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computer_name, ndr_charset_length(r->in.computer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); - NDR_CHECK(ndr_push_netr_CryptPassword(ndr, NDR_SCALARS, &r->in.new_password)); + if (r->in.credential == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + if (r->in.new_password == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_CryptPassword(ndr, NDR_SCALARS, r->in.new_password)); } if (flags & NDR_OUT) { if (r->out.return_authenticator == NULL) { @@ -12327,7 +12333,9 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordSet2(struct ndr_pull *ndr, { uint32_t _ptr_server_name; TALLOC_CTX *_mem_save_server_name_0; + TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; + TALLOC_CTX *_mem_save_new_password_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -12364,8 +12372,20 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordSet2(struct ndr_pull *ndr, } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.computer_name), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.computer_name, ndr_get_array_length(ndr, &r->in.computer_name), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); - NDR_CHECK(ndr_pull_netr_CryptPassword(ndr, NDR_SCALARS, &r->in.new_password)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.credential); + } + _mem_save_credential_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.credential, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credential_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.new_password); + } + _mem_save_new_password_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.new_password, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_CryptPassword(ndr, NDR_SCALARS, r->in.new_password)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_new_password_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC(ndr, r->out.return_authenticator); ZERO_STRUCTP(r->out.return_authenticator); } @@ -12401,8 +12421,14 @@ _PUBLIC_ void ndr_print_netr_ServerPasswordSet2(struct ndr_print *ndr, const cha ndr_print_string(ndr, "account_name", r->in.account_name); ndr_print_netr_SchannelType(ndr, "secure_channel_type", r->in.secure_channel_type); ndr_print_string(ndr, "computer_name", r->in.computer_name); - ndr_print_netr_Authenticator(ndr, "credential", &r->in.credential); - ndr_print_netr_CryptPassword(ndr, "new_password", &r->in.new_password); + ndr_print_ptr(ndr, "credential", r->in.credential); + ndr->depth++; + ndr_print_netr_Authenticator(ndr, "credential", r->in.credential); + ndr->depth--; + ndr_print_ptr(ndr, "new_password", r->in.new_password); + ndr->depth++; + ndr_print_netr_CryptPassword(ndr, "new_password", r->in.new_password); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { diff --git a/source3/librpc/gen_ndr/netlogon.h b/source3/librpc/gen_ndr/netlogon.h index 9e8605110f..1cea1f0f42 100644 --- a/source3/librpc/gen_ndr/netlogon.h +++ b/source3/librpc/gen_ndr/netlogon.h @@ -1355,8 +1355,8 @@ struct netr_ServerPasswordSet2 { const char *account_name;/* [charset(UTF16)] */ enum netr_SchannelType secure_channel_type; const char *computer_name;/* [charset(UTF16)] */ - struct netr_Authenticator credential; - struct netr_CryptPassword new_password; + struct netr_Authenticator *credential;/* [ref] */ + struct netr_CryptPassword *new_password;/* [ref] */ } in; struct { diff --git a/source3/librpc/idl/krb5pac.idl b/source3/librpc/idl/krb5pac.idl index 7c2f72d3cb..c039502d23 100644 --- a/source3/librpc/idl/krb5pac.idl +++ b/source3/librpc/idl/krb5pac.idl @@ -70,7 +70,7 @@ interface krb5pac [case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum; [case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum; [case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name; - [case(PAC_TYPE_UNKNOWN_12)] [subcontext(0)] DATA_BLOB_REM unknown; + [default] [subcontext(0)] DATA_BLOB_REM unknown; /* [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; */ } PAC_INFO; diff --git a/source3/librpc/idl/netlogon.idl b/source3/librpc/idl/netlogon.idl index 98cf1e7d32..74535fc073 100644 --- a/source3/librpc/idl/netlogon.idl +++ b/source3/librpc/idl/netlogon.idl @@ -1182,9 +1182,9 @@ interface netlogon [in] [string,charset(UTF16)] uint16 account_name[], [in] netr_SchannelType secure_channel_type, [in] [string,charset(UTF16)] uint16 computer_name[], - [in] netr_Authenticator credential, - [in] netr_CryptPassword new_password, - [out,ref] netr_Authenticator *return_authenticator + [in,ref] netr_Authenticator *credential, + [out,ref] netr_Authenticator *return_authenticator, + [in,ref] netr_CryptPassword *new_password ); /****************/ diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5bb33b11d7..fa21ad3467 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1910,7 +1910,7 @@ static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, } /* We now have a service ticket, now turn it into an AP-REQ. */ - authenticator->length = ntohs(fwdData.length + GSSAPI_CHECKSUM_SIZE); + authenticator->length = fwdData.length + GSSAPI_CHECKSUM_SIZE; /* Caller should call free() when they're done with this. */ authenticator->data = (char *)pChksum; diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index f4fdf9eb6f..08a49930b4 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -31,34 +31,60 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, const unsigned char new_trust_passwd_hash[16], uint32 sec_channel_type) { NTSTATUS result; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - /* Check if the netlogon pipe is open using schannel. If so we - already have valid creds. If not we must set them up. */ - - if (cli->auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - - result = rpccli_netlogon_setup_creds(cli, - cli->desthost, /* server name */ - lp_workgroup(), /* domain */ - global_myname(), /* client name */ - global_myname(), /* machine account name */ - orig_trust_passwd_hash, - sec_channel_type, - &neg_flags); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } + result = rpccli_netlogon_setup_creds(cli, + cli->desthost, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ + orig_trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; } - { + if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { + + struct netr_Authenticator clnt_creds, srv_cred; + struct netr_CryptPassword new_password; + struct samr_CryptPassword password_buf; + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + encode_pw_buffer(password_buf.data, new_trust_pwd_cleartext, STR_UNICODE); + + SamOEMhash(password_buf.data, cli->dc->sess_key, 516); + memcpy(new_password.data, password_buf.data, 512); + new_password.length = IVAL(password_buf.data, 512); + + result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet2: " + "credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + } else { + struct netr_Authenticator clnt_creds, srv_cred; struct samr_Password new_password; @@ -118,8 +144,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m E_md4hash(new_trust_passwd, new_trust_passwd_hash); - nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash, sec_channel_type); + nt_status = just_change_the_password(cli, mem_ctx, + orig_trust_passwd_hash, + new_trust_passwd, + new_trust_passwd_hash, + sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4 index 53ad46cb8d..9a4213d976 100644 --- a/source3/m4/aclocal.m4 +++ b/source3/m4/aclocal.m4 @@ -139,7 +139,7 @@ if eval test x"$build_lib" = "xyes" ; then LIBUC[_SHARED]=$LIBUC[_SHARED_TARGET] AC_MSG_RESULT(yes) if test x"$USESHARED" != x"true" -o x"$[LINK_]LIBUC" = "xSTATIC" ; then - LIBUC[_STATIC]=$LIBUC[_STATIC_TARGET] + enable_static=yes else LIBUC[_LIBS]=LIBLIBS fi @@ -152,7 +152,7 @@ else AC_MSG_RESULT(shared library not selected, but will supply static library) fi if test $enable_static = yes; then - LIBUC[_STATIC]=$LIBUC[_STATIC_TARGET] + LIBUC[_STATIC]=[\$\(]LIBUC[_OBJ0\)] fi m4_popdef([LIBNAME]) diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c index 4a732bca43..ee958b1be5 100644 --- a/source3/modules/vfs_tsmsm.c +++ b/source3/modules/vfs_tsmsm.c @@ -200,9 +200,9 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle, goto done; } - lerrno = 0; - do { + lerrno = 0; + ret = dm_get_dmattr(*dmsession_id, dmhandle, dmhandle_len, DM_NO_TOKEN, &dmname, buflen, buf, &rlen); if (ret == -1 && errno == EINVAL) { @@ -279,10 +279,13 @@ static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_s static ssize_t tsmsm_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, const DATA_BLOB *hdr, SMB_OFF_T offset, size_t n) { - bool file_online = tsmsm_aio_force(handle, fsp); + bool file_offline = tsmsm_aio_force(handle, fsp); - if(!file_online) - return ENOSYS; + if (file_offline) { + DEBUG(10,("tsmsm_sendfile on offline file - rejecting\n")); + errno = ENOSYS; + return -1; + } return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, hdr, offset, n); } @@ -333,7 +336,7 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle, if (tsmd->hsmscript == NULL) { /* no script enabled */ - DEBUG(1, ("tsmsm_set_offline: No tsmsm:hsmscript configured\n")); + DEBUG(1, ("tsmsm_set_offline: No 'tsmsm:hsm script' configured\n")); return 0; } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 83005f05bd..d9f2af4c10 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -296,8 +296,8 @@ static void reload_interfaces(time_t t) BlockSignals(false, SIGTERM); - /* We only count IPv4 interfaces here. */ - while (iface_count_v4() == 0 && !got_sig_term) { + /* We only count IPv4, non-loopback interfaces here. */ + while (iface_count_v4_nl() == 0 && !got_sig_term) { sleep(5); load_interfaces(); } diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index f7990def07..474ae1ca18 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -434,7 +434,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", char *component, *dc, *q1; char *q_orig = q; int str_offset; - char *saveptr; + char *saveptr = NULL; domain = get_mydnsdomname(talloc_tos()); if (!domain) { diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c index a4422d27d5..225def52cc 100644 --- a/source3/nmbd/nmbd_subnetdb.c +++ b/source3/nmbd/nmbd_subnetdb.c @@ -195,19 +195,20 @@ struct subnet_record *make_normal_subnet(const struct interface *iface) bool create_subnets(void) { /* We only count IPv4 interfaces whilst we're waiting. */ - int num_interfaces = iface_count_v4(); + int num_interfaces; int i; struct in_addr unicast_ip, ipzero; try_interfaces_again: - if (iface_count_v4() == 0) { - DEBUG(0,("create_subnets: No local interfaces !\n")); + /* Only count IPv4, non-loopback interfaces. */ + if (iface_count_v4_nl() == 0) { + DEBUG(0,("create_subnets: No local IPv4 non-loopback interfaces !\n")); DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n")); } - /* We only count IPv4 interfaces here. */ - while (iface_count_v4() == 0) { + /* We only count IPv4, non-loopback interfaces here. */ + while (iface_count_v4_nl() == 0) { void (*saved_handler)(int); /* diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 95b3d23dd4..c28c5d2697 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -12,6 +12,78 @@ #include "pam_winbind.h" +static const char *_pam_error_code_str(int err) +{ + switch (err) { + case PAM_SUCCESS: + return "PAM_SUCCESS"; + case PAM_OPEN_ERR: + return "PAM_OPEN_ERR"; + case PAM_SYMBOL_ERR: + return "PAM_SYMBOL_ERR"; + case PAM_SERVICE_ERR: + return "PAM_SERVICE_ERR"; + case PAM_SYSTEM_ERR: + return "PAM_SYSTEM_ERR"; + case PAM_BUF_ERR: + return "PAM_BUF_ERR"; + case PAM_PERM_DENIED: + return "PAM_PERM_DENIED"; + case PAM_AUTH_ERR: + return "PAM_AUTH_ERR"; + case PAM_CRED_INSUFFICIENT: + return "PAM_CRED_INSUFFICIENT"; + case PAM_AUTHINFO_UNAVAIL: + return "PAM_AUTHINFO_UNAVAIL"; + case PAM_USER_UNKNOWN: + return "PAM_USER_UNKNOWN"; + case PAM_MAXTRIES: + return "PAM_MAXTRIES"; + case PAM_NEW_AUTHTOK_REQD: + return "PAM_NEW_AUTHTOK_REQD"; + case PAM_ACCT_EXPIRED: + return "PAM_ACCT_EXPIRED"; + case PAM_SESSION_ERR: + return "PAM_SESSION_ERR"; + case PAM_CRED_UNAVAIL: + return "PAM_CRED_UNAVAIL"; + case PAM_CRED_EXPIRED: + return "PAM_CRED_EXPIRED"; + case PAM_CRED_ERR: + return "PAM_CRED_ERR"; + case PAM_NO_MODULE_DATA: + return "PAM_NO_MODULE_DATA"; + case PAM_CONV_ERR: + return "PAM_CONV_ERR"; + case PAM_AUTHTOK_ERR: + return "PAM_AUTHTOK_ERR"; + case PAM_AUTHTOK_RECOVERY_ERR: + return "PAM_AUTHTOK_RECOVERY_ERR"; + case PAM_AUTHTOK_LOCK_BUSY: + return "PAM_AUTHTOK_LOCK_BUSY"; + case PAM_AUTHTOK_DISABLE_AGING: + return "PAM_AUTHTOK_DISABLE_AGING"; + case PAM_TRY_AGAIN: + return "PAM_TRY_AGAIN"; + case PAM_IGNORE: + return "PAM_IGNORE"; + case PAM_ABORT: + return "PAM_ABORT"; + case PAM_AUTHTOK_EXPIRED: + return "PAM_AUTHTOK_EXPIRED"; + case PAM_MODULE_UNKNOWN: + return "PAM_MODULE_UNKNOWN"; + case PAM_BAD_ITEM: + return "PAM_BAD_ITEM"; + case PAM_CONV_AGAIN: + return "PAM_CONV_AGAIN"; + case PAM_INCOMPLETE: + return "PAM_INCOMPLETE"; + default: + return NULL; + } +} + #define _PAM_LOG_FUNCTION_ENTER(function, ctx) \ do { \ _pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] ENTER: " \ @@ -22,7 +94,8 @@ #define _PAM_LOG_FUNCTION_LEAVE(function, ctx, retval) \ do { \ _pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] LEAVE: " \ - function " returning %d", ctx->pamh, retval); \ + function " returning %d (%s)", ctx->pamh, retval, \ + _pam_error_code_str(retval)); \ _pam_log_state(ctx); \ } while (0) @@ -698,8 +771,7 @@ static int pam_winbind_request_log(struct pwb_context *ctx, /** * send a password expiry message if required * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param next_change expected (calculated) next expiry date. * @param already_expired pointer to a boolean to indicate if the password is * already expired. @@ -760,8 +832,7 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx, /** * Send a warning if the password expires in the near future * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param response The full authentication response structure. * @param already_expired boolean, is the pwd already expired? * @@ -850,8 +921,7 @@ static bool safe_append_string(char *dest, /** * Convert a names into a SID string, appending it to a buffer. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param user User in PAM request. * @param name Name to convert. * @param sid_list_buffer Where to append the string sid. @@ -906,8 +976,7 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx, /** * Convert a list of names into a list of sids. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param user User in PAM request. * @param name_list List of names or string sids, separated by commas. * @param sid_list_buffer Where to put the list of string sids. @@ -971,8 +1040,7 @@ out: /** * put krb5ccname variable into environment * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param krb5ccname env variable retrieved from winbindd. * * @return void. @@ -1010,8 +1078,7 @@ static void _pam_setup_krb5_env(struct pwb_context *ctx, /** * Set string into the PAM stack. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param data_name Key name for pam_set_data. * @param value String value. * @@ -1042,8 +1109,7 @@ static void _pam_set_data_string(struct pwb_context *ctx, /** * Set info3 strings into the PAM stack. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param data_name Key name for pam_set_data. * @param value String value. * @@ -1082,8 +1148,7 @@ static void _pam_free_data_info3(pam_handle_t *pamh) /** * Send PAM_ERROR_MSG for cached or grace logons. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param username User in PAM request. * @param info3_user_flgs Info3 flags containing logon type bits. * @@ -1120,8 +1185,7 @@ static void _pam_warn_logon_type(struct pwb_context *ctx, /** * Send PAM_ERROR_MSG for krb5 errors. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param username User in PAM request. * @param info3_user_flgs Info3 flags containing logon type bits. * @@ -1869,8 +1933,7 @@ static int get_warn_pwd_expire_from_config(struct pwb_context *ctx) /** * Retrieve the winbind separator. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * * @return string separator character. NULL on failure. */ @@ -1894,8 +1957,7 @@ static char winbind_get_separator(struct pwb_context *ctx) /** * Convert a upn to a name. * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param upn USer UPN to be trabslated. * * @return converted name. NULL pointer on failure. Caller needs to free. @@ -2370,8 +2432,7 @@ out: * evaluate whether we need to re-authenticate with kerberos after a * password change * - * @param pamh PAM handle - * @param ctrl PAM winbind options. + * @param ctx PAM winbind context. * @param user The username * * @return boolean Returns true if required, false if not. diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index be17a6fe45..c8c1910641 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -83,20 +83,20 @@ do { \ #include <security/pam_ext.h> #endif -#define WINBIND_DEBUG_ARG (1<<0) -#define WINBIND_USE_AUTHTOK_ARG (1<<1) -#define WINBIND_UNKNOWN_OK_ARG (1<<2) -#define WINBIND_TRY_FIRST_PASS_ARG (1<<3) -#define WINBIND_USE_FIRST_PASS_ARG (1<<4) -#define WINBIND__OLD_PASSWORD (1<<5) -#define WINBIND_REQUIRED_MEMBERSHIP (1<<6) -#define WINBIND_KRB5_AUTH (1<<7) -#define WINBIND_KRB5_CCACHE_TYPE (1<<8) -#define WINBIND_CACHED_LOGIN (1<<9) -#define WINBIND_CONFIG_FILE (1<<10) -#define WINBIND_SILENT (1<<11) -#define WINBIND_DEBUG_STATE (1<<12) -#define WINBIND_WARN_PWD_EXPIRE (1<<13) +#define WINBIND_DEBUG_ARG 0x00000001 +#define WINBIND_USE_AUTHTOK_ARG 0x00000002 +#define WINBIND_UNKNOWN_OK_ARG 0x00000004 +#define WINBIND_TRY_FIRST_PASS_ARG 0x00000008 +#define WINBIND_USE_FIRST_PASS_ARG 0x00000010 +#define WINBIND__OLD_PASSWORD 0x00000020 +#define WINBIND_REQUIRED_MEMBERSHIP 0x00000040 +#define WINBIND_KRB5_AUTH 0x00000080 +#define WINBIND_KRB5_CCACHE_TYPE 0x00000100 +#define WINBIND_CACHED_LOGIN 0x00000200 +#define WINBIND_CONFIG_FILE 0x00000400 +#define WINBIND_SILENT 0x00000800 +#define WINBIND_DEBUG_STATE 0x00001000 +#define WINBIND_WARN_PWD_EXPIRE 0x00002000 /* * here is the string to inform the user that the new passwords they diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index b113fc3336..6e6d2bbbf8 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -176,11 +176,13 @@ static int winbind_named_pipe_sock(const char *dir) /* Check permissions on unix socket directory */ if (lstat(dir, &st) == -1) { + errno = ENOENT; return -1; } if (!S_ISDIR(st.st_mode) || (st.st_uid != 0 && st.st_uid != geteuid())) { + errno = ENOENT; return -1; } @@ -199,6 +201,7 @@ static int winbind_named_pipe_sock(const char *dir) the winbindd daemon is not running. */ if (lstat(path, &st) == -1) { + errno = ENOENT; SAFE_FREE(path); return -1; } @@ -208,6 +211,7 @@ static int winbind_named_pipe_sock(const char *dir) if (!S_ISSOCK(st.st_mode) || (st.st_uid != 0 && st.st_uid != geteuid())) { + errno = ENOENT; return -1; } @@ -368,6 +372,7 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv) restart: if (winbind_open_pipe_sock(recursing, need_priv) == -1) { + errno = ENOENT; return -1; } @@ -564,7 +569,11 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv, if (winbind_write_sock(request, sizeof(*request), request->wb_flags & WBFLAG_RECURSE, - need_priv) == -1) { + need_priv) == -1) + { + /* Set ENOENT for consistency. Required by some apps */ + errno = ENOENT; + return NSS_STATUS_UNAVAIL; } @@ -572,7 +581,11 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv, (winbind_write_sock(request->extra_data.data, request->extra_len, request->wb_flags & WBFLAG_RECURSE, - need_priv) == -1)) { + need_priv) == -1)) + { + /* Set ENOENT for consistency. Required by some apps */ + errno = ENOENT; + return NSS_STATUS_UNAVAIL; } @@ -596,6 +609,9 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) /* Wait for reply */ if (winbindd_read_reply(response) == -1) { + /* Set ENOENT for consistency. Required by some apps */ + errno = ENOENT; + return NSS_STATUS_UNAVAIL; } diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index c1d41a53fd..463d9233d0 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -879,6 +879,33 @@ static bool wbinfo_lookupname(const char *full_name) return true; } +static char *wbinfo_prompt_pass(const char *prefix, + const char *username) +{ + char *prompt; + const char *ret = NULL; + + prompt = talloc_asprintf(talloc_tos(), "Enter %s's ", username); + if (!prompt) { + return NULL; + } + if (prefix) { + prompt = talloc_asprintf_append(prompt, "%s ", prefix); + if (!prompt) { + return NULL; + } + } + prompt = talloc_asprintf_append(prompt, "password: "); + if (!prompt) { + return NULL; + } + + ret = getpass(prompt); + TALLOC_FREE(prompt); + + return SMB_STRDUP(ret); +} + /* Authenticate a user with a plaintext password */ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags) @@ -887,6 +914,7 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags) struct winbindd_response response; NSS_STATUS result; char *p; + char *password; /* Send off request */ @@ -900,8 +928,12 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags) fstrcpy(request.data.auth.user, username); fstrcpy(request.data.auth.pass, p + 1); *p = '%'; - } else + } else { fstrcpy(request.data.auth.user, username); + password = wbinfo_prompt_pass(NULL, username); + fstrcpy(request.data.auth.pass, password); + SAFE_FREE(password); + } request.flags = flags; @@ -947,7 +979,7 @@ static bool wbinfo_auth(char *username) wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; char *s = NULL; char *p = NULL; - const char *password = NULL; + char *password = NULL; char *name = NULL; if ((s = SMB_STRDUP(username)) == NULL) { @@ -957,16 +989,9 @@ static bool wbinfo_auth(char *username) if ((p = strchr(s, '%')) != NULL) { *p = 0; p++; - password = p; + password = SMB_STRDUP(p); } else { - char *prompt; - asprintf(&prompt, "Enter %s's password:", username); - if (!prompt) { - return false; - } - - password = getpass(prompt); - SAFE_FREE(prompt); + password = wbinfo_prompt_pass(NULL, username); } name = s; @@ -985,6 +1010,7 @@ static bool wbinfo_auth(char *username) #endif SAFE_FREE(s); + SAFE_FREE(password); return WBC_ERROR_IS_OK(wbc_status); } @@ -1001,26 +1027,18 @@ static bool wbinfo_auth_crap(char *username) DATA_BLOB nt = data_blob_null; fstring name_user; fstring name_domain; - fstring pass; + char *pass; char *p; p = strchr(username, '%'); if (p) { *p = 0; - fstrcpy(pass, p + 1); + pass = SMB_STRDUP(p + 1); } else { - char *prompt; - asprintf(&prompt, "Enter %s's password:", username); - if (!prompt) { - return false; - } - - fstrcpy(pass, getpass(prompt)); - SAFE_FREE(prompt); - + pass = wbinfo_prompt_pass(NULL, username); } - + parse_wbinfo_domain_user(username, name_domain, name_user); params.account_name = name_user; @@ -1049,6 +1067,7 @@ static bool wbinfo_auth_crap(char *username) &lm, &nt, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); + SAFE_FREE(pass); return false; } data_blob_free(&names_blob); @@ -1093,6 +1112,7 @@ static bool wbinfo_auth_crap(char *username) data_blob_free(&nt); data_blob_free(&lm); + SAFE_FREE(pass); return WBC_ERROR_IS_OK(wbc_status); } diff --git a/source3/nsswitch/winbind_nss_solaris.c b/source3/nsswitch/winbind_nss_solaris.c index 5a72393788..865b6ebbb0 100644 --- a/source3/nsswitch/winbind_nss_solaris.c +++ b/source3/nsswitch/winbind_nss_solaris.c @@ -359,7 +359,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response int addrcount = 0; int len = 0; struct in_addr *addrp; +#if defined(AF_INET6) struct in6_addr *addrp6; +#endif int i; /* response is tab separated list of ip addresses with hostname @@ -391,7 +393,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response addrp -= addrcount; he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*)); he->h_addr_list -= addrcount+1; - } else { + } +#if defined(AF_INET6) + else { he->h_length = sizeof(struct in6_addr); addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen, sizeof(struct in6_addr)); @@ -399,6 +403,7 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*)); he->h_addr_list -= addrcount+1; } +#endif /* buffer too small?! */ if((char *)he->h_addr_list < buffer ) { @@ -418,7 +423,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response argp->erange = 1; return NSS_STR_PARSE_ERANGE; } - } else { + } +#if defined(AF_INET6) + else { he->h_addr_list[i] = (char *)&addrp6[i]; if (strchr(data, ':') != 0) { if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) { @@ -434,6 +441,7 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]); } } +#endif data = p+1; } @@ -481,6 +489,7 @@ _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args) AF_INET or for AF_INET6 and AI_ALL|AI_V4MAPPED we have to map IPv4 to IPv6. */ +#if defined(AF_INET6) #ifdef HAVE_NSS_XBYY_KEY_IPNODE af = argp->key.ipnode.af_family; if(af == AF_INET6 && argp->key.ipnode.flags == 0) { @@ -491,6 +500,7 @@ _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args) /* I'm not that sure if this is correct, but... */ af = AF_INET6; #endif +#endif strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1); request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0'; @@ -539,6 +549,7 @@ _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args) ZERO_STRUCT(response); ZERO_STRUCT(request); +#if defined(AF_INET6) /* winbindd currently does not resolve IPv6 */ if(argp->key.hostaddr.type == AF_INET6) { argp->h_errno = NO_DATA; @@ -546,7 +557,15 @@ _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args) } p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr, - request.data.winsreq, INET6_ADDRSTRLEN); + request.data.winsreq, sizeof request.data.winsreq); +#else + snprintf(request.data.winsreq, sizeof request.data.winsreq, + "%u.%u.%u.%u", + ((unsigned char *)argp->key.hostaddr.addr)[0], + ((unsigned char *)argp->key.hostaddr.addr)[1], + ((unsigned char *)argp->key.hostaddr.addr)[2], + ((unsigned char *)argp->key.hostaddr.addr)[3]); +#endif ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index bc111df4e1..fbcc26a81d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -240,6 +240,7 @@ struct global { int map_to_guest; int oplock_break_wait_time; int winbind_cache_time; + int winbind_reconnect_delay; int winbind_max_idle_children; char **szWinbindNssInfo; int iLockSpinTime; @@ -4363,6 +4364,15 @@ static struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { + .label = "winbind reconnect delay", + .type = P_INTEGER, + .p_class = P_GLOBAL, + .ptr = &Globals.winbind_reconnect_delay, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { .label = "winbind enum users", .type = P_BOOL, .p_class = P_GLOBAL, @@ -4829,6 +4839,7 @@ static void init_globals(bool first_time_only) Globals.clustering = False; Globals.winbind_cache_time = 300; /* 5 minutes */ + Globals.winbind_reconnect_delay = 30; /* 30 seconds */ Globals.bWinbindEnumUsers = False; Globals.bWinbindEnumGroups = False; Globals.bWinbindUseDefaultDomain = False; @@ -4839,7 +4850,7 @@ static void init_globals(bool first_time_only) Globals.bWinbindRefreshTickets = False; Globals.bWinbindOfflineLogon = False; - Globals.iIdmapCacheTime = 900; /* 15 minutes by default */ + Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */ Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */ Globals.bPassdbExpandExplicit = False; @@ -5082,7 +5093,7 @@ FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon) FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames) FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly) -FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */ +FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend) FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend) FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime) FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime) @@ -5341,6 +5352,7 @@ FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize) FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt) FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) +FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay) FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo) FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 57152c34b5..706df48923 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -1301,20 +1301,28 @@ static bool legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid) void uid_to_sid(DOM_SID *psid, uid_t uid) { + bool expired = true; + bool ret; ZERO_STRUCTP(psid); if (fetch_sid_from_uid_cache(psid, uid)) return; - if (!winbind_uid_to_sid(psid, uid)) { - if (!winbind_ping()) { - legacy_uid_to_sid(psid, uid); + /* Check the winbindd cache directly. */ + ret = idmap_cache_find_uid2sid(uid, psid, &expired); + + if (!ret || expired || (ret && is_null_sid(psid))) { + /* Not in cache. Ask winbindd. */ + if (!winbind_uid_to_sid(psid, uid)) { + if (!winbind_ping()) { + legacy_uid_to_sid(psid, uid); + return; + } + + DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n", + uid)); return; } - - DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n", - uid)); - return; } DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid, @@ -1330,25 +1338,33 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) void gid_to_sid(DOM_SID *psid, gid_t gid) { + bool expired = true; + bool ret; ZERO_STRUCTP(psid); if (fetch_sid_from_gid_cache(psid, gid)) return; - if (!winbind_gid_to_sid(psid, gid)) { - if (!winbind_ping()) { - legacy_gid_to_sid(psid, gid); + /* Check the winbindd cache directly. */ + ret = idmap_cache_find_gid2sid(gid, psid, &expired); + + if (!ret || expired || (ret && is_null_sid(psid))) { + /* Not in cache. Ask winbindd. */ + if (!winbind_gid_to_sid(psid, gid)) { + if (!winbind_ping()) { + legacy_gid_to_sid(psid, gid); + return; + } + + DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n", + gid)); return; } - - DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n", - gid)); - return; } DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid, sid_string_dbg(psid))); - + store_gid_sid_cache(psid, gid); return; } @@ -1359,6 +1375,8 @@ void gid_to_sid(DOM_SID *psid, gid_t gid) bool sid_to_uid(const DOM_SID *psid, uid_t *puid) { + bool expired = true; + bool ret; uint32 rid; gid_t gid; @@ -1381,14 +1399,20 @@ bool sid_to_uid(const DOM_SID *psid, uid_t *puid) return true; } - if (!winbind_sid_to_uid(puid, psid)) { - if (!winbind_ping()) { - return legacy_sid_to_uid(psid, puid); - } + /* Check the winbindd cache directly. */ + ret = idmap_cache_find_sid2uid(psid, puid, &expired); - DEBUG(5, ("winbind failed to find a uid for sid %s\n", - sid_string_dbg(psid))); - return false; + if (!ret || expired || (ret && (*puid == (uid_t)-1))) { + /* Not in cache. Ask winbindd. */ + if (!winbind_sid_to_uid(puid, psid)) { + if (!winbind_ping()) { + return legacy_sid_to_uid(psid, puid); + } + + DEBUG(5, ("winbind failed to find a uid for sid %s\n", + sid_string_dbg(psid))); + return false; + } } /* TODO: Here would be the place to allocate both a gid and a uid for @@ -1408,6 +1432,8 @@ bool sid_to_uid(const DOM_SID *psid, uid_t *puid) bool sid_to_gid(const DOM_SID *psid, gid_t *pgid) { + bool expired = true; + bool ret; uint32 rid; uid_t uid; @@ -1429,24 +1455,28 @@ bool sid_to_gid(const DOM_SID *psid, gid_t *pgid) return true; } - /* Ask winbindd if it can map this sid to a gid. - * (Idmap will check it is a valid SID and of the right type) */ + /* Check the winbindd cache directly. */ + ret = idmap_cache_find_sid2gid(psid, pgid, &expired); - if ( !winbind_sid_to_gid(pgid, psid) ) { - if (!winbind_ping()) { - return legacy_sid_to_gid(psid, pgid); - } + if (!ret || expired || (ret && (*pgid == (gid_t)-1))) { + /* Not in cache or negative. Ask winbindd. */ + /* Ask winbindd if it can map this sid to a gid. + * (Idmap will check it is a valid SID and of the right type) */ - DEBUG(10,("winbind failed to find a gid for sid %s\n", - sid_string_dbg(psid))); - return false; + if ( !winbind_sid_to_gid(pgid, psid) ) { + if (!winbind_ping()) { + return legacy_sid_to_gid(psid, pgid); + } + + DEBUG(10,("winbind failed to find a gid for sid %s\n", + sid_string_dbg(psid))); + return false; + } } DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid), (unsigned int)*pgid )); store_gid_sid_cache(psid, *pgid); - return true; } - diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ad2f512647..41dde87c42 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -979,8 +979,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, while(1) { RPC_HDR rhdr; - char *ret_data; - uint32 ret_data_len; + char *ret_data = NULL; + uint32 ret_data_len = 0; /* Ensure we have enough data for a pdu. */ ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu); diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 7ece482d75..4e211cfb81 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -521,7 +521,16 @@ NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p, return NT_STATUS_ACCESS_DENIED; } - srv_flgs = 0x000001ff; + /* 0x000001ff */ + srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT | + NETLOGON_NEG_PERSISTENT_SAMREPL | + NETLOGON_NEG_ARCFOUR | + NETLOGON_NEG_PROMOTION_COUNT | + NETLOGON_NEG_CHANGELOG_BDC | + NETLOGON_NEG_FULL_SYNC_REPL | + NETLOGON_NEG_MULTIPLE_SIDS | + NETLOGON_NEG_REDO | + NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL; if (lp_server_schannel() != false) { srv_flgs |= NETLOGON_NEG_SCHANNEL; diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index 2889e3c13f..74275368bd 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -268,12 +268,15 @@ bool schedule_aio_read_and_X(connection_struct *conn, a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + become_root(); if (SMB_VFS_AIO_READ(fsp,a) == -1) { DEBUG(0,("schedule_aio_read_and_X: aio_read failed. " "Error %s\n", strerror(errno) )); delete_aio_ex(aio_ex); + unbecome_root(); return False; } + unbecome_root(); DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, " "offset %.0f, len = %u (mid = %u)\n", @@ -366,13 +369,16 @@ bool schedule_aio_write_and_X(connection_struct *conn, a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + become_root(); if (SMB_VFS_AIO_WRITE(fsp,a) == -1) { DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. " "Error %s\n", strerror(errno) )); delete_aio_ex(aio_ex); + unbecome_root(); return False; } - + unbecome_root(); + release_level_2_oplocks_on_change(fsp); if (!write_through && !lp_syncalways(SNUM(fsp->conn)) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 149e6ecbd9..b6951272d7 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -455,6 +455,12 @@ void reply_ntcreate_and_X(struct smb_request *req) fname)); /* + * we need to remove ignored bits when they come directly from the client + * because we reuse some of them for internal stuff + */ + create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + + /* * If it's an IPC, use the pipe handler. */ @@ -858,6 +864,12 @@ static void call_nt_transact_create(connection_struct *conn, allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32); #endif + /* + * we need to remove ignored bits when they come directly from the client + * because we reuse some of them for internal stuff + */ + create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + /* Ensure the data_len is correct for the sd and ea values given. */ if ((ea_len + sd_len > data_count) || (ea_len > data_count) || (sd_len > data_count) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 03efd09f06..8b32907a4b 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2560,6 +2560,11 @@ NTSTATUS create_file_unixpath(connection_struct *conn, goto fail; } + if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + if (req == NULL) { oplock_request |= INTERNAL_OPEN_ONLY; } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b3d691fbe7..06aa835cb0 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3198,8 +3198,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, setup_readX_header((char *)headerbuf, smb_maxcnt); if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) { - /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */ - if (errno == ENOSYS) { + /* Returning ENOSYS or EINVAL means no data at all was sent. + Do this as a normal read. */ + if (errno == ENOSYS || errno == EINVAL) { goto normal_read; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 041596b953..9c9d0a97bc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1738,16 +1738,19 @@ void reply_sesssetup_and_X(struct smb_request *req) return; } - nt_status = create_local_token(server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("create_local_token failed: %s\n", - nt_errstr(nt_status))); - data_blob_free(&nt_resp); - data_blob_free(&lm_resp); - data_blob_clear_free(&plaintext_password); - reply_nterror(req, nt_status_squash(nt_status)); - END_PROFILE(SMBsesssetupX); - return; + if (!server_info->ptok) { + nt_status = create_local_token(server_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(10, ("create_local_token failed: %s\n", + nt_errstr(nt_status))); + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); + reply_nterror(req, nt_status_squash(nt_status)); + END_PROFILE(SMBsesssetupX); + return; + } } data_blob_clear_free(&plaintext_password); diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index c01aace8f5..c0922efe6b 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -219,7 +219,7 @@ NTSTATUS rpc_vampire_ldif_internals(struct net_context *c, int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv) { if (c->display_usage) { - d_printf("Usage\n" + d_printf("Usage:\n" "net rpc vampire ldif\n" " Dump remote SAM database to LDIF file or stdout\n"); return 0; @@ -343,7 +343,7 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv) int ret = 0; if (c->display_usage) { - d_printf("Usage\n" + d_printf("Usage:\n" "net rpc vampire keytab\n" " Dump remote SAM database to Kerberos keytab file\n"); return 0; diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index eb39c739e7..88850d29df 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -476,7 +476,7 @@ bool net_find_pdc(struct sockaddr_storage *server_ss, NTSTATUS net_make_ipc_connection(struct net_context *c, unsigned flags, struct cli_state **pcli) { - return net_make_ipc_connection_ex(c, NULL, NULL, NULL, flags, pcli); + return net_make_ipc_connection_ex(c, c->opt_workgroup, NULL, NULL, flags, pcli); } NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, @@ -492,7 +492,8 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain, if ( !server || !pss ) { if (!net_find_server(c, domain, flags, &server_ss, &server_name)) { - d_fprintf(stderr, "Unable to find a suitable server\n"); + d_fprintf(stderr, "Unable to find a suitable server " + "for domain %s\n", domain); nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 6699763cd2..750030d916 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -1228,9 +1228,9 @@ static struct server_id parse_dest(const char *dest) struct server_id result = {-1}; pid_t pid; - /* Zero is a special return value for broadcast smbd */ + /* Zero is a special return value for broadcast to all processes */ - if (strequal(dest, "smbd")) { + if (strequal(dest, "all")) { return interpret_pid(MSG_BROADCAST_PID_STR); } @@ -1245,7 +1245,6 @@ static struct server_id parse_dest(const char *dest) dest = "winbindd"; } - if (!(strequal(dest, "winbindd") || strequal(dest, "nmbd"))) { /* Check for numeric pid number */ @@ -1266,7 +1265,7 @@ static struct server_id parse_dest(const char *dest) fprintf(stderr,"Can't find pid for destination '%s'\n", dest); return result; -} +} /* Execute smbcontrol command */ diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 2a6beca5a2..b10a1a4ba9 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -87,7 +87,7 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid) DEBUG(10,("gid = [%lu]\n", (unsigned long)gid)); - if (idmap_cache_find_uid2sid(gid, sid, &expired)) { + if (idmap_cache_find_gid2sid(gid, sid, &expired)) { DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid, expired ? " (expired)": "")); if (expired && idmap_is_online()) { diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index fe0c076209..04b0b39f81 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -153,6 +153,7 @@ struct winbindd_child { struct fd_event event; struct timed_event *lockout_policy_event; + struct timed_event *machine_password_change_event; struct winbindd_async_request *requests; const struct winbindd_child_dispatch_table *table; @@ -204,6 +205,7 @@ struct winbindd_domain { uint32_t id_range_low, id_range_high; /* A working DC */ + pid_t dc_probe_pid; /* Child we're using to detect the DC. */ fstring dcname; struct sockaddr_storage dcaddr; diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 47df4e4058..71f1a56519 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -8,17 +8,17 @@ Copyright (C) Gerald (Jerry) Carter 2003-2005. Copyright (C) Volker Lendecke 2004-2005 Copyright (C) Jeremy Allison 2006 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -27,14 +27,14 @@ We need to manage connections to domain controllers without having to mess up the main winbindd code with other issues. The aim of the connection manager is to: - + - make connections to domain controllers and cache them - re-establish connections when networks or servers go down - centralise the policy on connection timeouts, domain controller selection etc - manage re-entrancy for when winbindd becomes able to handle multiple outstanding rpc requests - + Why not have connection management as part of the rpc layer like tng? Good question. This code may morph into libsmb/rpc_cache.c or something like that but at the moment it's simply staying as part of winbind. I @@ -171,20 +171,33 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) struct dc_name_ip *dcs = NULL; int num_dcs = 0; TALLOC_CTX *mem_ctx = NULL; - pid_t child_pid; pid_t parent_pid = sys_getpid(); /* Stop zombies */ CatchChild(); - child_pid = sys_fork(); + if (domain->dc_probe_pid != (pid_t)-1) { + /* + * We might already have a DC probe + * child working, check. + */ + if (process_exists_by_pid(domain->dc_probe_pid)) { + DEBUG(10,("fork_child_dc_connect: pid %u already " + "checking for DC's.\n", + (unsigned int)domain->dc_probe_pid)); + return true; + } + domain->dc_probe_pid = (pid_t)-1; + } + + domain->dc_probe_pid = sys_fork(); - if (child_pid == -1) { + if (domain->dc_probe_pid == (pid_t)-1) { DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno))); return False; } - if (child_pid != 0) { + if (domain->dc_probe_pid != (pid_t)0) { /* Parent */ messaging_register(winbind_messaging_context(), NULL, MSG_WINBIND_TRY_TO_GO_ONLINE, @@ -201,6 +214,11 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) if (!reinit_after_fork(winbind_messaging_context(), true)) { DEBUG(0,("reinit_after_fork() failed\n")); + messaging_send_buf(winbind_messaging_context(), + pid_to_procid(parent_pid), + MSG_WINBIND_FAILED_TO_GO_ONLINE, + (uint8 *)domain->name, + strlen(domain->name)+1); _exit(0); } @@ -218,6 +236,11 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) mem_ctx = talloc_init("fork_child_dc_connect"); if (!mem_ctx) { DEBUG(0,("talloc_init failed.\n")); + messaging_send_buf(winbind_messaging_context(), + pid_to_procid(parent_pid), + MSG_WINBIND_FAILED_TO_GO_ONLINE, + (uint8 *)domain->name, + strlen(domain->name)+1); _exit(0); } @@ -291,12 +314,12 @@ static void check_domain_online_handler(struct event_context *ctx, static void calc_new_online_timeout_check(struct winbindd_domain *domain) { - int wbc = lp_winbind_cache_time(); + int wbr = lp_winbind_reconnect_delay(); if (domain->startup) { domain->check_online_timeout = 10; - } else if (domain->check_online_timeout < wbc) { - domain->check_online_timeout = wbc; + } else if (domain->check_online_timeout < wbr) { + domain->check_online_timeout = wbr; } } @@ -336,7 +359,7 @@ void set_domain_offline(struct winbindd_domain *domain) } /* If we're in statup mode, check again in 10 seconds, not in - lp_winbind_cache_time() seconds (which is 5 mins by default). */ + lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */ calc_new_online_timeout_check(domain); @@ -360,7 +383,7 @@ void set_domain_offline(struct winbindd_domain *domain) if ( domain->primary ) { struct winbindd_child *idmap = idmap_child(); - + if ( idmap->pid != 0 ) { messaging_send_buf(winbind_messaging_context(), pid_to_procid(idmap->pid), @@ -439,7 +462,7 @@ static void set_domain_online(struct winbindd_domain *domain) if ( domain->primary ) { struct winbindd_child *idmap = idmap_child(); - + if ( idmap->pid != 0 ) { messaging_send_buf(winbind_messaging_context(), pid_to_procid(idmap->pid), @@ -530,7 +553,7 @@ void winbind_add_failed_connection_entry(const struct winbindd_domain *domain, an authenticated connection if DCs have the RestrictAnonymous registry entry set > 0, or the "Additional restrictions for anonymous connections" set in the win2k Local Security Policy. - + Caller to free() result in domain, username, password */ @@ -539,12 +562,12 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password) *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL); *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL); *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL); - + if (*username && **username) { if (!*domain || !**domain) *domain = smb_xstrdup(lp_workgroup()); - + if (!*password || !**password) *password = smb_xstrdup(""); @@ -680,7 +703,7 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, { const char *account_name; const char *name = NULL; - + /* If we are a DC and this is not our own domain */ if (IS_DC) { @@ -690,10 +713,10 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, if (!our_domain) return NT_STATUS_INVALID_SERVER_STATE; - + name = our_domain->name; } - + if (!get_trust_pw_clear(name, machine_password, &account_name, NULL)) { @@ -715,7 +738,7 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, if (!our_domain) { return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - + if (asprintf(machine_krb5_principal, "%s$@%s", account_name, our_domain->alt_name) == -1) { @@ -852,7 +875,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, domain->name, machine_password); + cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); goto session_setup_done; } } @@ -877,7 +900,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, domain->name, machine_password); + cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); goto session_setup_done; } } @@ -914,6 +937,9 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, anon_fallback: /* Fall back to anonymous connection, this might fail later */ + DEBUG(10,("cm_prepare_connection: falling back to anonymous " + "connection for DC %s\n", + controller )); if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0, NULL, 0, ""))) { @@ -1316,7 +1342,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, TALLOC_FREE(dcnames); num_dcnames = 0; - + TALLOC_FREE(addrs); num_addrs = 0; @@ -1342,7 +1368,7 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, /* we have to check the server affinity cache here since later we selecte a DC based on response time and not preference */ - + /* Check the negative connection cache before talking to it. It going down may have triggered the reconnection. */ @@ -1592,26 +1618,26 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx = NULL; DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name )); - + /* Our primary domain doesn't need to worry about trust flags. Force it to go through the network setup */ if ( domain->primary ) { return False; } - + our_domain = find_our_domain(); - + if ( !connection_ok(our_domain) ) { DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n")); return False; } /* This won't work unless our domain is AD */ - + if ( !our_domain->active_directory ) { return False; } - + /* Use DsEnumerateDomainTrusts to get us the trust direction and type */ @@ -1672,13 +1698,13 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ) if ( !winbindd_can_contact_domain( domain) ) domain->internal = True; - + break; } } - + talloc_destroy( mem_ctx ); - + return domain->initialized; } @@ -1775,7 +1801,7 @@ no_dssetup: result = rpccli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); - + if (NT_STATUS_IS_OK(result)) { /* This particular query is exactly what Win2k clients use to determine that the DC is active directory */ @@ -1904,6 +1930,10 @@ static bool cm_get_schannel_dcinfo(struct winbindd_domain *domain, /* Return a pointer to the struct dcinfo from the netlogon pipe. */ + if (!domain->conn.netlogon_pipe->dc) { + return false; + } + *ppdc = domain->conn.netlogon_pipe->dc; return True; } @@ -1930,6 +1960,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } + /* * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated * sign and sealed pipe using the machine account password by @@ -2303,7 +2334,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error " "was %s\n", nt_errstr(result))); - + /* make sure we return something besides OK */ return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE; } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 1e8325f983..916e8c07c7 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -840,6 +840,111 @@ static void account_lockout_policy_handler(struct event_context *ctx, child); } +static time_t get_machine_password_timeout(void) +{ + /* until we have gpo support use lp setting */ + return lp_machine_password_timeout(); +} + +static bool calculate_next_machine_pwd_change(const char *domain, + struct timeval *t) +{ + time_t pass_last_set_time; + time_t timeout; + time_t next_change; + char *pw; + + pw = secrets_fetch_machine_password(domain, + &pass_last_set_time, + NULL); + + if (pw == NULL) { + DEBUG(0,("cannot fetch own machine password ????")); + return false; + } + + SAFE_FREE(pw); + + timeout = get_machine_password_timeout(); + if (timeout == 0) { + DEBUG(10,("machine password never expires\n")); + return false; + } + + if (time(NULL) < (pass_last_set_time + timeout)) { + next_change = pass_last_set_time + timeout; + DEBUG(10,("machine password still valid until: %s\n", + http_timestring(next_change))); + *t = timeval_set(next_change, 0); + return true; + } + + DEBUG(10,("machine password expired, needs immediate change\n")); + + *t = timeval_zero(); + + return true; +} + +static void machine_password_change_handler(struct event_context *ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + struct winbindd_child *child = + (struct winbindd_child *)private_data; + struct rpc_pipe_client *netlogon_pipe = NULL; + TALLOC_CTX *frame; + NTSTATUS result; + struct timeval next_change; + + DEBUG(10,("machine_password_change_handler called\n")); + + TALLOC_FREE(child->machine_password_change_event); + + if (!calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + return; + } + + if (!winbindd_can_contact_domain(child->domain)) { + DEBUG(10,("machine_password_change_handler: Removing myself since I " + "do not have an incoming trust to domain %s\n", + child->domain->name)); + return; + } + + result = cm_connect_netlogon(child->domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to connect netlogon pipe: %s\n", + nt_errstr(result))); + return; + } + + frame = talloc_stackframe(); + + result = trust_pw_find_change_and_store_it(netlogon_pipe, + frame, + child->domain->name); + TALLOC_FREE(frame); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to change machine password: %s\n", + nt_errstr(result))); + } else { + DEBUG(10,("machine_password_change_handler: " + "successfully changed machine password\n")); + } + + child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL, + next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); +} + /* Deal with a request to go offline. */ static void child_msg_offline(struct messaging_context *msg, @@ -1138,6 +1243,21 @@ static bool fork_domain_child(struct winbindd_child *child) child); } + if (child->domain && child->domain->primary && + lp_server_role() == ROLE_DOMAIN_MEMBER) { + + struct timeval next_change; + + if (calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + child->machine_password_change_event = event_add_timed( + winbind_event_context(), NULL, next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); + } + } + while (1) { int ret; diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 01a4054d44..50936c01a3 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -86,10 +86,7 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do "good" : "bad")); done: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n", state->response.data.auth.nt_status_string)); diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 0f9f1e1621..a7911f60aa 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -176,7 +176,7 @@ static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx, } fill_domain_username(state->response.data.auth.unix_username, - nt_domain, nt_username, True); + nt_domain, nt_username, true); DEBUG(5,("Setting unix username to [%s]\n", state->response.data.auth.unix_username)); @@ -310,8 +310,8 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, TALLOC_FREE(frame); - status = sid_array_from_info3(mem_ctx, info3, - &token->user_sids, + status = sid_array_from_info3(mem_ctx, info3, + &token->user_sids, &token->num_sids, true, false); if (!NT_STATUS_IS_OK(status)) { @@ -338,13 +338,13 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } } - + /* Do not distinguish this error from a wrong username/pw */ return NT_STATUS_LOGON_FAILURE; } -struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, +struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, const char *domain_name) { struct winbindd_domain *domain; @@ -353,7 +353,7 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, domain = find_domain_from_name_noinit(domain_name); if (domain == NULL) { DEBUG(3, ("Authentication for domain [%s] refused " - "as it is not a trusted domain\n", + "as it is not a trusted domain\n", domain_name)); } return domain; @@ -370,27 +370,30 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, if (state->request.flags & WBFLAG_PAM_CONTACT_TRUSTDOM) { domain = find_domain_from_name_noinit(domain_name); if (domain == NULL) { - DEBUG(3, ("Authentication for domain [%s] skipped " - "as it is not a trusted domain\n", + DEBUG(3, ("Authentication for domain [%s] skipped " + "as it is not a trusted domain\n", domain_name)); } else { return domain; - } + } } return find_our_domain(); } -static void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) +static void fill_in_password_policy(struct winbindd_response *r, + const struct samr_DomInfo1 *p) { - resp->data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); - - /* we might have given a more useful error above */ - if (*resp->data.auth.error_string == '\0') - fstrcpy(resp->data.auth.error_string, - get_friendly_nt_error_msg(result)); - resp->data.auth.pam_error = nt_status_to_pam(result); + r->data.auth.policy.min_length_password = + p->min_password_length; + r->data.auth.policy.password_history = + p->password_history_length; + r->data.auth.policy.password_properties = + p->password_properties; + r->data.auth.policy.expire = + nt_time_to_unix_abs((NTTIME *)&(p->max_password_age)); + r->data.auth.policy.min_passwordage = + nt_time_to_unix_abs((NTTIME *)&(p->min_password_age)); } static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, @@ -402,9 +405,9 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, if ( !winbindd_can_contact_domain( domain ) ) { DEBUG(5,("fillup_password_policy: No inbound trust to " - "contact domain %s\n", domain->name)); + "contact domain %s\n", domain->name)); return NT_STATUS_NOT_SUPPORTED; - } + } methods = domain->methods; @@ -413,22 +416,13 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, return status; } - state->response.data.auth.policy.min_length_password = - password_policy.min_password_length; - state->response.data.auth.policy.password_history = - password_policy.password_history_length; - state->response.data.auth.policy.password_properties = - password_policy.password_properties; - state->response.data.auth.policy.expire = - nt_time_to_unix_abs((NTTIME *)&(password_policy.max_password_age)); - state->response.data.auth.policy.min_passwordage = - nt_time_to_unix_abs((NTTIME *)&(password_policy.min_password_age)); + fill_in_password_policy(&state->response, &password_policy); return NT_STATUS_OK; } -static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, +static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, uint16 *lockout_threshold) { struct winbindd_methods *methods; @@ -449,8 +443,8 @@ static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain return NT_STATUS_OK; } -static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, +static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, uint32 *password_properties) { struct winbindd_methods *methods; @@ -473,7 +467,7 @@ static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, #ifdef HAVE_KRB5 -static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, +static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, const char *type, uid_t uid, bool *internal_ccache) @@ -484,7 +478,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, const char *gen_cc = NULL; - *internal_ccache = True; + *internal_ccache = true; if (uid == -1) { goto memory_ccache; @@ -503,7 +497,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, goto memory_ccache; } - *internal_ccache = False; + *internal_ccache = false; goto done; memory_ccache: @@ -532,11 +526,11 @@ static void setup_return_cc_name(struct winbindd_cli_state *state, const char *c if (!strequal(type, "FILE") && !strequal(type, "WRFILE")) { - DEBUG(10,("won't return krbccname for a %s type ccache\n", + DEBUG(10,("won't return krbccname for a %s type ccache\n", type)); return; } - + fstrcpy(state->response.data.auth.krb5ccname, cc); } @@ -577,13 +571,13 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, uid_t uid = -1; ADS_STRUCT *ads; time_t time_offset = 0; - bool internal_ccache = True; + bool internal_ccache = true; ZERO_STRUCTP(info3); *info3 = NULL; - - /* 1st step: + + /* 1st step: * prepare a krb5_cc_cache string for the user */ uid = get_uid_from_state(state); @@ -593,31 +587,31 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, cc = generate_krb5_ccache(state->mem_ctx, state->request.data.auth.krb5_cc_type, - state->request.data.auth.uid, + state->request.data.auth.uid, &internal_ccache); if (cc == NULL) { return NT_STATUS_NO_MEMORY; } - /* 2nd step: + /* 2nd step: * get kerberos properties */ - + if (domain->private_data) { ads = (ADS_STRUCT *)domain->private_data; - time_offset = ads->auth.time_offset; + time_offset = ads->auth.time_offset; } - /* 3rd step: + /* 3rd step: * do kerberos auth and setup ccache as the user */ parse_domain_user(state->request.data.auth.user, name_domain, name_user); realm = domain->alt_name; strupper_m(realm); - - principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm); + + principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm); if (principal_s == NULL) { return NT_STATUS_NO_MEMORY; } @@ -644,8 +638,8 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, &ticket_lifetime, &renewal_until, cc, - True, - True, + true, + true, WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, info3); if (!internal_ccache) { @@ -665,7 +659,7 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, * environment */ if (!internal_ccache) { - + setup_return_cc_name(state, cc); result = add_ccache_to_list(principal_s, @@ -676,11 +670,11 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, uid, time(NULL), ticket_lifetime, - renewal_until, - False); + renewal_until, + false); if (!NT_STATUS_IS_OK(result)) { - DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n", + DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n", nt_errstr(result))); } } else { @@ -737,12 +731,12 @@ static bool check_request_flags(uint32_t flags) ( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) || ( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)|| !(flags & flags_edata) ) { - return True; + return true; } DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags)); - return False; + return false; } /**************************************************************** @@ -836,7 +830,7 @@ void winbindd_pam_auth(struct winbindd_cli_state *state) } /* Parse domain and username */ - + ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR ); if (!canonicalize_username(state->request.data.auth.user, @@ -869,7 +863,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, struct netr_SamInfo3 **info3) { NTSTATUS result = NT_STATUS_LOGON_FAILURE; - uint16 max_allowed_bad_attempts; + uint16 max_allowed_bad_attempts; fstring name_domain, name_user; DOM_SID sid; enum lsa_SidType type; @@ -878,7 +872,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, const uint8 *cached_salt; struct netr_SamInfo3 *my_info3; time_t kickoff_time, must_change_time; - bool password_good = False; + bool password_good = false; #ifdef HAVE_KRB5 struct winbindd_tdc_domain *tdc_domain = NULL; #endif @@ -890,7 +884,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, DEBUG(10,("winbindd_dual_pam_auth_cached\n")); /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); @@ -908,10 +902,10 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, return NT_STATUS_LOGON_FAILURE; } - result = winbindd_get_creds(domain, - state->mem_ctx, - &sid, - &my_info3, + result = winbindd_get_creds(domain, + state->mem_ctx, + &sid, + &my_info3, &cached_nt_pass, &cached_salt); if (!NT_STATUS_IS_OK(result)) { @@ -936,42 +930,42 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, E_md5hash(cached_salt, new_nt_pass, salted_hash); password_good = (memcmp(cached_nt_pass, salted_hash, NT_HASH_LEN) == 0) ? - True : False; + true : false; } else { /* Old cached cred - direct store of nt_hash (bad bad bad !). */ password_good = (memcmp(cached_nt_pass, new_nt_pass, NT_HASH_LEN) == 0) ? - True : False; + true : false; } if (password_good) { /* User *DOES* know the password, update logon_time and reset * bad_pw_count */ - + my_info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT; - + if (my_info3->base.acct_flags & ACB_AUTOLOCK) { return NT_STATUS_ACCOUNT_LOCKED_OUT; } - + if (my_info3->base.acct_flags & ACB_DISABLED) { return NT_STATUS_ACCOUNT_DISABLED; } - + if (my_info3->base.acct_flags & ACB_WSTRUST) { return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } - + if (my_info3->base.acct_flags & ACB_SVRTRUST) { return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } - + if (my_info3->base.acct_flags & ACB_DOMTRUST) { return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } if (!(my_info3->base.acct_flags & ACB_NORMAL)) { - DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n", + DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n", my_info3->base.acct_flags)); return NT_STATUS_LOGON_FAILURE; } @@ -988,7 +982,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, /* return NT_STATUS_PASSWORD_EXPIRED; */ goto success; } - + #ifdef HAVE_KRB5 if ((state->request.flags & WBFLAG_PAM_KRB5) && ((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) && @@ -999,7 +993,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, char *realm = NULL; const char *principal_s = NULL; const char *service = NULL; - bool internal_ccache = False; + bool internal_ccache = false; uid = get_uid_from_state(state); if (uid == -1) { @@ -1041,7 +1035,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, time(NULL), time(NULL) + lp_winbind_cache_time(), time(NULL) + WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, - True); + true); if (!NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_cached: failed " @@ -1113,7 +1107,7 @@ failed: my_info3); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n", + DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n", nt_errstr(result))); } @@ -1121,7 +1115,7 @@ failed: } NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, - struct winbindd_cli_state *state, + struct winbindd_cli_state *state, struct netr_SamInfo3 **info3) { struct winbindd_domain *contact_domain; @@ -1129,38 +1123,38 @@ NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, NTSTATUS result; DEBUG(10,("winbindd_dual_pam_auth_kerberos\n")); - + /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + } else { if (is_myname(name_domain)) { DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + contact_domain = find_domain_from_name(name_domain); if (contact_domain == NULL) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); contact_domain = find_our_domain(); } } - if (contact_domain->initialized && + if (contact_domain->initialized && contact_domain->active_directory) { goto try_login; } @@ -1212,13 +1206,13 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, *info3 = NULL; DEBUG(10,("winbindd_dual_pam_auth_samlogon\n")); - + /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); /* do password magic */ - + generate_random_buffer(chal, 8); if (lp_client_ntlmv2_auth()) { @@ -1226,17 +1220,17 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, DATA_BLOB names_blob; DATA_BLOB nt_response; DATA_BLOB lm_response; - server_chal = data_blob_talloc(state->mem_ctx, chal, 8); - + server_chal = data_blob_talloc(state->mem_ctx, chal, 8); + /* note that the 'workgroup' here is a best guess - we don't know the server's domain at this point. The 'server name' is also - dodgy... + dodgy... */ names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); - - if (!SMBNTLMv2encrypt(name_user, name_domain, - state->request.data.auth.pass, - &server_chal, + + if (!SMBNTLMv2encrypt(name_user, name_domain, + state->request.data.auth.pass, + &server_chal, &names_blob, &lm_response, &nt_response, NULL)) { data_blob_free(&names_blob); @@ -1255,35 +1249,35 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, data_blob_free(&nt_response); } else { - if (lp_client_lanman_auth() - && SMBencrypt(state->request.data.auth.pass, - chal, + if (lp_client_lanman_auth() + && SMBencrypt(state->request.data.auth.pass, + chal, local_lm_response)) { - lm_resp = data_blob_talloc(state->mem_ctx, - local_lm_response, + lm_resp = data_blob_talloc(state->mem_ctx, + local_lm_response, sizeof(local_lm_response)); } else { lm_resp = data_blob_null; } - SMBNTencrypt(state->request.data.auth.pass, + SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response); - nt_resp = data_blob_talloc(state->mem_ctx, - local_nt_response, + nt_resp = data_blob_talloc(state->mem_ctx, + local_nt_response, sizeof(local_nt_response)); } - + /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + } else { if (is_myname(name_domain)) { DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); @@ -1300,7 +1294,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, netlogon_fn_t logon_fn; ZERO_STRUCTP(my_info3); - retry = False; + retry = false; result = cm_connect_netlogon(contact_domain, &netlogon_pipe); @@ -1312,7 +1306,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, /* It is really important to try SamLogonEx here, * because in a clustered environment, we want to use * one machine account from multiple physical - * computers. + * computers. * * With a normal SamLogon call, we must keep the * credentials chain updated and intact between all @@ -1326,7 +1320,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, * When using SamLogonEx, the credentials are not * supplied, but the session key is implied by the * wrapping SamLogon context. - * + * * -- abartlet 21 April 2008 */ @@ -1351,8 +1345,8 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, && contact_domain->can_do_samlogon_ex) { DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " "retrying with NetSamLogon\n")); - contact_domain->can_do_samlogon_ex = False; - retry = True; + contact_domain->can_do_samlogon_ex = false; + retry = true; continue; } @@ -1361,15 +1355,15 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, our connection. */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { - retry = True; + retry = true; continue; } - + /* if we get access denied, a possible cause was that we had and open connection to the DC, but someone changed our machine account password out from underneath us using 'net rpc changetrustpw' */ - + if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth: sam_logon returned " "ACCESS_DENIED. Maybe the trust account " @@ -1377,16 +1371,16 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, "Killing connections to domain %s\n", name_domain)); invalidate_cm_connection(&contact_domain->conn); - retry = True; - } - + retry = true; + } + } while ( (attempts < 2) && retry ); /* handle the case where a NT4 DC does not fill in the acct_flags in * the samlogon reply info3. When accurate info3 is required by the * caller, we look up the account flags ourselve - gd */ - if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && + if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) { struct rpc_pipe_client *samr_pipe; @@ -1395,11 +1389,11 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, NTSTATUS status_tmp; uint32 acct_flags; - status_tmp = cm_connect_sam(contact_domain, state->mem_ctx, + status_tmp = cm_connect_sam(contact_domain, state->mem_ctx, &samr_pipe, &samr_domain_handle); if (!NT_STATUS_IS_OK(status_tmp)) { - DEBUG(3, ("could not open handle to SAMR pipe: %s\n", + DEBUG(3, ("could not open handle to SAMR pipe: %s\n", nt_errstr(status_tmp))); goto done; } @@ -1448,10 +1442,10 @@ done: } enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_LOGON_FAILURE; - NTSTATUS krb5_result = NT_STATUS_OK; + NTSTATUS krb5_result = NT_STATUS_OK; fstring name_domain, name_user; struct netr_SamInfo3 *info3 = NULL; @@ -1470,12 +1464,12 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, } /* Parse domain and username */ - + ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR ); parse_domain_user(state->request.data.auth.user, name_domain, name_user); - if (domain->online == False) { + if (domain->online == false) { result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; if (domain->startup) { /* Logons are very important to users. If we're offline and @@ -1494,11 +1488,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, /* Check for Kerberos authentication */ if (domain->online && (state->request.flags & WBFLAG_PAM_KRB5)) { - + result = winbindd_dual_pam_auth_kerberos(domain, state, &info3); /* save for later */ krb5_result = result; - + if (NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_kerberos succeeded\n")); @@ -1512,7 +1506,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { DEBUG(10,("winbindd_dual_pam_auth_kerberos setting domain to offline\n")); set_domain_offline( domain ); - goto cached_logon; + goto cached_logon; } /* there are quite some NT_STATUS errors where there is no @@ -1531,7 +1525,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) { goto process_result; } - + if (state->request.flags & WBFLAG_PAM_FALLBACK_AFTER_KRB5) { DEBUG(3,("falling back to samlogon\n")); goto sam_logon; @@ -1544,7 +1538,7 @@ sam_logon: /* Check for Samlogon authentication */ if (domain->online) { result = winbindd_dual_pam_auth_samlogon(domain, state, &info3); - + if (NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n")); /* add the Krb5 err if we have one */ @@ -1552,18 +1546,18 @@ sam_logon: info3->base.user_flags |= LOGON_KRB5_FAIL_CLOCK_SKEW; } goto process_result; - } + } - DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n", + DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n", nt_errstr(result))); if (NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS) || NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT) || - NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) + NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { DEBUG(10,("winbindd_dual_pam_auth_samlogon setting domain to offline\n")); set_domain_offline( domain ); - goto cached_logon; + goto cached_logon; } if (domain->online) { @@ -1574,9 +1568,9 @@ sam_logon: cached_logon: /* Check for Cached logons */ - if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) && + if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) && lp_winbind_offline_logon()) { - + result = winbindd_dual_pam_auth_cached(domain, state, &info3); if (NT_STATUS_IS_OK(result)) { @@ -1591,7 +1585,7 @@ cached_logon: process_result: if (NT_STATUS_IS_OK(result)) { - + DOM_SID user_sid; /* In all codepaths where result == NT_STATUS_OK info3 must have @@ -1608,19 +1602,19 @@ process_result: this is our primary domain so we don't invalidate the cache entry by storing the seq_num for the wrong domain). */ - if ( domain->primary ) { + if ( domain->primary ) { sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid); - cache_name2sid(domain, name_domain, name_user, + cache_name2sid(domain, name_domain, name_user, SID_NAME_USER, &user_sid); } - + /* Check if the user is in the right group */ if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3, state->request.data.auth.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n", - state->request.data.auth.user, + state->request.data.auth.user, state->request.data.auth.require_membership_of_sid)); goto done; } @@ -1665,8 +1659,8 @@ process_result: /* This is not entirely correct I believe, but it is consistent. Only apply the password policy settings - too warn users for our own domain. Cannot obtain these - from trusted DCs all the time so don't do it at all. + too warn users for our own domain. Cannot obtain these + from trusted DCs all the time so don't do it at all. -- jerry */ result = NT_STATUS_NOT_SUPPORTED; @@ -1674,16 +1668,16 @@ process_result: result = fillup_password_policy(our_domain, state); } - if (!NT_STATUS_IS_OK(result) - && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ) + if (!NT_STATUS_IS_OK(result) + && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ) { - DEBUG(10,("Failed to get password policies for domain %s: %s\n", + DEBUG(10,("Failed to get password policies for domain %s: %s\n", domain->name, nt_errstr(result))); goto done; } } - result = NT_STATUS_OK; + result = NT_STATUS_OK; } done: @@ -1692,26 +1686,20 @@ done: (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { result = NT_STATUS_NO_LOGON_SERVERS; } - - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - /* we might have given a more useful error above */ - if (!*state->response.data.auth.error_string) - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", - state->request.data.auth.user, + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", + state->request.data.auth.user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } /********************************************************************** - Challenge Response Authentication Protocol + Challenge Response Authentication Protocol **********************************************************************/ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) @@ -1775,7 +1763,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) set_auth_errors(&state->response, result); DEBUG(5, ("CRAP authentication for %s\\%s returned %s (PAM: %d)\n", state->request.data.auth_crap.domain, - state->request.data.auth_crap.user, + state->request.data.auth_crap.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -1784,7 +1772,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result; struct netr_SamInfo3 *info3 = NULL; @@ -1817,7 +1805,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } else if (lp_winbind_use_default_domain()) { name_domain = lp_workgroup(); } else { - DEBUG(5,("no domain specified with username (%s) - failing auth\n", + DEBUG(5,("no domain specified with username (%s) - failing auth\n", name_user)); result = NT_STATUS_NO_SUCH_USER; goto done; @@ -1825,7 +1813,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, name_domain, name_user)); - + if (*state->request.data.auth_crap.workstation) { workstation = state->request.data.auth_crap.workstation; } else { @@ -1834,8 +1822,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp) || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) { - DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", - state->request.data.auth_crap.lm_resp_len, + DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", + state->request.data.auth_crap.lm_resp_len, state->request.data.auth_crap.nt_resp_len)); result = NT_STATUS_INVALID_PARAMETER; goto done; @@ -1847,11 +1835,11 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.nt_resp_len); /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth_crap.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth_crap.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } @@ -1867,7 +1855,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, do { netlogon_fn_t logon_fn; - retry = False; + retry = false; netlogon_pipe = NULL; result = cm_connect_netlogon(contact_domain, &netlogon_pipe); @@ -1887,7 +1875,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.logon_parameters, contact_domain->dcname, name_user, - name_domain, + name_domain, /* Bug #3248 - found by Stefan Burkei. */ workstation, /* We carefully set this above so use it... */ state->request.data.auth_crap.chal, @@ -1899,8 +1887,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, && contact_domain->can_do_samlogon_ex) { DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " "retrying with NetSamLogon\n")); - contact_domain->can_do_samlogon_ex = False; - retry = True; + contact_domain->can_do_samlogon_ex = false; + retry = true; continue; } @@ -1911,14 +1899,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, our connection. */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { - retry = True; + retry = true; continue; } /* if we get access denied, a possible cause was that we had and open connection to the DC, but someone changed our machine account password out from underneath us using 'net rpc changetrustpw' */ - + if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth: sam_logon returned " "ACCESS_DENIED. Maybe the trust account " @@ -1926,8 +1914,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, "Killing connections to domain %s\n", name_domain)); invalidate_cm_connection(&contact_domain->conn); - retry = True; - } + retry = true; + } } while ( (attempts < 2) && retry ); @@ -1942,7 +1930,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so " "crap authentication is rejected\n", - state->request.data.auth_crap.user, + state->request.data.auth_crap.user, state->request.data.auth_crap.require_membership_of_sid)); goto done; } @@ -1965,21 +1953,14 @@ done: result = nt_status_squash(result); } - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - - /* we might have given a more useful error above */ - if (!*state->response.data.auth.error_string) { - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - } - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", name_domain, name_user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2002,7 +1983,7 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state) set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s" "(PAM: %d)\n", - state->request.data.auth.user, + state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -2012,8 +1993,8 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state) contact_domain = find_domain_from_name(domain); if (!contact_domain) { set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", - state->request.data.chauthtok.user, domain, user, domain)); + DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + state->request.data.chauthtok.user, domain, user, domain)); request_error(state); return; } @@ -2028,7 +2009,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact char *newpass = NULL; POLICY_HND dom_pol; struct rpc_pipe_client *cli; - bool got_info = False; + bool got_info = false; struct samr_DomInfo1 *info = NULL; struct samr_ChangeReject *reject = NULL; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -2068,21 +2049,13 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact /* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */ if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) { - state->response.data.auth.policy.min_length_password = - info->min_password_length; - state->response.data.auth.policy.password_history = - info->password_history_length; - state->response.data.auth.policy.password_properties = - info->password_properties; - state->response.data.auth.policy.expire = - nt_time_to_unix_abs((NTTIME *)&info->max_password_age); - state->response.data.auth.policy.min_passwordage = - nt_time_to_unix_abs((NTTIME *)&info->min_password_age); + + fill_in_password_policy(&state->response, info); state->response.data.auth.reject_reason = reject->reason; - got_info = True; + got_info = true; } /* only fallback when the chgpasswd_user3 call is not supported */ @@ -2092,18 +2065,18 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n", nt_errstr(result))); - + result = rpccli_samr_chgpasswd_user2(cli, state->mem_ctx, user, newpass, oldpass); /* Windows 2000 returns NT_STATUS_ACCOUNT_RESTRICTION. Map to the same status code as Windows 2003. */ if ( NT_STATUS_EQUAL(NT_STATUS_ACCOUNT_RESTRICTION, result ) ) { - result = NT_STATUS_PASSWORD_RESTRICTION; + result = NT_STATUS_PASSWORD_RESTRICTION; } } -done: +done: if (NT_STATUS_IS_OK(result) && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN)) { @@ -2151,7 +2124,7 @@ done: if (!NT_STATUS_IS_OK(result) && !got_info && contact_domain) { NTSTATUS policy_ret; - + policy_ret = fillup_password_policy(contact_domain, state); /* failure of this is non critical, it will just provide no @@ -2166,17 +2139,14 @@ done: process_result: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", domain, user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2211,7 +2181,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) } if ((sys_getpeereid(state->sock, &caller_uid)) != 0) { - DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", + DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", strerror(errno))); goto failed; } @@ -2247,7 +2217,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) } enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_NOT_SUPPORTED; @@ -2265,7 +2235,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, } #ifdef HAVE_KRB5 - + if (state->request.data.logoff.uid < 0) { DEBUG(0,("winbindd_pam_logoff: invalid uid\n")); goto process_result; @@ -2280,7 +2250,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, goto process_result; } - if (!ccache_entry_identical(state->request.data.logoff.user, + if (!ccache_entry_identical(state->request.data.logoff.user, state->request.data.logoff.uid, state->request.data.logoff.krb5ccname)) { DEBUG(0,("winbindd_pam_logoff: cached entry differs.\n")); @@ -2302,10 +2272,7 @@ process_result: winbindd_delete_memory_creds(state->request.data.logoff.user); - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2322,12 +2289,12 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state) sizeof(state->request.data.chng_pswd_auth_crap.user)-1]=0; state->request.data.chng_pswd_auth_crap.domain[ sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0; - + DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n", (unsigned long)state->pid, state->request.data.chng_pswd_auth_crap.domain, state->request.data.chng_pswd_auth_crap.user)); - + if (*state->request.data.chng_pswd_auth_crap.domain != '\0') { domain_name = state->request.data.chng_pswd_auth_crap.domain; } else if (lp_winbind_use_default_domain()) { @@ -2347,7 +2314,7 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state) set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); DEBUG(5, ("CRAP change password for %s\\%s returned %s (PAM: %d)\n", state->request.data.chng_pswd_auth_crap.domain, - state->request.data.chng_pswd_auth_crap.user, + state->request.data.chng_pswd_auth_crap.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -2373,7 +2340,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0; *domain = 0; *user = 0; - + DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n", (unsigned long)state->pid, state->request.data.chng_pswd_auth_crap.domain, @@ -2411,7 +2378,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, domain, user)); - + /* Change password */ new_nt_password = data_blob_talloc( state->mem_ctx, @@ -2450,18 +2417,15 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc, new_lm_password, old_lm_hash_enc); - done: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, - get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + done: + + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", domain, user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 0e0db3e859..c5b7b07931 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -590,6 +590,7 @@ void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); +void set_auth_errors(struct winbindd_response *resp, NTSTATUS result); /* The following definitions come from winbindd/winbindd_wins.c */ diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 77b17787c9..83c5053f78 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -180,11 +180,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const domain->initialized = False; domain->online = is_internal_domain(sid); domain->check_online_timeout = 0; + domain->dc_probe_pid = (pid_t)-1; if (sid) { sid_copy(&domain->sid, sid); } - /* Link to domain list */ DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); @@ -1544,3 +1544,15 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) } #endif /* HAVE_KRB5_LOCATE_PLUGIN_H */ + +void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) +{ + resp->data.auth.nt_status = NT_STATUS_V(result); + fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); + + /* we might have given a more useful error above */ + if (*resp->data.auth.error_string == '\0') + fstrcpy(resp->data.auth.error_string, + get_friendly_nt_error_msg(result)); + resp->data.auth.pam_error = nt_status_to_pam(result); +} |