summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2009-03-26 15:31:02 +0100
committerJelmer Vernooij <jelmer@samba.org>2009-03-26 15:31:02 +0100
commit1e200c1952adab450909ac35252be4636c3e1053 (patch)
tree575e1337aaec5cf8decb10567a4876c1650441c6 /source3
parentca202cf464aec82e63be4b2160f394f56b8c195e (diff)
parent853f9283fb8fbcd2078e3cf8e99d6c8e24d77346 (diff)
downloadsamba-1e200c1952adab450909ac35252be4636c3e1053.tar.gz
samba-1e200c1952adab450909ac35252be4636c3e1053.tar.bz2
samba-1e200c1952adab450909ac35252be4636c3e1053.zip
Merge branch 'master' of git://git.samba.org/samba
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in57
-rw-r--r--source3/configure.in51
-rw-r--r--source3/include/async_smb.h2
-rw-r--r--source3/include/client.h42
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/proto.h100
-rw-r--r--source3/include/rpc_dce.h10
-rw-r--r--source3/include/smb.h19
-rw-r--r--source3/include/smb_signing.h46
-rw-r--r--source3/lib/avahi.c275
-rw-r--r--source3/lib/netapi/cm.c5
-rw-r--r--source3/lib/netapi/user.c18
-rw-r--r--source3/lib/util_file.c2
-rw-r--r--source3/lib/wbclient.c12
-rw-r--r--source3/libnet/libnet_samsync.c3
-rw-r--r--source3/libsmb/async_smb.c43
-rw-r--r--source3/libsmb/cliconnect.c46
-rw-r--r--source3/libsmb/clientgen.c104
-rw-r--r--source3/libsmb/clisigning.c87
-rw-r--r--source3/libsmb/clitrans.c54
-rw-r--r--source3/libsmb/dsgetdcname.c2
-rw-r--r--source3/libsmb/smb_seal.c3
-rw-r--r--source3/libsmb/smb_signing.c1020
-rw-r--r--source3/libsmb/unexpected.c2
-rw-r--r--source3/locking/locking.c3
-rw-r--r--source3/modules/onefs_acl.c10
-rw-r--r--source3/modules/onefs_open.c13
-rw-r--r--source3/modules/vfs_dirsort.c194
-rw-r--r--source3/nmbd/nmbd.c6
-rw-r--r--source3/nmbd/nmbd_processlogon.c238
-rw-r--r--source3/param/loadparm.c15
-rw-r--r--source3/passdb/lookup_sid.c2
-rw-r--r--source3/printing/nt_printing.c11
-rw-r--r--source3/registry/regfio.c26
-rw-r--r--source3/rpc_client/cli_pipe.c580
-rw-r--r--source3/rpc_client/rpc_transport_np.c127
-rw-r--r--source3/rpc_client/rpc_transport_smbd.c93
-rw-r--r--source3/rpc_client/rpc_transport_sock.c82
-rw-r--r--source3/rpc_parse/parse_misc.c57
-rw-r--r--source3/rpc_parse/parse_sec.c436
-rw-r--r--source3/rpc_server/srv_lsa_nt.c4
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c269
-rw-r--r--source3/rpcclient/cmd_spoolss.c13
-rw-r--r--source3/samba4.mk12
-rwxr-xr-xsource3/selftest/tests.sh4
-rw-r--r--source3/smbd/aio.c13
-rw-r--r--source3/smbd/avahi_register.c170
-rw-r--r--source3/smbd/blocking.c5
-rw-r--r--source3/smbd/globals.h1
-rw-r--r--source3/smbd/ipc.c4
-rw-r--r--source3/smbd/negprot.c2
-rw-r--r--source3/smbd/notify.c7
-rw-r--r--source3/smbd/nttrans.c7
-rw-r--r--source3/smbd/open.c9
-rw-r--r--source3/smbd/oplock.c27
-rw-r--r--source3/smbd/password.c8
-rw-r--r--source3/smbd/pipes.c1
-rw-r--r--source3/smbd/process.c52
-rw-r--r--source3/smbd/reply.c30
-rw-r--r--source3/smbd/server.c11
-rw-r--r--source3/smbd/service.c2
-rw-r--r--source3/smbd/sesssetup.c25
-rw-r--r--source3/smbd/signing.c158
-rw-r--r--source3/smbd/trans2.c7
-rw-r--r--source3/utils/net_rpc_printer.c9
-rw-r--r--source3/winbindd/winbindd_pam.c2
66 files changed, 2496 insertions, 2253 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index cf74182f27..1c9c0c1204 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -73,6 +73,7 @@ WINBIND_NSS_EXTRA_LIBS=@WINBIND_NSS_EXTRA_LIBS@
WINBIND_NSS_PTHREAD=@WINBIND_NSS_PTHREAD@
PAM_WINBIND_EXTRA_LIBS=@PAM_WINBIND_EXTRA_LIBS@
DNSSD_LIBS=@DNSSD_LIBS@
+AVAHI_LIBS=@AVAHI_LIBS@
POPT_LIBS=@POPTLIBS@
LIBTALLOC_LIBS=@LIBTALLOC_LIBS@
LIBTDB_LIBS=@LIBTDB_LIBS@
@@ -158,7 +159,7 @@ CODEPAGEDIR = @codepagedir@
# the directory where pid files go
PIDDIR = @piddir@
-FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) -I$(CTDBDIR)/include $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4
+FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4
PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
-DPRIVATE_DIR=\"$(PRIVATE_DIR)\" \
@@ -173,7 +174,6 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
-DMODULESDIR=\"$(MODULESDIR)\" \
-DLOGFILEBASE=\"$(LOGFILEBASE)\" \
-DSHLIBEXT=\"@SHLIBEXT@\" \
- -DCTDBDIR=\"$(CTDBDIR)\" \
-DNCALRPCDIR=\"$(NCALRPCDIR)\" \
-DCONFIGDIR=\"$(CONFIGDIR)\" \
-DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \
@@ -255,6 +255,8 @@ AFS_OBJ = lib/afs.o
AFS_SETTOKEN_OBJ = lib/afs_settoken.o
+AVAHI_OBJ = @AVAHI_OBJ@
+
SERVER_MUTEX_OBJ = lib/server_mutex.o
PASSCHANGE_OBJ = libsmb/passchange.o
@@ -282,7 +284,8 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \
../librpc/ndr/ndr_sec_helper.o \
librpc/ndr/ndr_string.o \
../librpc/ndr/uuid.o \
- librpc/ndr/util.o
+ librpc/ndr/util.o \
+ ../librpc/gen_ndr/ndr_dcerpc.o
RPCCLIENT_NDR_OBJ = rpc_client/ndr.o
@@ -316,7 +319,7 @@ RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o
# this includes only the low level parse code, not stuff
# that requires knowledge of security contexts
-RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) rpc_parse/parse_sec.o
+RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0)
RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o \
rpc_client/init_netlogon.o \
@@ -364,7 +367,8 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
lib/substitute.o lib/dbwrap_util.o \
lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \
- lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
+ lib/tallocmsg.o lib/dmallocmsg.o \
+ libsmb/clisigning.o libsmb/smb_signing.o \
lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \
lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \
lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
@@ -687,6 +691,7 @@ VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \
VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o
PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
+VFS_DIRSORT_OBJ = modules/vfs_dirsort.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -731,7 +736,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/change_trust_pw.o smbd/fake_file.o \
smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
$(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
- smbd/dmapi.o \
+ smbd/dmapi.o smbd/signing.o \
smbd/file_access.o \
smbd/dnsregister.o smbd/globals.o \
$(MANGLE_OBJ) @VFS_STATIC@
@@ -741,7 +746,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
- $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
+ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
$(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \
@@ -1277,6 +1282,10 @@ everything:: all libtalloc libsmbclient libnetapi debug2html smbfilter talloctor
.SUFFIXES:
.SUFFIXES: .c .o .lo
+.PHONY: showflags SHOWFLAGS
+
+showflags: SHOWFLAGS
+
SHOWFLAGS::
@echo "Using CFLAGS = $(CFLAGS)"
@echo " PICFLAG = $(PICFLAG)"
@@ -1385,7 +1394,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE
@echo Linking $@
@$(CC) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
- $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \
+ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \
$(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
$(WINBIND_LIBS) $(ZLIB_LIBS)
@@ -1433,19 +1442,19 @@ bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHAR
@$(CC) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
-bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @BUILD_POPT@
+bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ)
@echo Linking $@
- @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
+ @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS)
-bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @BUILD_POPT@
+bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ)
@echo Linking $@
- @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
+ @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS)
-bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
+bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
-lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \
- $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \
+ $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \
$(LIBTDB_LIBS) $(NSCD_LIBS)
bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@@ -1571,7 +1580,7 @@ bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH
bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
+ @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(AVAHI_LIBS) \
$(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \
$(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
@SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
@@ -1609,37 +1618,37 @@ bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @L
@echo Linking $@
@$(CC) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(LDBRENAME_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
- $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/versiontest: $(BINARY_PREREQS) lib/version_test.o $(VERSION_OBJ)
@echo Linking $@
@@ -2625,6 +2634,10 @@ bin/security.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/security.o
@echo "Building plugin $@"
@$(SHLD_MODULE) libgpo/gpext/security.o
+bin/dirsort.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_DIRSORT_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_DIRSORT_OBJ)
+
#########################################################
## IdMap NSS plugins
@@ -2648,7 +2661,7 @@ bin/ntlm_auth@EXEEXT@: $(BINARY_PREREQS) $(NTLM_AUTH_OBJ) $(PARAM_OBJ) \
bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) @LIBTALLOC_SHARED@ @LIBWBCLIENT_SHARED@ @LIBTDB_SHARED@
@echo "Linking shared library $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_OBJ) -lpam $(DYNEXP) \
- $(LIBS) $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \
+ $(LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
diff --git a/source3/configure.in b/source3/configure.in
index dc5850aba1..1cf8d9ca4a 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -152,13 +152,11 @@ AC_SUBST(NSCD_LIBS)
# do this here since AC_CACHE_CHECK apparently sets the CFLAGS to "-g -O2"
# if it has no value. This prevent *very* large debug binaries from occurring
# by default.
-if test "x$CFLAGS" = x; then
- CFLAGS="-O"
-fi
if test "x$debug" = "xyes" ; then
CFLAGS="${CFLAGS} -g"
-else
- CFLAGS="${CFLAGS} -O"
+fi
+if test "x$CFLAGS" = x; then
+ CFLAGS="-O"
fi
m4_include(../lib/socket_wrapper/config.m4)
@@ -879,7 +877,7 @@ fi
AC_CHECK_FUNCS(dirfd)
if test x"$ac_cv_func_dirfd" = x"yes"; then
- default_shared_modules="$default_shared_modules vfs_syncops"
+ default_shared_modules="$default_shared_modules vfs_syncops vfs_dirsort"
fi
AC_CACHE_CHECK([for struct sigevent type],samba_cv_struct_sigevent, [
@@ -5975,10 +5973,10 @@ AC_SUBST(FLAGS1)
# Check if user wants DNS service discovery support
AC_ARG_ENABLE(dnssd,
-[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=auto)])])
+[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=no)])])
AC_SUBST(DNSSD_LIBS)
-if test x"$enable_dnssd" != x"no"; then
+if test x"$enable_dnssd" == x"yes"; then
have_dnssd_support=yes
AC_CHECK_HEADERS(dns_sd.h)
@@ -6007,6 +6005,42 @@ if test x"$enable_dnssd" != x"no"; then
fi
#################################################
+# Check if user wants avahi support
+
+AC_ARG_ENABLE(avahi,
+[AS_HELP_STRING([--enable-avahi], [Enable Avahi support (default=auto)])])
+
+AC_SUBST(AVAHI_LIBS)
+if test x"$enable_avahi" != x"no"; then
+ have_avahi_support=yes
+
+ AC_CHECK_HEADERS(avahi-common/watch.h)
+ if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ AC_CHECK_HEADERS(avahi-client/client.h)
+ if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ AC_CHECK_LIB_EXT(avahi-client, AVAHI_LIBS, avahi_client_new)
+ if test x"$ac_cv_lib_ext_avahi_client_avahi_client_new" != x"yes"; then
+ have_avahi_support=no
+ fi
+
+ if test x"$have_avahi_support" = x"yes"; then
+ AC_DEFINE(WITH_AVAHI_SUPPORT, 1,
+ [Whether to enable avahi support])
+ AC_SUBST(AVAHI_OBJ, "lib/avahi.o smbd/avahi_register.o")
+ else
+ if test x"$enable_avahi" = x"yes"; then
+ AC_MSG_ERROR(avahi support not available)
+ fi
+ fi
+fi
+
+#################################################
# Check to see if we should use the included iniparser
AC_ARG_WITH(included-iniparser,
@@ -6213,6 +6247,7 @@ SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS)
SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS)
SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h
index 7fc4ff7d27..2ac1101a1e 100644
--- a/source3/include/async_smb.h
+++ b/source3/include/async_smb.h
@@ -63,6 +63,8 @@ struct cli_request {
*/
uint16_t mid;
+ uint32_t seqnum;
+
/**
* The bytes we have to ship to the server
*/
diff --git a/source3/include/client.h b/source3/include/client.h
index 320a90e66b..73a1d7b554 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -71,26 +71,26 @@ struct rpc_cli_transport {
/**
* Trigger an async read from the server. May return a short read.
*/
- struct async_req *(*read_send)(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t size,
- void *priv);
+ struct tevent_req *(*read_send)(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t size,
+ void *priv);
/**
* Get the result from the read_send operation.
*/
- NTSTATUS (*read_recv)(struct async_req *req, ssize_t *preceived);
+ NTSTATUS (*read_recv)(struct tevent_req *req, ssize_t *preceived);
/**
* Trigger an async write to the server. May return a short write.
*/
- struct async_req *(*write_send)(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const uint8_t *data, size_t size,
- void *priv);
+ struct tevent_req *(*write_send)(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const uint8_t *data, size_t size,
+ void *priv);
/**
* Get the result from the read_send operation.
*/
- NTSTATUS (*write_recv)(struct async_req *req, ssize_t *psent);
+ NTSTATUS (*write_recv)(struct tevent_req *req, ssize_t *psent);
/**
* This is an optimization for the SMB transport. It models the
@@ -98,15 +98,15 @@ struct rpc_cli_transport {
* trip. The transport implementation is free to set this to NULL,
* cli_pipe.c will fall back to the explicit write/read routines.
*/
- struct async_req *(*trans_send)(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t data_len,
- uint32_t max_rdata_len,
- void *priv);
+ struct tevent_req *(*trans_send)(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t data_len,
+ uint32_t max_rdata_len,
+ void *priv);
/**
* Get the result from the trans_send operation.
*/
- NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx,
+ NTSTATUS (*trans_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx,
uint8_t **prdata, uint32_t *prdata_len);
void *priv;
};
@@ -166,6 +166,13 @@ struct smb_trans_enc_state {
} s;
};
+struct cli_state_seqnum {
+ struct cli_state_seqnum *prev, *next;
+ uint16_t mid;
+ uint32_t seqnum;
+ bool persistent;
+};
+
struct cli_state {
/**
* A list of subsidiary connections for DFS.
@@ -217,6 +224,7 @@ struct cli_state {
size_t max_xmit;
size_t max_mux;
char *outbuf;
+ struct cli_state_seqnum *seqnum;
char *inbuf;
unsigned int bufsize;
int initialised;
@@ -231,7 +239,7 @@ struct cli_state {
TALLOC_CTX *call_mem_ctx;
#endif
- smb_sign_info sign_info;
+ struct smb_signing_state *signing_state;
struct smb_trans_enc_state *trans_enc_state; /* Setup if we're encrypting SMB's. */
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 4bf4b5c735..c883e17713 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -598,6 +598,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "messages.h"
#include "locking.h"
#include "smb_perfcount.h"
+#include "smb_signing.h"
#include "smb.h"
#include "nameserv.h"
#include "secrets.h"
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9bffa4d319..77be0aba09 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -150,6 +150,10 @@ bool is_trusted_domain(const char* dom_name);
NTSTATUS auth_winbind_init(void);
+/* The following definitions come from auth/auth_wbc.c */
+
+NTSTATUS auth_wbc_init(void);
+
/* The following definitions come from auth/pampass.c */
bool smb_pam_claim_session(char *user, char *tty, char *rhost);
@@ -2410,6 +2414,10 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx,
int cli_set_message(char *buf,int num_words,int num_bytes,bool zero);
unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout);
void cli_set_port(struct cli_state *cli, int port);
+bool cli_state_seqnum_persistent(struct cli_state *cli,
+ uint16_t mid);
+bool cli_state_seqnum_remove(struct cli_state *cli,
+ uint16_t mid);
bool cli_receive_smb(struct cli_state *cli);
ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len);
bool cli_receive_smb_readX_header(struct cli_state *cli);
@@ -3181,29 +3189,34 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf);
NTSTATUS cli_decrypt_message(struct cli_state *cli);
NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out);
-/* The following definitions come from libsmb/smb_signing.c */
+/* The following definitions come from libsmb/clisigning.c */
bool cli_simple_set_signing(struct cli_state *cli,
const DATA_BLOB user_session_key,
const DATA_BLOB response);
-bool cli_null_set_signing(struct cli_state *cli);
bool cli_temp_set_signing(struct cli_state *cli);
-void cli_free_signing_context(struct cli_state *cli);
-void cli_calculate_sign_mac(struct cli_state *cli, char *buf);
-bool cli_check_sign_mac(struct cli_state *cli, char *buf);
-bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid);
-bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid);
+void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum);
+bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum);
bool client_is_signing_on(struct cli_state *cli);
-bool srv_oplock_set_signing(bool onoff);
-bool srv_check_sign_mac(const char *inbuf, bool must_be_ok);
-void srv_calculate_sign_mac(char *outbuf);
-void srv_defer_sign_response(uint16 mid);
-void srv_cancel_sign_response(uint16 mid, bool cancel);
-void srv_set_signing_negotiated(void);
-bool srv_is_signing_active(void);
-bool srv_is_signing_negotiated(void);
-bool srv_signing_started(void);
-void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response);
+bool client_is_signing_allowed(struct cli_state *cli);
+bool client_is_signing_mandatory(struct cli_state *cli);
+void cli_set_signing_negotiated(struct cli_state *cli);
+
+/* The following definitions come from smbd/signing.c */
+
+struct smbd_server_connection;
+bool srv_check_sign_mac(struct smbd_server_connection *conn,
+ const char *inbuf, uint32_t *seqnum);
+void srv_calculate_sign_mac(struct smbd_server_connection *conn,
+ char *outbuf, uint32_t seqnum);
+void srv_cancel_sign_response(struct smbd_server_connection *conn);
+bool srv_init_signing(struct smbd_server_connection *conn);
+void srv_set_signing_negotiated(struct smbd_server_connection *conn);
+bool srv_is_signing_active(struct smbd_server_connection *conn);
+bool srv_is_signing_negotiated(struct smbd_server_connection *conn);
+void srv_set_signing(struct smbd_server_connection *conn,
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response);
/* The following definitions come from libsmb/smbdes.c */
@@ -3779,6 +3792,8 @@ bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
/* The following definitions come from nmbd/nmbd_processlogon.c */
+bool initialize_nmbd_proxy_logon(void);
+
void process_logon_packet(struct packet_struct *p, char *buf,int len,
const char *mailslot);
@@ -4345,7 +4360,7 @@ const char *lp_printcapname(void);
bool lp_disable_spoolss( void );
void lp_set_spoolss_state( uint32 state );
uint32 lp_get_spoolss_state( void );
-bool lp_use_sendfile(int snum);
+bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state);
void set_use_sendfile(int snum, bool val);
void set_store_dos_attributes(int snum, bool val);
void lp_set_mangling_method(const char *new_method);
@@ -4828,7 +4843,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value );
WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level);
bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level);
-bool del_driver_init(char *drivername);
+bool del_driver_init(const char *drivername);
WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len);
WERROR get_a_printer( Printer_entry *print_hnd,
NT_PRINTER_INFO_LEVEL **pp_printer,
@@ -4840,8 +4855,8 @@ WERROR get_a_printer_search( Printer_entry *print_hnd,
const char *sharename);
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level);
uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
-WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
- fstring drivername, const char *architecture, uint32 version);
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level,
+ const char *drivername, const char *architecture, uint32_t version);
uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 );
bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info );
@@ -5241,22 +5256,22 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
/* The following definitions come from rpc_client/cli_pipe.c */
-struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- uint8_t op_num,
- prs_struct *req_data);
-NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ uint8_t op_num,
+ prs_struct *req_data);
+NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
prs_struct *reply_pdu);
NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
uint8 op_num,
prs_struct *in_data,
prs_struct *out_data);
-struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- struct cli_pipe_auth_data *auth);
-NTSTATUS rpc_pipe_bind_recv(struct async_req *req);
+struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ struct cli_pipe_auth_data *auth);
+NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req);
NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
struct cli_pipe_auth_data *auth);
unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
@@ -5678,10 +5693,8 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);
bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime);
bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
-bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
bool smb_io_uuid(const char *desc, struct GUID *uuid,
prs_struct *ps, int depth);
-void init_unistr(UNISTR *str, const char *buf);
void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags);
/* The following definitions come from rpc_parse/parse_prs.c */
@@ -5803,11 +5816,6 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
RPC_AUTH_SCHANNEL_CHK * chk,
prs_struct *ps, int depth);
-/* The following definitions come from rpc_parse/parse_sec.c */
-
-bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
-bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
-
/* The following definitions come from rpc_server/srv_eventlog_lib.c */
TDB_CONTEXT *elog_init_tdb( char *tdbfilename );
@@ -6720,7 +6728,9 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname);
void smbd_setup_sig_term_handler(void);
void smbd_setup_sig_hup_handler(void);
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
+bool srv_send_smb(int fd, char *buffer,
+ bool no_signing, uint32_t seqnum,
+ bool do_encrypt,
struct smb_perfcount_data *pcd);
int srv_set_message(char *buf,
int num_words,
@@ -7217,6 +7227,16 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid);
NTSTATUS nss_info_template_init( void );
+/* The following definitions come from lib/avahi.c */
+
+struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev);
+
+/* The following definitions come from smbd/avahi_register.c */
+
+void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ uint16_t port);
+
/* Misc protos */
#endif /* _PROTO_H_ */
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 580b14f1d8..ca58040757 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -81,16 +81,6 @@ enum RPC_PKT_TYPE {
#define RPC_PIPE_AUTH_SEAL_LEVEL 0x6
#endif
-#define DCERPC_FAULT_OP_RNG_ERROR 0x1c010002
-#define DCERPC_FAULT_UNK_IF 0x1c010003
-#define DCERPC_FAULT_INVALID_TAG 0x1c000006
-#define DCERPC_FAULT_CONTEXT_MISMATCH 0x1c00001a
-#define DCERPC_FAULT_OTHER 0x00000001
-#define DCERPC_FAULT_ACCESS_DENIED 0x00000005
-#define DCERPC_FAULT_CANT_PERFORM 0x000006d8
-#define DCERPC_FAULT_NDR 0x000006f7
-
-
/* Netlogon schannel auth type and level */
#define SCHANNEL_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
#define SCHANNEL_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 281a218256..01e6ddf64c 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -252,6 +252,8 @@ struct id_map {
#include "librpc/gen_ndr/drsuapi.h"
#include "librpc/gen_ndr/drsblobs.h"
#include "librpc/gen_ndr/spoolss.h"
+#include "librpc/gen_ndr/dcerpc.h"
+#include "librpc/gen_ndr/ndr_dcerpc.h"
struct lsa_dom_info {
bool valid;
@@ -621,6 +623,7 @@ struct smb_request {
uint16 flags2;
uint16 smbpid;
uint16 mid;
+ uint32_t seqnum;
uint16 vuid;
uint16 tid;
uint8 wct;
@@ -722,6 +725,7 @@ struct pending_message_list {
struct timeval request_time; /* When was this first issued? */
struct timed_event *te;
struct smb_perfcount_data pcd;
+ uint32_t seqnum;
bool encrypted;
DATA_BLOB buf;
DATA_BLOB private_data;
@@ -1847,21 +1851,6 @@ struct ip_service {
/* Special name type used to cause a _kerberos DNS lookup. */
#define KDC_NAME_TYPE 0xDCDC
-/* Used by the SMB signing functions. */
-
-typedef struct smb_sign_info {
- void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si);
- bool (*check_incoming_message)(const char *inbuf, struct smb_sign_info *si, bool must_be_ok);
- void (*free_signing_context)(struct smb_sign_info *si);
- void *signing_context;
-
- bool negotiated_smb_signing;
- bool allow_smb_signing;
- bool doing_signing;
- bool mandatory_signing;
- bool seen_valid; /* Have I ever seen a validly signed packet? */
-} smb_sign_info;
-
struct ea_struct {
uint8 flags;
char *name;
diff --git a/source3/include/smb_signing.h b/source3/include/smb_signing.h
new file mode 100644
index 0000000000..770c40cb35
--- /dev/null
+++ b/source3/include/smb_signing.h
@@ -0,0 +1,46 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB Signing Code
+ Copyright (C) Jeremy Allison 2003.
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
+ Copyright (C) Stefan Metzmacher 2009
+
+ 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/>.
+*/
+
+#ifndef _SMB_SIGNING_H_
+#define _SMB_SIGNING_H_
+
+struct smb_signing_state;
+
+struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
+ bool allowed,
+ bool mandatory);
+uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway);
+void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway);
+void smb_signing_sign_pdu(struct smb_signing_state *si,
+ uint8_t *outbuf, uint32_t seqnum);
+bool smb_signing_check_pdu(struct smb_signing_state *si,
+ const uint8_t *inbuf, uint32_t seqnum);
+bool smb_signing_set_bsrspyl(struct smb_signing_state *si);
+bool smb_signing_activate(struct smb_signing_state *si,
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response);
+bool smb_signing_is_active(struct smb_signing_state *si);
+bool smb_signing_is_allowed(struct smb_signing_state *si);
+bool smb_signing_is_mandatory(struct smb_signing_state *si);
+bool smb_signing_set_negotiated(struct smb_signing_state *si);
+bool smb_signing_is_negotiated(struct smb_signing_state *si);
+
+#endif /* _SMB_SIGNING_H_ */
diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c
new file mode 100644
index 0000000000..269b329e64
--- /dev/null
+++ b/source3/lib/avahi.c
@@ -0,0 +1,275 @@
+/*
+ Unix SMB/CIFS implementation.
+ Connect avahi to lib/tevents
+ Copyright (C) Volker Lendecke 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+#include <avahi-common/watch.h>
+
+struct avahi_poll_context {
+ struct tevent_context *ev;
+ AvahiWatch **watches;
+ AvahiTimeout **timeouts;
+};
+
+struct AvahiWatch {
+ struct avahi_poll_context *ctx;
+ struct tevent_fd *fde;
+ int fd;
+ AvahiWatchEvent latest_event;
+ AvahiWatchCallback callback;
+ void *userdata;
+};
+
+struct AvahiTimeout {
+ struct avahi_poll_context *ctx;
+ struct tevent_timer *te;
+ AvahiTimeoutCallback callback;
+ void *userdata;
+};
+
+static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event)
+{
+ return ((event & AVAHI_WATCH_IN) ? TEVENT_FD_READ : 0)
+ | ((event & AVAHI_WATCH_OUT) ? TEVENT_FD_WRITE : 0);
+}
+
+static void avahi_fd_handler(struct tevent_context *ev,
+ struct tevent_fd *fde, uint16_t flags,
+ void *private_data);
+
+static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd,
+ AvahiWatchEvent event,
+ AvahiWatchCallback callback,
+ void *userdata)
+{
+ struct avahi_poll_context *ctx = talloc_get_type_abort(
+ api->userdata, struct avahi_poll_context);
+ int num_watches = talloc_array_length(ctx->watches);
+ AvahiWatch **tmp, *watch_ctx;
+
+ tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ ctx->watches = tmp;
+
+ watch_ctx = talloc(tmp, AvahiWatch);
+ if (watch_ctx == NULL) {
+ goto fail;
+ }
+ ctx->watches[num_watches] = watch_ctx;
+
+ watch_ctx->ctx = ctx;
+ watch_ctx->fde = tevent_add_fd(ctx->ev, watch_ctx, fd,
+ avahi_flags_map_to_tevent(event),
+ avahi_fd_handler, watch_ctx);
+ if (watch_ctx->fde == NULL) {
+ goto fail;
+ }
+ watch_ctx->callback = callback;
+ watch_ctx->userdata = userdata;
+ return watch_ctx;
+
+ fail:
+ TALLOC_FREE(watch_ctx);
+ ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *,
+ num_watches);
+ return NULL;
+}
+
+static void avahi_fd_handler(struct tevent_context *ev,
+ struct tevent_fd *fde, uint16_t flags,
+ void *private_data)
+{
+ AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch);
+
+ watch_ctx->latest_event =
+ ((flags & TEVENT_FD_READ) ? AVAHI_WATCH_IN : 0)
+ | ((flags & TEVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0);
+
+ watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event,
+ watch_ctx->userdata);
+}
+
+static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event)
+{
+ tevent_fd_set_flags(w->fde, avahi_flags_map_to_tevent(event));
+}
+
+static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w)
+{
+ return w->latest_event;
+}
+
+static void avahi_watch_free(AvahiWatch *w)
+{
+ int i, num_watches;
+ AvahiWatch **watches = w->ctx->watches;
+ struct avahi_poll_context *ctx;
+
+ num_watches = talloc_array_length(watches);
+
+ for (i=0; i<num_watches; i++) {
+ if (w == watches[i]) {
+ break;
+ }
+ }
+ if (i == num_watches) {
+ return;
+ }
+ ctx = w->ctx;
+ TALLOC_FREE(w);
+ memmove(&watches[i], &watches[i+1],
+ sizeof(*watches) * (num_watches - i - 1));
+ ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *,
+ num_watches - 1);
+}
+
+static void avahi_timeout_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data);
+
+static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api,
+ const struct timeval *tv,
+ AvahiTimeoutCallback callback,
+ void *userdata)
+{
+ struct avahi_poll_context *ctx = talloc_get_type_abort(
+ api->userdata, struct avahi_poll_context);
+ int num_timeouts = talloc_array_length(ctx->timeouts);
+ AvahiTimeout **tmp, *timeout_ctx;
+
+ tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
+ num_timeouts + 1);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ ctx->timeouts = tmp;
+
+ timeout_ctx = talloc(tmp, AvahiTimeout);
+ if (timeout_ctx == NULL) {
+ goto fail;
+ }
+ ctx->timeouts[num_timeouts] = timeout_ctx;
+
+ timeout_ctx->ctx = ctx;
+ if (tv == NULL) {
+ timeout_ctx->te = NULL;
+ } else {
+ timeout_ctx->te = tevent_add_timer(ctx->ev, timeout_ctx,
+ *tv, avahi_timeout_handler,
+ timeout_ctx);
+ if (timeout_ctx->te == NULL) {
+ goto fail;
+ }
+ }
+ timeout_ctx->callback = callback;
+ timeout_ctx->userdata = userdata;
+ return timeout_ctx;
+
+ fail:
+ TALLOC_FREE(timeout_ctx);
+ ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
+ num_timeouts);
+ return NULL;
+}
+
+static void avahi_timeout_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data)
+{
+ AvahiTimeout *timeout_ctx = talloc_get_type_abort(
+ private_data, AvahiTimeout);
+
+ TALLOC_FREE(timeout_ctx->te);
+ timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata);
+}
+
+static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv)
+{
+ TALLOC_FREE(t->te);
+
+ if (tv == NULL) {
+ /*
+ * Disable this timer
+ */
+ return;
+ }
+
+ t->te = tevent_add_timer(t->ctx->ev, t, *tv, avahi_timeout_handler, t);
+ /*
+ * No failure mode defined here
+ */
+ SMB_ASSERT(t->te != NULL);
+}
+
+static void avahi_timeout_free(AvahiTimeout *t)
+{
+ int i, num_timeouts;
+ AvahiTimeout **timeouts = t->ctx->timeouts;
+ struct avahi_poll_context *ctx;
+
+ num_timeouts = talloc_array_length(timeouts);
+
+ for (i=0; i<num_timeouts; i++) {
+ if (t == timeouts[i]) {
+ break;
+ }
+ }
+ if (i == num_timeouts) {
+ return;
+ }
+ ctx = t->ctx;
+ TALLOC_FREE(t);
+ memmove(&timeouts[i], &timeouts[i+1],
+ sizeof(*timeouts) * (num_timeouts - i - 1));
+ ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *,
+ num_timeouts - 1);
+}
+
+struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev)
+{
+ struct AvahiPoll *result;
+ struct avahi_poll_context *ctx;
+
+ result = talloc(mem_ctx, struct AvahiPoll);
+ if (result == NULL) {
+ return result;
+ }
+ ctx = talloc_zero(result, struct avahi_poll_context);
+ if (ctx == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+ ctx->ev = ev;
+
+ result->watch_new = avahi_watch_new;
+ result->watch_update = avahi_watch_update;
+ result->watch_get_events = avahi_watch_get_events;
+ result->watch_free = avahi_watch_free;
+ result->timeout_new = avahi_timeout_new;
+ result->timeout_update = avahi_timeout_update;
+ result->timeout_free = avahi_timeout_free;
+ result->userdata = ctx;
+
+ return result;
+}
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index b676ae63dd..d28b2b2126 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -57,6 +57,11 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
false, false,
PROTOCOL_NT1,
0, 0x20);
+ if (cli_ipc) {
+ cli_set_username(cli_ipc, ctx->username);
+ cli_set_password(cli_ipc, ctx->password);
+ cli_set_domain(cli_ipc, ctx->workgroup);
+ }
TALLOC_FREE(auth_info);
if (!cli_ipc) {
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index e760a8b1de..1cbb883169 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -1497,6 +1497,9 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
NTSTATUS status = NT_STATUS_OK;
WERROR werr;
+ WERROR werr_tmp;
+
+ *r->out.entries_read = 0;
ZERO_STRUCT(connect_handle);
ZERO_STRUCT(domain_handle);
@@ -1540,15 +1543,18 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
&total_size,
&returned_size,
&info);
- if (!NT_STATUS_IS_OK(status)) {
- werr = ntstatus_to_werror(status);
+ werr = ntstatus_to_werror(status);
+ if (NT_STATUS_IS_ERR(status)) {
goto done;
}
- werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
- r->in.level,
- r->out.entries_read,
- r->out.buffer);
+ werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
+ r->in.level,
+ r->out.entries_read,
+ r->out.buffer);
+ if (!W_ERROR_IS_OK(werr_tmp)) {
+ werr = werr_tmp;
+ }
done:
/* if last query */
if (NT_STATUS_IS_OK(status) ||
diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c
index c5a9b7c29a..50ff844762 100644
--- a/source3/lib/util_file.c
+++ b/source3/lib/util_file.c
@@ -39,7 +39,7 @@ static char *file_pload(const char *syscmd, size_t *size)
total = 0;
while ((n = read(fd, buf, sizeof(buf))) > 0) {
- p = (char *)SMB_REALLOC(p, total + n + 1);
+ p = talloc_realloc(NULL, p, char, total + n + 1);
if (!p) {
DEBUG(0,("file_pload: failed to expand buffer!\n"));
close(fd);
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 3cf992c7de..c22e168454 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -449,8 +449,8 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
ZERO_STRUCT(state->wb_req);
state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
- subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
- &state->wb_req);
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue,
+ state->wb_ctx->fd, &state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;
}
@@ -480,8 +480,8 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq)
state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
- subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
- &state->wb_req);
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue,
+ state->wb_ctx->fd, &state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;
}
@@ -673,8 +673,8 @@ static void wb_trans_connect_done(struct tevent_req *subreq)
return;
}
- subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd,
- state->wb_req);
+ subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue,
+ state->wb_ctx->fd, state->wb_req);
if (tevent_req_nomem(subreq, req)) {
return;
}
diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 73d4439743..0c00b8518a 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -422,9 +422,6 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
TALLOC_FREE(delta_enum_array);
- /* Increment sync_context */
- sync_context += 1;
-
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
out:
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 066ac7bdb8..86fd5c8bef 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -550,7 +550,7 @@ void cli_chain_uncork(struct cli_state *cli)
_smb_setlen_large(((char *)req->outbuf), smblen);
}
- cli_calculate_sign_mac(cli, (char *)req->outbuf);
+ cli_calculate_sign_mac(cli, (char *)req->outbuf, &req->seqnum);
if (cli_encryption_on(cli)) {
NTSTATUS status;
@@ -811,9 +811,16 @@ NTSTATUS cli_pull_reply(struct async_req *req,
*/
-static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu)
+static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu,
+ struct cli_request **_req,
+ uint16_t *_mid)
{
NTSTATUS status;
+ struct cli_request *req = NULL;
+ uint16_t mid;
+
+ *_req = NULL;
+ *_mid = 0;
if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */
&& (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ {
@@ -846,11 +853,27 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu)
}
}
- if (!cli_check_sign_mac(cli, pdu)) {
+ mid = SVAL(pdu, smb_mid);
+
+ for (req = cli->outstanding_requests; req; req = req->next) {
+ if (req->mid == mid) {
+ break;
+ }
+ }
+
+ if (!req) {
+ /* oplock breaks are not signed */
+ goto done;
+ }
+
+ if (!cli_check_sign_mac(cli, pdu, req->seqnum+1)) {
DEBUG(10, ("cli_check_sign_mac failed\n"));
return NT_STATUS_ACCESS_DENIED;
}
+done:
+ *_req = req;
+ *_mid = mid;
return NT_STATUS_OK;
}
@@ -863,7 +886,7 @@ static void handle_incoming_pdu(struct cli_state *cli)
{
struct cli_request *req, *next;
uint16_t mid;
- size_t raw_pdu_len, buf_len, pdu_len, rest_len;
+ size_t raw_pdu_len, buf_len, rest_len;
char *pdu;
int i;
NTSTATUS status;
@@ -923,23 +946,13 @@ static void handle_incoming_pdu(struct cli_state *cli)
}
}
- status = validate_smb_crypto(cli, pdu);
+ status = validate_smb_crypto(cli, pdu, &req, &mid);
if (!NT_STATUS_IS_OK(status)) {
goto invalidate_requests;
}
- mid = SVAL(pdu, smb_mid);
-
DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid));
- for (req = cli->outstanding_requests; req; req = req->next) {
- if (req->mid == mid) {
- break;
- }
- }
-
- pdu_len = smb_len(pdu) + 4;
-
if (req == NULL) {
DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid));
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index ebb01c44a6..aa1ca595a7 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -505,11 +505,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
ok = cli_simple_set_signing(cli, session_key, nt_response);
#endif
if (ok) {
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli, cli->outbuf);
-
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
result = NT_STATUS_ACCESS_DENIED;
goto end;
}
@@ -747,11 +743,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
if (cli_simple_set_signing(
cli, session_key_krb5, data_blob_null)) {
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli, cli->outbuf);
-
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
nt_status = NT_STATUS_ACCESS_DENIED;
goto nt_error;
}
@@ -873,11 +865,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
if (cli_simple_set_signing(
cli, ntlmssp_state->session_key, data_blob_null)) {
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli, cli->outbuf);
-
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
nt_status = NT_STATUS_ACCESS_DENIED;
}
}
@@ -1540,13 +1528,16 @@ NTSTATUS cli_negprot_recv(struct async_req *req)
cli->protocol = prots[protnum].prot;
- if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
+ if ((cli->protocol < PROTOCOL_NT1) &&
+ client_is_signing_mandatory(cli)) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
return NT_STATUS_ACCESS_DENIED;
}
if (cli->protocol >= PROTOCOL_NT1) {
struct timespec ts;
+ bool negotiated_smb_signing = false;
+
/* NT protocol */
cli->sec_mode = CVAL(vwv + 1, 0);
cli->max_mux = SVAL(vwv + 1, 1);
@@ -1579,22 +1570,24 @@ NTSTATUS cli_negprot_recv(struct async_req *req)
if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
/* Fail if server says signing is mandatory and we don't want to support it. */
- if (!cli->sign_info.allow_smb_signing) {
+ if (!client_is_signing_allowed(cli)) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
return NT_STATUS_ACCESS_DENIED;
}
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
- } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
+ negotiated_smb_signing = true;
+ } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
/* Fail if client says signing is mandatory and the server doesn't support it. */
if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
return NT_STATUS_ACCESS_DENIED;
}
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
+ negotiated_smb_signing = true;
} else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
- cli->sign_info.negotiated_smb_signing = True;
+ negotiated_smb_signing = true;
+ }
+
+ if (negotiated_smb_signing) {
+ cli_set_signing_negotiated(cli);
}
if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
@@ -1841,10 +1834,9 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
tevent_req_set_callback(r445, smb_sock_connected, fd445);
tevent_req_set_callback(r139, smb_sock_connected, fd139);
- while ((fd139->fd == -1)
- && tevent_req_is_in_progress(r139)
- && (fd445->fd == -1)
- && tevent_req_is_in_progress(r445)) {
+ while ((fd445->fd == -1) && (fd139->fd == -1)
+ && (tevent_req_is_in_progress(r139)
+ || tevent_req_is_in_progress(r445))) {
event_loop_once(ev);
}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index c1ba4e5c4f..6186387076 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -135,6 +135,79 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen)
return len;
}
+static bool cli_state_set_seqnum(struct cli_state *cli, uint16_t mid, uint32_t seqnum)
+{
+ struct cli_state_seqnum *c;
+
+ for (c = cli->seqnum; c; c = c->next) {
+ if (c->mid == mid) {
+ c->seqnum = seqnum;
+ return true;
+ }
+ }
+
+ c = talloc_zero(cli, struct cli_state_seqnum);
+ if (!c) {
+ return false;
+ }
+
+ c->mid = mid;
+ c->seqnum = seqnum;
+ c->persistent = false;
+ DLIST_ADD_END(cli->seqnum, c, struct cli_state_seqnum *);
+
+ return true;
+}
+
+bool cli_state_seqnum_persistent(struct cli_state *cli,
+ uint16_t mid)
+{
+ struct cli_state_seqnum *c;
+
+ for (c = cli->seqnum; c; c = c->next) {
+ if (c->mid == mid) {
+ c->persistent = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool cli_state_seqnum_remove(struct cli_state *cli,
+ uint16_t mid)
+{
+ struct cli_state_seqnum *c;
+
+ for (c = cli->seqnum; c; c = c->next) {
+ if (c->mid == mid) {
+ DLIST_REMOVE(cli->seqnum, c);
+ TALLOC_FREE(c);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static uint32_t cli_state_get_seqnum(struct cli_state *cli, uint16_t mid)
+{
+ struct cli_state_seqnum *c;
+
+ for (c = cli->seqnum; c; c = c->next) {
+ if (c->mid == mid) {
+ uint32_t seqnum = c->seqnum;
+ if (!c->persistent) {
+ DLIST_REMOVE(cli->seqnum, c);
+ TALLOC_FREE(c);
+ }
+ return seqnum;
+ }
+ }
+
+ return 0;
+}
+
/****************************************************************************
Recv an smb.
****************************************************************************/
@@ -142,6 +215,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen)
bool cli_receive_smb(struct cli_state *cli)
{
ssize_t len;
+ uint16_t mid;
+ uint32_t seqnum;
/* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
if (cli->fd == -1)
@@ -177,7 +252,10 @@ bool cli_receive_smb(struct cli_state *cli)
return false;
}
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ mid = SVAL(cli->inbuf,smb_mid);
+ seqnum = cli_state_get_seqnum(cli, mid);
+
+ if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) {
/*
* If we get a signature failure in sessionsetup, then
* the server sometimes just reflects the sent signature
@@ -264,12 +342,20 @@ bool cli_send_smb(struct cli_state *cli)
ssize_t ret;
char *buf_out = cli->outbuf;
bool enc_on = cli_encryption_on(cli);
+ uint32_t seqnum;
/* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
if (cli->fd == -1)
return false;
- cli_calculate_sign_mac(cli, cli->outbuf);
+ cli_calculate_sign_mac(cli, cli->outbuf, &seqnum);
+
+ if (!cli_state_set_seqnum(cli, cli->mid, seqnum)) {
+ DEBUG(0,("Failed to store mid[%u]/seqnum[%u]\n",
+ (unsigned int)cli->mid,
+ (unsigned int)seqnum));
+ return false;
+ }
if (enc_on) {
NTSTATUS status = cli_encrypt_message(cli, cli->outbuf,
@@ -506,6 +592,7 @@ struct cli_state *cli_initialise_ex(int signing_state)
cli->bufsize = CLI_BUFFER_SIZE+4;
cli->max_xmit = cli->bufsize;
cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
+ cli->seqnum = 0;
cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
cli->oplock_handler = cli_oplock_ack;
cli->case_sensitive = false;
@@ -556,9 +643,12 @@ struct cli_state *cli_initialise_ex(int signing_state)
#endif
/* initialise signing */
- cli->sign_info.allow_smb_signing = allow_smb_signing;
- cli->sign_info.mandatory_signing = mandatory_signing;
- cli_null_set_signing(cli);
+ cli->signing_state = smb_signing_init(cli,
+ allow_smb_signing,
+ mandatory_signing);
+ if (!cli->signing_state) {
+ goto error;
+ }
cli->initialised = 1;
@@ -641,7 +731,6 @@ void cli_shutdown(struct cli_state *cli)
SAFE_FREE(cli->outbuf);
SAFE_FREE(cli->inbuf);
- cli_free_signing_context(cli);
data_blob_free(&cli->secblob);
data_blob_free(&cli->user_session_key);
@@ -740,7 +829,6 @@ static void cli_echo_recv_helper(struct async_req *req)
cli_req->data.echo.num_echos -= 1;
if (cli_req->data.echo.num_echos == 0) {
- client_set_trans_sign_state_off(cli_req->cli, cli_req->mid);
async_req_done(req);
return;
}
@@ -782,8 +870,6 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
req = talloc_get_type_abort(result->private_data, struct cli_request);
- client_set_trans_sign_state_on(cli, req->mid);
-
req->data.echo.num_echos = num_echos;
req->data.echo.data.data = talloc_move(req, &data_copy);
req->data.echo.data.length = data.length;
diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c
new file mode 100644
index 0000000000..0d0e926e6c
--- /dev/null
+++ b/source3/libsmb/clisigning.c
@@ -0,0 +1,87 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB Signing Code
+ Copyright (C) Jeremy Allison 2003.
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
+ Copyright (C) Stefan Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+bool cli_simple_set_signing(struct cli_state *cli,
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response)
+{
+ bool ok;
+
+ ok = smb_signing_activate(cli->signing_state,
+ user_session_key,
+ response);
+ if (!ok) {
+ return false;
+ }
+
+ cli->readbraw_supported = false;
+ cli->writebraw_supported = false;
+
+ return true;
+}
+
+bool cli_temp_set_signing(struct cli_state *cli)
+{
+ return smb_signing_set_bsrspyl(cli->signing_state);
+}
+
+void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum)
+{
+ *seqnum = smb_signing_next_seqnum(cli->signing_state, false);
+ smb_signing_sign_pdu(cli->signing_state, (uint8_t *)buf, *seqnum);
+}
+
+bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum)
+{
+ bool ok;
+
+ ok = smb_signing_check_pdu(cli->signing_state,
+ (const uint8_t *)buf,
+ seqnum);
+
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
+void cli_set_signing_negotiated(struct cli_state *cli)
+{
+ smb_signing_set_negotiated(cli->signing_state);
+}
+
+bool client_is_signing_on(struct cli_state *cli)
+{
+ return smb_signing_is_active(cli->signing_state);
+}
+
+bool client_is_signing_allowed(struct cli_state *cli)
+{
+ return smb_signing_is_allowed(cli->signing_state);
+}
+
+bool client_is_signing_mandatory(struct cli_state *cli)
+{
+ return smb_signing_is_mandatory(cli->signing_state);
+}
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index 0266c0307e..c566972b21 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -94,14 +94,12 @@ bool cli_send_trans(struct cli_state *cli, int trans,
return False;
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
- client_set_trans_sign_state_on(cli, mid);
+ cli_state_seqnum_persistent(cli, mid);
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) || cli_is_error(cli)) {
- client_set_trans_sign_state_off(cli, mid);
+ cli_state_seqnum_remove(cli, mid);
return(False);
}
@@ -137,12 +135,11 @@ bool cli_send_trans(struct cli_state *cli, int trans,
show_msg(cli->outbuf);
- client_set_trans_sign_state_off(cli, mid);
cli->mid = mid;
if (!cli_send_smb(cli)) {
+ cli_state_seqnum_remove(cli, mid);
return False;
}
- client_set_trans_sign_state_on(cli, mid);
tot_data += this_ldata;
tot_param += this_lparam;
@@ -165,10 +162,14 @@ bool cli_receive_trans(struct cli_state *cli,int trans,
unsigned int this_data,this_param;
NTSTATUS status;
bool ret = False;
+ uint16_t mid;
*data_len = *param_len = 0;
+ mid = SVAL(cli->inbuf,smb_mid);
+
if (!cli_receive_smb(cli)) {
+ cli_state_seqnum_remove(cli, mid);
return False;
}
@@ -179,6 +180,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans,
DEBUG(0,("Expected %s response, got command 0x%02x\n",
trans==SMBtrans?"SMBtrans":"SMBtrans2",
CVAL(cli->inbuf,smb_com)));
+ cli_state_seqnum_remove(cli, mid);
return False;
}
@@ -331,6 +333,8 @@ bool cli_receive_trans(struct cli_state *cli,int trans,
out:
+ cli_state_seqnum_remove(cli, mid);
+
if (ret) {
/* Ensure the last 2 bytes of param and data are 2 null
* bytes. These are malloc'ed, but not included in any
@@ -344,7 +348,6 @@ bool cli_receive_trans(struct cli_state *cli,int trans,
}
}
- client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid));
return ret;
}
@@ -412,14 +415,12 @@ bool cli_send_nt_trans(struct cli_state *cli,
return False;
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
- client_set_trans_sign_state_on(cli, mid);
+ cli_state_seqnum_persistent(cli, mid);
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) || cli_is_error(cli)) {
- client_set_trans_sign_state_off(cli, mid);
+ cli_state_seqnum_remove(cli, mid);
return(False);
}
@@ -454,12 +455,11 @@ bool cli_send_nt_trans(struct cli_state *cli,
show_msg(cli->outbuf);
- client_set_trans_sign_state_off(cli, mid);
cli->mid = mid;
if (!cli_send_smb(cli)) {
+ cli_state_seqnum_remove(cli, mid);
return False;
}
- client_set_trans_sign_state_on(cli, mid);
tot_data += this_ldata;
tot_param += this_lparam;
@@ -483,10 +483,14 @@ bool cli_receive_nt_trans(struct cli_state *cli,
uint8 eclass;
uint32 ecode;
bool ret = False;
+ uint16_t mid;
*data_len = *param_len = 0;
+ mid = SVAL(cli->inbuf,smb_mid);
+
if (!cli_receive_smb(cli)) {
+ cli_state_seqnum_remove(cli, mid);
return False;
}
@@ -496,6 +500,7 @@ bool cli_receive_nt_trans(struct cli_state *cli,
if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
CVAL(cli->inbuf,smb_com)));
+ cli_state_seqnum_remove(cli, mid);
return(False);
}
@@ -669,6 +674,8 @@ bool cli_receive_nt_trans(struct cli_state *cli,
out:
+ cli_state_seqnum_remove(cli, mid);
+
if (ret) {
/* Ensure the last 2 bytes of param and data are 2 null
* bytes. These are malloc'ed, but not included in any
@@ -682,7 +689,6 @@ bool cli_receive_nt_trans(struct cli_state *cli,
}
}
- client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid));
return ret;
}
@@ -696,6 +702,7 @@ struct cli_trans_state {
struct event_context *ev;
uint8_t cmd;
uint16_t mid;
+ uint32_t seqnum;
const char *pipe_name;
uint16_t fid;
uint16_t function;
@@ -919,6 +926,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
cli_req = talloc_get_type_abort(result->private_data,
struct cli_request);
state->mid = cli_req->mid;
+ state->seqnum = cli_req->seqnum;
} else {
uint16_t num_bytes = talloc_get_size(bytes);
/*
@@ -939,12 +947,10 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
cli_req->recv_helper.fn = cli_trans_recv_helper;
cli_req->recv_helper.priv = state;
cli_req->mid = state->mid;
- client_set_trans_sign_state_off(state->cli, state->mid);
cli_chain_uncork(state->cli);
+ state->seqnum = cli_req->seqnum;
}
- client_set_trans_sign_state_on(state->cli, state->mid);
-
fail:
TALLOC_FREE(frame);
return result;
@@ -953,6 +959,8 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
static void cli_trans_ship_rest(struct async_req *req,
struct cli_trans_state *state)
{
+ struct cli_request *cli_req;
+
state->secondary_request_ctx = talloc_new(state);
if (state->secondary_request_ctx == NULL) {
async_req_nterror(req, NT_STATUS_NO_MEMORY);
@@ -961,14 +969,19 @@ static void cli_trans_ship_rest(struct async_req *req,
while ((state->param_sent < state->num_param)
|| (state->data_sent < state->num_data)) {
- struct async_req *cli_req;
+ struct async_req *subreq;
- cli_req = cli_ship_trans(state->secondary_request_ctx, state);
- if (cli_req == NULL) {
+ subreq = cli_ship_trans(state->secondary_request_ctx, state);
+ if (subreq == NULL) {
async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
}
+
+ cli_req = talloc_get_type_abort(req->private_data,
+ struct cli_request);
+
+ cli_req->seqnum = state->seqnum;
}
static NTSTATUS cli_pull_trans(struct async_req *req,
@@ -1174,7 +1187,6 @@ static void cli_trans_recv_helper(struct async_req *req)
if ((state->rparam.total == state->rparam.received)
&& (state->rdata.total == state->rdata.received)) {
- client_set_trans_sign_state_off(state->cli, state->mid);
async_req_done(req);
}
}
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 3491544175..1064a63d97 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -311,7 +311,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *
/****************************************************************
****************************************************************/
-#define RETURN_ON_FALSE(x) if (!x) return false;
+#define RETURN_ON_FALSE(x) if (!(x)) return false;
static bool check_cldap_reply_required_flags(uint32_t ret_flags,
uint32_t req_flags)
diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c
index 795c8bc14c..2f7305c5b6 100644
--- a/source3/libsmb/smb_seal.c
+++ b/source3/libsmb/smb_seal.c
@@ -136,7 +136,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num);
- sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+ ZERO_STRUCT(sig);
status = ntlmssp_seal_packet(ntlmssp_state,
(unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
@@ -153,6 +153,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
/* First 16 data bytes are signature for SSPI compatibility. */
memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE);
+ data_blob_free(&sig);
*ppbuf_out = buf_out;
return NT_STATUS_OK;
}
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index a3ed0e7572..32d2883965 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -1,8 +1,9 @@
-/*
+/*
Unix SMB/CIFS implementation.
SMB Signing Code
Copyright (C) Jeremy Allison 2003.
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
+ Copyright (C) Stefan Metzmacher 2009
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
@@ -20,260 +21,89 @@
#include "includes.h"
-/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */
-struct outstanding_packet_lookup {
- struct outstanding_packet_lookup *prev, *next;
- uint16 mid;
- uint32 reply_seq_num;
- bool can_delete; /* Set to False in trans state. */
-};
+/* Used by the SMB signing functions. */
-struct smb_basic_signing_context {
- DATA_BLOB mac_key;
- uint32 send_seq_num;
- struct outstanding_packet_lookup *outstanding_packet_list;
-};
-
-static bool store_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 reply_seq_num)
-{
- struct outstanding_packet_lookup *t;
+struct smb_signing_state {
+ /* is signing localy allowed */
+ bool allowed;
- /* Ensure we only add a mid once. */
- for (t = *list; t; t = t->next) {
- if (t->mid == mid) {
- return False;
- }
- }
+ /* is signing localy mandatory */
+ bool mandatory;
- t = SMB_XMALLOC_P(struct outstanding_packet_lookup);
- ZERO_STRUCTP(t);
+ /* is signing negotiated by the peer */
+ bool negotiated;
- t->mid = mid;
- t->reply_seq_num = reply_seq_num;
- t->can_delete = True;
+ /* send BSRSPYL signatures */
+ bool bsrspyl;
- /*
- * Add to the *start* of the list not the end of the list.
- * This ensures that the *last* send sequence with this mid
- * is returned by preference.
- * This can happen if the mid wraps and one of the early
- * mid numbers didn't get a reply and is still lurking on
- * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>.
- */
+ bool active; /* Have I ever seen a validly signed packet? */
- DLIST_ADD(*list, t);
- DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n",
- (unsigned int)reply_seq_num, (unsigned int)mid ));
- return True;
-}
+ /* mac_key.length > 0 means signing is started */
+ DATA_BLOB mac_key;
-static bool get_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 *reply_seq_num)
-{
- struct outstanding_packet_lookup *t;
-
- for (t = *list; t; t = t->next) {
- if (t->mid == mid) {
- *reply_seq_num = t->reply_seq_num;
- DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
- (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
- if (t->can_delete) {
- DLIST_REMOVE(*list, t);
- SAFE_FREE(t);
- }
- return True;
- }
- }
- return False;
-}
+ /* the next expected seqnum */
+ uint32_t seqnum;
+};
-static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry)
+static void smb_signing_reset_info(struct smb_signing_state *si)
{
- struct outstanding_packet_lookup *t;
-
- for (t = *list; t; t = t->next) {
- if (t->mid == mid) {
- t->can_delete = can_delete_entry;
- return True;
- }
- }
- return False;
+ si->active = false;
+ si->bsrspyl = false;
+ data_blob_free(&si->mac_key);
+ si->seqnum = 0;
}
-/***********************************************************
- SMB signing - Common code before we set a new signing implementation
-************************************************************/
-
-static bool cli_set_smb_signing_common(struct cli_state *cli)
+struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
+ bool allowed,
+ bool mandatory)
{
- if (!cli->sign_info.allow_smb_signing) {
- return False;
- }
+ struct smb_signing_state *si;
- if (!cli->sign_info.negotiated_smb_signing
- && !cli->sign_info.mandatory_signing) {
- return False;
+ si = talloc_zero(mem_ctx, struct smb_signing_state);
+ if (si == NULL) {
+ return NULL;
}
- if (cli->sign_info.doing_signing) {
- return False;
+ if (mandatory) {
+ allowed = true;
}
- if (cli->sign_info.free_signing_context)
- cli->sign_info.free_signing_context(&cli->sign_info);
-
- /* These calls are INCOMPATIBLE with SMB signing */
- cli->readbraw_supported = False;
- cli->writebraw_supported = False;
-
- return True;
-}
-
-/***********************************************************
- SMB signing - Common code for 'real' implementations
-************************************************************/
-
-static bool set_smb_signing_real_common(struct smb_sign_info *si)
-{
- if (si->mandatory_signing) {
- DEBUG(5, ("Mandatory SMB signing enabled!\n"));
- }
-
- si->doing_signing = True;
- DEBUG(5, ("SMB signing enabled!\n"));
-
- return True;
-}
-
-static void mark_packet_signed(char *outbuf)
-{
- uint16 flags2;
- flags2 = SVAL(outbuf,smb_flg2);
- flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
- SSVAL(outbuf,smb_flg2, flags2);
-}
-
-/***********************************************************
- SMB signing - NULL implementation - calculate a MAC to send.
-************************************************************/
-
-static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- /* we can't zero out the sig, as we might be trying to send a
- session request - which is NBT-level, not SMB level and doesn't
- have the field */
- return;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - check a MAC sent by server.
-************************************************************/
-
-static bool null_check_incoming_message(const char *inbuf,
- struct smb_sign_info *si,
- bool must_be_ok)
-{
- return True;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - free signing context
-************************************************************/
-
-static void null_free_signing_context(struct smb_sign_info *si)
-{
- return;
-}
-
-/**
- SMB signing - NULL implementation - setup the MAC key.
-
- @note Used as an initialisation only - it will not correctly
- shut down a real signing mechanism
-*/
-
-static bool null_set_signing(struct smb_sign_info *si)
-{
- si->signing_context = NULL;
-
- si->sign_outgoing_message = null_sign_outgoing_message;
- si->check_incoming_message = null_check_incoming_message;
- si->free_signing_context = null_free_signing_context;
-
- return True;
-}
-
-/**
- * Free the signing context
- */
-
-static void free_signing_context(struct smb_sign_info *si)
-{
- if (si->free_signing_context) {
- si->free_signing_context(si);
- si->signing_context = NULL;
- }
+ si->allowed = allowed;
+ si->mandatory = mandatory;
- null_set_signing(si);
+ return si;
}
-
-static bool signing_good(const char *inbuf, struct smb_sign_info *si,
- bool good, uint32 seq, bool must_be_ok)
+static bool smb_signing_good(struct smb_signing_state *si,
+ bool good, uint32_t seq)
{
if (good) {
-
- if (!si->doing_signing) {
- si->doing_signing = True;
+ if (!si->active) {
+ si->active = true;
}
+ return true;
+ }
- if (!si->seen_valid) {
- si->seen_valid = True;
- }
-
- } else {
- if (!si->mandatory_signing && !si->seen_valid) {
-
- if (!must_be_ok) {
- return True;
- }
- /* Non-mandatory signing - just turn off if this is the first bad packet.. */
- DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n"
- "isn't sending correct signatures. Turning off.\n"));
- si->negotiated_smb_signing = False;
- si->allow_smb_signing = False;
- si->doing_signing = False;
- free_signing_context(si);
- return True;
- } else if (!must_be_ok) {
- /* This packet is known to be unsigned */
- return True;
- } else {
- /* Mandatory signing or bad packet after signing started - fail and disconnect. */
- if (seq)
- DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
- return False;
- }
+ if (!si->mandatory && !si->active) {
+ /* Non-mandatory signing - just turn off if this is the first bad packet.. */
+ DEBUG(5, ("smb_signing_good: signing negotiated but not required and peer\n"
+ "isn't sending correct signatures. Turning off.\n"));
+ smb_signing_reset_info(si);
+ return true;
}
- return True;
-}
-/***********************************************************
- SMB signing - Simple implementation - calculate a MAC on the packet
-************************************************************/
+ /* Mandatory signing or bad packet after signing started - fail and disconnect. */
+ DEBUG(0, ("smb_signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
+ return false;
+}
-static void simple_packet_signature(struct smb_basic_signing_context *data,
- const uchar *buf, uint32 seq_number,
- unsigned char calc_md5_mac[16])
+static void smb_signing_md5(const DATA_BLOB *mac_key,
+ const uint8_t *buf, uint32_t seq_number,
+ uint8_t calc_md5_mac[16])
{
const size_t offset_end_of_sig = (smb_ss_field + 8);
- unsigned char sequence_buf[8];
+ uint8_t sequence_buf[8];
struct MD5Context md5_ctx;
-#if 0
- /* JRA - apparently this is incorrect. */
- unsigned char key_buf[16];
-#endif
/*
* Firstly put the sequence number into the first 4 bytes.
@@ -282,7 +112,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
* We do this here, to avoid modifying the packet.
*/
- DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
+ DEBUG(10,("smb_signing_md5: sequence number %u\n", seq_number ));
SIVAL(sequence_buf, 0, seq_number);
SIVAL(sequence_buf, 4, 0);
@@ -295,17 +125,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
MD5Init(&md5_ctx);
/* intialise with the key */
- MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length);
-#if 0
- /* JRA - apparently this is incorrect. */
- /* NB. When making and verifying SMB signatures, Windows apparently
- zero-pads the key to 128 bits if it isn't long enough.
- From Nalin Dahyabhai <nalin@redhat.com> */
- if (data->mac_key.length < sizeof(key_buf)) {
- memset(key_buf, 0, sizeof(key_buf));
- MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length);
- }
-#endif
+ MD5Update(&md5_ctx, mac_key->data, mac_key->length);
/* copy in the first bit of the SMB header */
MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
@@ -317,690 +137,234 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
MD5Update(&md5_ctx, buf + offset_end_of_sig,
smb_len(buf) - (offset_end_of_sig - 4));
- /* calculate the MD5 sig */
+ /* calculate the MD5 sig */
MD5Final(calc_md5_mac, &md5_ctx);
}
-
-/***********************************************************
- SMB signing - Client implementation - send the MAC.
-************************************************************/
-
-static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- unsigned char calc_md5_mac[16];
- struct smb_basic_signing_context *data =
- (struct smb_basic_signing_context *)si->signing_context;
-
- if (!si->doing_signing)
- return;
-
- /* JRA Paranioa test - we should be able to get rid of this... */
- if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
- smb_len(outbuf) ));
- abort();
- }
-
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- simple_packet_signature(data, (const unsigned char *)outbuf,
- data->send_seq_num, calc_md5_mac);
-
- DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
- dump_data(10, calc_md5_mac, 8);
-
- memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
-
-/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote server actually verifies signatures...*/
-
- /* Instead of re-introducing the trans_info_conect we
- used to have here, we use the fact that during a
- SMBtrans/SMBtrans2/SMBnttrans send that the mid stays
- constant. This means that calling store_sequence_for_reply()
- will return False for all trans secondaries, as the mid is already
- on the stored sequence list. As the send_seqence_number must
- remain constant for all primary+secondary trans sends, we
- only increment the send sequence number when we successfully
- add a new entry to the outstanding sequence list. This means
- I can isolate the fix here rather than re-adding the trans
- signing on/off calls in libsmb/clitrans2.c JRA.
- */
-
- if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) {
- data->send_seq_num += 2;
- }
-}
-
-/***********************************************************
- SMB signing - Client implementation - check a MAC sent by server.
-************************************************************/
-
-static bool client_check_incoming_message(const char *inbuf,
- struct smb_sign_info *si,
- bool must_be_ok)
+uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway)
{
- bool good;
- uint32 reply_seq_number;
- unsigned char calc_md5_mac[16];
- unsigned char *server_sent_mac;
-
- struct smb_basic_signing_context *data =
- (struct smb_basic_signing_context *)si->signing_context;
+ uint32_t seqnum;
- if (!si->doing_signing)
- return True;
-
- if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
- return False;
+ if (si->mac_key.length == 0) {
+ return 0;
}
- if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) {
- DEBUG(1, ("client_check_incoming_message: received message "
- "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) ));
- return False;
- }
-
- simple_packet_signature(data, (const unsigned char *)inbuf,
- reply_seq_number, calc_md5_mac);
-
- server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
- good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
-
- if (!good) {
- DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
- dump_data(5, calc_md5_mac, 8);
-
- DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
- dump_data(5, server_sent_mac, 8);
-#if 1 /* JRATEST */
- {
- int i;
- for (i = -5; i < 5; i++) {
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac);
- if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \
-We were expecting seq %u\n", reply_seq_number+i, reply_seq_number ));
- break;
- }
- }
- }
-#endif /* JRATEST */
-
+ seqnum = si->seqnum;
+ if (oneway) {
+ si->seqnum += 1;
} else {
- DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
- dump_data(10, server_sent_mac, 8);
- }
- return signing_good(inbuf, si, good, reply_seq_number, must_be_ok);
-}
-
-/***********************************************************
- SMB signing - Simple implementation - free signing context
-************************************************************/
-
-static void simple_free_signing_context(struct smb_sign_info *si)
-{
- struct smb_basic_signing_context *data =
- (struct smb_basic_signing_context *)si->signing_context;
- struct outstanding_packet_lookup *list;
- struct outstanding_packet_lookup *next;
-
- for (list = data->outstanding_packet_list; list; list = next) {
- next = list->next;
- DLIST_REMOVE(data->outstanding_packet_list, list);
- SAFE_FREE(list);
+ si->seqnum += 2;
}
- data_blob_free(&data->mac_key);
-
- SAFE_FREE(si->signing_context);
-
- return;
+ return seqnum;
}
-/***********************************************************
- SMB signing - Simple implementation - setup the MAC key.
-************************************************************/
-
-bool cli_simple_set_signing(struct cli_state *cli,
- const DATA_BLOB user_session_key,
- const DATA_BLOB response)
+void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway)
{
- struct smb_basic_signing_context *data;
-
- if (!user_session_key.length)
- return False;
-
- if (!cli_set_smb_signing_common(cli)) {
- return False;
- }
-
- if (!set_smb_signing_real_common(&cli->sign_info)) {
- return False;
+ if (si->mac_key.length == 0) {
+ return;
}
- data = SMB_XMALLOC_P(struct smb_basic_signing_context);
- memset(data, '\0', sizeof(*data));
-
- cli->sign_info.signing_context = data;
-
- data->mac_key = data_blob(NULL, response.length + user_session_key.length);
-
- memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
-
- DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
- dump_data(10, user_session_key.data, user_session_key.length);
-
- if (response.length) {
- memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
- DEBUG(10, ("cli_simple_set_signing: response_data\n"));
- dump_data(10, response.data, response.length);
+ if (oneway) {
+ si->seqnum -= 1;
} else {
- DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
+ si->seqnum -= 2;
}
-
- dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
-
- /* Initialise the sequence number */
- data->send_seq_num = 0;
-
- /* Initialise the list of outstanding packets */
- data->outstanding_packet_list = NULL;
-
- cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
- cli->sign_info.check_incoming_message = client_check_incoming_message;
- cli->sign_info.free_signing_context = simple_free_signing_context;
-
- return True;
}
-/***********************************************************
- SMB signing - TEMP implementation - calculate a MAC to send.
-************************************************************/
-
-static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
+void smb_signing_sign_pdu(struct smb_signing_state *si,
+ uint8_t *outbuf, uint32_t seqnum)
{
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- /* I wonder what BSRSPYL stands for - but this is what MS
- actually sends! */
- memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
- return;
-}
-
-/***********************************************************
- SMB signing - TEMP implementation - check a MAC sent by server.
-************************************************************/
+ uint8_t calc_md5_mac[16];
+ uint16_t flags2;
-static bool temp_check_incoming_message(const char *inbuf,
- struct smb_sign_info *si, bool foo)
-{
- return True;
-}
-
-/***********************************************************
- SMB signing - TEMP implementation - free signing context
-************************************************************/
-
-static void temp_free_signing_context(struct smb_sign_info *si)
-{
- return;
-}
-
-/***********************************************************
- SMB signing - NULL implementation - setup the MAC key.
-************************************************************/
-
-bool cli_null_set_signing(struct cli_state *cli)
-{
- return null_set_signing(&cli->sign_info);
-}
-
-/***********************************************************
- SMB signing - temp implementation - setup the MAC key.
-************************************************************/
-
-bool cli_temp_set_signing(struct cli_state *cli)
-{
- if (!cli_set_smb_signing_common(cli)) {
- return False;
- }
-
- cli->sign_info.signing_context = NULL;
-
- cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
- cli->sign_info.check_incoming_message = temp_check_incoming_message;
- cli->sign_info.free_signing_context = temp_free_signing_context;
-
- return True;
-}
-
-void cli_free_signing_context(struct cli_state *cli)
-{
- free_signing_context(&cli->sign_info);
-}
-
-/**
- * Sign a packet with the current mechanism
- */
-
-void cli_calculate_sign_mac(struct cli_state *cli, char *buf)
-{
- cli->sign_info.sign_outgoing_message(buf, &cli->sign_info);
-}
-
-/**
- * Check a packet with the current mechanism
- * @return False if we had an established signing connection
- * which had a bad checksum, True otherwise.
- */
-
-bool cli_check_sign_mac(struct cli_state *cli, char *buf)
-{
- if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) {
- free_signing_context(&cli->sign_info);
- return False;
- }
- return True;
-}
-
-/***********************************************************
- Enter trans/trans2/nttrans state.
-************************************************************/
-
-bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid)
-{
- struct smb_sign_info *si = &cli->sign_info;
- struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
-
- if (!si->doing_signing) {
- return True;
- }
-
- if (!data) {
- return False;
- }
-
- if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) {
- return False;
- }
-
- return True;
-}
-
-/***********************************************************
- Leave trans/trans2/nttrans state.
-************************************************************/
-
-bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid)
-{
- uint32 reply_seq_num;
- struct smb_sign_info *si = &cli->sign_info;
- struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
-
- if (!si->doing_signing) {
- return True;
- }
-
- if (!data) {
- return False;
- }
-
- if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) {
- return False;
- }
-
- /* Now delete the stored mid entry. */
- if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) {
- return False;
- }
-
- return True;
-}
-
-/***********************************************************
- Is client signing on ?
-************************************************************/
-
-bool client_is_signing_on(struct cli_state *cli)
-{
- struct smb_sign_info *si = &cli->sign_info;
- return si->doing_signing;
-}
-
-/***********************************************************
- SMB signing - Server implementation - send the MAC.
-************************************************************/
-
-static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
-{
- unsigned char calc_md5_mac[16];
- struct smb_basic_signing_context *data =
- (struct smb_basic_signing_context *)si->signing_context;
- uint32 send_seq_number = data->send_seq_num-1;
- uint16 mid;
-
- if (!si->doing_signing) {
- return;
+ if (si->mac_key.length == 0) {
+ if (!si->bsrspyl) {
+ return;
+ }
}
/* JRA Paranioa test - we should be able to get rid of this... */
if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
- smb_len(outbuf) ));
+ DEBUG(1,("smb_signing_sign_pdu: Logic error. "
+ "Can't check signature on short packet! smb_len = %u\n",
+ smb_len(outbuf)));
abort();
}
/* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(outbuf);
-
- mid = SVAL(outbuf, smb_mid);
-
- /* See if this is a reply for a deferred packet. */
- get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number);
+ flags2 = SVAL(outbuf,smb_flg2);
+ flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
+ SSVAL(outbuf, smb_flg2, flags2);
- simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
+ if (si->bsrspyl) {
+ /* I wonder what BSRSPYL stands for - but this is what MS
+ actually sends! */
+ memcpy(calc_md5_mac, "BSRSPYL ", 8);
+ } else {
+ smb_signing_md5(&si->mac_key, outbuf,
+ seqnum, calc_md5_mac);
+ }
- DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
+ DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n"));
dump_data(10, calc_md5_mac, 8);
memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
-/* cli->outbuf[smb_ss_field+2]=0;
- Uncomment this to test if the remote client actually verifies signatures...*/
+/* outbuf[smb_ss_field+2]=0;
+ Uncomment this to test if the remote server actually verifies signatures...*/
}
-/***********************************************************
- SMB signing - Server implementation - check a MAC sent by server.
-************************************************************/
-
-static bool srv_check_incoming_message(const char *inbuf,
- struct smb_sign_info *si,
- bool must_be_ok)
+bool smb_signing_check_pdu(struct smb_signing_state *si,
+ const uint8_t *inbuf, uint32_t seqnum)
{
bool good;
- struct smb_basic_signing_context *data =
- (struct smb_basic_signing_context *)si->signing_context;
- uint32 reply_seq_number = data->send_seq_num;
- uint32 saved_seq;
- unsigned char calc_md5_mac[16];
- unsigned char *server_sent_mac;
+ uint8_t calc_md5_mac[16];
+ const uint8_t *reply_sent_mac;
- if (!si->doing_signing)
- return True;
+ if (si->mac_key.length == 0) {
+ return true;
+ }
if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
+ DEBUG(1,("smb_signing_check_pdu: Can't check signature "
+ "on short packet! smb_len = %u\n",
+ smb_len(inbuf)));
return False;
}
- /* We always increment the sequence number. */
- data->send_seq_num += 2;
-
- saved_seq = reply_seq_number;
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
+ smb_signing_md5(&si->mac_key, inbuf,
+ seqnum, calc_md5_mac);
- server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
- good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
+ reply_sent_mac = &inbuf[smb_ss_field];
+ good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0);
if (!good) {
+ int i;
+ const int sign_range = 5;
- if (saved_seq) {
- DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
- (unsigned int)saved_seq));
- dump_data(5, calc_md5_mac, 8);
-
- DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
- (unsigned int)reply_seq_number));
- dump_data(5, server_sent_mac, 8);
- }
+ DEBUG(5, ("smb_signing_check_pdu: BAD SIG: wanted SMB signature of\n"));
+ dump_data(5, calc_md5_mac, 8);
-#if 1 /* JRATEST */
- {
- int i;
- reply_seq_number -= 5;
- for (i = 0; i < 10; i++, reply_seq_number++) {
- simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
- if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
- DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \
-We were expecting seq %u\n", reply_seq_number, saved_seq ));
- break;
- }
+ DEBUG(5, ("smb_signing_check_pdu: BAD SIG: got SMB signature of\n"));
+ dump_data(5, reply_sent_mac, 8);
+
+ for (i = -sign_range; i < sign_range; i++) {
+ smb_signing_md5(&si->mac_key, inbuf,
+ seqnum+i, calc_md5_mac);
+ if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) {
+ DEBUG(0,("smb_signing_check_pdu: "
+ "out of seq. seq num %u matches. "
+ "We were expecting seq %u\n",
+ (unsigned int)seqnum+i,
+ (unsigned int)seqnum));
+ break;
}
}
-#endif /* JRATEST */
-
} else {
- DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num));
- dump_data(10, server_sent_mac, 8);
+ DEBUG(10, ("smb_signing_check_pdu: seq %u: "
+ "got good SMB signature of\n",
+ (unsigned int)seqnum));
+ dump_data(10, reply_sent_mac, 8);
}
- return (signing_good(inbuf, si, good, saved_seq, must_be_ok));
+ return smb_signing_good(si, good, seqnum);
}
-/***********************************************************
- SMB signing - server API's.
-************************************************************/
-
-static struct smb_sign_info srv_sign_info = {
- null_sign_outgoing_message,
- null_check_incoming_message,
- null_free_signing_context,
- NULL,
- False,
- False,
- False,
- False
-};
-
-/***********************************************************
- Turn signing off or on for oplock break code.
-************************************************************/
-
-bool srv_oplock_set_signing(bool onoff)
+bool smb_signing_set_bsrspyl(struct smb_signing_state *si)
{
- bool ret = srv_sign_info.doing_signing;
- srv_sign_info.doing_signing = onoff;
- return ret;
-}
-
-/***********************************************************
- Called to validate an incoming packet from the client.
-************************************************************/
-
-bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
-{
- /* Check if it's a non-session message. */
- if(CVAL(inbuf,0)) {
- return True;
+ if (!si->negotiated) {
+ return false;
}
- return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
-}
-
-/***********************************************************
- Called to sign an outgoing packet to the client.
-************************************************************/
-
-void srv_calculate_sign_mac(char *outbuf)
-{
- /* Check if it's a non-session message. */
- if(CVAL(outbuf,0)) {
- return;
+ if (si->active) {
+ return false;
}
- srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
-}
+ si->bsrspyl = true;
-/***********************************************************
- Called by server to defer an outgoing packet.
-************************************************************/
+ return true;
+}
-void srv_defer_sign_response(uint16 mid)
+bool smb_signing_activate(struct smb_signing_state *si,
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response)
{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing)
- return;
+ size_t len;
+ off_t ofs;
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+ if (!user_session_key.length) {
+ return false;
+ }
- if (!data)
- return;
+ if (!si->negotiated) {
+ return false;
+ }
- /*
- * Ensure we only store this mid reply once...
- */
+ if (si->active) {
+ return false;
+ }
- store_sequence_for_reply(&data->outstanding_packet_list, mid,
- data->send_seq_num-1);
-}
+ if (si->mac_key.length > 0) {
+ return false;
+ }
-/***********************************************************
- Called to remove sequence records when a deferred packet is
- cancelled by mid. This should never find one....
-************************************************************/
+ smb_signing_reset_info(si);
-void srv_cancel_sign_response(uint16 mid, bool cancel)
-{
- struct smb_basic_signing_context *data;
- uint32 dummy_seq;
+ len = response.length + user_session_key.length;
+ si->mac_key = data_blob_talloc(si, NULL, len);
- if (!srv_sign_info.doing_signing)
- return;
+ ofs = 0;
+ memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length);
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+ DEBUG(10, ("smb_signing_activate: user_session_key\n"));
+ dump_data(10, user_session_key.data, user_session_key.length);
- if (!data)
- return;
+ if (response.length) {
+ ofs = user_session_key.length;
+ memcpy(&si->mac_key.data[ofs], response.data, response.length);
+ DEBUG(10, ("smb_signing_activate: response_data\n"));
+ dump_data(10, response.data, response.length);
+ } else {
+ DEBUG(10, ("smb_signing_activate: NULL response_data\n"));
+ }
- DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
+ dump_data_pw("smb_signing_activate: mac key is:\n",
+ si->mac_key.data, si->mac_key.length);
- while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq))
- ;
+ /* Initialise the sequence number */
+ si->seqnum = 2;
- /* cancel doesn't send a reply so doesn't burn a sequence number. */
- if (cancel) {
- data->send_seq_num -= 1;
- }
+ return true;
}
-/***********************************************************
- Called by server negprot when signing has been negotiated.
-************************************************************/
-
-void srv_set_signing_negotiated(void)
+bool smb_signing_is_active(struct smb_signing_state *si)
{
- srv_sign_info.allow_smb_signing = True;
- srv_sign_info.negotiated_smb_signing = True;
- if (lp_server_signing() == Required)
- srv_sign_info.mandatory_signing = True;
-
- srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
- srv_sign_info.check_incoming_message = temp_check_incoming_message;
- srv_sign_info.free_signing_context = temp_free_signing_context;
+ return si->active;
}
-/***********************************************************
- Returns whether signing is active. We can't use sendfile or raw
- reads/writes if it is.
-************************************************************/
-
-bool srv_is_signing_active(void)
+bool smb_signing_is_allowed(struct smb_signing_state *si)
{
- return srv_sign_info.doing_signing;
+ return si->allowed;
}
-
-/***********************************************************
- Returns whether signing is negotiated. We can't use it unless it was
- in the negprot.
-************************************************************/
-
-bool srv_is_signing_negotiated(void)
+bool smb_signing_is_mandatory(struct smb_signing_state *si)
{
- return srv_sign_info.negotiated_smb_signing;
+ return si->mandatory;
}
-/***********************************************************
- Returns whether signing is actually happening
-************************************************************/
-
-bool srv_signing_started(void)
+bool smb_signing_set_negotiated(struct smb_signing_state *si)
{
- struct smb_basic_signing_context *data;
-
- if (!srv_sign_info.doing_signing) {
- return False;
+ if (!si->allowed) {
+ return false;
}
- data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
- if (!data)
- return False;
+ si->negotiated = true;
- if (data->send_seq_num == 0) {
- return False;
- }
-
- return True;
+ return true;
}
-/***********************************************************
- Turn on signing from this packet onwards.
-************************************************************/
-
-void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
+bool smb_signing_is_negotiated(struct smb_signing_state *si)
{
- struct smb_basic_signing_context *data;
-
- if (!user_session_key.length)
- return;
-
- if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
- DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
- (unsigned int)srv_sign_info.negotiated_smb_signing,
- (unsigned int)srv_sign_info.mandatory_signing ));
- return;
- }
-
- /* Once we've turned on, ignore any more sessionsetups. */
- if (srv_sign_info.doing_signing) {
- return;
- }
-
- if (srv_sign_info.free_signing_context)
- srv_sign_info.free_signing_context(&srv_sign_info);
-
- srv_sign_info.doing_signing = True;
-
- data = SMB_XMALLOC_P(struct smb_basic_signing_context);
- memset(data, '\0', sizeof(*data));
-
- srv_sign_info.signing_context = data;
-
- data->mac_key = data_blob(NULL, response.length + user_session_key.length);
-
- memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
- if (response.length)
- memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
-
- dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
-
- DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
- BOOLSTR(srv_sign_info.negotiated_smb_signing),
- BOOLSTR(srv_sign_info.mandatory_signing) ));
-
- /* Initialise the sequence number */
- data->send_seq_num = 0;
-
- /* Initialise the list of outstanding packets */
- data->outstanding_packet_list = NULL;
-
- srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
- srv_sign_info.check_incoming_message = srv_check_incoming_message;
- srv_sign_info.free_signing_context = simple_free_signing_context;
+ return si->negotiated;
}
diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c
index df4d2119e2..d123e24aa8 100644
--- a/source3/libsmb/unexpected.c
+++ b/source3/libsmb/unexpected.c
@@ -162,6 +162,8 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf,
state->match_type,
ip,
port);
+ if (!p)
+ return 0;
if ((state->match_type == NMB_PACKET &&
p->packet.nmb.header.name_trn_id == state->match_id) ||
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index bafb89522a..70841225a7 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -887,7 +887,8 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
}
if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) {
- DEBUG(3, ("fill_share_mode_lock failed\n"));
+ DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
+ "around (file not open)\n"));
TALLOC_FREE(lck);
return NULL;
}
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 6f23d608d4..8ee31abc88 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -825,7 +825,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
/* Setup owner */
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_ACCESS_DENIED;
SMB_ASSERT(owner.id.uid >= 0);
@@ -835,7 +835,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
/* Setup group */
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
if (!onefs_og_to_identity(psd->group_sid, &group, true, snum))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_ACCESS_DENIED;
SMB_ASSERT(group.id.gid >= 0);
@@ -846,7 +846,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) {
if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces,
snum))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_ACCESS_DENIED;
if (ignore_aces == true)
security_info_sent &= ~DACL_SECURITY_INFORMATION;
@@ -863,7 +863,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
if (psd->sacl) {
if (!onefs_samba_acl_to_acl(psd->sacl,
&saclp, &ignore_aces, snum))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_ACCESS_DENIED;
if (ignore_aces == true) {
security_info_sent &=
@@ -877,7 +877,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
DEBUG(5,("Setting up SD\n"));
if (aclu_initialize_sd(sd, psd->type, ownerp, groupp,
(daclp ? &daclp : NULL), (saclp ? &saclp : NULL), false))
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_ACCESS_DENIED;
return NT_STATUS_OK;
}
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index c5030f4ab8..c23c176b79 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -208,14 +208,14 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
NO_OPLOCK) {
DEBUG(0,("Oplock(%d) being requested on a stream! "
- "Ignoring oplock request: base=%s, stream=%s",
+ "Ignoring oplock request: base=%s, stream=%s\n",
oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
base, stream));
/* Recover by requesting NO_OPLOCK instead. */
oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
}
- DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
+ DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
base, fsp->base_fsp->fh->fd, stream));
base_fd = fsp->base_fsp->fh->fd;
@@ -386,15 +386,6 @@ static void defer_open(struct share_mode_lock *lck,
exit_server("push_deferred_smb_message failed");
}
add_deferred_open(lck, req->mid, request_time, state->id);
-
- /*
- * Push the MID of this packet on the signing queue.
- * We only do this once, the first time we push the packet
- * onto the deferred open queue, as this has a side effect
- * of incrementing the response sequence number.
- */
-
- srv_defer_sign_response(req->mid);
}
static void schedule_defer_open(struct share_mode_lock *lck,
diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
new file mode 100644
index 0000000000..53d1820c11
--- /dev/null
+++ b/source3/modules/vfs_dirsort.c
@@ -0,0 +1,194 @@
+/*
+ * VFS module to provide a sorted directory list.
+ *
+ * Copyright (C) Andy Kelk (andy@mopoke.co.uk), 2009
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+static int compare_dirent (const void *a, const void *b) {
+ const SMB_STRUCT_DIRENT *da = (const SMB_STRUCT_DIRENT *) a;
+ const SMB_STRUCT_DIRENT *db = (const SMB_STRUCT_DIRENT *) b;
+ return StrCaseCmp(da->d_name, db->d_name);
+}
+
+struct dirsort_privates {
+ long pos;
+ SMB_STRUCT_DIRENT *directory_list;
+ long number_of_entries;
+ time_t mtime;
+ SMB_STRUCT_DIR *source_directory;
+ int fd;
+};
+
+static void free_dirsort_privates(void **datap) {
+ struct dirsort_privates *data = (struct dirsort_privates *) *datap;
+ SAFE_FREE(data->directory_list);
+ SAFE_FREE(data);
+ *datap = NULL;
+
+ return;
+}
+
+static void open_and_sort_dir (vfs_handle_struct *handle)
+{
+ SMB_STRUCT_DIRENT *dp;
+ struct stat dir_stat;
+ long current_pos;
+ struct dirsort_privates *data = NULL;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return);
+
+ data->number_of_entries = 0;
+
+ if (fstat(data->fd, &dir_stat) == 0) {
+ data->mtime = dir_stat.st_mtime;
+ }
+
+ while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
+ != NULL) {
+ data->number_of_entries++;
+ }
+
+ /* Open the underlying directory and count the number of entries
+ Skip back to the beginning as we'll read it again */
+ SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);
+
+ /* Set up an array and read the directory entries into it */
+ SAFE_FREE(data->directory_list); /* destroy previous cache if needed */
+ data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC(
+ data->number_of_entries * sizeof(SMB_STRUCT_DIRENT));
+ current_pos = data->pos;
+ data->pos = 0;
+ while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory,
+ NULL)) != NULL) {
+ data->directory_list[data->pos++] = *dp;
+ }
+
+ /* Sort the directory entries by name */
+ data->pos = current_pos;
+ qsort(data->directory_list, data->number_of_entries,
+ sizeof(SMB_STRUCT_DIRENT), compare_dirent);
+}
+
+static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
+ const char *fname, const char *mask,
+ uint32 attr)
+{
+ struct dirsort_privates *data = NULL;
+
+ /* set up our private data about this directory */
+ data = (struct dirsort_privates *)SMB_MALLOC(
+ sizeof(struct dirsort_privates));
+
+ data->directory_list = NULL;
+ data->pos = 0;
+
+ /* Open the underlying directory and count the number of entries */
+ data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
+ attr);
+
+ data->fd = dirfd(data->source_directory);
+
+ SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
+ struct dirsort_privates, return NULL);
+
+ open_and_sort_dir(handle);
+
+ return data->source_directory;
+}
+
+static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp)
+{
+ struct dirsort_privates *data = NULL;
+ time_t current_mtime;
+ struct stat dir_stat;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
+ return NULL);
+
+ if (fstat(data->fd, &dir_stat) == -1) {
+ return NULL;
+ }
+
+ current_mtime = dir_stat.st_mtime;
+
+ /* throw away cache and re-read the directory if we've changed */
+ if (current_mtime > data->mtime) {
+ open_and_sort_dir(handle);
+ }
+
+ if (data->pos >= data->number_of_entries) {
+ return NULL;
+ }
+
+ return &data->directory_list[data->pos++];
+}
+
+static void dirsort_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp,
+ long offset)
+{
+ struct dirsort_privates *data = NULL;
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return);
+
+ data->pos = offset;
+}
+
+static long dirsort_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ struct dirsort_privates *data = NULL;
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
+ return -1);
+
+ return data->pos;
+}
+
+static void dirsort_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ struct dirsort_privates *data = NULL;
+ SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return);
+
+ data->pos = 0;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple dirsort_op_tuples[] = {
+
+ /* Directory operations */
+
+ {SMB_VFS_OP(dirsort_opendir), SMB_VFS_OP_OPENDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(dirsort_readdir), SMB_VFS_OP_READDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(dirsort_seekdir), SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(dirsort_telldir), SMB_VFS_OP_TELLDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(dirsort_rewinddir), SMB_VFS_OP_REWINDDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ {NULL, SMB_VFS_OP_NOOP,
+ SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_dirsort_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "dirsort",
+ dirsort_op_tuples);
+}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 3279466602..daf4c295a6 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -988,6 +988,12 @@ static bool open_sockets(bool isdaemon, int port)
exit(1);
}
+ if (!initialize_nmbd_proxy_logon()) {
+ DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
+ kill_async_dns_child();
+ exit(1);
+ }
+
TALLOC_FREE(frame);
process();
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 59a2ca405e..8173337da0 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -24,6 +24,9 @@
*/
#include "includes.h"
+#include "../libcli/netlogon.h"
+#include "../libcli/cldap/cldap.h"
+#include "../lib/tsocket/tsocket.h"
struct sam_database_info {
uint32 index;
@@ -65,6 +68,235 @@ static void delayed_init_logon_handler(struct event_context *event_ctx,
TALLOC_FREE(te);
}
+struct nmbd_proxy_logon_context {
+ struct cldap_socket *cldap_sock;
+};
+
+static struct nmbd_proxy_logon_context *global_nmbd_proxy_logon;
+
+bool initialize_nmbd_proxy_logon(void)
+{
+ const char *cldap_server = lp_parm_const_string(-1, "nmbd_proxy_logon",
+ "cldap_server", NULL);
+ struct nmbd_proxy_logon_context *ctx;
+ NTSTATUS status;
+ struct in_addr addr;
+ char addrstr[INET_ADDRSTRLEN];
+ const char *server_str;
+ int ret;
+ struct tsocket_address *server_addr;
+
+ if (!cldap_server) {
+ return true;
+ }
+
+ addr = interpret_addr2(cldap_server);
+ server_str = inet_ntop(AF_INET, &addr,
+ addrstr, sizeof(addrstr));
+ if (!server_str || strcmp("0.0.0.0", server_str) == 0) {
+ DEBUG(0,("Failed to resolve[%s] for nmbd_proxy_logon\n",
+ cldap_server));
+ return false;
+ }
+
+ ctx = talloc_zero(nmbd_event_context(),
+ struct nmbd_proxy_logon_context);
+ if (!ctx) {
+ return false;
+ }
+
+ ret = tsocket_address_inet_from_strings(ctx, "ipv4",
+ server_str, LDAP_PORT,
+ &server_addr);
+ if (ret != 0) {
+ TALLOC_FREE(ctx);
+ status = map_nt_error_from_unix(errno);
+ DEBUG(0,("Failed to create cldap tsocket_address for %s - %s\n",
+ server_str, nt_errstr(status)));
+ return false;
+ }
+
+ /* we create a connected udp socket */
+ status = cldap_socket_init(ctx, nmbd_event_context(), NULL,
+ server_addr, &ctx->cldap_sock);
+ TALLOC_FREE(server_addr);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(ctx);
+ DEBUG(0,("failed to create cldap socket for %s: %s\n",
+ server_str, nt_errstr(status)));
+ return false;
+ }
+
+ global_nmbd_proxy_logon = ctx;
+ return true;
+}
+
+struct nmbd_proxy_logon_state {
+ struct in_addr local_ip;
+ struct packet_struct *p;
+ const char *remote_name;
+ uint8_t remote_name_type;
+ const char *remote_mailslot;
+ struct nbt_netlogon_packet req;
+ struct nbt_netlogon_response resp;
+ struct cldap_netlogon io;
+};
+
+static int nmbd_proxy_logon_state_destructor(struct nmbd_proxy_logon_state *s)
+{
+ s->p->locked = false;
+ free_packet(s->p);
+ return 0;
+}
+
+static void nmbd_proxy_logon_done(struct tevent_req *subreq);
+
+static void nmbd_proxy_logon(struct nmbd_proxy_logon_context *ctx,
+ struct in_addr local_ip,
+ struct packet_struct *p,
+ uint8_t *buf,
+ uint32_t len)
+{
+ struct nmbd_proxy_logon_state *state;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob = data_blob_const(buf, len);
+ const char *computer_name = NULL;
+ const char *mailslot_name = NULL;
+ const char *user_name = NULL;
+ const char *domain_sid = NULL;
+ uint32_t acct_control = 0;
+ uint32_t nt_version = 0;
+ struct tevent_req *subreq;
+ fstring source_name;
+ struct dgram_packet *dgram = &p->packet.dgram;
+
+ state = TALLOC_ZERO_P(ctx, struct nmbd_proxy_logon_state);
+ if (!state) {
+ DEBUG(0,("failed to allocate nmbd_proxy_logon_state\n"));
+ return;
+ }
+
+ pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
+ state->remote_name = talloc_strdup(state, source_name);
+ state->remote_name_type = dgram->source_name.name_type,
+ state->local_ip = local_ip;
+ state->p = p;
+
+ ndr_err = ndr_pull_struct_blob(
+ &blob, state, NULL, &state->req,
+ (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(0,("failed parse nbt_letlogon_packet: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(state);
+ return;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("nmbd_proxy_logon:\n"));
+ NDR_PRINT_DEBUG(nbt_netlogon_packet, &state->req);
+ }
+
+ switch (state->req.command) {
+ case LOGON_SAM_LOGON_REQUEST:
+ computer_name = state->req.req.logon.computer_name;
+ user_name = state->req.req.logon.user_name;
+ mailslot_name = state->req.req.logon.mailslot_name;
+ acct_control = state->req.req.logon.acct_control;
+ if (state->req.req.logon.sid_size > 0) {
+ domain_sid = dom_sid_string(state,
+ &state->req.req.logon.sid);
+ if (!domain_sid) {
+ DEBUG(0,("failed to get a string for sid\n"));
+ TALLOC_FREE(state);
+ return;
+ }
+ }
+ nt_version = state->req.req.logon.nt_version;
+ break;
+
+ default:
+ /* this can't happen as the caller already checks the command */
+ break;
+ }
+
+ state->remote_mailslot = mailslot_name;
+
+ if (user_name && strlen(user_name) == 0) {
+ user_name = NULL;
+ }
+
+ if (computer_name && strlen(computer_name) == 0) {
+ computer_name = NULL;
+ }
+
+ /*
+ * as the socket is connected,
+ * we don't need to specify the destination
+ */
+ state->io.in.dest_address = NULL;
+ state->io.in.dest_port = 0;
+ state->io.in.realm = NULL;
+ state->io.in.host = computer_name;
+ state->io.in.user = user_name;
+ state->io.in.domain_guid = NULL;
+ state->io.in.domain_sid = domain_sid;
+ state->io.in.acct_control = acct_control;
+ state->io.in.version = nt_version;
+ state->io.in.map_response = false;
+
+ subreq = cldap_netlogon_send(state,
+ ctx->cldap_sock,
+ &state->io);
+ if (!subreq) {
+ DEBUG(0,("failed to send cldap netlogon call\n"));
+ TALLOC_FREE(state);
+ return;
+ }
+ tevent_req_set_callback(subreq, nmbd_proxy_logon_done, state);
+
+ /* we reply async */
+ state->p->locked = true;
+ talloc_set_destructor(state, nmbd_proxy_logon_state_destructor);
+}
+
+static void nmbd_proxy_logon_done(struct tevent_req *subreq)
+{
+ struct nmbd_proxy_logon_state *state =
+ tevent_req_callback_data(subreq,
+ struct nmbd_proxy_logon_state);
+ NTSTATUS status;
+ DATA_BLOB response;
+
+ status = cldap_netlogon_recv(subreq, NULL, state, &state->io);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("failed to recv cldap netlogon call: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(state);
+ return;
+ }
+
+ status = push_netlogon_samlogon_response(&response, state, NULL,
+ &state->io.out.netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("failed to push netlogon_samlogon_response: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(state);
+ return;
+ }
+
+ send_mailslot(true, state->remote_mailslot,
+ (char *)response.data, response.length,
+ global_myname(), 0x0,
+ state->remote_name,
+ state->remote_name_type,
+ state->p->ip,
+ state->local_ip,
+ state->p->port);
+ TALLOC_FREE(state);
+}
+
/****************************************************************************
Process a domain logon packet
**************************************************************************/
@@ -318,6 +550,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
char *q = buf + 2;
fstring asccomp;
+ if (global_nmbd_proxy_logon) {
+ nmbd_proxy_logon(global_nmbd_proxy_logon,
+ ip, p, (uint8_t *)buf, len);
+ return;
+ }
+
q += 2;
if (PTR_DIFF(q, buf) >= len) {
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index f49a1bc4c9..66fb8bf1bc 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -9542,10 +9542,6 @@ const char *lp_printcapname(void)
return PRINTCAP_NAME;
}
-/*******************************************************************
- Ensure we don't use sendfile if server smb signing is active.
-********************************************************************/
-
static uint32 spoolss_state;
bool lp_disable_spoolss( void )
@@ -9572,15 +9568,20 @@ uint32 lp_get_spoolss_state( void )
Ensure we don't use sendfile if server smb signing is active.
********************************************************************/
-bool lp_use_sendfile(int snum)
+bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
{
+ bool sign_active = false;
+
/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
if (Protocol < PROTOCOL_NT1) {
- return False;
+ return false;
+ }
+ if (signing_state) {
+ sign_active = smb_signing_is_active(signing_state);
}
return (_lp_use_sendfile(snum) &&
(get_remote_arch() != RA_WIN95) &&
- !srv_is_signing_active());
+ !sign_active);
}
/*******************************************************************
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 9c20042a62..a5c2d50366 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -804,7 +804,7 @@ NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
} else {
/* This is a normal SID with rid component */
if (!sid_split_rid(&sid, &rid)) {
- result = NT_STATUS_INVALID_PARAMETER;
+ result = NT_STATUS_INVALID_SID;
goto fail;
}
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 8e6fe1f364..a99485d381 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2275,7 +2275,9 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
+static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
+ const char *drivername, const char *arch,
+ uint32_t version)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA dbuf;
@@ -4448,7 +4450,7 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
Delete driver init data stored for a specified driver
****************************************************************************/
-bool del_driver_init(char *drivername)
+bool del_driver_init(const char *drivername)
{
char *key;
bool ret;
@@ -4837,8 +4839,9 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
/****************************************************************************
****************************************************************************/
-WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
- fstring drivername, const char *architecture, uint32 version)
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level,
+ const char *drivername, const char *architecture,
+ uint32_t version)
{
WERROR result;
diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c
index d002bd72e7..e1c04c4777 100644
--- a/source3/registry/regfio.c
+++ b/source3/registry/regfio.c
@@ -712,8 +712,30 @@ static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_
if ( !prs_uint32( "size", ps, depth, &sk->size))
return False;
- if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth ))
- return False;
+ {
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx = prs_get_mem_context(&hbin->ps);
+ DATA_BLOB blob;
+
+ if (MARSHALLING(&hbin->ps)) {
+ status = marshall_sec_desc(mem_ctx,
+ sk->sec_desc,
+ &blob.data, &blob.length);
+ if (!NT_STATUS_IS_OK(status))
+ return False;
+ if (!prs_copy_data_in(&hbin->ps, (const char *)blob.data, blob.length))
+ return False;
+ } else {
+ blob = data_blob_const(prs_data_p(&hbin->ps),
+ prs_data_size(&hbin->ps));
+ status = unmarshall_sec_desc(mem_ctx,
+ blob.data, blob.length,
+ &sk->sec_desc);
+ if (!NT_STATUS_IS_OK(status))
+ return False;
+ prs_set_offset(&hbin->ps, blob.length);
+ }
+ }
end_off = prs_offset( &hbin->ps );
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 57f49fb83a..6b83c170f5 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -207,18 +207,18 @@ struct rpc_read_state {
size_t num_read;
};
-static void rpc_read_done(struct async_req *subreq);
+static void rpc_read_done(struct tevent_req *subreq);
-static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_cli_transport *transport,
- uint8_t *data, size_t size)
+static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_cli_transport *transport,
+ uint8_t *data, size_t size)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_read_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_read_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -234,34 +234,33 @@ static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- subreq->async.fn = rpc_read_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, rpc_read_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_read_done(struct async_req *subreq)
+static void rpc_read_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_read_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_read_state *state = tevent_req_data(
+ req, struct rpc_read_state);
NTSTATUS status;
ssize_t received;
status = state->transport->read_recv(subreq, &received);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
state->num_read += received;
if (state->num_read == state->size) {
- async_req_done(req);
+ tevent_req_done(req);
return;
}
@@ -269,16 +268,15 @@ static void rpc_read_done(struct async_req *subreq)
state->data + state->num_read,
state->size - state->num_read,
state->transport->priv);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_read_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_read_done, req);
}
-static NTSTATUS rpc_read_recv(struct async_req *req)
+static NTSTATUS rpc_read_recv(struct tevent_req *req)
{
- return async_req_simple_recv_ntstatus(req);
+ return tevent_req_simple_recv_ntstatus(req);
}
struct rpc_write_state {
@@ -289,18 +287,18 @@ struct rpc_write_state {
size_t num_written;
};
-static void rpc_write_done(struct async_req *subreq);
+static void rpc_write_done(struct tevent_req *subreq);
-static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_cli_transport *transport,
- const uint8_t *data, size_t size)
+static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_cli_transport *transport,
+ const uint8_t *data, size_t size)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_write_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_write_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -315,34 +313,33 @@ static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- subreq->async.fn = rpc_write_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, rpc_write_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_write_done(struct async_req *subreq)
+static void rpc_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_write_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_write_state *state = tevent_req_data(
+ req, struct rpc_write_state);
NTSTATUS status;
ssize_t written;
status = state->transport->write_recv(subreq, &written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
state->num_written += written;
if (state->num_written == state->size) {
- async_req_done(req);
+ tevent_req_done(req);
return;
}
@@ -350,16 +347,15 @@ static void rpc_write_done(struct async_req *subreq)
state->data + state->num_written,
state->size - state->num_written,
state->transport->priv);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_write_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_write_done, req);
}
-static NTSTATUS rpc_write_recv(struct async_req *req)
+static NTSTATUS rpc_write_recv(struct tevent_req *req)
{
- return async_req_simple_recv_ntstatus(req);
+ return tevent_req_simple_recv_ntstatus(req);
}
@@ -399,22 +395,23 @@ struct get_complete_frag_state {
prs_struct *pdu;
};
-static void get_complete_frag_got_header(struct async_req *subreq);
-static void get_complete_frag_got_rest(struct async_req *subreq);
+static void get_complete_frag_got_header(struct tevent_req *subreq);
+static void get_complete_frag_got_rest(struct tevent_req *subreq);
-static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- struct rpc_hdr_info *prhdr,
- prs_struct *pdu)
+static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ struct rpc_hdr_info *prhdr,
+ prs_struct *pdu)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct get_complete_frag_state *state;
uint32_t pdu_len;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct get_complete_frag_state)) {
+ req = tevent_req_create(mem_ctx, &state,
+ struct get_complete_frag_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -437,9 +434,9 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
status = NT_STATUS_NO_MEMORY;
goto post_status;
}
- subreq->async.fn = get_complete_frag_got_header;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, get_complete_frag_got_header,
+ req);
+ return req;
}
status = parse_rpc_header(cli, prhdr, pdu);
@@ -463,43 +460,44 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
status = NT_STATUS_NO_MEMORY;
goto post_status;
}
- subreq->async.fn = get_complete_frag_got_rest;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, get_complete_frag_got_rest,
+ req);
+ return req;
}
status = NT_STATUS_OK;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
+ if (NT_STATUS_IS_OK(status)) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_nterror(req, status);
}
- TALLOC_FREE(result);
- return NULL;
+ return tevent_req_post(req, ev);
}
-static void get_complete_frag_got_header(struct async_req *subreq)
+static void get_complete_frag_got_header(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct get_complete_frag_state *state = talloc_get_type_abort(
- req->private_data, struct get_complete_frag_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct get_complete_frag_state *state = tevent_req_data(
+ req, struct get_complete_frag_state);
NTSTATUS status;
status = rpc_read_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
- async_req_nterror(req, NT_STATUS_NO_MEMORY);
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -512,31 +510,30 @@ static void get_complete_frag_got_header(struct async_req *subreq)
state, state->ev, state->cli->transport,
(uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
state->prhdr->frag_len - RPC_HEADER_LEN);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = get_complete_frag_got_rest;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
}
-static void get_complete_frag_got_rest(struct async_req *subreq)
+static void get_complete_frag_got_rest(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
NTSTATUS status;
status = rpc_read_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS get_complete_frag_recv(struct async_req *req)
+static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
{
- return async_req_simple_recv_ntstatus(req);
+ return tevent_req_simple_recv_ntstatus(req);
}
/****************************************************************************
@@ -1037,22 +1034,22 @@ struct cli_api_pipe_state {
uint32_t rdata_len;
};
-static void cli_api_pipe_trans_done(struct async_req *subreq);
-static void cli_api_pipe_write_done(struct async_req *subreq);
-static void cli_api_pipe_read_done(struct async_req *subreq);
+static void cli_api_pipe_trans_done(struct tevent_req *subreq);
+static void cli_api_pipe_write_done(struct tevent_req *subreq);
+static void cli_api_pipe_read_done(struct tevent_req *subreq);
-static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_cli_transport *transport,
- uint8_t *data, size_t data_len,
- uint32_t max_rdata_len)
+static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_cli_transport *transport,
+ uint8_t *data, size_t data_len,
+ uint32_t max_rdata_len)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct cli_api_pipe_state *state;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct cli_api_pipe_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -1072,12 +1069,10 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
subreq = transport->trans_send(state, ev, data, data_len,
max_rdata_len, transport->priv);
if (subreq == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = cli_api_pipe_trans_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
+ return req;
}
/*
@@ -1089,56 +1084,54 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- subreq->async.fn = cli_api_pipe_write_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
+ return req;
status = NT_STATUS_INVALID_PARAMETER;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
- }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void cli_api_pipe_trans_done(struct async_req *subreq)
+static void cli_api_pipe_trans_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct cli_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct cli_api_pipe_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_api_pipe_state *state = tevent_req_data(
+ req, struct cli_api_pipe_state);
NTSTATUS status;
status = state->transport->trans_recv(subreq, state, &state->rdata,
&state->rdata_len);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static void cli_api_pipe_write_done(struct async_req *subreq)
+static void cli_api_pipe_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct cli_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct cli_api_pipe_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_api_pipe_state *state = tevent_req_data(
+ req, struct cli_api_pipe_state);
NTSTATUS status;
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
- if (async_req_nomem(state->rdata, req)) {
+ if (tevent_req_nomem(state->rdata, req)) {
return;
}
@@ -1150,40 +1143,39 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
subreq = state->transport->read_send(state, state->ev, state->rdata,
RPC_HEADER_LEN,
state->transport->priv);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = cli_api_pipe_read_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
}
-static void cli_api_pipe_read_done(struct async_req *subreq)
+static void cli_api_pipe_read_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct cli_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct cli_api_pipe_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_api_pipe_state *state = tevent_req_data(
+ req, struct cli_api_pipe_state);
NTSTATUS status;
ssize_t received;
status = state->transport->read_recv(subreq, &received);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
state->rdata_len = received;
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
uint8_t **prdata, uint32_t *prdata_len)
{
- struct cli_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct cli_api_pipe_state);
+ struct cli_api_pipe_state *state = tevent_req_data(
+ req, struct cli_api_pipe_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
@@ -1237,22 +1229,22 @@ static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
return 0;
}
-static void rpc_api_pipe_trans_done(struct async_req *subreq);
-static void rpc_api_pipe_got_pdu(struct async_req *subreq);
+static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
+static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
-static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- prs_struct *data, /* Outgoing PDU */
- uint8_t expected_pkt_type)
+static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ prs_struct *data, /* Outgoing PDU */
+ uint8_t expected_pkt_type)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_api_pipe_state *state;
uint16_t max_recv_frag;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_api_pipe_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -1288,27 +1280,25 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
(uint8_t *)prs_data_p(data),
prs_offset(data), max_recv_frag);
if (subreq == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = rpc_api_pipe_trans_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
+ return req;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
- }
- TALLOC_FREE(result);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ fail:
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_api_pipe_trans_done(struct async_req *subreq)
+static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_api_pipe_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_state);
NTSTATUS status;
uint8_t *rdata = NULL;
uint32_t rdata_len = 0;
@@ -1318,14 +1308,14 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
if (rdata == NULL) {
DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
rpccli_pipe_txt(debug_ctx(), state->cli)));
- async_req_done(req);
+ tevent_req_done(req);
return;
}
@@ -1336,7 +1326,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
*/
rdata_copy = (char *)memdup(rdata, rdata_len);
TALLOC_FREE(rdata);
- if (async_req_nomem(rdata_copy, req)) {
+ if (tevent_req_nomem(rdata_copy, req)) {
return;
}
prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
@@ -1344,19 +1334,18 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq)
/* Ensure we have enough data for a pdu. */
subreq = get_complete_frag_send(state, state->ev, state->cli,
&state->rhdr, &state->incoming_frag);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_api_pipe_got_pdu;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
}
-static void rpc_api_pipe_got_pdu(struct async_req *subreq)
+static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_api_pipe_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_state);
NTSTATUS status;
char *rdata = NULL;
uint32_t rdata_len = 0;
@@ -1366,7 +1355,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("get_complete_frag failed: %s\n",
nt_errstr(status)));
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -1381,7 +1370,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
nt_errstr(status)));
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -1405,13 +1394,13 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
"%s\n",
state->incoming_pdu.bigendian_data?"big":"little",
state->incoming_frag.bigendian_data?"big":"little"));
- async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
/* Now copy the data portion out of the pdu into rbuf. */
if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
- async_req_nterror(req, NT_STATUS_NO_MEMORY);
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1422,7 +1411,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
&state->incoming_frag);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -1430,27 +1419,26 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
rpccli_pipe_txt(debug_ctx(), state->cli),
(unsigned)prs_data_size(&state->incoming_pdu)));
- async_req_done(req);
+ tevent_req_done(req);
return;
}
subreq = get_complete_frag_send(state, state->ev, state->cli,
&state->rhdr, &state->incoming_frag);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_api_pipe_got_pdu;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
}
-static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
prs_struct *reply_pdu)
{
- struct rpc_api_pipe_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_state);
+ struct rpc_api_pipe_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
@@ -2043,24 +2031,25 @@ static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
return 0;
}
-static void rpc_api_pipe_req_write_done(struct async_req *subreq);
-static void rpc_api_pipe_req_done(struct async_req *subreq);
+static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
+static void rpc_api_pipe_req_done(struct tevent_req *subreq);
static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
bool *is_last_frag);
-struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- uint8_t op_num,
- prs_struct *req_data)
+struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ uint8_t op_num,
+ prs_struct *req_data)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_api_pipe_req_state *state;
NTSTATUS status;
bool is_last_frag;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_api_pipe_req_state)) {
+ req = tevent_req_create(mem_ctx, &state,
+ struct rpc_api_pipe_req_state);
+ if (req == NULL) {
return NULL;
}
state->ev = ev;
@@ -2081,8 +2070,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
state, MARSHALL)) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
@@ -2097,30 +2085,27 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
&state->outgoing_frag,
RPC_RESPONSE);
if (subreq == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = rpc_api_pipe_req_done;
- subreq->async.priv = result;
+ tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
} else {
subreq = rpc_write_send(
state, ev, cli->transport,
(uint8_t *)prs_data_p(&state->outgoing_frag),
prs_offset(&state->outgoing_frag));
if (subreq == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = rpc_api_pipe_req_write_done;
- subreq->async.priv = result;
+ tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
+ req);
}
- return result;
+ return req;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
- }
- TALLOC_FREE(result);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ fail:
+ TALLOC_FREE(req);
return NULL;
}
@@ -2209,25 +2194,25 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
return status;
}
-static void rpc_api_pipe_req_write_done(struct async_req *subreq)
+static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_req_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_api_pipe_req_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_req_state);
NTSTATUS status;
bool is_last_frag;
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
status = prepare_next_frag(state, &is_last_frag);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -2235,50 +2220,49 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
subreq = rpc_api_pipe_send(state, state->ev, state->cli,
&state->outgoing_frag,
RPC_RESPONSE);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_api_pipe_req_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
} else {
subreq = rpc_write_send(
state, state->ev,
state->cli->transport,
(uint8_t *)prs_data_p(&state->outgoing_frag),
prs_offset(&state->outgoing_frag));
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = rpc_api_pipe_req_write_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
+ req);
}
}
-static void rpc_api_pipe_req_done(struct async_req *subreq)
+static void rpc_api_pipe_req_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_req_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_api_pipe_req_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_req_state);
NTSTATUS status;
status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
prs_struct *reply_pdu)
{
- struct rpc_api_pipe_req_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_api_pipe_req_state);
+ struct rpc_api_pipe_req_state *state = tevent_req_data(
+ req, struct rpc_api_pipe_req_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
/*
* We always have to initialize to reply pdu, even if there is
* none. The rpccli_* caller routines expect this.
@@ -2306,7 +2290,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
+ struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
ev = event_context_init(frame);
@@ -2319,9 +2303,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
- }
+ tevent_req_poll(req, ev);
status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
fail:
@@ -2522,29 +2504,29 @@ static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
return 0;
}
-static void rpc_pipe_bind_step_one_done(struct async_req *subreq);
-static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
+static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
+static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
struct rpc_pipe_bind_state *state,
struct rpc_hdr_info *phdr,
prs_struct *reply_pdu);
-static void rpc_bind_auth3_write_done(struct async_req *subreq);
-static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
+static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
+static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
struct rpc_pipe_bind_state *state,
struct rpc_hdr_info *phdr,
prs_struct *reply_pdu);
-static void rpc_bind_ntlmssp_api_done(struct async_req *subreq);
+static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
-struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct rpc_pipe_client *cli,
- struct cli_pipe_auth_data *auth)
+struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ struct cli_pipe_auth_data *auth)
{
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_pipe_bind_state *state;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_pipe_bind_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
+ if (req == NULL) {
return NULL;
}
@@ -2577,27 +2559,25 @@ struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
RPC_BINDACK);
if (subreq == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = rpc_pipe_bind_step_one_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
+ return req;
post_status:
- if (async_post_ntstatus(result, ev, status)) {
- return result;
- }
- TALLOC_FREE(result);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ fail:
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
+static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_pipe_bind_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_pipe_bind_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_pipe_bind_state *state = tevent_req_data(
+ req, struct rpc_pipe_bind_state);
prs_struct reply_pdu;
struct rpc_hdr_info hdr;
struct rpc_hdr_ba_info hdr_ba;
@@ -2609,7 +2589,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
rpccli_pipe_txt(debug_ctx(), state->cli),
nt_errstr(status)));
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -2617,7 +2597,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
prs_mem_free(&reply_pdu);
- async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+ tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
@@ -2625,14 +2605,14 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
"RPC_HDR_BA.\n"));
prs_mem_free(&reply_pdu);
- async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+ tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
prs_mem_free(&reply_pdu);
- async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+ tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
@@ -2649,7 +2629,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
case PIPE_AUTH_TYPE_SCHANNEL:
/* Bind complete. */
prs_mem_free(&reply_pdu);
- async_req_done(req);
+ tevent_req_done(req);
break;
case PIPE_AUTH_TYPE_NTLMSSP:
@@ -2658,7 +2638,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
&reply_pdu);
prs_mem_free(&reply_pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
}
break;
@@ -2668,7 +2648,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
&reply_pdu);
prs_mem_free(&reply_pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
}
break;
@@ -2679,11 +2659,11 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
(unsigned int)state->cli->auth->auth_type));
prs_mem_free(&reply_pdu);
- async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
}
}
-static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
+static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
struct rpc_pipe_bind_state *state,
struct rpc_hdr_info *phdr,
prs_struct *reply_pdu)
@@ -2691,7 +2671,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
DATA_BLOB server_response = data_blob_null;
DATA_BLOB client_reply = data_blob_null;
struct rpc_hdr_auth_info hdr_auth;
- struct async_req *subreq;
+ struct tevent_req *subreq;
NTSTATUS status;
if ((phdr->auth_len == 0)
@@ -2742,27 +2722,26 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req,
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
- subreq->async.fn = rpc_bind_auth3_write_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
return NT_STATUS_OK;
}
-static void rpc_bind_auth3_write_done(struct async_req *subreq)
+static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
NTSTATUS status;
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
+static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
struct rpc_pipe_bind_state *state,
struct rpc_hdr_info *phdr,
prs_struct *reply_pdu)
@@ -2772,7 +2751,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
DATA_BLOB client_reply = data_blob_null;
DATA_BLOB tmp_blob = data_blob_null;
RPC_HDR_AUTH hdr_auth;
- struct async_req *subreq;
+ struct tevent_req *subreq;
NTSTATUS status;
if ((phdr->auth_len == 0)
@@ -2850,17 +2829,16 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req,
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;
}
- subreq->async.fn = rpc_bind_ntlmssp_api_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
return NT_STATUS_OK;
}
-static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
+static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_pipe_bind_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_pipe_bind_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_pipe_bind_state *state = tevent_req_data(
+ req, struct rpc_pipe_bind_state);
DATA_BLOB server_spnego_response = data_blob_null;
DATA_BLOB tmp_blob = data_blob_null;
prs_struct reply_pdu;
@@ -2871,7 +2849,7 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
@@ -2879,19 +2857,19 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
"unmarshall RPC_HDR.\n"));
- async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+ tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
if (!prs_set_offset(
&reply_pdu,
hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
- async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
- async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -2904,7 +2882,7 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
OID_NTLMSSP, &tmp_blob)) {
data_blob_free(&server_spnego_response);
data_blob_free(&tmp_blob);
- async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -2913,12 +2891,12 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
"%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli)));
- async_req_done(req);
+ tevent_req_done(req);
}
-NTSTATUS rpc_pipe_bind_recv(struct async_req *req)
+NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
{
- return async_req_simple_recv_ntstatus(req);
+ return tevent_req_simple_recv_ntstatus(req);
}
NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
@@ -2926,7 +2904,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
+ struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
ev = event_context_init(frame);
@@ -2939,9 +2917,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
- }
+ tevent_req_poll(req, ev);
status = rpc_pipe_bind_recv(req);
fail:
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index 80ff384046..8b45cb4e9c 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -51,18 +51,19 @@ struct rpc_np_write_state {
static void rpc_np_write_done(struct async_req *subreq);
-static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
priv, struct rpc_transport_np_state);
- struct async_req *result, *subreq;
+ struct tevent_req *req;
+ struct async_req *subreq;
struct rpc_np_write_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_np_write_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state);
+ if (req == NULL) {
return NULL;
}
state->size = size;
@@ -75,37 +76,37 @@ static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
goto fail;
}
subreq->async.fn = rpc_np_write_done;
- subreq->async.priv = result;
- return result;
+ subreq->async.priv = req;
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
static void rpc_np_write_done(struct async_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_np_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_write_state);
+ struct tevent_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct tevent_req);
+ struct rpc_np_write_state *state = tevent_req_data(
+ req, struct rpc_np_write_state);
NTSTATUS status;
status = cli_write_andx_recv(subreq, &state->written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten)
+static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten)
{
- struct rpc_np_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_write_state);
+ struct rpc_np_write_state *state = tevent_req_data(
+ req, struct rpc_np_write_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*pwritten = state->written;
@@ -120,18 +121,19 @@ struct rpc_np_read_state {
static void rpc_np_read_done(struct async_req *subreq);
-static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
priv, struct rpc_transport_np_state);
- struct async_req *result, *subreq;
+ struct tevent_req *req;
+ struct async_req *subreq;
struct rpc_np_read_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_np_read_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state);
+ if (req == NULL) {
return NULL;
}
state->data = data;
@@ -143,19 +145,19 @@ static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
goto fail;
}
subreq->async.fn = rpc_np_read_done;
- subreq->async.priv = result;
- return result;
+ subreq->async.priv = req;
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
static void rpc_np_read_done(struct async_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_np_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_read_state);
+ struct tevent_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct tevent_req);
+ struct rpc_np_read_state *state = tevent_req_data(
+ req, struct rpc_np_read_state);
NTSTATUS status;
uint8_t *rcvbuf;
@@ -169,27 +171,27 @@ static void rpc_np_read_done(struct async_req *subreq)
}
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(subreq);
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
if (state->received > state->size) {
TALLOC_FREE(subreq);
- async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
memcpy(state->data, rcvbuf, state->received);
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived)
+static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived)
{
- struct rpc_np_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_read_state);
+ struct rpc_np_read_state *state = tevent_req_data(
+ req, struct rpc_np_read_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*preceived = state->received;
@@ -204,19 +206,20 @@ struct rpc_np_trans_state {
static void rpc_np_trans_done(struct async_req *subreq);
-static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t data_len,
- uint32_t max_rdata_len,
- void *priv)
+static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t data_len,
+ uint32_t max_rdata_len,
+ void *priv)
{
struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
priv, struct rpc_transport_np_state);
- struct async_req *result, *subreq;
+ struct tevent_req *req;
+ struct async_req *subreq;
struct rpc_np_trans_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_np_trans_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state);
+ if (req == NULL) {
return NULL;
}
@@ -231,40 +234,40 @@ static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
goto fail;
}
subreq->async.fn = rpc_np_trans_done;
- subreq->async.priv = result;
- return result;
+ subreq->async.priv = req;
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
static void rpc_np_trans_done(struct async_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_np_trans_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_trans_state);
+ struct tevent_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct tevent_req);
+ struct rpc_np_trans_state *state = tevent_req_data(
+ req, struct rpc_np_trans_state);
NTSTATUS status;
status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
&state->rdata, &state->rdata_len);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
uint8_t **prdata, uint32_t *prdata_len)
{
- struct rpc_np_trans_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_np_trans_state);
+ struct rpc_np_trans_state *state = tevent_req_data(
+ req, struct rpc_np_trans_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*prdata = talloc_move(mem_ctx, &state->rdata);
diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c
index bf4aa65dae..bde8d04208 100644
--- a/source3/rpc_client/rpc_transport_smbd.c
+++ b/source3/rpc_client/rpc_transport_smbd.c
@@ -432,20 +432,20 @@ struct rpc_smbd_write_state {
ssize_t written;
};
-static void rpc_smbd_write_done(struct async_req *subreq);
+static void rpc_smbd_write_done(struct tevent_req *subreq);
-static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_smbd_state *transp = talloc_get_type_abort(
priv, struct rpc_transport_smbd_state);
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_smbd_write_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_smbd_write_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_write_state);
+ if (req == NULL) {
return NULL;
}
state->sub_transp = transp->sub_transp;
@@ -460,40 +460,38 @@ static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx,
rpc_cli_smbd_stdout_reader, transp->conn) == NULL) {
goto fail;
}
-
- subreq->async.fn = rpc_smbd_write_done;
- subreq->async.priv = result;
- return result;
+ tevent_req_set_callback(subreq, rpc_smbd_write_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_smbd_write_done(struct async_req *subreq)
+static void rpc_smbd_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_smbd_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_smbd_write_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_smbd_write_state *state = tevent_req_data(
+ req, struct rpc_smbd_write_state);
NTSTATUS status;
status = state->sub_transp->write_recv(subreq, &state->written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_smbd_write_recv(struct async_req *req, ssize_t *pwritten)
+static NTSTATUS rpc_smbd_write_recv(struct tevent_req *req, ssize_t *pwritten)
{
- struct rpc_smbd_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_smbd_write_state);
+ struct rpc_smbd_write_state *state = tevent_req_data(
+ req, struct rpc_smbd_write_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*pwritten = state->written;
@@ -505,20 +503,20 @@ struct rpc_smbd_read_state {
ssize_t received;
};
-static void rpc_smbd_read_done(struct async_req *subreq);
+static void rpc_smbd_read_done(struct tevent_req *subreq);
-static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_smbd_state *transp = talloc_get_type_abort(
priv, struct rpc_transport_smbd_state);
- struct async_req *result, *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_smbd_read_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_smbd_read_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_read_state);
+ if (req == NULL) {
return NULL;
}
state->sub_transp = transp->sub_transp;
@@ -533,40 +531,37 @@ static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx,
rpc_cli_smbd_stdout_reader, transp->conn) == NULL) {
goto fail;
}
-
- subreq->async.fn = rpc_smbd_read_done;
- subreq->async.priv = result;
- return result;
-
+ tevent_req_set_callback(subreq, rpc_smbd_read_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
-static void rpc_smbd_read_done(struct async_req *subreq)
+static void rpc_smbd_read_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct rpc_smbd_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_smbd_read_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_smbd_read_state *state = tevent_req_data(
+ req, struct rpc_smbd_read_state);
NTSTATUS status;
status = state->sub_transp->read_recv(subreq, &state->received);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_nterror(req, status);
+ tevent_req_nterror(req, status);
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_smbd_read_recv(struct async_req *req, ssize_t *preceived)
+static NTSTATUS rpc_smbd_read_recv(struct tevent_req *req, ssize_t *preceived)
{
- struct rpc_smbd_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_smbd_read_state);
+ struct rpc_smbd_read_state *state = tevent_req_data(
+ req, struct rpc_smbd_read_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*preceived = state->received;
diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c
index b1d9d8fbe1..570d792c9c 100644
--- a/source3/rpc_client/rpc_transport_sock.c
+++ b/source3/rpc_client/rpc_transport_sock.c
@@ -41,19 +41,18 @@ struct rpc_sock_read_state {
static void rpc_sock_read_done(struct tevent_req *subreq);
-static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
priv, struct rpc_transport_sock_state);
- struct async_req *result;
- struct tevent_req *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_sock_read_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_sock_read_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state);
+ if (req == NULL) {
return NULL;
}
@@ -61,36 +60,36 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- tevent_req_set_callback(subreq, rpc_sock_read_done, result);
- return result;
+ tevent_req_set_callback(subreq, rpc_sock_read_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
static void rpc_sock_read_done(struct tevent_req *subreq)
{
- struct async_req *req =
- tevent_req_callback_data(subreq, struct async_req);
- struct rpc_sock_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_sock_read_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_sock_read_state *state = tevent_req_data(
+ req, struct rpc_sock_read_state);
int err;
state->received = async_recv_recv(subreq, &err);
if (state->received == -1) {
- async_req_nterror(req, map_nt_error_from_unix(err));
+ tevent_req_nterror(req, map_nt_error_from_unix(err));
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived)
+static NTSTATUS rpc_sock_read_recv(struct tevent_req *req, ssize_t *preceived)
{
- struct rpc_sock_read_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_sock_read_state);
+ struct rpc_sock_read_state *state = tevent_req_data(
+ req, struct rpc_sock_read_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*preceived = state->received;
@@ -103,55 +102,54 @@ struct rpc_sock_write_state {
static void rpc_sock_write_done(struct tevent_req *subreq);
-static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const uint8_t *data, size_t size,
- void *priv)
+static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const uint8_t *data, size_t size,
+ void *priv)
{
struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
priv, struct rpc_transport_sock_state);
- struct async_req *result;
- struct tevent_req *subreq;
+ struct tevent_req *req, *subreq;
struct rpc_sock_write_state *state;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct rpc_sock_write_state)) {
+ req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state);
+ if (req == NULL) {
return NULL;
}
subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);
if (subreq == NULL) {
goto fail;
}
- tevent_req_set_callback(subreq, rpc_sock_write_done, result);
- return result;
+ tevent_req_set_callback(subreq, rpc_sock_write_done, req);
+ return req;
fail:
- TALLOC_FREE(result);
+ TALLOC_FREE(req);
return NULL;
}
static void rpc_sock_write_done(struct tevent_req *subreq)
{
- struct async_req *req =
- tevent_req_callback_data(subreq, struct async_req);
- struct rpc_sock_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_sock_write_state);
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct rpc_sock_write_state *state = tevent_req_data(
+ req, struct rpc_sock_write_state);
int err;
state->sent = async_send_recv(subreq, &err);
if (state->sent == -1) {
- async_req_nterror(req, map_nt_error_from_unix(err));
+ tevent_req_nterror(req, map_nt_error_from_unix(err));
return;
}
- async_req_done(req);
+ tevent_req_done(req);
}
-static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent)
+static NTSTATUS rpc_sock_write_recv(struct tevent_req *req, ssize_t *psent)
{
- struct rpc_sock_write_state *state = talloc_get_type_abort(
- req->private_data, struct rpc_sock_write_state);
+ struct rpc_sock_write_state *state = tevent_req_data(
+ req, struct rpc_sock_write_state);
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
+ if (tevent_req_is_nterror(req, &status)) {
return status;
}
*psent = state->sent;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 8b4135a1e8..1ea4ecf46f 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -101,44 +101,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
}
/*******************************************************************
- Reads or writes a DOM_SID structure.
-********************************************************************/
-
-bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
-{
- int i;
-
- if (sid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_dom_sid");
- depth++;
-
- if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
- return False;
-
- if(!prs_uint8 ("num_auths ", ps, depth, (uint8 *)&sid->num_auths))
- return False;
-
- for (i = 0; i < 6; i++)
- {
- fstring tmp;
- slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
- if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
- return False;
- }
-
- /* oops! XXXX should really issue a warning here... */
- if (sid->num_auths > MAXSUBAUTHS)
- sid->num_auths = MAXSUBAUTHS;
-
- if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a struct GUID
********************************************************************/
@@ -167,25 +129,6 @@ bool smb_io_uuid(const char *desc, struct GUID *uuid,
}
/*******************************************************************
- Inits a UNISTR structure.
-********************************************************************/
-
-void init_unistr(UNISTR *str, const char *buf)
-{
- size_t len;
-
- if (buf == NULL) {
- str->buffer = NULL;
- return;
- }
-
- len = rpcstr_push_talloc(talloc_tos(), &str->buffer, buf);
- if (len == (size_t)-1) {
- str->buffer = NULL;
- }
-}
-
-/*******************************************************************
Inits a UNISTR2 structure.
********************************************************************/
diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c
deleted file mode 100644
index 91d8591a05..0000000000
--- a/source3/rpc_parse/parse_sec.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2005.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/*******************************************************************
- Reads or writes a SEC_ACE structure.
-********************************************************************/
-
-static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps,
- int depth)
-{
- uint32 old_offset;
- uint32 offset_ace_size;
- uint8 type;
-
- if (psa == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "sec_io_ace");
- depth++;
-
- old_offset = prs_offset(ps);
-
- if (MARSHALLING(ps)) {
- type = (uint8)psa->type;
- }
-
- if(!prs_uint8("type ", ps, depth, &type))
- return False;
-
- if (UNMARSHALLING(ps)) {
- psa->type = (enum security_ace_type)type;
- }
-
- if(!prs_uint8("flags", ps, depth, &psa->flags))
- return False;
-
- if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
- return False;
-
- if(!prs_uint32("access_mask", ps, depth, &psa->access_mask))
- return False;
-
- /* check whether object access is present */
- if (!sec_ace_object(psa->type)) {
- if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
- return False;
- } else {
- if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags))
- return False;
-
- if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
- if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth))
- return False;
-
- if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
- if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth))
- return False;
-
- if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth))
- return False;
- }
-
- /* Theorectically an ACE can have a size greater than the
- sum of its components. When marshalling, pad with extra null bytes up to the
- correct size. */
-
- if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
- uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
- uint32 i;
- uint8 c = 0;
-
- for (i = 0; i < extra_len; i++) {
- if (!prs_uint8("ace extra space", ps, depth, &c))
- return False;
- }
- }
-
- if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a SEC_ACL structure.
-
- First of the xx_io_xx functions that allocates its data structures
- for you as it reads them.
-********************************************************************/
-
-static bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps,
- int depth)
-{
- unsigned int i;
- uint32 old_offset;
- uint32 offset_acl_size;
- SEC_ACL *psa;
- uint16 revision;
-
- /*
- * Note that the size is always a multiple of 4 bytes due to the
- * nature of the data structure. Therefore the prs_align() calls
- * have been removed as they through us off when doing two-layer
- * marshalling such as in the printing code (RPC_BUFFER). --jerry
- */
-
- if (ppsa == NULL)
- return False;
-
- psa = *ppsa;
-
- if(UNMARSHALLING(ps) && psa == NULL) {
- /*
- * This is a read and we must allocate the stuct to read into.
- */
- if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL)
- return False;
- *ppsa = psa;
- }
-
- prs_debug(ps, depth, desc, "sec_io_acl");
- depth++;
-
- old_offset = prs_offset(ps);
-
- if (MARSHALLING(ps)) {
- revision = (uint16)psa->revision;
- }
-
- if(!prs_uint16("revision", ps, depth, &revision))
- return False;
-
- if (UNMARSHALLING(ps)) {
- psa->revision = (enum security_acl_revision)revision;
- }
-
- if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
- return False;
-
- if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (psa->num_aces) {
- if((psa->aces = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces)) == NULL)
- return False;
- } else {
- psa->aces = NULL;
- }
- }
-
- for (i = 0; i < psa->num_aces; i++) {
- fstring tmp;
- slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
- if(!sec_io_ace(tmp, &psa->aces[i], ps, depth))
- return False;
- }
-
- /* Theorectically an ACL can have a size greater than the
- sum of its components. When marshalling, pad with extra null bytes up to the
- correct size. */
-
- if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
- uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
- uint8 c = 0;
-
- for (i = 0; i < extra_len; i++) {
- if (!prs_uint8("acl extra space", ps, depth, &c))
- return False;
- }
- }
-
- if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a SEC_DESC structure.
- If reading and the *ppsd = NULL, allocates the structure.
-********************************************************************/
-
-bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
-{
- uint32 old_offset;
- uint32 max_offset = 0; /* after we're done, move offset to end */
- uint32 tmp_offset = 0;
- uint32 off_sacl, off_dacl, off_owner_sid, off_grp_sid;
- uint16 revision;
-
- SEC_DESC *psd;
-
- if (ppsd == NULL)
- return False;
-
- psd = *ppsd;
-
- if (psd == NULL) {
- if(UNMARSHALLING(ps)) {
- if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL)
- return False;
- *ppsd = psd;
- } else {
- /* Marshalling - just ignore. */
- return True;
- }
- }
-
- prs_debug(ps, depth, desc, "sec_io_desc");
- depth++;
-
- /* start of security descriptor stored for back-calc offset purposes */
- old_offset = prs_offset(ps);
-
- if (MARSHALLING(ps)) {
- revision = (uint16)psd->revision;
- }
-
- if(!prs_uint16("revision", ps, depth, &revision))
- return False;
-
- if (UNMARSHALLING(ps)) {
- psd->revision = (enum security_descriptor_revision)revision;
- }
-
- if(!prs_uint16("type ", ps, depth, &psd->type))
- return False;
-
- if (MARSHALLING(ps)) {
- uint32 offset = SEC_DESC_HEADER_SIZE;
-
- /*
- * Work out the offsets here, as we write it out.
- */
-
- if (psd->sacl != NULL) {
- off_sacl = offset;
- offset += psd->sacl->size;
- } else {
- off_sacl = 0;
- }
-
- if (psd->dacl != NULL) {
- off_dacl = offset;
- offset += psd->dacl->size;
- } else {
- off_dacl = 0;
- }
-
- if (psd->owner_sid != NULL) {
- off_owner_sid = offset;
- offset += ndr_size_dom_sid(psd->owner_sid, NULL, 0);
- } else {
- off_owner_sid = 0;
- }
-
- if (psd->group_sid != NULL) {
- off_grp_sid = offset;
- offset += ndr_size_dom_sid(psd->group_sid, NULL, 0);
- } else {
- off_grp_sid = 0;
- }
- }
-
- if(!prs_uint32("off_owner_sid", ps, depth, &off_owner_sid))
- return False;
-
- if(!prs_uint32("off_grp_sid ", ps, depth, &off_grp_sid))
- return False;
-
- if(!prs_uint32("off_sacl ", ps, depth, &off_sacl))
- return False;
-
- if(!prs_uint32("off_dacl ", ps, depth, &off_dacl))
- return False;
-
- max_offset = MAX(max_offset, prs_offset(ps));
-
- if (off_owner_sid != 0) {
-
- tmp_offset = prs_offset(ps);
- if(!prs_set_offset(ps, old_offset + off_owner_sid))
- return False;
-
- if (UNMARSHALLING(ps)) {
- /* reading */
- if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
- return False;
- }
-
- if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
- return False;
-
- max_offset = MAX(max_offset, prs_offset(ps));
-
- if (!prs_set_offset(ps,tmp_offset))
- return False;
- }
-
- if (psd->group_sid != 0) {
-
- tmp_offset = prs_offset(ps);
- if(!prs_set_offset(ps, old_offset + off_grp_sid))
- return False;
-
- if (UNMARSHALLING(ps)) {
- /* reading */
- if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL)
- return False;
- }
-
- if(!smb_io_dom_sid("grp_sid", psd->group_sid, ps, depth))
- return False;
-
- max_offset = MAX(max_offset, prs_offset(ps));
-
- if (!prs_set_offset(ps,tmp_offset))
- return False;
- }
-
- if ((psd->type & SEC_DESC_SACL_PRESENT) && off_sacl) {
- tmp_offset = prs_offset(ps);
- if(!prs_set_offset(ps, old_offset + off_sacl))
- return False;
- if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
- return False;
- max_offset = MAX(max_offset, prs_offset(ps));
- if (!prs_set_offset(ps,tmp_offset))
- return False;
- }
-
- if ((psd->type & SEC_DESC_DACL_PRESENT) && off_dacl != 0) {
- tmp_offset = prs_offset(ps);
- if(!prs_set_offset(ps, old_offset + off_dacl))
- return False;
- if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
- return False;
- max_offset = MAX(max_offset, prs_offset(ps));
- if (!prs_set_offset(ps,tmp_offset))
- return False;
- }
-
- if(!prs_set_offset(ps, max_offset))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a SEC_DESC_BUF structure.
-********************************************************************/
-
-bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
-{
- uint32 off_len;
- uint32 off_max_len;
- uint32 old_offset;
- uint32 size;
- uint32 len;
- SEC_DESC_BUF *psdb;
- uint32 ptr;
-
- if (ppsdb == NULL)
- return False;
-
- psdb = *ppsdb;
-
- if (UNMARSHALLING(ps) && psdb == NULL) {
- if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL)
- return False;
- *ppsdb = psdb;
- }
-
- prs_debug(ps, depth, desc, "sec_io_desc_buf");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32_pre("max_len", ps, depth, &psdb->sd_size, &off_max_len))
- return False;
-
- ptr = 1;
- if(!prs_uint32 ("ptr ", ps, depth, &ptr))
- return False;
-
- len = ndr_size_security_descriptor(psdb->sd, NULL, 0);
- if(!prs_uint32_pre("len ", ps, depth, &len, &off_len))
- return False;
-
- old_offset = prs_offset(ps);
-
- /* reading, length is non-zero; writing, descriptor is non-NULL */
- if ((UNMARSHALLING(ps) && psdb->sd_size != 0) || (MARSHALLING(ps) && psdb->sd != NULL)) {
- if(!sec_io_desc("sec ", &psdb->sd, ps, depth))
- return False;
- }
-
- if(!prs_align(ps))
- return False;
-
- size = prs_offset(ps) - old_offset;
- if(!prs_uint32_post("max_len", ps, depth, &psdb->sd_size, off_max_len, size == 0 ? psdb->sd_size : size))
- return False;
-
- if(!prs_uint32_post("len ", ps, depth, &len, off_len, size))
- return False;
-
- return True;
-}
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index ed54c3a86e..5fdcaf2d4a 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -827,6 +827,10 @@ NTSTATUS _lsa_LookupSids(pipes_struct *p,
&names,
&mapped_count);
+ if (NT_STATUS_IS_ERR(status)) {
+ return status;
+ }
+
/* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName,
num_sids);
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index b66f48aa29..15c137a88c 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -393,7 +393,7 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
Check if it's \\server or \\server\printer
****************************************************************************/
-static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
+static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
{
DEBUG(3,("Setting printer type=%s\n", handlename));
@@ -423,7 +423,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename
XcvDataPort() interface.
****************************************************************************/
-static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
+static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
{
int snum;
int n_services=lp_numservices();
@@ -434,9 +434,10 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
NT_PRINTER_INFO_LEVEL *printer = NULL;
WERROR result;
- DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
+ DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
+ (unsigned long)strlen(handlename)));
- aprinter = handlename;
+ aprinter = CONST_DISCARD(char *, handlename);
if ( *handlename == '\\' ) {
servername = canon_servername(handlename);
if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
@@ -556,7 +557,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
****************************************************************************/
static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
- char *name, uint32_t access_granted)
+ const char *name, uint32_t access_granted)
{
Printer_entry *new_printer;
@@ -1247,7 +1248,7 @@ static void receive_notify2_message_list(struct messaging_context *msg,
driver
********************************************************************/
-static bool srv_spoolss_drv_upgrade_printer(char* drivername)
+static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
{
int len = strlen(drivername);
@@ -1545,20 +1546,19 @@ bool convert_devicemode(const char *printername,
WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
struct spoolss_OpenPrinterEx *r)
{
- char *name = CONST_DISCARD(char *, r->in.printername);
int snum;
Printer_entry *Printer=NULL;
- if (!name) {
+ if (!r->in.printername) {
return WERR_INVALID_PARAM;
}
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
- DEBUGADD(3,("checking name: %s\n",name));
+ DEBUGADD(3,("checking name: %s\n", r->in.printername));
- if (!open_printer_hnd(p, r->out.handle, name, 0)) {
+ if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
ZERO_STRUCTP(r->out.handle);
return WERR_INVALID_PARAM;
}
@@ -1566,7 +1566,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
Printer = find_printer_index_by_hnd(p, r->out.handle);
if ( !Printer ) {
DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
- "handle we created for printer %s\n", name ));
+ "handle we created for printer %s\n", r->in.printername));
close_printer_handle(p, r->out.handle);
ZERO_STRUCTP(r->out.handle);
return WERR_INVALID_PARAM;
@@ -2075,7 +2075,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p,
* long architecture string
******************************************************************/
-static int get_version_id (char * arch)
+static int get_version_id(const char *arch)
{
int i;
struct table_node archi_table[]= {
@@ -2106,8 +2106,6 @@ static int get_version_id (char * arch)
WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
struct spoolss_DeletePrinterDriver *r)
{
- char *driver;
- char *arch;
NT_PRINTER_DRIVER_INFO_LEVEL info;
NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
int version;
@@ -2128,24 +2126,26 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
return WERR_ACCESS_DENIED;
}
- driver = CONST_DISCARD(char *, r->in.driver);
- arch = CONST_DISCARD(char *, r->in.architecture);
-
/* check that we have a valid driver name first */
- if ((version=get_version_id(arch)) == -1)
+ if ((version = get_version_id(r->in.architecture)) == -1)
return WERR_INVALID_ENVIRONMENT;
ZERO_STRUCT(info);
ZERO_STRUCT(info_win2k);
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver,
+ r->in.architecture,
+ version)))
{
/* try for Win2k driver if "Windows NT x86" */
if ( version == 2 ) {
version = 3;
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3,
+ r->in.driver,
+ r->in.architecture,
+ version))) {
status = WERR_UNKNOWN_PRINTER_DRIVER;
goto done;
}
@@ -2165,7 +2165,9 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
if ( version == 2 )
{
- if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
+ if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3,
+ r->in.driver,
+ r->in.architecture, 3)))
{
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
@@ -2203,8 +2205,6 @@ done:
WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
struct spoolss_DeletePrinterDriverEx *r)
{
- char *driver;
- char *arch;
NT_PRINTER_DRIVER_INFO_LEVEL info;
NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
int version;
@@ -2225,11 +2225,8 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
return WERR_ACCESS_DENIED;
}
- driver = CONST_DISCARD(char *, r->in.driver);
- arch = CONST_DISCARD(char *, r->in.architecture);
-
/* check that we have a valid driver name first */
- if ((version=get_version_id(arch)) == -1) {
+ if ((version = get_version_id(r->in.architecture)) == -1) {
/* this is what NT returns */
return WERR_INVALID_ENVIRONMENT;
}
@@ -2240,7 +2237,8 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
ZERO_STRUCT(info);
ZERO_STRUCT(info_win2k);
- status = get_a_printer_driver(&info, 3, driver, arch, version);
+ status = get_a_printer_driver(&info, 3, r->in.driver,
+ r->in.architecture, version);
if ( !W_ERROR_IS_OK(status) )
{
@@ -2256,7 +2254,9 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
/* try for Win2k driver if "Windows NT x86" */
version = 3;
- if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver,
+ r->in.architecture,
+ version))) {
status = WERR_UNKNOWN_PRINTER_DRIVER;
goto done;
}
@@ -2293,7 +2293,9 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
/* also check for W32X86/3 if necessary; maybe we already have? */
if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
- if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
+ if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3,
+ r->in.driver,
+ r->in.architecture, 3)))
{
if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
@@ -4202,61 +4204,88 @@ static bool snum_is_shared_printer(int snum)
Spoolss_enumprinters.
********************************************************************/
-static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
- uint32_t flags,
- union spoolss_PrinterInfo **info_p,
- uint32_t *count)
+static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
+ uint32_t level,
+ uint32_t flags,
+ union spoolss_PrinterInfo **info_p,
+ uint32_t *count_p)
{
int snum;
int n_services = lp_numservices();
union spoolss_PrinterInfo *info = NULL;
+ uint32_t count = 0;
WERROR result = WERR_OK;
- DEBUG(4,("enum_all_printers_info_1\n"));
-
- *count = 0;
+ *count_p = 0;
+ *info_p = NULL;
- for (snum=0; snum<n_services; snum++) {
+ for (snum = 0; snum < n_services; snum++) {
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- struct spoolss_PrinterInfo1 info1;
if (!snum_is_shared_printer(snum)) {
continue;
}
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
+ DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
+ lp_servicename(snum), snum));
- result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(result)) {
- continue;
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ union spoolss_PrinterInfo,
+ count + 1);
+ if (!info) {
+ result = WERR_NOMEM;
+ goto out;
}
- result = construct_printer_info1(info, ntprinter, flags, &info1, snum);
- free_a_printer(&ntprinter,2);
+ result = get_a_printer(NULL, &ntprinter, 2,
+ lp_const_servicename(snum));
if (!W_ERROR_IS_OK(result)) {
- continue;
+ goto out;
}
- info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
- union spoolss_PrinterInfo,
- *count + 1);
- if (!info) {
- DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
- result = WERR_NOMEM;
+ switch (level) {
+ case 0:
+ result = construct_printer_info0(info, ntprinter,
+ &info[count].info0, snum);
+ break;
+ case 1:
+ result = construct_printer_info1(info, ntprinter, flags,
+ &info[count].info1, snum);
+ break;
+ case 2:
+ result = construct_printer_info2(info, ntprinter,
+ &info[count].info2, snum);
+ break;
+ case 4:
+ result = construct_printer_info4(info, ntprinter,
+ &info[count].info4, snum);
+ break;
+ case 5:
+ result = construct_printer_info5(info, ntprinter,
+ &info[count].info5, snum);
+ break;
+
+ default:
+ result = WERR_UNKNOWN_LEVEL;
+ free_a_printer(&ntprinter, 2);
goto out;
}
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count));
+ free_a_printer(&ntprinter, 2);
+ if (!W_ERROR_IS_OK(result)) {
+ goto out;
+ }
- info[*count].info1 = info1;
- (*count)++;
+ count++;
}
+ *count_p = count;
+ *info_p = info;
+
out:
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(info);
- *count = 0;
return result;
}
@@ -4266,6 +4295,35 @@ static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
}
/********************************************************************
+ * handle enumeration of printers at level 0
+ ********************************************************************/
+
+static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ const char *servername,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
+{
+ DEBUG(4,("enum_all_printers_info_0\n"));
+
+ return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
+}
+
+
+/********************************************************************
+********************************************************************/
+
+static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
+{
+ DEBUG(4,("enum_all_printers_info_1\n"));
+
+ return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
+}
+
+/********************************************************************
enum_all_printers_info_1_local.
*********************************************************************/
@@ -4341,64 +4399,12 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
********************************************************************/
static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
- union spoolss_PrinterInfo **info_p,
+ union spoolss_PrinterInfo **info,
uint32_t *count)
{
- int snum;
- int n_services = lp_numservices();
- union spoolss_PrinterInfo *info = NULL;
- WERROR result = WERR_OK;
+ DEBUG(4,("enum_all_printers_info_2\n"));
- *count = 0;
-
- for (snum=0; snum<n_services; snum++) {
-
- struct spoolss_PrinterInfo2 info2;
- NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-
- if (!snum_is_shared_printer(snum)) {
- continue;
- }
-
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(result)) {
- continue;
- }
-
- result = construct_printer_info2(info, ntprinter, &info2, snum);
- free_a_printer(&ntprinter, 2);
- if (!W_ERROR_IS_OK(result)) {
- continue;
- }
-
- info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
- union spoolss_PrinterInfo,
- *count + 1);
- if (!info) {
- DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
- result = WERR_NOMEM;
- goto out;
- }
-
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1));
-
- info[*count].info2 = info2;
-
- (*count)++;
- }
-
- out:
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- *count = 0;
- return result;
- }
-
- *info_p = info;
-
- return WERR_OK;
+ return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
}
/********************************************************************
@@ -4458,6 +4464,22 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
}
/********************************************************************
+ * handle enumeration of printers at level 4
+ ********************************************************************/
+
+static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
+ uint32_t flags,
+ const char *servername,
+ union spoolss_PrinterInfo **info,
+ uint32_t *count)
+{
+ DEBUG(4,("enum_all_printers_info_4\n"));
+
+ return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
+}
+
+
+/********************************************************************
* handle enumeration of printers at level 5
********************************************************************/
@@ -4467,8 +4489,9 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
union spoolss_PrinterInfo **info,
uint32_t *count)
{
-/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/
- return WERR_OK;
+ DEBUG(4,("enum_all_printers_info_5\n"));
+
+ return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
}
/****************************************************************
@@ -4510,6 +4533,10 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p,
W_ERROR_HAVE_NO_MEMORY(name);
switch (r->in.level) {
+ case 0:
+ result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
+ r->out.info, r->out.count);
+ break;
case 1:
result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
r->out.info, r->out.count);
@@ -4518,14 +4545,14 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p,
result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
r->out.info, r->out.count);
break;
+ case 4:
+ result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
+ r->out.info, r->out.count);
+ break;
case 5:
result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
r->out.info, r->out.count);
break;
- case 3:
- case 4:
- result = WERR_OK; /* ??? */
- break;
default:
return WERR_UNKNOWN_LEVEL;
}
@@ -7247,7 +7274,7 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
WERROR err = WERR_OK;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- fstring driver_name;
+ const char *driver_name = NULL;
uint32_t version;
const char *fn;
@@ -7297,12 +7324,10 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
switch(level) {
case 3:
- fstrcpy(driver_name,
- driver.info_3->name ? driver.info_3->name : "");
+ driver_name = driver.info_3->name ? driver.info_3->name : "";
break;
case 6:
- fstrcpy(driver_name,
- driver.info_6->name ? driver.info_6->name : "");
+ driver_name = driver.info_6->name ? driver.info_6->name : "";
break;
}
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 18c0790569..c9c457b364 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -257,9 +257,10 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
union spoolss_PrinterInfo *info;
uint32_t i, count;
const char *name;
+ uint32_t flags = PRINTER_ENUM_LOCAL;
- if (argc > 3) {
- printf("Usage: %s [level] [name]\n", argv[0]);
+ if (argc > 4) {
+ printf("Usage: %s [level] [name] [flags]\n", argv[0]);
return WERR_OK;
}
@@ -267,14 +268,18 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
level = atoi(argv[1]);
}
- if (argc == 3) {
+ if (argc >= 3) {
name = argv[2];
} else {
name = cli->srv_name_slash;
}
+ if (argc == 4) {
+ flags = atoi(argv[3]);
+ }
+
result = rpccli_spoolss_enumprinters(cli, mem_ctx,
- PRINTER_ENUM_LOCAL,
+ flags,
name,
level,
0,
diff --git a/source3/samba4.mk b/source3/samba4.mk
index 7e7690aadf..3f661bdd14 100644
--- a/source3/samba4.mk
+++ b/source3/samba4.mk
@@ -225,32 +225,32 @@ test4-%::
valgrindtest4:: valgrindtest-all
valgrindtest4-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest4-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest4-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv
gdbtest4:: gdbtest4-all
gdbtest4-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest4-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest4-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv
plugins: $(PLUGINS)
diff --git a/source3/selftest/tests.sh b/source3/selftest/tests.sh
index f88dab0337..ea59f0ee8e 100755
--- a/source3/selftest/tests.sh
+++ b/source3/selftest/tests.sh
@@ -120,6 +120,10 @@ plantest "blackbox.smbclient_s3.plain" dc BINDIR="$BINDIR" script/tests/test_smb
plantest "blackbox.smbclient_s3.plain member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD
plantest "blackbox.smbclient_s3.plain domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD
+# sign, only the member server allows signing
+plantest "blackbox.smbclient_s3.sign member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD "--signing=required"
+plantest "blackbox.smbclient_s3.sign domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD "--signing=required"
+
# encrypted
plantest "blackbox.smbclient_s3.crypt" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$USERNAME \$PASSWORD "-e"
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index cfa4b430eb..77616be48c 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -197,7 +197,6 @@ bool schedule_aio_read_and_X(connection_struct *conn,
fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
(unsigned int)aio_ex->req->mid ));
- srv_defer_sign_response(aio_ex->req->mid);
outstanding_aio_calls++;
return True;
}
@@ -303,6 +302,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
show_msg(aio_ex->outbuf);
if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
+ true, aio_ex->req->seqnum+1,
IS_CONN_ENCRYPTED(fsp->conn),
&req->pcd)) {
exit_server_cleanly("handle_aio_write: srv_send_smb "
@@ -310,8 +310,6 @@ bool schedule_aio_write_and_X(connection_struct *conn,
}
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
"behind for file %s\n", fsp->fsp_name ));
- } else {
- srv_defer_sign_response(aio_ex->req->mid);
}
outstanding_aio_calls++;
@@ -347,7 +345,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
/* If errno is ECANCELED then don't return anything to the
* client. */
if (errno == ECANCELED) {
- srv_cancel_sign_response(aio_ex->req->mid, false);
return 0;
}
@@ -378,6 +375,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
smb_setlen(outbuf,outsize - 4);
show_msg(outbuf);
if (!srv_send_smb(smbd_server_fd(),outbuf,
+ true, aio_ex->req->seqnum+1,
IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) {
exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
"failed.");
@@ -441,7 +439,6 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
/* If errno is ECANCELED then don't return anything to the
* client. */
if (errno == ECANCELED) {
- srv_cancel_sign_response(aio_ex->req->mid, false);
return 0;
}
@@ -475,7 +472,9 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
}
show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn),
+ if (!srv_send_smb(smbd_server_fd(),outbuf,
+ true, aio_ex->req->seqnum+1,
+ IS_CONN_ENCRYPTED(fsp->conn),
NULL)) {
exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
}
@@ -534,7 +533,6 @@ void smbd_aio_complete_mid(unsigned int mid)
if (!aio_ex) {
DEBUG(3,("smbd_aio_complete_mid: Can't find record to "
"match mid %u.\n", mid));
- srv_cancel_sign_response(mid, false);
return;
}
@@ -544,7 +542,6 @@ void smbd_aio_complete_mid(unsigned int mid)
* ignore. */
DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
"aio outstanding (mid[%u]).\n", mid));
- srv_cancel_sign_response(mid, false);
return;
}
diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
new file mode 100644
index 0000000000..1903b0ef96
--- /dev/null
+++ b/source3/smbd/avahi_register.c
@@ -0,0 +1,170 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Register _smb._tcp with avahi
+ *
+ * Copyright (C) Volker Lendecke 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include <avahi-client/client.h>
+#include <avahi-client/publish.h>
+#include <avahi-common/error.h>
+
+struct avahi_state_struct {
+ struct AvahiPoll *poll;
+ AvahiClient *client;
+ AvahiEntryGroup *entry_group;
+ uint16_t port;
+};
+
+static void avahi_entry_group_callback(AvahiEntryGroup *g,
+ AvahiEntryGroupState status,
+ void *userdata)
+{
+ struct avahi_state_struct *state = talloc_get_type_abort(
+ userdata, struct avahi_state_struct);
+ int error;
+
+ switch (status) {
+ case AVAHI_ENTRY_GROUP_ESTABLISHED:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_ESTABLISHED\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_FAILURE:
+ error = avahi_client_errno(state->client);
+
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_FAILURE: %s\n",
+ avahi_strerror(error)));
+ break;
+ case AVAHI_ENTRY_GROUP_COLLISION:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_COLLISION\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_UNCOMMITED:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_UNCOMMITED\n"));
+ break;
+ case AVAHI_ENTRY_GROUP_REGISTERING:
+ DEBUG(10, ("avahi_entry_group_callback: "
+ "AVAHI_ENTRY_GROUP_REGISTERING\n"));
+ break;
+ }
+}
+
+static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
+ void *userdata)
+{
+ struct avahi_state_struct *state = talloc_get_type_abort(
+ userdata, struct avahi_state_struct);
+ int error;
+
+ switch (status) {
+ case AVAHI_CLIENT_S_RUNNING:
+ DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n"));
+
+ state->entry_group = avahi_entry_group_new(
+ c, avahi_entry_group_callback, state);
+ if (state->entry_group == NULL) {
+ error = avahi_client_errno(c);
+ DEBUG(10, ("avahi_entry_group_new failed: %s\n",
+ avahi_strerror(error)));
+ break;
+ }
+ if (avahi_entry_group_add_service(
+ state->entry_group, AVAHI_IF_UNSPEC,
+ AVAHI_PROTO_UNSPEC, 0, global_myname(),
+ "_smb._tcp", NULL, NULL, state->port, NULL) < 0) {
+ error = avahi_client_errno(c);
+ DEBUG(10, ("avahi_entry_group_add_service failed: "
+ "%s\n", avahi_strerror(error)));
+ avahi_entry_group_free(state->entry_group);
+ state->entry_group = NULL;
+ break;
+ }
+ if (avahi_entry_group_commit(state->entry_group) < 0) {
+ error = avahi_client_errno(c);
+ DEBUG(10, ("avahi_entry_group_commit failed: "
+ "%s\n", avahi_strerror(error)));
+ avahi_entry_group_free(state->entry_group);
+ state->entry_group = NULL;
+ break;
+ }
+ break;
+ case AVAHI_CLIENT_FAILURE:
+ error = avahi_client_errno(c);
+
+ DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n",
+ avahi_strerror(error)));
+
+ if (error != AVAHI_ERR_DISCONNECTED) {
+ break;
+ }
+ avahi_client_free(c);
+ state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL,
+ avahi_client_callback, state,
+ &error);
+ if (state->client == NULL) {
+ DEBUG(10, ("avahi_client_new failed: %s\n",
+ avahi_strerror(error)));
+ break;
+ }
+ break;
+ case AVAHI_CLIENT_S_COLLISION:
+ DEBUG(10, ("avahi_client_callback: "
+ "AVAHI_CLIENT_S_COLLISION\n"));
+ break;
+ case AVAHI_CLIENT_S_REGISTERING:
+ DEBUG(10, ("avahi_client_callback: "
+ "AVAHI_CLIENT_S_REGISTERING\n"));
+ break;
+ case AVAHI_CLIENT_CONNECTING:
+ DEBUG(10, ("avahi_client_callback: "
+ "AVAHI_CLIENT_CONNECTING\n"));
+ break;
+ }
+}
+
+void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ uint16_t port)
+{
+ struct avahi_state_struct *state;
+ int error;
+
+ state = talloc(mem_ctx, struct avahi_state_struct);
+ if (state == NULL) {
+ return state;
+ }
+ state->port = port;
+ state->poll = tevent_avahi_poll(state, ev);
+ if (state->poll == NULL) {
+ goto fail;
+ }
+ state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL,
+ avahi_client_callback, state,
+ &error);
+ if (state->client == NULL) {
+ DEBUG(10, ("avahi_client_new failed: %s\n",
+ avahi_strerror(error)));
+ goto fail;
+ }
+ return state;
+
+ fail:
+ TALLOC_FREE(state);
+ return NULL;
+}
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 42849931f3..4c61428692 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -204,9 +204,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
(unsigned int)blr->expire_time.tv_usec, lock_timeout,
blr->fsp->fnum, blr->fsp->fsp_name ));
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(blr->req->mid);
-
return True;
}
@@ -260,6 +257,7 @@ static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTAT
reply_nterror(blr->req, status);
if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
+ true, blr->req->seqnum+1,
blr->req->encrypted, NULL)) {
exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
@@ -343,6 +341,7 @@ static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS
if (!srv_send_smb(smbd_server_fd(),
(char *)blr->req->outbuf,
+ true, blr->req->seqnum+1,
IS_CONN_ENCRYPTED(blr->fsp->conn),
NULL)) {
exit_server_cleanly("blocking_lock_reply_error: "
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 6ac92ed3dd..b646bc30fd 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -202,6 +202,7 @@ extern int num_children;
struct smbd_server_connection {
struct fd_event *fde;
uint64_t num_requests;
+ struct smb_signing_state *signing_state;
};
extern struct smbd_server_connection *smbd_server_conn;
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index f20c851297..d39aab4f47 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -134,6 +134,7 @@ void send_trans_reply(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn), &req->pcd)) {
exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
}
@@ -190,6 +191,7 @@ void send_trans_reply(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn), &req->pcd))
exit_server_cleanly("send_trans_reply: srv_send_smb "
"failed.");
@@ -296,6 +298,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
send:
if (!srv_send_smb(
smbd_server_fd(), (char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn) || req->encrypted,
&req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -322,6 +325,7 @@ static void api_dcerpc_cmd_read_done(struct tevent_req *subreq)
reply_nterror(req, status);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn)
||req->encrypted, &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb "
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index a921954c49..e548c587c1 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -316,7 +316,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice)
capabilities &= ~CAP_RAW_MODE;
if (lp_server_signing() == Required)
secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
- srv_set_signing_negotiated();
+ srv_set_signing_negotiated(smbd_server_conn);
} else {
DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
if (lp_server_signing() == Required) {
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 8ceeaf5f55..fdab2ca848 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -143,7 +143,9 @@ static void change_notify_reply_packet(connection_struct *conn,
}
show_msg((char *)req->outbuf);
- if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)req->outbuf,
+ true, req->seqnum+1,
req->encrypted, &req->pcd)) {
exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
@@ -260,9 +262,6 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
map->mid = request->req->mid;
DLIST_ADD(notify_changes_by_mid, map);
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(request->req->mid);
-
return NT_STATUS_OK;
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 9c7fb1914e..7e75eea6b4 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -230,6 +230,7 @@ void send_nt_replies(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn),
&req->pcd)) {
exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
@@ -440,6 +441,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
START_PROFILE(SMBntcreateX);
+ SET_STAT_INVALID(sbuf);
+
if (req->wct < 24) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
@@ -864,6 +867,8 @@ static void call_nt_transact_create(connection_struct *conn,
uint8_t oplock_granted;
TALLOC_CTX *ctx = talloc_tos();
+ SET_STAT_INVALID(sbuf);
+
DEBUG(5,("call_nt_transact_create\n"));
/*
@@ -1129,9 +1134,9 @@ void reply_ntcancel(struct smb_request *req)
*/
START_PROFILE(SMBntcancel);
+ srv_cancel_sign_response(smbd_server_conn);
remove_pending_change_notify_requests_by_mid(req->mid);
remove_pending_lock_requests_by_mid(req->mid);
- srv_cancel_sign_response(req->mid, true);
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index d529b009d5..52df4fa143 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1033,15 +1033,6 @@ static void defer_open(struct share_mode_lock *lck,
exit_server("push_deferred_smb_message failed");
}
add_deferred_open(lck, req->mid, request_time, state->id);
-
- /*
- * Push the MID of this packet on the signing queue.
- * We only do this once, the first time we push the packet
- * onto the deferred open queue, as this has a side effect
- * of incrementing the response sequence number.
- */
-
- srv_defer_sign_response(req->mid);
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 22870283fa..ce00397bbd 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -361,7 +361,6 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
struct share_mode_entry msg;
files_struct *fsp;
char *break_msg;
- bool sign_state;
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
@@ -423,20 +422,14 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
wait_before_sending_break();
}
- /* Save the server smb signing state. */
- sign_state = srv_oplock_set_signing(False);
-
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
- break_msg,
+ break_msg, false, 0,
IS_CONN_ENCRYPTED(fsp->conn),
NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
- /* Restore the sign state to what it was. */
- srv_oplock_set_signing(sign_state);
-
TALLOC_FREE(break_msg);
/* Async level2 request, don't send a reply, just remove the oplock. */
@@ -457,7 +450,6 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
files_struct *fsp;
char *break_msg;
bool break_to_level2 = False;
- bool sign_state;
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
@@ -530,20 +522,14 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
wait_before_sending_break();
}
- /* Save the server smb signing state. */
- sign_state = srv_oplock_set_signing(False);
-
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
- break_msg,
+ break_msg, false, 0,
IS_CONN_ENCRYPTED(fsp->conn),
NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
- /* Restore the sign state to what it was. */
- srv_oplock_set_signing(sign_state);
-
TALLOC_FREE(break_msg);
fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
@@ -570,7 +556,6 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
unsigned long file_id;
files_struct *fsp;
char *break_msg;
- bool sign_state;
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
@@ -610,20 +595,14 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
exit_server("Could not talloc break_msg\n");
}
- /* Save the server smb signing state. */
- sign_state = srv_oplock_set_signing(False);
-
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
- break_msg,
+ break_msg, false, 0,
IS_CONN_ENCRYPTED(fsp->conn),
NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
- /* Restore the sign state to what it was. */
- srv_oplock_set_signing(sign_state);
-
TALLOC_FREE(break_msg);
fsp->sent_oplock_break = BREAK_TO_NONE_SENT;
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 15d120a79c..076965e783 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -298,11 +298,13 @@ int register_existing_vuid(uint16 vuid,
vuser->server_info->unix_name);
}
- if (srv_is_signing_negotiated() && !vuser->server_info->guest &&
- !srv_signing_started()) {
+ if (srv_is_signing_negotiated(smbd_server_conn) &&
+ !vuser->server_info->guest) {
/* Try and turn on server signing on the first non-guest
* sessionsetup. */
- srv_set_signing(vuser->server_info->user_session_key, response_blob);
+ srv_set_signing(smbd_server_conn,
+ vuser->server_info->user_session_key,
+ response_blob);
}
/* fill in the current_user_info struct */
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 2686cf41d9..7ae7435646 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -216,6 +216,7 @@ static void pipe_write_done(struct tevent_req *subreq)
send:
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
&req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 18fbdd7939..65778ab0fc 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -32,16 +32,20 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf,
Send an smb to a fd.
****************************************************************************/
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
- struct smb_perfcount_data *pcd)
+bool srv_send_smb(int fd, char *buffer,
+ bool do_signing, uint32_t seqnum,
+ bool do_encrypt,
+ struct smb_perfcount_data *pcd)
{
size_t len = 0;
size_t nwritten=0;
ssize_t ret;
char *buf_out = buffer;
- /* Sign the outgoing packet if required. */
- srv_calculate_sign_mac(buf_out);
+ if (do_signing) {
+ /* Sign the outgoing packet if required. */
+ srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
+ }
if (do_encrypt) {
NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
@@ -275,7 +279,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
if (CVAL(lenbuf,0) == 0 && min_recv_size &&
(smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
(min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
- !srv_is_signing_active()) {
+ !srv_is_signing_active(smbd_server_conn)) {
return receive_smb_raw_talloc_partial_read(
mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
@@ -311,7 +315,8 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
char **buffer, unsigned int timeout,
size_t *p_unread, bool *p_encrypted,
- size_t *p_len)
+ size_t *p_len,
+ uint32_t *seqnum)
{
size_t len = 0;
NTSTATUS status;
@@ -336,7 +341,7 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
}
/* Check the incoming SMB signature. */
- if (!srv_check_sign_mac(*buffer, true)) {
+ if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) {
DEBUG(0, ("receive_smb: SMB Signature verification failed on "
"incoming packet!\n"));
return NT_STATUS_INVALID_NETWORK_RESPONSE;
@@ -366,6 +371,7 @@ void init_smb_request(struct smb_request *req,
req->flags2 = SVAL(inbuf, smb_flg2);
req->smbpid = SVAL(inbuf, smb_pid);
req->mid = SVAL(inbuf, smb_mid);
+ req->seqnum = 0;
req->vuid = SVAL(inbuf, smb_uid);
req->tid = SVAL(inbuf, smb_tid);
req->wct = CVAL(inbuf, smb_wct);
@@ -401,7 +407,8 @@ void init_smb_request(struct smb_request *req,
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted, struct smb_perfcount_data *deferred_pcd);
+ uint32_t seqnum, bool encrypted,
+ struct smb_perfcount_data *deferred_pcd);
static void smbd_deferred_open_timer(struct event_context *ev,
struct timed_event *te,
@@ -427,7 +434,7 @@ static void smbd_deferred_open_timer(struct event_context *ev,
process_smb(smbd_server_conn, inbuf,
msg->buf.length, 0,
- msg->encrypted, &msg->pcd);
+ msg->seqnum, msg->encrypted, &msg->pcd);
}
/****************************************************************************
@@ -458,6 +465,7 @@ static bool push_queued_message(struct smb_request *req,
}
msg->request_time = request_time;
+ msg->seqnum = req->seqnum;
msg->encrypted = req->encrypted;
SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
@@ -913,7 +921,7 @@ static const struct smb_message_struct {
/* 0x30 */ { NULL, NULL, 0 },
/* 0x31 */ { NULL, NULL, 0 },
/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
-/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER},
+/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
/* 0x36 */ { NULL, NULL, 0 },
@@ -1362,7 +1370,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
****************************************************************************/
static void construct_reply(char *inbuf, int size, size_t unread_bytes,
- bool encrypted,
+ uint32_t seqnum, bool encrypted,
struct smb_perfcount_data *deferred_pcd)
{
connection_struct *conn;
@@ -1374,6 +1382,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
+ req->seqnum = seqnum;
/* we popped this message off the queue - keep original perf data */
if (deferred_pcd)
@@ -1405,6 +1414,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn)||req->encrypted,
&req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -1420,7 +1430,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes,
****************************************************************************/
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted, struct smb_perfcount_data *deferred_pcd)
+ uint32_t seqnum, bool encrypted,
+ struct smb_perfcount_data *deferred_pcd)
{
int msg_type = CVAL(inbuf,0);
@@ -1442,7 +1453,7 @@ static void process_smb(struct smbd_server_connection *conn,
show_msg((char *)inbuf);
- construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd);
+ construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
trans_num++;
done:
@@ -1637,6 +1648,7 @@ void chain_reply(struct smb_request *req)
talloc_get_size(req->chain_outbuf) - 4);
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn)
||req->encrypted,
&req->pcd)) {
@@ -1761,6 +1773,7 @@ void chain_reply(struct smb_request *req)
show_msg((char *)(req->chain_outbuf));
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
&req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
@@ -1830,6 +1843,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
bool encrypted = false;
TALLOC_CTX *mem_ctx = talloc_tos();
NTSTATUS status;
+ uint32_t seqnum;
/* TODO: make this completely nonblocking */
@@ -1838,7 +1852,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
0, /* timeout */
&unread_bytes,
&encrypted,
- &inbuf_len);
+ &inbuf_len, &seqnum);
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
goto process;
}
@@ -1850,7 +1864,8 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
}
process:
- process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL);
+ process_smb(conn, inbuf, inbuf_len, unread_bytes,
+ seqnum, encrypted, NULL);
}
static void smbd_server_connection_handler(struct event_context *ev,
@@ -2015,7 +2030,8 @@ void smbd_process(void)
unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ("Connection denied from %s\n",
client_addr(get_client_fd(),addr,sizeof(addr)) ) );
- (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL);
+ (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
+ 0, false, NULL);
exit_server_cleanly("connection denied");
}
@@ -2041,6 +2057,10 @@ void smbd_process(void)
DEBUG(0,("Changed root to %s\n", lp_rootdir()));
}
+ if (!srv_init_signing(smbd_server_conn)) {
+ exit_server("Failed to init smb_signing");
+ }
+
/* Setup oplocks */
if (!init_oplocks(smbd_messaging_context()))
exit_server("Failed to init oplocks");
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 8b560bd8ca..16eb4a7fd7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -497,7 +497,7 @@ void reply_special(char *inbuf)
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- srv_send_smb(smbd_server_fd(), outbuf, false, NULL);
+ srv_send_smb(smbd_server_fd(), outbuf, false, 0, false, NULL);
return;
}
@@ -1606,6 +1606,8 @@ void reply_open(struct smb_request *req)
START_PROFILE(SMBopen);
+ SET_STAT_INVALID(sbuf);
+
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBopen);
@@ -1741,6 +1743,8 @@ void reply_open_and_X(struct smb_request *req)
return;
}
+ SET_STAT_INVALID(sbuf);
+
open_flags = SVAL(req->vwv+2, 0);
deny_mode = SVAL(req->vwv+3, 0);
smb_attr = SVAL(req->vwv+5, 0);
@@ -1945,6 +1949,7 @@ void reply_mknew(struct smb_request *req)
START_PROFILE(SMBcreate);
ZERO_STRUCT(ft);
+ SET_STAT_INVALID(sbuf);
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -2123,6 +2128,7 @@ void reply_ctemp(struct smb_request *req)
return;
}
+ SET_STAT_INVALID(sbuf);
SMB_VFS_STAT(conn,fname,&sbuf);
/* We should fail if file does not exist. */
@@ -2766,7 +2772,8 @@ static void send_file_readbraw(connection_struct *conn,
*/
if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
- (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
+ (fsp->wcp == NULL) &&
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
ssize_t sendfile_read = -1;
char header[4];
DATA_BLOB header_blob;
@@ -2870,7 +2877,8 @@ void reply_readbraw(struct smb_request *req)
START_PROFILE(SMBreadbraw);
- if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
+ if (srv_is_signing_active(smbd_server_conn) ||
+ is_encrypted_packet(req->inbuf)) {
exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - "
"raw reads/writes are disallowed.");
}
@@ -3274,7 +3282,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
if (!req_is_in_chain(req) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
- lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
+ (fsp->wcp == NULL) &&
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
@@ -3450,7 +3459,8 @@ void reply_read_and_X(struct smb_request *req)
return;
}
/* We currently don't do this on signed or sealed data. */
- if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) {
+ if (srv_is_signing_active(smbd_server_conn) ||
+ is_encrypted_packet(req->inbuf)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
@@ -3558,7 +3568,7 @@ void reply_writebraw(struct smb_request *req)
*/
SCVAL(req->inbuf,smb_com,SMBwritec);
- if (srv_is_signing_active()) {
+ if (srv_is_signing_active(smbd_server_conn)) {
END_PROFILE(SMBwritebraw);
exit_server_cleanly("reply_writebraw: SMB signing is active - "
"raw reads/writes are disallowed.");
@@ -3653,9 +3663,10 @@ void reply_writebraw(struct smb_request *req)
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
if (!srv_send_smb(smbd_server_fd(),
- buf,
- IS_CONN_ENCRYPTED(conn),
- &req->pcd)) {
+ buf,
+ false, 0, /* no signing */
+ IS_CONN_ENCRYPTED(conn),
+ &req->pcd)) {
exit_server_cleanly("reply_writebraw: srv_send_smb "
"failed.");
}
@@ -4757,6 +4768,7 @@ void reply_echo(struct smb_request *req)
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn)||req->encrypted,
cur_pcd))
exit_server_cleanly("reply_echo: srv_send_smb failed.");
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index d27f98281b..67836f785b 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -643,8 +643,19 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent,
#endif
if (dns_port != 0) {
+#ifdef WITH_DNSSD_SUPPORT
smbd_setup_mdns_registration(smbd_event_context(),
parent, dns_port);
+#endif
+#ifdef WITH_AVAHI_SUPPORT
+ void *avahi_conn;
+
+ avahi_conn = avahi_start_register(
+ smbd_event_context(), smbd_event_context(), dns_port);
+ if (avahi_conn == NULL) {
+ DEBUG(10, ("avahi_start_register failed\n"));
+ }
+#endif
}
return true;
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index eb16a2601e..e33f04d971 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -1110,7 +1110,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
dbgtext( "%s (%s) ", get_remote_machine_name(),
conn->client_address );
- dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
+ dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
dbgtext( "connect to service %s ", lp_servicename(snum) );
dbgtext( "initially as user %s ",
conn->server_info->unix_name );
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 2c29192220..e8878a29ab 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -91,25 +91,6 @@ static int push_signature(uint8 **outbuf)
}
/****************************************************************************
- Start the signing engine if needed. Don't fail signing here.
-****************************************************************************/
-
-static void sessionsetup_start_signing_engine(
- const auth_serversupplied_info *server_info,
- const uint8 *inbuf)
-{
- if (!server_info->guest && !srv_signing_started()) {
- /* We need to start the signing engine
- * here but a W2K client sends the old
- * "BSRSPYL " signature instead of the
- * correct one. Subsequent packets will
- * be correct.
- */
- srv_check_sign_mac((char *)inbuf, False);
- }
-}
-
-/****************************************************************************
Send a security blob via a session setup reply.
****************************************************************************/
@@ -579,7 +560,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
SSVAL(req->outbuf, smb_uid, sess_vuid);
- sessionsetup_start_signing_engine(server_info, req->inbuf);
/* Successful logon. Keep this vuid. */
*p_invalidate_vuid = False;
}
@@ -668,9 +648,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
if (server_info->guest) {
SSVAL(req->outbuf,smb_vwv2,1);
}
-
- sessionsetup_start_signing_engine(server_info,
- (uint8 *)req->inbuf);
}
out:
@@ -1804,8 +1781,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
/* current_user_info is changed on new vuid */
reload_services( True );
-
- sessionsetup_start_signing_engine(server_info, req->inbuf);
}
data_blob_free(&nt_resp);
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
new file mode 100644
index 0000000000..b56eb71f45
--- /dev/null
+++ b/source3/smbd/signing.c
@@ -0,0 +1,158 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB Signing Code
+ Copyright (C) Jeremy Allison 2003.
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
+ Copyright (C) Stefan Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+
+
+/***********************************************************
+ Called to validate an incoming packet from the client.
+************************************************************/
+
+bool srv_check_sign_mac(struct smbd_server_connection *conn,
+ const char *inbuf, uint32_t *seqnum)
+{
+ /* Check if it's a non-session message. */
+ if(CVAL(inbuf,0)) {
+ return true;
+ }
+
+ *seqnum = smb_signing_next_seqnum(conn->signing_state, false);
+ return smb_signing_check_pdu(conn->signing_state,
+ (const uint8_t *)inbuf,
+ *seqnum);
+}
+
+/***********************************************************
+ Called to sign an outgoing packet to the client.
+************************************************************/
+
+void srv_calculate_sign_mac(struct smbd_server_connection *conn,
+ char *outbuf, uint32_t seqnum)
+{
+ /* Check if it's a non-session message. */
+ if(CVAL(outbuf,0)) {
+ return;
+ }
+
+ smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum);
+}
+
+
+/***********************************************************
+ Called to indicate a oneway request
+************************************************************/
+void srv_cancel_sign_response(struct smbd_server_connection *conn)
+{
+ smb_signing_cancel_reply(conn->signing_state, true);
+}
+
+/***********************************************************
+ Called by server negprot when signing has been negotiated.
+************************************************************/
+
+bool srv_init_signing(struct smbd_server_connection *conn)
+{
+ bool allowed = true;
+ bool mandatory = false;
+
+ switch (lp_server_signing()) {
+ case Required:
+ mandatory = true;
+ break;
+ case Auto:
+ break;
+ case True:
+ break;
+ case False:
+ allowed = false;
+ break;
+ }
+
+ conn->signing_state = smb_signing_init(smbd_event_context(),
+ allowed, mandatory);
+ if (!conn->signing_state) {
+ return false;
+ }
+
+ return true;
+}
+
+void srv_set_signing_negotiated(struct smbd_server_connection *conn)
+{
+ smb_signing_set_negotiated(conn->signing_state);
+}
+
+/***********************************************************
+ Returns whether signing is active. We can't use sendfile or raw
+ reads/writes if it is.
+************************************************************/
+
+bool srv_is_signing_active(struct smbd_server_connection *conn)
+{
+ return smb_signing_is_active(conn->signing_state);
+}
+
+
+/***********************************************************
+ Returns whether signing is negotiated. We can't use it unless it was
+ in the negprot.
+************************************************************/
+
+bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
+{
+ return smb_signing_is_negotiated(conn->signing_state);
+}
+
+/***********************************************************
+ Turn on signing from this packet onwards.
+************************************************************/
+
+void srv_set_signing(struct smbd_server_connection *conn,
+ const DATA_BLOB user_session_key,
+ const DATA_BLOB response)
+{
+ bool negotiated;
+ bool mandatory;
+
+ if (!user_session_key.length)
+ return;
+
+ negotiated = smb_signing_is_negotiated(conn->signing_state);
+ mandatory = smb_signing_is_mandatory(conn->signing_state);
+
+ if (!negotiated && !mandatory) {
+ DEBUG(5,("srv_set_signing: signing negotiated = %u, "
+ "mandatory_signing = %u. Not allowing smb signing.\n",
+ negotiated, mandatory));
+ return;
+ }
+
+ if (!smb_signing_activate(conn->signing_state,
+ user_session_key, response)) {
+ return;
+ }
+
+ DEBUG(3,("srv_set_signing: turning on SMB signing: "
+ "signing negotiated = %u, mandatory_signing = %u.\n",
+ negotiated, mandatory));
+}
+
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ee1dda98b2..04b1145e58 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -832,6 +832,7 @@ void send_trans2_replies(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
+ true, req->seqnum+1,
IS_CONN_ENCRYPTED(conn),
&req->pcd))
exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
@@ -894,6 +895,8 @@ static void call_trans2open(connection_struct *conn,
uint32 create_options = 0;
TALLOC_CTX *ctx = talloc_tos();
+ SET_STAT_INVALID(sbuf);
+
/*
* Ensure we have enough parameters to perform the operation.
*/
@@ -2892,8 +2895,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
case SMB_QUERY_CIFS_UNIX_INFO:
{
bool large_write = lp_min_receive_file_size() &&
- !srv_is_signing_active();
- bool large_read = !srv_is_signing_active();
+ !srv_is_signing_active(smbd_server_conn);
+ bool large_read = !srv_is_signing_active(smbd_server_conn);
int encrypt_caps = 0;
if (!lp_unix_extensions()) {
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index 1d0e9a38be..9721628f02 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -2260,14 +2260,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
info_dst.info2.secdesc = NULL;
#if 0
- if (asprintf(&devicename, "\\\\%s\\%s", longname,
- printername) < 0) {
+ info_dst.info2.devmode.devicename =
+ talloc_asprintf(mem_ctx, "\\\\%s\\%s",
+ longname, printername);
+ if (!info_dst.info2.devmode.devicename) {
nt_status = NT_STATUS_NO_MEMORY;
goto done;
}
-
- init_unistr(&ctr_dst.printers_2->devmode->devicename,
- devicename);
#endif
if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
level, &info_dst))
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 15d1b7e2bf..54bcac2b04 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1854,7 +1854,7 @@ 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)) {
- if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB ||
+ if (!(state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) ||
state->request.extra_len != state->request.data.auth_crap.nt_resp_len) {
DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
state->request.data.auth_crap.lm_resp_len,