summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in171
-rw-r--r--source3/auth/auth_netlogond.c6
-rw-r--r--source3/client/smbspool.c9
-rw-r--r--source3/configure.in231
-rw-r--r--source3/include/async_sock.h51
-rw-r--r--source3/include/idmap.h5
-rw-r--r--source3/include/includes.h39
-rw-r--r--source3/include/ntdomain.h3
-rw-r--r--source3/include/proto.h265
-rw-r--r--source3/include/rpc_eventlog.h100
-rw-r--r--source3/include/rpc_lsa.h60
-rw-r--r--source3/include/rpc_misc.h201
-rw-r--r--source3/include/smb.h26
-rw-r--r--source3/include/smb_macros.h2
-rw-r--r--source3/include/smbprofile.h4
-rw-r--r--source3/include/util_tdb.h38
-rw-r--r--source3/include/vfs.h4
-rw-r--r--source3/include/vfs_macros.h3
-rw-r--r--source3/lib/async_sock.c693
-rw-r--r--source3/lib/ctdbd_conn.c50
-rw-r--r--source3/lib/events.c48
-rw-r--r--source3/lib/interface.c7
-rw-r--r--source3/lib/netapi/cm.c2
-rw-r--r--source3/lib/smbconf/testsuite.c60
-rw-r--r--source3/lib/tdb_validate.c502
-rw-r--r--source3/lib/tdb_validate.h79
-rw-r--r--source3/lib/time.c58
-rw-r--r--source3/lib/util.c14
-rw-r--r--source3/lib/util_seaccess.c5
-rw-r--r--source3/lib/util_sock.c22
-rw-r--r--source3/lib/util_tdb.c484
-rw-r--r--source3/lib/wb_reqtrans.c50
-rw-r--r--source3/lib/wbclient.c52
-rw-r--r--source3/libads/kerberos_verify.c130
-rw-r--r--source3/libads/ldap.c8
-rw-r--r--source3/libnet/libnet_join.c9
-rw-r--r--source3/libnet/libnet_samsync_ldif.c88
-rw-r--r--source3/librpc/ndr/ndr_string.c23
-rw-r--r--source3/libsmb/async_smb.c43
-rw-r--r--source3/libsmb/cliconnect.c348
-rw-r--r--source3/libsmb/clidfs.c9
-rw-r--r--source3/libsmb/clientgen.c41
-rw-r--r--source3/libsmb/clifile.c155
-rw-r--r--source3/libsmb/clireadwrite.c30
-rw-r--r--source3/libsmb/clitrans.c20
-rw-r--r--source3/libsmb/credentials.c2
-rw-r--r--source3/libsmb/libsmb_server.c17
-rw-r--r--source3/libsmb/namecache.c21
-rw-r--r--source3/libsmb/namequery.c2
-rw-r--r--source3/libsmb/passchange.c10
-rw-r--r--source3/m4/check_path.m439
-rw-r--r--source3/modules/onefs_acl.c2
-rw-r--r--source3/modules/onefs_streams.c8
-rw-r--r--source3/modules/vfs_aio_fork.c3
-rw-r--r--source3/modules/vfs_default.c39
-rw-r--r--source3/modules/vfs_full_audit.c17
-rw-r--r--source3/modules/vfs_onefs.c27
-rw-r--r--source3/modules/vfs_streams_depot.c8
-rw-r--r--source3/modules/vfs_streams_xattr.c4
-rw-r--r--source3/nmbd/asyncdns.c12
-rw-r--r--source3/nmbd/nmbd.c134
-rw-r--r--source3/nmbd/nmbd_become_dmb.c3
-rw-r--r--source3/nmbd/nmbd_packets.c8
-rw-r--r--source3/nmbd/nmbd_subnetdb.c3
-rw-r--r--source3/nmbd/nmbd_synclists.c2
-rw-r--r--source3/param/loadparm.c45
-rw-r--r--source3/passdb/passdb.c121
-rw-r--r--source3/printing/printing.c18
-rw-r--r--source3/registry/reg_init_basic.c8
-rw-r--r--source3/registry/reg_init_full.c8
-rw-r--r--source3/rpc_client/cli_pipe.c217
-rw-r--r--source3/rpc_client/init_netlogon.c18
-rw-r--r--source3/rpc_client/rpc_transport_np.c162
-rw-r--r--source3/rpc_client/rpc_transport_smbd.c694
-rw-r--r--source3/rpc_parse/parse_eventlog.c210
-rw-r--r--source3/rpc_parse/parse_misc.c1137
-rw-r--r--source3/rpc_parse/parse_prs.c50
-rw-r--r--source3/rpc_server/srv_eventlog.c119
-rw-r--r--source3/rpc_server/srv_eventlog_lib.c606
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c382
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c22
-rw-r--r--source3/rpc_server/srv_pipe.c83
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c321
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c2
-rw-r--r--source3/rpcclient/cmd_eventlog.c67
-rw-r--r--source3/rpcclient/rpcclient.c9
-rw-r--r--source3/samba4-templates.mk8
-rw-r--r--source3/samba4.m423
-rw-r--r--source3/samba4.mk5
-rwxr-xr-xsource3/script/tests/selftest.sh59
-rw-r--r--source3/script/tests/test_functions.sh7
-rwxr-xr-xsource3/script/tests/test_local_s3.sh2
-rwxr-xr-xsource3/script/tests/test_net_misc.sh4
-rwxr-xr-xsource3/script/tests/test_net_registry.sh9
-rwxr-xr-xsource3/script/tests/test_net_s3.sh2
-rwxr-xr-xsource3/script/tests/test_ntlm_auth_s3.sh2
-rwxr-xr-xsource3/script/tests/test_posix_s3.sh2
-rwxr-xr-xsource3/script/tests/test_smbclient_s3.sh45
-rwxr-xr-xsource3/script/tests/test_smbtorture_s3.sh2
-rwxr-xr-xsource3/script/tests/test_testparm_s3.sh2
-rwxr-xr-xsource3/script/tests/test_wbinfo_s3.sh2
-rwxr-xr-xsource3/script/tests/tests_all.sh4
-rw-r--r--source3/script/tests/tests_smbclient_s3.sh2
-rwxr-xr-xsource3/selftest/tests.sh140
-rw-r--r--source3/services/services_db.c16
-rw-r--r--source3/smbd/aio.c156
-rw-r--r--source3/smbd/blocking.c7
-rw-r--r--source3/smbd/dnsregister.c208
-rw-r--r--source3/smbd/file_access.c11
-rw-r--r--source3/smbd/filename.c30
-rw-r--r--source3/smbd/globals.c15
-rw-r--r--source3/smbd/globals.h12
-rw-r--r--source3/smbd/ipc.c148
-rw-r--r--source3/smbd/lanman.c218
-rw-r--r--source3/smbd/mangle_hash.c2
-rw-r--r--source3/smbd/mangle_hash2.c2
-rw-r--r--source3/smbd/negprot.c2
-rw-r--r--source3/smbd/nttrans.c4
-rw-r--r--source3/smbd/open.c70
-rw-r--r--source3/smbd/oplock.c64
-rw-r--r--source3/smbd/oplock_irix.c15
-rw-r--r--source3/smbd/oplock_linux.c66
-rw-r--r--source3/smbd/pipes.c247
-rw-r--r--source3/smbd/posix_acls.c560
-rw-r--r--source3/smbd/process.c396
-rw-r--r--source3/smbd/reply.c55
-rw-r--r--source3/smbd/server.c821
-rw-r--r--source3/smbd/sesssetup.c4
-rw-r--r--source3/smbd/trans2.c52
-rw-r--r--source3/torture/locktest.c7
-rw-r--r--source3/torture/masktest.c7
-rw-r--r--source3/torture/torture.c25
-rw-r--r--source3/utils/eventlogadm.c81
-rw-r--r--source3/utils/net.c8
-rw-r--r--source3/utils/net_ads.c8
-rw-r--r--source3/utils/net_eventlog.c313
-rw-r--r--source3/utils/net_proto.h3
-rw-r--r--source3/utils/net_rpc.c18
-rw-r--r--source3/utils/net_rpc_join.c7
-rw-r--r--source3/utils/smbcacls.c10
-rw-r--r--source3/winbindd/idmap_tdb.c5
-rw-r--r--source3/winbindd/winbindd.c227
-rw-r--r--source3/winbindd/winbindd_cache.c1
-rw-r--r--source3/winbindd/winbindd_cm.c9
-rw-r--r--source3/winbindd/winbindd_dual.c13
-rw-r--r--source3/winbindd/winbindd_group.c6
-rw-r--r--source3/winbindd/winbindd_proto.h5
-rw-r--r--source3/winbindd/winbindd_user.c26
148 files changed, 6703 insertions, 6485 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index cbbf821b22..8e8932bc5f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -19,6 +19,8 @@ datarootdir=@datarootdir@
selftest_prefix=@selftest_prefix@
selftest_shrdir=@selftest_shrdir@
smbtorture4_path=@smbtorture4_path@
+smbtorture4_option=@smbtorture4_option@
+selftest_custom_conf=@selftest_custom_conf@
LIBS=@LIBS@
CC=@CC@
@@ -129,7 +131,6 @@ INSTALLPERMS_DATA = 0644
LOGFILEBASE = @logfilebase@
CONFIGFILE = $(CONFIGDIR)/smb.conf
LMHOSTSFILE = $(CONFIGDIR)/lmhosts
-CTDBDIR = @ctdbdir@
NCALRPCDIR = @ncalrpcdir@
# This is where smbpasswd et al go
@@ -241,6 +242,8 @@ TDB_LIB_OBJ = lib/util_tdb.o ../lib/util/util_tdb.o \
lib/dbwrap_ctdb.o \
lib/dbwrap_rbt.o @LIBTDB_STATIC@
+TDB_VALIDATE_OBJ = lib/tdb_validate.o
+
SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@
VERSION_OBJ = lib/version.o
@@ -277,7 +280,6 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \
../librpc/gen_ndr/ndr_security.o \
../librpc/ndr/ndr_sec_helper.o \
librpc/ndr/ndr_string.o \
- librpc/ndr/sid.o \
../librpc/ndr/uuid.o \
librpc/ndr/util.o
@@ -289,6 +291,9 @@ LIBNDR_GEN_OBJ0 = ../librpc/gen_ndr/ndr_samr.o \
LIBNDR_GEN_OBJ1 = ../librpc/gen_ndr/ndr_netlogon.o \
../librpc/ndr/ndr_netlogon.o
+LIBNDR_GEN_OBJ2 = ../librpc/gen_ndr/ndr_spoolss.o \
+ ../librpc/ndr/ndr_spoolss_buf.o
+
LIBNDR_GEN_OBJ = ../librpc/gen_ndr/ndr_wkssvc.o \
$(LIBNDR_GEN_OBJ0) \
../librpc/gen_ndr/ndr_dfs.o \
@@ -341,7 +346,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/messages_ctdbd.o lib/packet.o lib/ctdbd_conn.o \
lib/interfaces.o lib/memcache.o \
lib/util_transfer_file.o ../lib/async_req/async_req.o \
- lib/async_sock.o \
+ ../lib/async_req/async_sock.o ../lib/async_req/async_req_ntstatus.o \
$(TDB_LIB_OBJ) \
$(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/interface.o lib/pidfile.o \
@@ -362,7 +367,8 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/ldap_escape.o @CHARSET_STATIC@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \
libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \
- lib/file_id.o lib/idmap_cache.o
+ lib/file_id.o lib/idmap_cache.o \
+ ../libcli/security/dom_sid.o
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
@@ -527,6 +533,7 @@ REG_FULL_OBJ = $(REG_SMBCONF_OBJ) \
registry/reg_perfcount.o \
registry/reg_util_legacy.o
+LIB_EVENTLOG_OBJ = rpc_server/srv_eventlog_lib.o
RPC_LSA_OBJ = rpc_server/srv_lsa_nt.o ../librpc/gen_ndr/srv_lsa.o
@@ -562,8 +569,8 @@ RPC_DFS_OBJ = ../librpc/gen_ndr/srv_dfs.o rpc_server/srv_dfs_nt.o
RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
-RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o \
- rpc_server/srv_eventlog_lib.o ../librpc/gen_ndr/srv_eventlog.o
+RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \
+ $(LIB_EVENTLOG_OBJ) ../librpc/gen_ndr/srv_eventlog.o
RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o \
rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
@@ -574,10 +581,10 @@ RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ)
RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \
rpc_parse/parse_spoolss.o \
- rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o
+ rpc_parse/parse_buffer.o
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \
- rpc_client/rpc_transport_sock.o
+ rpc_client/rpc_transport_sock.o rpc_client/rpc_transport_smbd.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
@@ -893,7 +900,8 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \
$(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o \
utils/net_conf.o utils/net_join.o utils/net_user.o \
utils/net_group.o utils/net_file.o utils/net_registry.o \
- auth/token_util.o utils/net_dom.o utils/net_share.o utils/net_lua.o
+ auth/token_util.o utils/net_dom.o utils/net_share.o utils/net_lua.o \
+ utils/net_eventlog.o
# these are not processed by make proto
NET_OBJ2 = utils/net_registry_util.o utils/net_help_common.o
@@ -911,7 +919,8 @@ NET_OBJ = $(NET_OBJ1) \
$(REG_SMBCONF_OBJ) @LIBNETAPI_STATIC@ $(LIBNET_OBJ) \
$(LIBSMBCONF_OBJ) \
@LIBWBCLIENT_STATIC@ \
- $(PRIVILEGES_BASIC_OBJ)
+ $(PRIVILEGES_BASIC_OBJ) @LIBLUA_STATIC@ \
+ $(LIB_EVENTLOG_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
@@ -980,7 +989,9 @@ EVTLOGADM_OBJ0 = utils/eventlogadm.o
EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBSAMBA_OBJ) \
- registry/reg_eventlog.o rpc_server/srv_eventlog_lib.o
+ registry/reg_eventlog.o $(LIB_EVENTLOG_OBJ) \
+ ../librpc/gen_ndr/ndr_eventlog.o \
+ ../librpc/gen_ndr/ndr_lsa.o
SHARESEC_OBJ0 = utils/sharesec.o
SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -1064,7 +1075,8 @@ WINBINDD_OBJ = \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
$(DCUTIL_OBJ) $(IDMAP_OBJ) $(NSS_INFO_OBJ) \
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ) \
- $(LIBADS_SERVER_OBJ) $(SERVER_MUTEX_OBJ) $(LDB_OBJ)
+ $(LIBADS_SERVER_OBJ) $(SERVER_MUTEX_OBJ) $(LDB_OBJ) \
+ $(TDB_VALIDATE_OBJ)
WBINFO_OBJ = ../nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(POPT_LIB_OBJ) $(AFS_SETTOKEN_OBJ) \
@@ -1341,7 +1353,7 @@ bin/.dummy:
bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @BUILD_POPT@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
+ @$(CC) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
$(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \
$(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
@@ -1349,33 +1361,33 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE
bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(ZLIB_LIBS)
bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \
+ @$(CC) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \
$(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) $(POPT_LIBS) $(KRB5LIBS) \
$(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
+ @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
$(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
$(WINBIND_LIBS) $(ZLIB_LIBS)
bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) \
$(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) $(DNSSD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/net@EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @LIBNETAPI_SHARED@ @LIBLUA_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
+ @$(CC) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
$(POPT_LIBS) $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \
$(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \
@INIPARSERLIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(LIBNETAPI_LIBS) $(LIBLUA_LIBS) -lm \
@@ -1383,213 +1395,213 @@ bin/net@EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @L
bin/profiles@EXEEXT@: $(BINARY_PREREQS) $(PROFILES_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
+ @$(CC) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
$(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \
+ @$(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@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
+ @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @BUILD_POPT@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
+ @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS)
bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
-lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \
$(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \
$(LIBTDB_LIBS) $(NSCD_LIBS)
bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/smbstatus@EXEEXT@: $(BINARY_PREREQS) $(STATUS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/smbcontrol@EXEEXT@: $(BINARY_PREREQS) $(SMBCONTROL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ \
+ @$(CC) -DUSING_SMBCONTROL -o $@ \
$(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(LDAP_LIBS) @LIBUNWIND_PTRACE@ $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/smbtree@EXEEXT@: $(BINARY_PREREQS) $(SMBTREE_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/smbpasswd@EXEEXT@: $(BINARY_PREREQS) $(SMBPASSWD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \
+ @$(CC) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \
$(DYNEXP) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/pdbedit@EXEEXT@: $(BINARY_PREREQS) $(PDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(POPT_LIBS) $(PASSDB_LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) \
$(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/smbget@EXEEXT@: $(BINARY_PREREQS) $(SMBGET_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/nmblookup@EXEEXT@: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(POPT_LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/smbtorture@EXEEXT@: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) \
$(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/talloctort@EXEEXT@: $(BINARY_PREREQS) $(TALLOCTORT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) \
+ @$(CC) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) \
$(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/replacetort@EXEEXT@: $(REPLACETORT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(REPLACETORT_OBJ) $(LDFLAGS) \
+ @$(CC) @PIE_LDFLAGS@ -o $@ $(REPLACETORT_OBJ) $(LDFLAGS) \
$(DYNEXP) $(LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS)
bin/smbconftort@EXEEXT@: $(SMBCONFTORT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCONFTORT_OBJ) $(LDFLAGS) \
+ @$(CC) @PIE_LDFLAGS@ -o $@ $(SMBCONFTORT_OBJ) $(LDFLAGS) \
$(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/masktest@EXEEXT@: $(BINARY_PREREQS) $(MASKTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/msgtest@EXEEXT@: $(BINARY_PREREQS) $(MSGTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/smbcacls@EXEEXT@: $(BINARY_PREREQS) $(SMBCACLS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/smbcquotas@EXEEXT@: $(BINARY_PREREQS) $(SMBCQUOTAS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/eventlogadm@EXEEXT@: $(BINARY_PREREQS) $(EVTLOGADM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(EVTLOGADM_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(EVTLOGADM_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/sharesec@EXEEXT@: $(BINARY_PREREQS) $(SHARESEC_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SHARESEC_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(SHARESEC_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/locktest@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/nsstest@EXEEXT@: $(BINARY_PREREQS) $(NSSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PDBTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(PDBTEST_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \
$(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) $(ZLIB_LIBS)
bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
- $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
+ @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
+ $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \
$(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
@SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
$(WINBIND_LIBS) $(ZLIB_LIBS)
bin/smbiconv@EXEEXT@: $(BINARY_PREREQS) $(SMBICONV_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
+ @$(CC) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \
$(TERMLIBS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/log2pcap@EXEEXT@: $(BINARY_PREREQS) $(LOG2PCAP_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) \
$(POPT_LIBS) $(LIBS) $(LIBTALLOC_LIBS)
bin/locktest2@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST2_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/debug2html@EXEEXT@: $(BINARY_PREREQS) $(DEBUG2HTML_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS)
bin/smbfilter@EXEEXT@: $(BINARY_PREREQS) $(SMBFILTER_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) \
+ @$(CC) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS)
bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) \
+ @$(CC) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) \
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
@@ -2259,14 +2271,14 @@ bin/librpc_echo.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_ECHO_OBJ)
bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo "Linking $@"
- @$(CC) $(FLAGS) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
$(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \
$(PASSDB_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) \
$(ZLIB_LIBS)
bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo "Linking $@"
- @$(CC) $(FLAGS) -o $@ $(VLP_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(VLP_OBJ) $(LDFLAGS) $(DYNEXP) \
$(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) \
@@ -2557,14 +2569,14 @@ bin/security.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/security.o
bin/wbinfo@EXEEXT@: $(BINARY_PREREQS) $(WBINFO_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) \
+ @$(CC) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) \
$(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
$(WINBIND_LIBS)
bin/ntlm_auth@EXEEXT@: $(BINARY_PREREQS) $(NTLM_AUTH_OBJ) $(PARAM_OBJ) \
$(LIB_NONSMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \
+ @$(CC) -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBS) \
$(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
@@ -2577,53 +2589,53 @@ bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) @LIBTALLOC_SHAR
bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBBACKUP_OBJ) $(DYNEXP) \
+ @$(CC) -o $@ $(LDFLAGS) $(TDBBACKUP_OBJ) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/tdbtool@EXEEXT@: $(BINARY_PREREQS) $(TDBTOOL_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBTOOL_OBJ) $(DYNEXP) \
+ @$(CC) -o $@ $(LDFLAGS) $(TDBTOOL_OBJ) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/tdbdump@EXEEXT@: $(BINARY_PREREQS) $(TDBDUMP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBDUMP_OBJ) $(DYNEXP) \
+ @$(CC) -o $@ $(LDFLAGS) $(TDBDUMP_OBJ) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/tdbtorture@EXEEXT@: $(BINARY_PREREQS) $(TDBTORTURE_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBTORTURE_OBJ) $(DYNEXP) \
+ @$(CC) -o $@ $(LDFLAGS) $(TDBTORTURE_OBJ) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
bin/t_strcmp@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
- $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
+ $(CC) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
torture/t_strcmp.o -L ./bin -lbigballofmud
bin/t_strstr@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o
- $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
+ $(CC) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
torture/t_strstr.o -L ./bin -lbigballofmud
bin/t_strappend@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strappend.o
- $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
+ $(CC) -o $@ $(DYNEXP) $(LIBS) $(LIBTALLOC_LIBS) \
torture/t_strappend.o -L ./bin -lbigballofmud
bin/t_stringoverflow@EXEEXT@: $(BINARY_PREREQS) bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o
- $(CC) $(FLAGS) -o $@ $(DYNEXP) torture/t_stringoverflow.o \
+ $(CC) -o $@ $(DYNEXP) torture/t_stringoverflow.o \
-L./bin -lbigballofmud
bin/timelimit@EXEEXT@: script/tests/timelimit.o
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(DYNEXP) script/tests/timelimit.o
+ @$(CC) -o $@ $(DYNEXP) script/tests/timelimit.o
bin/rpc_open_tcp@EXEEXT@: $(BINARY_PREREQS) $(RPC_OPEN_TCP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
@echo "Linking $@"
- @$(CC) $(FLAGS) -o $@ $(RPC_OPEN_TCP_OBJ) $(LDFLAGS) $(DYNEXP) \
+ @$(CC) -o $@ $(RPC_OPEN_TCP_OBJ) $(LDFLAGS) $(DYNEXP) \
$(LIBS) $(LIBTALLOC_LIBS) @LIBTDB_SHARED@ $(WINBIND_LIBS) \
$(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS)
bin/test_lp_load@EXEEXT@: $(BINARY_PREREQS) $(TEST_LP_LOAD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@
@echo "Linking $@"
- @$(CC) $(FLAGS) -o $@ $(TEST_LP_LOAD_OBJ) \
+ @$(CC) -o $@ $(TEST_LP_LOAD_OBJ) \
$(LDFLAGS) $(DYNEEXP) $(LIBS) \
$(LDAP_LIBS) \
$(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS)
@@ -2928,9 +2940,12 @@ test_pam_modules:: pam_modules
##
## Targets for 'make test'
##
+
+TEST_EXTRA_ARGS = ${smbtorture4_option} ${selftest_shrdir} ${selftest_custom_conf}
+
test:: all torture timelimit
@echo Running Test suite
- @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" ${selftest_shrdir}
+ @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all ${TEST_EXTRA_ARGS}
valgrindtest:: all torture timelimit
@echo Running Test suite with valgrind
@@ -2939,17 +2954,23 @@ valgrindtest:: all torture timelimit
WINBINDD_VALGRIND="xterm -n winbindd -e valgrind -q --db-attach=yes --num-callers=30" \
SMBD_VALGRIND="xterm -n smbd -e valgrind -q --db-attach=yes --num-callers=30" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
- PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}"
+ PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all ${TEST_EXTRA_ARGS}
SELFTEST_FORMAT = plain
selftestdir = ../selftest
+S3_LD_LIBPATH_OVERRIDE = $(LIB_PATH_VAR)="$(builddir)/bin"
+
selftest:: all torture timelimit
- @$(selftestdir)/selftest.pl --prefix=st --target=samba3 \
+ @LIB_PATH_VAR=$(LIB_PATH_VAR) $(S3_LD_LIBPATH_OVERRIDE) \
+ SAMBA4SHAREDDIR="$(builddir)/bin/shared" SMBTORTURE4=$(smbtorture4_path) \
+ PERL="$(PERL)" PYTHON="$(PYTHON)" \
+ $(PERL) $(selftestdir)/selftest.pl \
+ --prefix=${selftest_prefix} --target=samba3 \
--testlist="$(srcdir)/selftest/tests.sh|" \
--expected-failures=$(srcdir)/selftest/knownfail \
--exclude=$(srcdir)/selftest/skip \
- --socket-wrapper $(TESTS) --format=$(SELFTEST_FORMAT)
+ --socket-wrapper $(TESTS) --format=$(SELFTEST_FORMAT) --immediate
selftest-%:
$(MAKE) selftest TESTS=$*
diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c
index a57f3b74a3..c39dd8c752 100644
--- a/source3/auth/auth_netlogond.c
+++ b/source3/auth/auth_netlogond.c
@@ -134,8 +134,6 @@ static char *mymachinepw(TALLOC_CTX *mem_ctx)
return NULL;
}
- pwd[sizeof(pwd)-1] = '\0';
-
nread = read(fd, pwd, sizeof(pwd)-1);
close(fd);
@@ -144,7 +142,7 @@ static char *mymachinepw(TALLOC_CTX *mem_ctx)
return NULL;
}
- DEBUG(0, ("pwd: %d [%s]\n", (int)nread, pwd));
+ pwd[nread] = '\0';
if (pwd[nread-1] == '\n') {
pwd[nread-1] = '\0';
@@ -238,8 +236,6 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
goto done;
}
- TALLOC_FREE(auth);
-
plaintext_machinepw = mymachinepw(talloc_tos());
if (plaintext_machinepw == NULL) {
status = NT_STATUS_NO_MEMORY;
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 1910ccd4fe..7943cf5828 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -432,10 +432,13 @@ smb_complete_connection(const char *myname,
return NULL;
}
- if (!cli_send_tconX(cli, share, "?????", password, strlen(password) + 1)) {
- fprintf(stderr, "ERROR: Tree connect failed (%s)\n", cli_errstr(cli));
+ nt_status = cli_tcon_andx(cli, share, "?????", password,
+ strlen(password) + 1);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ fprintf(stderr, "ERROR: Tree connect failed (%s)\n",
+ nt_errstr(nt_status));
- if (get_exit_code(cli, cli_nt_error(cli)) == 2) {
+ if (get_exit_code(cli, nt_status) == 2) {
*need_auth = true;
}
diff --git a/source3/configure.in b/source3/configure.in
index 321924889a..306566f26e 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -63,7 +63,7 @@ SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TEVENT_CFLAGS}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TDB_CFLAGS}"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/libaddns"
SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/librpc"
-SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/async_req"
+SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/.."
SAMBA_CONFIGURE_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/popt"
@@ -414,7 +414,7 @@ AC_SUBST(DYNEXP)
dnl Add modules that have to be built by default here
dnl These have to be built static:
-default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
+default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
dnl These are preferably build shared, and static if dlopen() is not available
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer"
@@ -1027,7 +1027,7 @@ fi
AC_CHECK_FUNCS(getcwd fchown chmod fchmod mknod mknod64)
AC_CHECK_FUNCS(strtol)
-AC_CHECK_FUNCS(fstat strchr chflags)
+AC_CHECK_FUNCS(strchr chflags)
AC_CHECK_FUNCS(getrlimit fsync fdatasync setpgid)
AC_CHECK_FUNCS(setsid glob strpbrk crypt16 getauthuid)
AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent)
@@ -1395,7 +1395,7 @@ if test x"$samba_cv_stat_hires" = x"yes" ; then
[whether struct stat has sub-second timestamps])
fi
-AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec], samba_cv_stat_hires_notimespec,
+AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec suffixed nsec], samba_cv_stat_hires_notimespec,
[
AC_TRY_COMPILE(
[
@@ -1423,7 +1423,7 @@ AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct tim
t.tv_sec = s.st_atime;
t.tv_nsec = s.st_atimensec;
],
- samba_cv_stat_hires=yes, samba_cv_stat_hires=no)
+ samba_cv_stat_hires_notimespec=yes, samba_cv_stat_hires_notimespec=no)
])
if test x"$samba_cv_stat_hires_notimespec" = x"yes" ; then
@@ -1431,7 +1431,87 @@ if test x"$samba_cv_stat_hires_notimespec" = x"yes" ; then
AC_DEFINE(HAVE_STAT_ST_ATIMENSEC, 1, [whether struct stat contains st_atimensec])
AC_DEFINE(HAVE_STAT_ST_CTIMENSEC, 1, [whether struct stat contains st_ctimensec])
AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1,
- [whether struct stat has sub-second timestamps without struct timespec])
+ [whether struct stat has sub-second timestamps without struct timespec suffixed nsec])
+fi
+
+dnl AIX stype sub-second timestamps:
+AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec suffixed _n], samba_cv_stat_hires_notimespec_n,
+ [
+ AC_TRY_COMPILE(
+ [
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+ ],
+ [
+ struct timespec t;
+ struct stat s = {0};
+ t.tv_sec = s.st_mtime;
+ t.tv_nsec = s.st_mtime_n;
+ t.tv_sec = s.st_ctime;
+ t.tv_nsec = s.st_ctime_n;
+ t.tv_sec = s.st_atime;
+ t.tv_nsec = s.st_atime_n;
+ ],
+ samba_cv_stat_hires_notimespec_n=yes, samba_cv_stat_hires_notimespec_n=no)
+ ])
+
+if test x"$samba_cv_stat_hires_notimespec_n" = x"yes" ; then
+ AC_DEFINE(HAVE_STAT_ST_MTIME_N, 1, [whether struct stat contains st_mtime_n])
+ AC_DEFINE(HAVE_STAT_ST_ATIME_N, 1, [whether struct stat contains st_atime_n])
+ AC_DEFINE(HAVE_STAT_ST_CTIME_N, 1, [whether struct stat contains st_ctime_n])
+ AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1,
+ [whether struct stat has sub-second timestamps without struct timespec suffixed _n])
+fi
+
+dnl Tru64 has _micro_second_ resolution:
+AC_CACHE_CHECK([whether struct stat has sub-second timestamps in st_uXtime], samba_cv_stat_hires_uxtime,
+ [
+ AC_TRY_COMPILE(
+ [
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+ ],
+ [
+ struct timespec t;
+ struct stat s = {0};
+ t.tv_sec = s.st_mtime;
+ t.tv_nsec = s.st_umtime * 1000;
+ t.tv_sec = s.st_ctime;
+ t.tv_nsec = s.st_uctime * 1000;
+ t.tv_sec = s.st_atime;
+ t.tv_nsec = s.st_uatime * 1000;
+ ],
+ samba_cv_stat_hires_uxtime=yes, samba_cv_stat_hires_uxtime=no)
+ ])
+
+if test x"$samba_cv_stat_hires_uxtime" = x"yes" ; then
+ AC_DEFINE(HAVE_STAT_ST_UMTIME, 1, [whether struct stat contains st_umtime])
+ AC_DEFINE(HAVE_STAT_ST_UATIME, 1, [whether struct stat contains st_uatime])
+ AC_DEFINE(HAVE_STAT_ST_UCTIME, 1, [whether struct stat contains st_uctime])
+ AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1,
+ [whether struct stat has sub-second timestamps in st_uXtime])
fi
AC_CACHE_CHECK([whether struct stat has st_birthtimespec], samba_cv_stat_st_birthtimespec,
@@ -1457,7 +1537,7 @@ AC_CACHE_CHECK([whether struct stat has st_birthtimespec], samba_cv_stat_st_birt
struct stat s = {0};
t = s.st_birthtimespec;
],
- samba_cv_stat_st_birthtimespec=yes, samba_cv_stat_birthtimespec=no)
+ samba_cv_stat_st_birthtimespec=yes, samba_cv_stat_st_birthtimespec=no)
])
if test x"$samba_cv_stat_st_birthtimespec" = x"yes" ; then
@@ -1487,7 +1567,7 @@ AC_CACHE_CHECK([whether struct stat has st_birthtimensec], samba_cv_stat_st_birt
struct stat s = {0};
t.tv_nsec = s.st_birthtimensec;
],
- samba_cv_stat_st_birthtimensec=yes, samba_cv_stat_birthtimensec=no)
+ samba_cv_stat_st_birthtimensec=yes, samba_cv_stat_st_birthtimensec=no)
])
if test x"$samba_cv_stat_st_birthtimensec" = x"yes" ; then
@@ -1517,7 +1597,7 @@ AC_CACHE_CHECK([whether struct stat has st_birthtime], samba_cv_stat_st_birthtim
struct stat s = {0};
t = s.st_birthtime;
],
- samba_cv_stat_st_birthtime=yes, samba_cv_stat_birthtime=no)
+ samba_cv_stat_st_birthtime=yes, samba_cv_stat_st_birthtime=no)
])
if test x"$samba_cv_stat_st_birthtime" = x"yes" ; then
@@ -5152,17 +5232,128 @@ AC_MSG_RESULT([$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT])
#################################################
# check for cluster extensions
-AC_MSG_CHECKING(whether to include cluster support)
+CTDB_CFLAGS=""
+AC_SUBST(CTDB_CFLAGS)
+AC_ARG_WITH(ctdb,
+[AS_HELP_STRING([--with-ctdb=DIR], [Where to find ctdb sources])],
+[ case "$withval" in
+ yes|no)
+ AC_MSG_WARN([--with-ctdb called without argument])
+ ;;
+ *)
+ CTDB_CPPFLAGS="-I$withval/include"
+ ;;
+ esac])
+
+SAVED_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $CTDB_CPPFLAGS"
+ctdb_broken="missing or broken headers"
+
+AC_CHECK_HEADERS(ctdb.h ctdb_private.h,,,[
+#include "confdefs.h"
+#define NO_CONFIG_H
+#include "replace.h"
+#include "system/wait.h"
+#include "system/network.h"
+#define private #error __USED_RESERVED_WORD_private__
+#include <talloc.h>
+#include <tdb.h>
+#include <ctdb.h>
+])
+
+AC_HAVE_DECL(CTDB_CONTROL_TRANS2_COMMIT_RETRY,[
+#include "confdefs.h"
+#define NO_CONFIG_H
+#include "replace.h"
+#include "system/wait.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tdb.h>
+#include <ctdb.h>
+#include <ctdb_private.h>
+])
+if test x"$ac_cv_have_CTDB_CONTROL_TRANS2_COMMIT_RETRY_decl" = x"yes"; then
+ ctdb_broken=no
+else
+ ctdb_broken="missing transaction support"
+fi
+
+# in ctdb 1.0.57 ctdb_control_tcp was temparary renamed to ctdb_tcp_client
+AC_CHECK_TYPE(struct ctdb_tcp_client,[
+ AC_DEFINE([ctdb_control_tcp],[ctdb_tcp_client],[ctdb ipv4 support])
+],,[
+#include "confdefs.h"
+#define NO_CONFIG_H
+#include "replace.h"
+#include "system/wait.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tdb.h>
+#include <ctdb.h>
+#include <ctdb_private.h>
+])
+
+AC_CHECK_TYPE(struct ctdb_control_tcp,[
+ AC_DEFINE([HAVE_STRUCT_CTDB_CONTROL_TCP],[1],[ctdb ipv4 support])
+],[
+ ctdb_broken="missing struct ctdb_control_tcp"
+],[
+#include "confdefs.h"
+#define NO_CONFIG_H
+#include "replace.h"
+#include "system/wait.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tdb.h>
+#include <ctdb.h>
+#include <ctdb_private.h>
+])
+
+AC_CHECK_TYPE(struct ctdb_control_tcp_addr,[
+ AC_DEFINE([HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR],[1],[ctdb ipv6 support])
+],,[
+#include "confdefs.h"
+#define NO_CONFIG_H
+#include "replace.h"
+#include "system/wait.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tdb.h>
+#include <ctdb.h>
+#include <ctdb_private.h>
+])
+CPPFLAGS="$SAVED_CPPFLAGS"
+
+AC_MSG_CHECKING(cluster support)
AC_ARG_WITH(cluster-support,
-[AS_HELP_STRING([--with-cluster-support], [Enable cluster extensions (default=no)])])
-if test "x$with_cluster_support" = "xyes"; then
+[AS_HELP_STRING([--with-cluster-support], [Enable cluster extensions (default=auto)])])
+
+if test x"$with_cluster_support" = x ; then
+ with_cluster_support="auto"
+fi
+
+if test x"$ac_cv_header_ctdb_private_h" != x"yes"; then
+ if test "x$with_cluster_support" = "xyes"; then
+ AC_MSG_ERROR("ctdb_private.h is required for cluster support")
+ fi
+ with_cluster_support=no
+fi
+
+if test x"$ctdb_broken" != x"no"; then
+ if test "x$with_cluster_support" = "xyes"; then
+ AC_MSG_ERROR(["cluster support: $ctdb_broken"])
+ fi
+ with_cluster_support=no
+fi
+
+if test "x$with_cluster_support" != "xno"; then
AC_DEFINE(CLUSTER_SUPPORT,1,[Whether to enable cluster extensions])
+ SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${CTDB_CPPFLAGS}"
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
-
#################################################
# check for ACL support
@@ -5724,6 +5915,8 @@ fi
############################################
# See if we have the Linux splice syscall.
+case "$host_os" in
+*linux*)
AC_CACHE_CHECK([for Linux splice],
samba_cv_HAVE_LINUX_SPLICE,[
AC_TRY_LINK([
@@ -5734,6 +5927,11 @@ AC_CACHE_CHECK([for Linux splice],
[long ret = splice(0,0,1,0,400,0);],
samba_cv_HAVE_LINUX_SPLICE=yes,
samba_cv_HAVE_LINUX_SPLICE=no)])
+;;
+*)
+samba_cv_HAVE_LINUX_SPLICE=no
+;;
+esac
if test x"$samba_cv_HAVE_LINUX_SPLICE" = x"yes"; then
AC_DEFINE(HAVE_LINUX_SPLICE,1,
@@ -5999,7 +6197,7 @@ if test x"$enable_dnssd" != x"no"; then
AC_CHECK_FUNCS(DNSServiceRegister)
AC_CHECK_LIB_EXT(dns_sd, DNSSD_LIBS, DNSServiceRegister)
if test x"$ac_cv_func_DNSServiceRegister" != x"yes" -a \
- x"$ac_cv_lib_ext_DNSServiceRegister" != x"yes"; then
+ x"$ac_cv_lib_ext_dns_sd_DNSServiceRegister" != x"yes"; then
have_dnssd_support=no
fi
@@ -6142,7 +6340,7 @@ SMB_MODULE(rpc_netlogon, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RP
SMB_MODULE(rpc_netdfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
SMB_MODULE(rpc_srvsvc, \$(RPC_SVC_OBJ), "bin/librpc_svcsvc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
-SMB_MODULE(rpc_eventlog2, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog2.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_eventlog, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog.$SHLIBEXT", RPC)
SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
SMB_MODULE(rpc_rpcecho, \$(RPC_ECHO_OBJ), "bin/librpc_rpcecho.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC,smbd/server.o)
@@ -6339,7 +6537,10 @@ fi
if test x$enable_merged_build = xyes; then
MERGED_BUILD=1
+ saved_USESHARED="$USESHARED"
+ USESHARED="false"
m4_include(samba4.m4)
+ USESHARED="$saved_USESHARED"
fi
AC_SUBST(ZLIB_LIBS)
diff --git a/source3/include/async_sock.h b/source3/include/async_sock.h
deleted file mode 100644
index c6f95d64d5..0000000000
--- a/source3/include/async_sock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- async socket operations
- Copyright (C) Volker Lendecke 2008
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ASYNC_SOCK_H__
-#define __ASYNC_SOCK_H__
-
-#include "includes.h"
-
-ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno);
-size_t async_syscall_result_size_t(struct async_req *req, int *perrno);
-int async_syscall_result_int(struct async_req *req, int *perrno);
-
-struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const void *buffer, size_t length,
- int flags);
-struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, void *buffer, size_t length,
- int flags);
-struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len);
-NTSTATUS async_connect_recv(struct async_req *req, int *perrno);
-
-struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const void *buffer, size_t length,
- int flags);
-NTSTATUS sendall_recv(struct async_req *req);
-
-struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, void *buffer, size_t length,
- int flags);
-NTSTATUS recvall_recv(struct async_req *req);
-
-#endif
diff --git a/source3/include/idmap.h b/source3/include/idmap.h
index 4322192155..672e373108 100644
--- a/source3/include/idmap.h
+++ b/source3/include/idmap.h
@@ -22,11 +22,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* idmap version determines auto-conversion - this is the database
- structure version specifier. */
-
-#define IDMAP_VERSION 2
-
/* The interface version specifier.
Updated to 3 for enum types by JRA. */
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 9c7f15b9cb..4aa3c07343 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -619,11 +619,9 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "ntlmssp.h"
#include "auth.h"
#include "ntdomain.h"
-#include "rpc_lsa.h"
#include "reg_objects.h"
#include "reg_db.h"
#include "rpc_spoolss.h"
-#include "rpc_eventlog.h"
#include "rpc_perfcount.h"
#include "rpc_perfcount_defs.h"
#include "librpc/gen_ndr/notify.h"
@@ -647,9 +645,9 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "ctdbd_conn.h"
#include "../lib/util/talloc_stack.h"
#include "memcache.h"
-#include "async_req.h"
+#include "../lib/async_req/async_req_ntstatus.h"
#include "async_smb.h"
-#include "async_sock.h"
+#include "../lib/async_req/async_sock.h"
#include "services.h"
#include "eventlog.h"
@@ -678,20 +676,6 @@ struct printjob;
#include "smb_ldap.h"
-struct dns_reg_state;
-
-void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
- unsigned port,
- int *maxfd,
- fd_set *listen_set,
- struct timeval *timeout);
-
-void dns_register_close(struct dns_reg_state ** dns_state_ptr);
-
-
-bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
- fd_set *lfds, struct timeval *timeout);
-
/*
* Reasons for cache flush.
*/
@@ -893,8 +877,25 @@ char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...) PRINTF_ATT
#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
#endif
-#if defined(HAVE_KRB5)
+/*
+ * This should be under the HAVE_KRB5 flag but since they're used
+ * in lp_kerberos_method(), they ned to be always available
+ */
+#define KERBEROS_VERIFY_SECRETS 0
+#define KERBEROS_VERIFY_SYSTEM_KEYTAB 1
+#define KERBEROS_VERIFY_DEDICATED_KEYTAB 2
+#define KERBEROS_VERIFY_SECRETS_AND_KEYTAB 3
+
+/*
+ * If you add any entries to the above, please modify the below expressions
+ * so they remain accurate.
+ */
+#define USE_KERBEROS_KEYTAB (KERBEROS_VERIFY_SECRETS != lp_kerberos_method())
+#define USE_SYSTEM_KEYTAB \
+ ((KERBEROS_VERIFY_SECRETS_AND_KEYTAB == lp_kerberos_method()) || \
+ (KERBEROS_VERIFY_SYSTEM_KEYTAB == lp_kerberos_method()))
+#if defined(HAVE_KRB5)
krb5_error_code smb_krb5_parse_name(krb5_context context,
const char *name, /* in unix charset */
krb5_principal *principal);
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 3f501550da..2d6a358391 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -214,8 +214,7 @@ typedef struct pipes_struct {
struct auth_serversupplied_info *server_info;
- fstring name;
- fstring pipe_srv_name;
+ struct ndr_syntax_id syntax;
/* linked list of rpc dispatch tables associated
with the open rpc contexts */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 8838419705..267ee74482 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1128,6 +1128,7 @@ bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
bool socket_exist(const char *fname);
bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st);
+uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf);
SMB_OFF_T get_file_size(char *file_name);
char *attrib_string(uint16 mode);
void show_msg(char *buf);
@@ -1674,8 +1675,6 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
int num_rids, uint32 *rids,
const char **domain_name,
const char ***names, enum lsa_SidType **types);
-bool winbind_allocate_uid(uid_t *uid);
-bool winbind_allocate_gid(gid_t *gid);
/* The following definitions come from lib/wins_srv.c */
@@ -2324,9 +2323,19 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
const char *pass, int passlen,
const char *ntpass, int ntpasslen,
const char *workgroup);
+struct async_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli);
+NTSTATUS cli_session_setup_guest_recv(struct async_req *req);
bool cli_ulogoff(struct cli_state *cli);
-bool cli_send_tconX(struct cli_state *cli,
- const char *share, const char *dev, const char *pass, int passlen);
+struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *share, const char *dev,
+ const char *pass, int passlen);
+NTSTATUS cli_tcon_andx_recv(struct async_req *req);
+NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
+ const char *dev, const char *pass, int passlen);
bool cli_tdis(struct cli_state *cli);
void cli_negprot_sendsync(struct cli_state *cli);
NTSTATUS cli_negprot(struct cli_state *cli);
@@ -2462,6 +2471,8 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
DATA_BLOB data);
NTSTATUS cli_echo_recv(struct async_req *req);
NTSTATUS cli_echo(struct cli_state *cli, uint16_t num_echos, DATA_BLOB data);
+bool cli_ucs2(struct cli_state *cli);
+bool is_andx_req(uint8_t cmd);
/* The following definitions come from libsmb/clierror.c */
@@ -2499,8 +2510,31 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
uint32 FileAttributes, uint32 ShareAccess,
uint32 CreateDisposition, uint32 CreateOptions,
uint8 SecuityFlags);
+struct async_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ uint32_t CreatFlags,
+ uint32_t DesiredAccess,
+ uint32_t FileAttributes,
+ uint32_t ShareAccess,
+ uint32_t CreateDisposition,
+ uint32_t CreateOptions,
+ uint8_t SecurityFlags);
+NTSTATUS cli_ntcreate_recv(struct async_req *req, uint16_t *pfnum);
+NTSTATUS cli_ntcreate(struct cli_state *cli,
+ const char *fname,
+ uint32_t CreatFlags,
+ uint32_t DesiredAccess,
+ uint32_t FileAttributes,
+ uint32_t ShareAccess,
+ uint32_t CreateDisposition,
+ uint32_t CreateOptions,
+ uint8_t SecurityFlags,
+ uint16_t *pfid);
int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess);
-uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str);
+uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str,
+ size_t str_len, size_t *pconverted_size);
struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_state *cli,
const char *fname, int flags, int share_mode);
@@ -2944,7 +2978,6 @@ NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor);
/* The following definitions come from libsmb/namecache.c */
bool namecache_enable(void);
-bool namecache_shutdown(void);
bool namecache_store(const char *name,
int name_type,
int num_names,
@@ -3952,6 +3985,7 @@ bool lp_passdb_expand_explicit(void);
char *lp_ldap_suffix(void);
char *lp_ldap_admin_dn(void);
int lp_ldap_ssl(void);
+bool lp_ldap_ssl_ads(void);
int lp_ldap_passwd_sync(void);
bool lp_ldap_delete_dn(void);
int lp_ldap_replication_sleep(void);
@@ -4027,7 +4061,8 @@ bool lp_client_use_spnego(void);
bool lp_hostname_lookups(void);
bool lp_change_notify(const struct share_params *p );
bool lp_kernel_change_notify(const struct share_params *p );
-bool lp_use_kerberos_keytab(void);
+char * lp_dedicated_keytab_file(void);
+int lp_kerberos_method(void);
bool lp_defer_sharing_violations(void);
bool lp_enable_privileges(void);
bool lp_enable_asu_support(void);
@@ -5294,14 +5329,55 @@ NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *cli,
DATA_BLOB *session_key);
+NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *syntax,
+ struct rpc_pipe_client **presult);
/* The following definitions come from rpc_client/rpc_transport_np.c */
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const struct ndr_syntax_id *abstract_syntax);
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult);
NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
const struct ndr_syntax_id *abstract_syntax,
struct rpc_cli_transport **presult);
struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p);
+/* The following definitions come from rpc_client/rpc_transport_smbd.c */
+
+struct async_req *rpc_cli_smbd_conn_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ void (*stdout_callback)(char *buf,
+ size_t len,
+ void *priv),
+ void *priv);
+NTSTATUS rpc_cli_smbd_conn_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn **pconn);
+NTSTATUS rpc_cli_smbd_conn_init(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn **pconn,
+ void (*stdout_callback)(char *buf,
+ size_t len,
+ void *priv),
+ void *priv);
+
+struct async_req *rpc_transport_smbd_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *abstract_syntax);
+NTSTATUS rpc_transport_smbd_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult);
+NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_cli_transport **presult);
+
/* The following definitions come from rpc_client/rpc_transport_sock.c */
NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
@@ -5600,100 +5676,29 @@ bool smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16
bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc);
uint32 size_of_relative_string(UNISTR *string);
-/* The following definitions come from rpc_parse/parse_eventlog.c */
-
-bool eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u,
- prs_struct *ps, int depth);
-bool eventlog_io_r_read_eventlog(const char *desc,
- EVENTLOG_Q_READ_EVENTLOG *q_u,
- EVENTLOG_R_READ_EVENTLOG *r_u,
- prs_struct *ps,
- int depth);
-
/* The following definitions come from rpc_parse/parse_misc.c */
bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);
bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime);
-uint32 get_enum_hnd(ENUM_HND *enh);
-void init_enum_hnd(ENUM_HND *enh, uint32 hnd);
-bool smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth);
-void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
-bool smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2);
-bool smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
bool smb_io_uuid(const char *desc, struct GUID *uuid,
prs_struct *ps, int depth);
-void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
-bool smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth);
-void init_uni_hdr(UNIHDR *hdr, UNISTR2 *str2);
-bool smb_io_unihdr(const char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
-void init_buf_hdr(BUFHDR *hdr, int max_len, int len);
-bool smb_io_hdrbuf_pre(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
-bool smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
- uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
-bool smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
void init_unistr(UNISTR *str, const char *buf);
bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth);
-void init_rpc_blob_uint32(RPC_DATA_BLOB *str, uint32 val);
-void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len);
-void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf);
-void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len);
bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
void copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
-void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len);
-bool smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags);
-void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags);
-void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf );
void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf);
void init_unistr2_from_unistr(TALLOC_CTX *ctx, UNISTR2 *to, const UNISTR *from);
void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) ;
bool prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2);
bool prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 );
bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
-bool prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4);
-bool prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4);
-bool prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4);
-bool prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array );
-bool init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings );
-void init_dom_rid(DOM_RID *prid, uint32 rid, uint16 type, uint32 idx);
-bool smb_io_dom_rid(const char *desc, DOM_RID *rid, prs_struct *ps, int depth);
-bool smb_io_dom_rid2(const char *desc, DOM_RID2 *rid, prs_struct *ps, int depth);
-void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
-bool smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
-void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
-void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv,
- const char *comp_name);
-bool smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth);
-void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name);
-bool smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth);
-bool smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
-bool smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
-void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
- const char *logon_srv, const char *comp_name,
- const DOM_CRED *clnt_cred);
-bool smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-void init_clnt_info(DOM_CLNT_INFO *clnt,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- const DOM_CRED *cred);
-bool smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high);
-bool smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth);
-void init_owf_info(OWF_INFO *hash, const uint8 data[16]);
-bool smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
-bool smb_io_gid(const char *desc, DOM_GID *gid, prs_struct *ps, int depth);
bool smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
void init_unistr3(UNISTR3 *str, const char *buf);
bool smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth);
bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
-bool smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
-bool smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth);
-bool smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth);
-bool make_uni_hdr(UNIHDR *hdr, int len);
-bool make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
uint32 str_len_uni(UNISTR *source);
bool policy_handle_is_valid(const POLICY_HND *hnd);
@@ -5751,7 +5756,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin
bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str);
-bool prs_string2(bool charmode, const char *name, prs_struct *ps, int depth, STRING2 *str);
bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str);
bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth);
bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
@@ -5778,8 +5782,7 @@ bool prs_data_blob(prs_struct *prs, DATA_BLOB *blob, TALLOC_CTX *mem_ctx);
/* The following definitions come from rpc_parse/parse_rpc.c */
-const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
- const struct ndr_syntax_id *interface);
+const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface);
void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
uint32 call_id, int data_len, int auth_len);
bool smb_io_rpc_hdr(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
@@ -6172,33 +6175,43 @@ bool spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_st
bool make_monitorui_buf( RPC_BUFFER *buf, const char *dllname );
bool convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) ;
-/* The following definitions come from rpc_server/srv_eventlog.c */
-
-NTSTATUS rpc_eventlog2_init(void);
-void eventlog2_get_pipe_fns(struct api_struct **fns, int *n_fns);
-
/* The following definitions come from rpc_server/srv_eventlog_lib.c */
TDB_CONTEXT *elog_init_tdb( char *tdbfilename );
char *elog_tdbname(TALLOC_CTX *ctx, const char *name );
int elog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention );
bool prune_eventlog( TDB_CONTEXT * tdb );
-bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed );
-ELOG_TDB *elog_open_tdb( char *logname, bool force_clear );
+ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only );
int elog_close_tdb( ELOG_TDB *etdb, bool force_close );
-int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee );
-void fixup_eventlog_entry( Eventlog_entry * ee );
-bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor );
+bool parse_logentry( TALLOC_CTX *mem_ctx, char *line, struct eventlog_Record_tdb *entry, bool * eor );
+size_t fixup_eventlog_record_tdb(struct eventlog_Record_tdb *r);
+struct eventlog_Record_tdb *evlog_pull_record_tdb(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ uint32_t record_number);
+NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ struct eventlog_Record_tdb *r,
+ uint32_t *record_number);
+NTSTATUS evlog_push_record(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ struct EVENTLOGRECORD *r,
+ uint32_t *record_number);
+struct EVENTLOGRECORD *evlog_pull_record(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ uint32_t record_number);
+NTSTATUS evlog_evt_entry_to_tdb_entry(TALLOC_CTX *mem_ctx,
+ const struct EVENTLOGRECORD *e,
+ struct eventlog_Record_tdb *t);
+NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx,
+ const struct eventlog_Record_tdb *t,
+ struct EVENTLOGRECORD *e);
/* The following definitions come from rpc_server/srv_eventlog_nt.c */
-NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
- EVENTLOG_Q_READ_EVENTLOG * q_u,
- EVENTLOG_R_READ_EVENTLOG * r_u );
-
/* The following definitions come from rpc_server/srv_lsa_hnd.c */
-bool init_pipe_handle_list(pipes_struct *p, const char *pipe_name);
+bool init_pipe_handle_list(pipes_struct *p,
+ const struct ndr_syntax_id *syntax);
bool create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void *data_ptr);
bool find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p);
bool close_policy_hnd(pipes_struct *p, POLICY_HND *hnd);
@@ -6221,7 +6234,7 @@ NTSTATUS rpc_srv_register(int version, const char *clnt,
const char *srv,
const struct ndr_interface_table *iface,
const struct api_struct *cmds, int size);
-bool is_known_pipename(const char *cli_filename);
+bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax);
bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p);
bool api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p);
bool api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in,
@@ -6240,10 +6253,15 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
const char *client_address,
struct auth_serversupplied_info *server_info,
struct fake_file_handle **phandle);
-NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data,
- size_t len, ssize_t *nwritten);
-NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,
- ssize_t *nread, bool *is_data_outstanding);
+struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ const uint8_t *data, size_t len);
+NTSTATUS np_write_recv(struct async_req *req, ssize_t *nwritten);
+struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ uint8_t *data, size_t len);
+NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread,
+ bool *is_data_outstanding);
/* The following definitions come from rpc_server/srv_samr_util.c */
@@ -6476,8 +6494,6 @@ REGVAL_CTR *svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token );
/* The following definitions come from smbd/aio.c */
-void aio_request_done(uint16_t mid);
-bool aio_finished(void);
void initialize_async_io_handler(void);
bool schedule_aio_read_and_X(connection_struct *conn,
struct smb_request *req,
@@ -6488,23 +6504,9 @@ bool schedule_aio_write_and_X(connection_struct *conn,
files_struct *fsp, char *data,
SMB_OFF_T startpos,
size_t numtowrite);
-int process_aio_queue(void);
int wait_for_aio_completion(files_struct *fsp);
void cancel_aio_by_fsp(files_struct *fsp);
-bool aio_finished(void);
-void initialize_async_io_handler(void);
-int process_aio_queue(void);
-bool schedule_aio_read_and_X(connection_struct *conn,
- struct smb_request *req,
- files_struct *fsp, SMB_OFF_T startpos,
- size_t smb_maxcnt);
-bool schedule_aio_write_and_X(connection_struct *conn,
- struct smb_request *req,
- files_struct *fsp, char *data,
- SMB_OFF_T startpos,
- size_t numtowrite);
-void cancel_aio_by_fsp(files_struct *fsp);
-int wait_for_aio_completion(files_struct *fsp);
+void smbd_aio_complete_mid(unsigned int mid);
/* The following definitions come from smbd/blocking.c */
@@ -6668,14 +6670,9 @@ uint32 dmapi_file_flags(const char * const path);
/* The following definitions come from smbd/dnsregister.c */
-void dns_register_close(struct dns_reg_state **dns_state_ptr);
-void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
- unsigned port,
- int *maxfd,
- fd_set *listen_set,
- struct timeval *timeout);
-bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
- fd_set *lfds, struct timeval *timeout);
+bool smbd_setup_mdns_registration(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ uint16_t port);
/* The following definitions come from smbd/dosmode.c */
@@ -7035,13 +7032,11 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
/* The following definitions come from smbd/oplock.c */
int32 get_number_of_exclusive_open_oplocks(void);
-bool oplock_message_waiting(void);
-void process_kernel_oplocks(struct messaging_context *msg_ctx);
+void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp);
bool set_file_oplock(files_struct *fsp, int oplock_type);
void release_file_oplock(files_struct *fsp);
bool remove_oplock(files_struct *fsp);
bool downgrade_oplock(files_struct *fsp);
-int oplock_notify_fd(void);
void reply_to_oplock_break_requests(files_struct *fsp);
void release_level_2_oplocks_on_change(files_struct *fsp);
void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e);
@@ -7116,6 +7111,8 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname);
/* The following definitions come from smbd/process.c */
+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);
int srv_set_message(char *buf,
int num_words,
@@ -7141,7 +7138,6 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
void *private_data),
void *private_data);
NTSTATUS allow_new_trans(struct trans_state *list, int mid);
-void respond_to_all_remaining_local_messages(void);
void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes);
const char *smb_fn_name(int type);
void add_to_common_flags2(uint32 v);
@@ -7149,6 +7145,7 @@ void remove_from_common_flags2(uint32 v);
void construct_reply_common_req(struct smb_request *req, char *outbuf);
size_t req_wct_ofs(struct smb_request *req);
void chain_reply(struct smb_request *req);
+bool req_is_in_chain(struct smb_request *req);
void check_reload(time_t t);
void smbd_process(void);
@@ -7222,11 +7219,6 @@ void reply_ctemp(struct smb_request *req);
NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
uint32 dirtype, const char *name_in, bool has_wild);
void reply_unlink(struct smb_request *req);
-void send_file_readbraw(connection_struct *conn,
- files_struct *fsp,
- SMB_OFF_T startpos,
- size_t nread,
- ssize_t mincount);
void reply_readbraw(struct smb_request *req);
void reply_lockread(struct smb_request *req);
void reply_read(struct smb_request *req);
@@ -7400,7 +7392,6 @@ int sys_statvfs(const char *path, vfs_statvfs_struct *statbuf);
/* The following definitions come from smbd/trans2.c */
uint64_t smb_roundup(connection_struct *conn, uint64_t val);
-uint64_t get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf);
NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
files_struct *fsp, const char *fname,
const char *ea_name, struct ea_struct *pea);
@@ -7618,7 +7609,7 @@ NTSTATUS nss_info_template_init( void );
/* Misc protos */
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct wb_context *wb_ctx, bool need_priv,
const struct winbindd_request *wb_req);
NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
diff --git a/source3/include/rpc_eventlog.h b/source3/include/rpc_eventlog.h
deleted file mode 100644
index f17e448d9e..0000000000
--- a/source3/include/rpc_eventlog.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Marcin Krzysztof Porwit 2005.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _RPC_EVENTLOG_H /* _RPC_EVENTLOG_H */
-#define _RPC_EVENTLOG_H
-
-/* opcodes */
-
-#define EVENTLOG_CLEAREVENTLOG 0x00
-#define EVENTLOG_CLOSEEVENTLOG 0x02
-#define EVENTLOG_GETNUMRECORDS 0x04
-#define EVENTLOG_GETOLDESTENTRY 0x05
-#define EVENTLOG_OPENEVENTLOG 0x07
-#define EVENTLOG_READEVENTLOG 0x0a
-
-/* Eventlog read flags */
-/* defined in librpc/gen_ndr/eventlog.h */
-
-/* Event types */
-/* defined in librpc/gen_ndr/eventlog.h */
-
-/***********************************/
-
-typedef struct
-{
- POLICY_HND handle;
- uint32 flags;
- uint32 offset;
- uint32 max_read_size;
-} EVENTLOG_Q_READ_EVENTLOG;
-
-typedef struct {
- uint32 length;
- uint32 reserved1;
- uint32 record_number;
- uint32 time_generated;
- uint32 time_written;
- uint32 event_id;
- uint16 event_type;
- uint16 num_strings;
- uint16 event_category;
- uint16 reserved2;
- uint32 closing_record_number;
- uint32 string_offset;
- uint32 user_sid_length;
- uint32 user_sid_offset;
- uint32 data_length;
- uint32 data_offset;
-} Eventlog_record;
-
-typedef struct {
- uint32 source_name_len;
- smb_ucs2_t *source_name;
- uint32 computer_name_len;
- smb_ucs2_t *computer_name;
- uint32 sid_padding;
- smb_ucs2_t *sid;
- uint32 strings_len;
- smb_ucs2_t *strings;
- uint32 user_data_len;
- char *user_data;
- uint32 data_padding;
-} Eventlog_data_record;
-
-typedef struct eventlog_entry {
- Eventlog_record record;
- Eventlog_data_record data_record;
- uint8 *data;
- uint8 *end_of_data_padding;
- struct eventlog_entry *next;
-} Eventlog_entry;
-
-typedef struct {
- uint32 num_bytes_in_resp;
- uint32 bytes_in_next_record;
- uint32 num_records;
- Eventlog_entry *entry;
- uint8 *end_of_entries_padding;
- uint32 sent_size;
- uint32 real_size;
- NTSTATUS status;
-} EVENTLOG_R_READ_EVENTLOG;
-
-#endif /* _RPC_EVENTLOG_H */
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
deleted file mode 100644
index 1dc5ba4a7b..0000000000
--- a/source3/include/rpc_lsa.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
- Copyright (C) Gerald (Jerry) Carter 2005
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _RPC_LSA_H /* _RPC_LSA_H */
-#define _RPC_LSA_H
-
-#define LSA_POLICY_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS |\
- LSA_POLICY_VIEW_LOCAL_INFORMATION |\
- LSA_POLICY_VIEW_AUDIT_INFORMATION |\
- LSA_POLICY_GET_PRIVATE_INFORMATION |\
- LSA_POLICY_TRUST_ADMIN |\
- LSA_POLICY_CREATE_ACCOUNT |\
- LSA_POLICY_CREATE_SECRET |\
- LSA_POLICY_CREATE_PRIVILEGE |\
- LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS |\
- LSA_POLICY_SET_AUDIT_REQUIREMENTS |\
- LSA_POLICY_AUDIT_LOG_ADMIN |\
- LSA_POLICY_SERVER_ADMIN |\
- LSA_POLICY_LOOKUP_NAMES )
-
-
-#define LSA_POLICY_READ ( STANDARD_RIGHTS_READ_ACCESS |\
- LSA_POLICY_VIEW_LOCAL_INFORMATION |\
- LSA_POLICY_VIEW_AUDIT_INFORMATION |\
- LSA_POLICY_GET_PRIVATE_INFORMATION)
-
-#define LSA_POLICY_WRITE ( STD_RIGHT_READ_CONTROL_ACCESS |\
- LSA_POLICY_TRUST_ADMIN |\
- LSA_POLICY_CREATE_ACCOUNT |\
- LSA_POLICY_CREATE_SECRET |\
- LSA_POLICY_CREATE_PRIVILEGE |\
- LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS |\
- LSA_POLICY_SET_AUDIT_REQUIREMENTS |\
- LSA_POLICY_AUDIT_LOG_ADMIN |\
- LSA_POLICY_SERVER_ADMIN)
-
-#define LSA_POLICY_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS |\
- LSA_POLICY_VIEW_LOCAL_INFORMATION |\
- LSA_POLICY_LOOKUP_NAMES )
-
-#endif /* _RPC_LSA_H */
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
index 3a3c61ecec..1e9d43bfa0 100644
--- a/source3/include/rpc_misc.h
+++ b/source3/include/rpc_misc.h
@@ -92,10 +92,6 @@ enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_
**********************************************************************/
typedef struct policy_handle POLICY_HND;
-typedef struct {
- uint32 ptr_hnd; /* pointer to enumeration handle */
- uint32 handle; /* enumeration handle */
-} ENUM_HND;
#define OUR_HANDLE(hnd) (((hnd)==NULL) ? "NULL" :\
( IVAL((hnd)->uuid.node,2) == (uint32)sys_getpid() ? "OURS" : \
@@ -104,53 +100,6 @@ typedef struct {
/**********************************************************************
- * Buffer Headers -- use by SEC_DESC_BUF in winreg and netlogon code
- **********************************************************************/
-
-/* TODO: replace this with an encompassing buffer structure */
-typedef struct {
- uint32 buf_max_len;
- uint32 buf_len;
-} BUFHDR;
-
-/* this is a BUFHDR + a pointer to a buffer */
-typedef struct {
- uint32 info_level;
- uint32 length; /* uint8 chars */
- uint32 buffer;
-} BUFHDR2;
-
-/* generic buffer ? wrapped around void*? */
-typedef struct {
- uint32 size;
- uint32 buffer;
-} BUFHDR4;
-
-
-/**********************************************************************
- * Buffers
- **********************************************************************/
-
-/* buffer used by \winreg\ calls to fill in arbitrary REG_XXX values.
- It *may* look like a UNISTR2 but it is *not*. This is not a goof
- by the winreg developers. It is a generic buffer. buffer length
- is stored in bytes (not # of uint16's) */
-
-typedef struct {
- uint32 buf_max_len;
- uint32 offset;
- uint32 buf_len;
- uint16 *buffer;
-} REGVAL_BUFFER;
-
-/* generic rpc version of the DATA_BLOB. Just a length and uint8 array */
-
-typedef struct {
- uint32 buf_len;
- uint8 *buffer;
-} RPC_DATA_BLOB;
-
-/**********************************************************************
* Buffers use by spoolss (i might be able to replace it with
* an RPC_DATA_BLOB)
**********************************************************************/
@@ -162,22 +111,6 @@ typedef struct {
/**********************************************************************
- * Unicode and basic string headers
- **********************************************************************/
-
-typedef struct {
- uint16 str_str_len;
- uint16 str_max_len;
- uint32 buffer; /* non-zero */
-} STRHDR;
-
-typedef struct {
- uint16 uni_str_len;
- uint16 uni_max_len;
- uint32 buffer;
-} UNIHDR;
-
-/**********************************************************************
* UNICODE string variations
**********************************************************************/
@@ -205,138 +138,4 @@ typedef struct { /* UNISTR3 - XXXX not sure about this structure */
UNISTR str;
} UNISTR3;
-typedef struct { /* Buffer wrapped around a UNISTR2 */
- uint16 length; /* number of bytes not counting NULL terminatation */
- uint16 size; /* number of bytes including NULL terminatation */
- UNISTR2 *string;
-} UNISTR4;
-
-typedef struct {
- uint32 count;
- UNISTR4 *strings;
-} UNISTR4_ARRAY;
-
-
-/**********************************************************************
- * String variations
- **********************************************************************/
-
-typedef struct { /* STRING2 - string size (in uint8 chars) and buffer */
- uint32 str_max_len;
- uint32 offset;
- uint32 str_str_len;
- uint8 *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
-} STRING2;
-
-
-
-
-/**********************************************************************
- * Domain SID structures
- **********************************************************************/
-
-typedef struct {
- uint32 num_auths; /* length, bytes, including length of len :-) */
- DOM_SID sid;
-} DOM_SID2;
-
-
-/**********************************************************************
- * Domain SID structures
- **********************************************************************/
-
-/* DOM_RID - domain RID structure for ntlsa pipe */
-typedef struct {
- uint16 type; /* value is SID_NAME_USE enum */
- uint32 rid;
- uint32 rid_idx; /* referenced domain index */
-} DOM_RID;
-
-/* DOM_RID2 - second domain RID structure for ntlsa pipe */
-typedef struct {
- uint16 type; /* value is SID_NAME_USE enum */
- uint32 rid;
- uint32 rid_idx; /* referenced domain index */
- uint32 unknown;
-} DOM_RID2;
-
-typedef struct { /* DOM_RID3 - domain RID structure for samr pipe */
- uint32 rid; /* domain-relative (to a SID) id */
- uint32 type1; /* value is 0x1 */
- uint32 ptr_type; /* undocumented pointer */
- uint32 type2; /* value is 0x1 */
- uint32 unk; /* value is 0x2 */
-} DOM_RID3;
-
-/* DOM_RID4 - rid + user attributes */
-typedef struct domrid4_info
-{
- uint32 unknown;
- uint16 attr;
- uint32 rid; /* user RID */
-} DOM_RID4;
-
-/* DOM_GID - group id + user attributes */
-typedef struct {
- uint32 g_rid; /* a group RID */
- uint32 attr;
-} DOM_GID;
-
-/**********************************************************************
- * ????
- **********************************************************************/
-
-/* DOM_CLNT_SRV - client / server names */
-typedef struct clnt_srv_info {
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_comp_name; /* client machine name */
-} DOM_CLNT_SRV;
-
-/* DOM_LOG_INFO - login info */
-typedef struct log_info {
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- UNISTR2 uni_acct_name; /* account name */
- uint16 sec_chan; /* secure channel type */
- UNISTR2 uni_comp_name; /* client machine name */
-} DOM_LOG_INFO;
-
-/* DOM_CHAL - challenge info */
-typedef struct chal_info {
- unsigned char data[8]; /* credentials */
-} DOM_CHAL;
-
-/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info {
- DOM_CHAL challenge; /* credentials */
- UTIME timestamp; /* credential time-stamp */
-} DOM_CRED;
-
-/* DOM_CLNT_INFO - client info */
-typedef struct clnt_info {
- DOM_LOG_INFO login;
- DOM_CRED cred;
-} DOM_CLNT_INFO;
-
-/* DOM_CLNT_INFO2 - client info */
-typedef struct clnt_info2 {
- DOM_CLNT_SRV login;
- uint32 ptr_cred;
- DOM_CRED cred;
-} DOM_CLNT_INFO2;
-
-/* DOM_LOGON_ID - logon id */
-typedef struct logon_info {
- uint32 low;
- uint32 high;
-} DOM_LOGON_ID;
-
-/* OWF INFO */
-typedef struct owf_info {
- uint8 data[16];
-} OWF_INFO;
-
-
#endif /* _RPC_MISC_H */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index aa2db693a3..b441b3476a 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -367,6 +367,7 @@ struct uuid;
struct named_mutex;
struct pcap_cache;
struct wb_context;
+struct rpc_cli_smbd_conn;
struct vfs_fsp_data {
struct vfs_fsp_data *next;
@@ -623,7 +624,18 @@ struct smb_request {
uint16_t buflen;
const uint8_t *buf;
const uint8 *inbuf;
+
+ /*
+ * Async handling in the main smb processing loop is directed by
+ * outbuf: reply_xxx routines indicate sync behaviour by putting their
+ * reply into "outbuf". If they leave it as NULL, they take of it
+ * themselves, possibly later.
+ *
+ * If async handling is wanted, the reply_xxx routine must make sure
+ * that it talloc_move()s the smb_req somewhere else.
+ */
uint8 *outbuf;
+
size_t unread_bytes;
bool encrypted;
connection_struct *conn;
@@ -637,6 +649,11 @@ struct smb_request {
* Here we collect the outbufs from the chain handlers
*/
uint8_t *chain_outbuf;
+
+ /*
+ * state information for async smb handling
+ */
+ void *async_priv;
};
/* Defines for the sent_oplock_break field above. */
@@ -1242,7 +1259,7 @@ struct bitmap {
/* Mapping of access rights to UNIX perms. for a UNIX directory. */
#define UNIX_DIRECTORY_ACCESS_RWX FILE_GENERIC_ALL
#define UNIX_DIRECTORY_ACCESS_R FILE_GENERIC_READ
-#define UNIX_DIRECTORY_ACCESS_W FILE_GENERIC_WRITE
+#define UNIX_DIRECTORY_ACCESS_W (FILE_GENERIC_WRITE|FILE_DELETE_CHILD)
#define UNIX_DIRECTORY_ACCESS_X FILE_GENERIC_EXECUTE
#if 0
@@ -1549,11 +1566,6 @@ enum acl_compatibility {ACL_COMPAT_AUTO, ACL_COMPAT_WINNT, ACL_COMPAT_WIN2K};
#define COPYBUF_SIZE (8*1024)
/*
- * Used in chaining code.
- */
-extern int chain_size;
-
-/*
* Map the Core and Extended Oplock requesst bits down
* to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
*/
@@ -1680,12 +1692,10 @@ struct kernel_oplocks {
/* if a kernel does support oplocks then a structure of the following
typee is used to describe how to interact with the kernel */
struct kernel_oplocks_ops {
- files_struct * (*receive_message)(struct kernel_oplocks *ctx);
bool (*set_oplock)(struct kernel_oplocks *ctx,
files_struct *fsp, int oplock_type);
void (*release_oplock)(struct kernel_oplocks *ctx,
files_struct *fsp);
- bool (*msg_waiting)(struct kernel_oplocks *ctx);
};
#include "smb_macros.h"
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 92c60a7530..fd1bba16a7 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -135,7 +135,7 @@
/* Note that chain_size must be available as an extern int to this macro. */
-#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
+#define smb_offset(p,buf) (PTR_DIFF(p,buf+4))
#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|((PVAL(buf,1)&1)<<16))
#define _smb_setlen(buf,len) do { buf[0] = 0; buf[1] = ((len)&0x10000)>>16; \
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index 8945708ca3..131416b685 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -127,6 +127,10 @@ enum profile_stats_values
#define syscall_lstat_count __profile_stats_value(PR_VALUE_SYSCALL_LSTAT, count)
#define syscall_lstat_time __profile_stats_value(PR_VALUE_SYSCALL_LSTAT, time)
+ PR_VALUE_SYSCALL_GET_ALLOC_SIZE,
+#define syscall_get_alloc_size_count __profile_stats_value(PR_VALUE_SYSCALL_GET_ALLOC_SIZE, count)
+#define syscall_get_alloc_size_time __profile_stats_value(PR_VALUE_SYSCALL_GET_ALLOC_SIZE, time)
+
PR_VALUE_SYSCALL_UNLINK,
#define syscall_unlink_count __profile_stats_value(PR_VALUE_SYSCALL_UNLINK, count)
#define syscall_unlink_time __profile_stats_value(PR_VALUE_SYSCALL_UNLINK, time)
diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h
index 127176b887..c79436434f 100644
--- a/source3/include/util_tdb.h
+++ b/source3/include/util_tdb.h
@@ -24,6 +24,7 @@
#include "talloc.h" /* for tdb_wrap_open() */
#include "../libcli/util/ntstatus.h" /* for map_nt_error_from_tdb() */
+#include "../../lib/util/util_tdb.h"
struct tdb_wrap {
struct tdb_context *tdb;
@@ -31,47 +32,15 @@ struct tdb_wrap {
struct tdb_wrap *next, *prev;
};
-struct tdb_validation_status {
- bool tdb_error;
- bool bad_freelist;
- bool bad_entry;
- bool unknown_key;
- bool success;
-};
-
-typedef int (*tdb_validate_data_func)(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state);
-
-TDB_DATA make_tdb_data(const uint8_t *dptr, size_t dsize);
-TDB_DATA string_tdb_data(const char *string);
-TDB_DATA string_term_tdb_data(const char *string);
-
int tdb_chainlock_with_timeout( struct tdb_context *tdb, TDB_DATA key,
unsigned int timeout);
-int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval);
int tdb_lock_bystring_with_timeout(struct tdb_context *tdb, const char *keyval,
int timeout);
-void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval);
int tdb_read_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval,
unsigned int timeout);
-void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval);
-
-int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, TDB_DATA key);
-int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr);
-bool tdb_store_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t value);
-bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value);
-int tdb_store_int32_byblob(struct tdb_context *tdb, TDB_DATA key, int32_t v);
-int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v);
-bool tdb_fetch_uint32_byblob(struct tdb_context *tdb, TDB_DATA key, uint32_t *value);
-bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value);
-int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val);
-bool tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr,
- uint32_t *oldval, uint32_t change_val);
-int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags);
int tdb_trans_store_bystring(TDB_CONTEXT *tdb, const char *keystr,
TDB_DATA data, int flags);
-TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr);
-int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr);
int tdb_trans_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
int flag);
int tdb_trans_delete(struct tdb_context *tdb, TDB_DATA key);
@@ -90,9 +59,4 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
-int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn);
-int tdb_validate_open(const char *tdb_path, tdb_validate_data_func validate_fn);
-int tdb_validate_and_backup(const char *tdb_path,
- tdb_validate_data_func validate_fn);
-
#endif /* __TDBUTIL_H__ */
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 5df71da905..e9115ab807 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -112,6 +112,7 @@
/* Changed to version 25 - Jelmer's change from SMB_BIG_UINT to uint64_t. */
/* Leave at 25 - not yet released. Add create_file call. -- tprouty. */
/* Leave at 25 - not yet released. Add create time to ntimes. -- tstecher. */
+/* Leave at 25 - not yet released. Add get_alloc_size call. -- tprouty. */
#define SMB_VFS_INTERFACE_VERSION 25
@@ -189,6 +190,7 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_STAT,
SMB_VFS_OP_FSTAT,
SMB_VFS_OP_LSTAT,
+ SMB_VFS_OP_GET_ALLOC_SIZE,
SMB_VFS_OP_UNLINK,
SMB_VFS_OP_CHMOD,
SMB_VFS_OP_FCHMOD,
@@ -342,6 +344,7 @@ struct vfs_ops {
int (*stat)(struct vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf);
int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_STAT *sbuf);
int (*lstat)(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf);
+ uint64_t (*get_alloc_size)(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_STAT *sbuf);
int (*unlink)(struct vfs_handle_struct *handle, const char *path);
int (*chmod)(struct vfs_handle_struct *handle, const char *path, mode_t mode);
int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode);
@@ -496,6 +499,7 @@ struct vfs_ops {
struct vfs_handle_struct *stat;
struct vfs_handle_struct *fstat;
struct vfs_handle_struct *lstat;
+ struct vfs_handle_struct *get_alloc_size;
struct vfs_handle_struct *unlink;
struct vfs_handle_struct *chmod;
struct vfs_handle_struct *fchmod;
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index c6ccd4912a..e7a9cfdc76 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -62,6 +62,7 @@
#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (fname), (sbuf)))
#define SMB_VFS_FSTAT(fsp, sbuf) ((fsp)->conn->vfs.ops.fstat((fsp)->conn->vfs.handles.fstat, (fsp), (sbuf)))
#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_GET_ALLOC_SIZE(conn, fsp, sbuf) ((conn)->vfs.ops.get_alloc_size((conn)->vfs.handles.get_alloc_size, (fsp), (sbuf)))
#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (path)))
#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (path), (mode)))
#define SMB_VFS_FCHMOD(fsp, mode) ((fsp)->conn->vfs.ops.fchmod((fsp)->conn->vfs.handles.fchmod, (fsp), (mode)))
@@ -189,6 +190,7 @@
#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (fname), (sbuf)))
#define SMB_VFS_OPAQUE_FSTAT(fsp, sbuf) ((fsp)->conn->vfs_opaque.ops.fstat((fsp)->conn->vfs_opaque.handles.fstat, (fsp), (sbuf)))
#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_OPAQUE_GET_ALLOC_SIZE(conn, fsp, sbuf) ((conn)->vfs_opaque.ops.get_alloc_size((conn)->vfs_opaque.handles.get_alloc_size, (fsp), (sbuf)))
#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (path)))
#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (path), (mode)))
#define SMB_VFS_OPAQUE_FCHMOD(fsp, mode) ((fsp)->conn->vfs_opaque.ops.fchmod((fsp)->conn->vfs_opaque.handles.fchmod, (fsp), (mode)))
@@ -317,6 +319,7 @@
#define SMB_VFS_NEXT_STAT(handle, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (fname), (sbuf)))
#define SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf) ((handle)->vfs_next.ops.fstat((handle)->vfs_next.handles.fstat, (fsp), (sbuf)))
#define SMB_VFS_NEXT_LSTAT(handle, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_NEXT_GET_ALLOC_SIZE(conn, fsp, sbuf) ((conn)->vfs_next.ops.get_alloc_size((conn)->vfs_next.handles.get_alloc_size, (fsp), (sbuf)))
#define SMB_VFS_NEXT_UNLINK(handle, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (path)))
#define SMB_VFS_NEXT_CHMOD(handle, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (path), (mode)))
#define SMB_VFS_NEXT_FCHMOD(handle, fsp, mode) ((handle)->vfs_next.ops.fchmod((handle)->vfs_next.handles.fchmod, (fsp), (mode)))
diff --git a/source3/lib/async_sock.c b/source3/lib/async_sock.c
deleted file mode 100644
index 73ff6f2870..0000000000
--- a/source3/lib/async_sock.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- async socket syscalls
- Copyright (C) Volker Lendecke 2008
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/**
- * Discriminator for async_syscall_state
- */
-enum async_syscall_type {
- ASYNC_SYSCALL_SEND,
- ASYNC_SYSCALL_SENDALL,
- ASYNC_SYSCALL_RECV,
- ASYNC_SYSCALL_RECVALL,
- ASYNC_SYSCALL_CONNECT
-};
-
-/**
- * Holder for syscall arguments and the result
- */
-
-struct async_syscall_state {
- enum async_syscall_type syscall_type;
- struct fd_event *fde;
-
- union {
- struct param_send {
- int fd;
- const void *buffer;
- size_t length;
- int flags;
- } param_send;
- struct param_sendall {
- int fd;
- const void *buffer;
- size_t length;
- int flags;
- size_t sent;
- } param_sendall;
- struct param_recv {
- int fd;
- void *buffer;
- size_t length;
- int flags;
- } param_recv;
- struct param_recvall {
- int fd;
- void *buffer;
- size_t length;
- int flags;
- size_t received;
- } param_recvall;
- struct param_connect {
- /**
- * connect needs to be done on a nonblocking
- * socket. Keep the old flags around
- */
- long old_sockflags;
- int fd;
- const struct sockaddr *address;
- socklen_t address_len;
- } param_connect;
- } param;
-
- union {
- ssize_t result_ssize_t;
- size_t result_size_t;
- int result_int;
- } result;
- int sys_errno;
-};
-
-/**
- * @brief Create a new async syscall req
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] type Which syscall will this be
- * @param[in] pstate Where to put the newly created private_data state
- * @retval The new request
- *
- * This is a helper function to prepare a new struct async_req with an
- * associated struct async_syscall_state. The async_syscall_state will be put
- * into the async_req as private_data.
- */
-
-static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- enum async_syscall_type type,
- struct async_syscall_state **pstate)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- if (!async_req_setup(mem_ctx, &result, &state,
- struct async_syscall_state)) {
- return NULL;
- }
- state->syscall_type = type;
-
- result->private_data = state;
-
- *pstate = state;
-
- return result;
-}
-
-/**
- * @brief Create a new async syscall req based on a fd
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] type Which syscall will this be
- * @param[in] fd The file descriptor we work on
- * @param[in] fde_flags EVENT_FD_READ/WRITE -- what are we interested in?
- * @param[in] fde_cb The callback function for the file descriptor event
- * @param[in] pstate Where to put the newly created private_data state
- * @retval The new request
- *
- * This is a helper function to prepare a new struct async_req with an
- * associated struct async_syscall_state and an associated file descriptor
- * event.
- */
-
-static struct async_req *async_fde_syscall_new(
- TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- enum async_syscall_type type,
- int fd,
- uint16_t fde_flags,
- void (*fde_cb)(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv),
- struct async_syscall_state **pstate)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_syscall_new(mem_ctx, ev, type, &state);
- if (result == NULL) {
- return NULL;
- }
-
- state->fde = event_add_fd(ev, state, fd, fde_flags, fde_cb, result);
- if (state->fde == NULL) {
- TALLOC_FREE(result);
- return NULL;
- }
- *pstate = state;
- return result;
-}
-
-/**
- * Retrieve a ssize_t typed result from an async syscall
- * @param[in] req The syscall that has just finished
- * @param[out] perrno Where to put the syscall's errno
- * @retval The return value from the asynchronously called syscall
- */
-
-ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno)
-{
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
-
- *perrno = state->sys_errno;
- return state->result.result_ssize_t;
-}
-
-/**
- * Retrieve a size_t typed result from an async syscall
- * @param[in] req The syscall that has just finished
- * @param[out] perrno Where to put the syscall's errno
- * @retval The return value from the asynchronously called syscall
- */
-
-size_t async_syscall_result_size_t(struct async_req *req, int *perrno)
-{
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
-
- *perrno = state->sys_errno;
- return state->result.result_size_t;
-}
-
-/**
- * Retrieve a int typed result from an async syscall
- * @param[in] req The syscall that has just finished
- * @param[out] perrno Where to put the syscall's errno
- * @retval The return value from the asynchronously called syscall
- */
-
-int async_syscall_result_int(struct async_req *req, int *perrno)
-{
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
-
- *perrno = state->sys_errno;
- return state->result.result_int;
-}
-
-/**
- * fde event handler for the "send" syscall
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the send
- * @param[in] flags Can only be EVENT_FD_WRITE here
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_send_callback(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_send *p = &state->param.param_send;
-
- if (state->syscall_type != ASYNC_SYSCALL_SEND) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- state->result.result_ssize_t = send(p->fd, p->buffer, p->length,
- p->flags);
- state->sys_errno = errno;
-
- TALLOC_FREE(state->fde);
-
- async_req_done(req);
-}
-
-/**
- * Async version of send(2)
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to send to
- * @param[in] buffer The buffer to send
- * @param[in] length How many bytes to send
- * @param[in] flags flags passed to send(2)
- *
- * This function is a direct counterpart of send(2)
- */
-
-struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const void *buffer, size_t length,
- int flags)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_SEND,
- fd, EVENT_FD_WRITE, async_send_callback,
- &state);
- if (result == NULL) {
- return NULL;
- }
-
- state->param.param_send.fd = fd;
- state->param.param_send.buffer = buffer;
- state->param.param_send.length = length;
- state->param.param_send.flags = flags;
-
- return result;
-}
-
-/**
- * fde event handler for the "sendall" syscall group
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the send
- * @param[in] flags Can only be EVENT_FD_WRITE here
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_sendall_callback(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_sendall *p = &state->param.param_sendall;
-
- if (state->syscall_type != ASYNC_SYSCALL_SENDALL) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- state->result.result_ssize_t = send(p->fd, (char *)p->buffer + p->sent,
- p->length - p->sent, p->flags);
- state->sys_errno = errno;
-
- if (state->result.result_ssize_t == -1) {
- async_req_error(req, map_nt_error_from_unix(state->sys_errno));
- return;
- }
-
- if (state->result.result_ssize_t == 0) {
- async_req_error(req, NT_STATUS_END_OF_FILE);
- return;
- }
-
- p->sent += state->result.result_ssize_t;
- if (p->sent > p->length) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- if (p->sent == p->length) {
- TALLOC_FREE(state->fde);
- async_req_done(req);
- }
-}
-
-/**
- * @brief Send all bytes to a socket
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to send to
- * @param[in] buffer The buffer to send
- * @param[in] length How many bytes to send
- * @param[in] flags flags passed to send(2)
- *
- * async_sendall calls send(2) as long as it is necessary to send all of the
- * "length" bytes
- */
-
-struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, const void *buffer, size_t length,
- int flags)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_SENDALL,
- fd, EVENT_FD_WRITE, async_sendall_callback,
- &state);
- if (result == NULL) {
- return NULL;
- }
-
- state->param.param_sendall.fd = fd;
- state->param.param_sendall.buffer = buffer;
- state->param.param_sendall.length = length;
- state->param.param_sendall.flags = flags;
- state->param.param_sendall.sent = 0;
-
- return result;
-}
-
-NTSTATUS sendall_recv(struct async_req *req)
-{
- return async_req_simple_recv(req);
-}
-
-/**
- * fde event handler for the "recv" syscall
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the recv
- * @param[in] flags Can only be EVENT_FD_READ here
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_recv_callback(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_recv *p = &state->param.param_recv;
-
- if (state->syscall_type != ASYNC_SYSCALL_RECV) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- state->result.result_ssize_t = recv(p->fd, p->buffer, p->length,
- p->flags);
- state->sys_errno = errno;
-
- TALLOC_FREE(state->fde);
-
- async_req_done(req);
-}
-
-/**
- * Async version of recv(2)
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to recv from
- * @param[in] buffer The buffer to recv into
- * @param[in] length How many bytes to recv
- * @param[in] flags flags passed to recv(2)
- *
- * This function is a direct counterpart of recv(2)
- */
-
-struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, void *buffer, size_t length,
- int flags)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_RECV,
- fd, EVENT_FD_READ, async_recv_callback,
- &state);
-
- if (result == NULL) {
- return NULL;
- }
-
- state->param.param_recv.fd = fd;
- state->param.param_recv.buffer = buffer;
- state->param.param_recv.length = length;
- state->param.param_recv.flags = flags;
-
- return result;
-}
-
-/**
- * fde event handler for the "recvall" syscall group
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the recv
- * @param[in] flags Can only be EVENT_FD_READ here
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_recvall_callback(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_syscall_state *state = talloc_get_type_abort(
- req->private_data, struct async_syscall_state);
- struct param_recvall *p = &state->param.param_recvall;
-
- if (state->syscall_type != ASYNC_SYSCALL_RECVALL) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- state->result.result_ssize_t = recv(p->fd,
- (char *)p->buffer + p->received,
- p->length - p->received, p->flags);
- state->sys_errno = errno;
-
- if (state->result.result_ssize_t == -1) {
- async_req_error(req, map_nt_error_from_unix(state->sys_errno));
- return;
- }
-
- if (state->result.result_ssize_t == 0) {
- async_req_error(req, NT_STATUS_END_OF_FILE);
- return;
- }
-
- p->received += state->result.result_ssize_t;
- if (p->received > p->length) {
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
- return;
- }
-
- if (p->received == p->length) {
- TALLOC_FREE(state->fde);
- async_req_done(req);
- }
-}
-
-/**
- * Receive a specified number of bytes from a socket
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to recv from
- * @param[in] buffer The buffer to recv into
- * @param[in] length How many bytes to recv
- * @param[in] flags flags passed to recv(2)
- *
- * async_recvall will call recv(2) until "length" bytes are received
- */
-
-struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
- int fd, void *buffer, size_t length,
- int flags)
-{
- struct async_req *result;
- struct async_syscall_state *state;
-
- result = async_fde_syscall_new(
- mem_ctx, ev, ASYNC_SYSCALL_RECVALL,
- fd, EVENT_FD_READ, async_recvall_callback,
- &state);
- if (result == NULL) {
- return NULL;
- }
-
- state->param.param_recvall.fd = fd;
- state->param.param_recvall.buffer = buffer;
- state->param.param_recvall.length = length;
- state->param.param_recvall.flags = flags;
- state->param.param_recvall.received = 0;
-
- return result;
-}
-
-NTSTATUS recvall_recv(struct async_req *req)
-{
- return async_req_simple_recv(req);
-}
-
-struct async_connect_state {
- int fd;
- int result;
- int sys_errno;
- long old_sockflags;
-};
-
-static void async_connect_connected(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv);
-
-/**
- * @brief async version of connect(2)
- * @param[in] mem_ctx The memory context to hang the result off
- * @param[in] ev The event context to work from
- * @param[in] fd The socket to recv from
- * @param[in] address Where to connect?
- * @param[in] address_len Length of *address
- * @retval The async request
- *
- * This function sets the socket into non-blocking state to be able to call
- * connect in an async state. This will be reset when the request is finished.
- */
-
-struct async_req *async_connect_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, const struct sockaddr *address,
- socklen_t address_len)
-{
- struct async_req *result;
- struct async_connect_state *state;
- struct fd_event *fde;
- NTSTATUS status;
-
- if (!async_req_setup(mem_ctx, &result, &state,
- struct async_connect_state)) {
- return NULL;
- }
-
- /**
- * We have to set the socket to nonblocking for async connect(2). Keep
- * the old sockflags around.
- */
-
- state->fd = fd;
- state->sys_errno = 0;
-
- state->old_sockflags = sys_fcntl_long(fd, F_GETFL, 0);
- if (state->old_sockflags == -1) {
- goto post_errno;
- }
-
- set_blocking(fd, false);
-
- state->result = connect(fd, address, address_len);
- if (state->result == 0) {
- state->sys_errno = 0;
- status = NT_STATUS_OK;
- goto post_status;
- }
-
- /**
- * A number of error messages show that something good is progressing
- * and that we have to wait for readability.
- *
- * If none of them are present, bail out.
- */
-
- if (!(errno == EINPROGRESS || errno == EALREADY ||
-#ifdef EISCONN
- errno == EISCONN ||
-#endif
- errno == EAGAIN || errno == EINTR)) {
- goto post_errno;
- }
-
- fde = event_add_fd(ev, state, fd, EVENT_FD_READ | EVENT_FD_WRITE,
- async_connect_connected, result);
- if (fde == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
- }
- return result;
-
- post_errno:
- state->sys_errno = errno;
- status = map_nt_error_from_unix(state->sys_errno);
- post_status:
- sys_fcntl_long(fd, F_SETFL, state->old_sockflags);
- if (!async_post_status(result, ev, status)) {
- goto fail;
- }
- return result;
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-/**
- * fde event handler for connect(2)
- * @param[in] ev The event context that sent us here
- * @param[in] fde The file descriptor event associated with the connect
- * @param[in] flags Indicate read/writeability of the socket
- * @param[in] priv private data, "struct async_req *" in this case
- */
-
-static void async_connect_connected(struct event_context *ev,
- struct fd_event *fde, uint16_t flags,
- void *priv)
-{
- struct async_req *req = talloc_get_type_abort(
- priv, struct async_req);
- struct async_connect_state *state = talloc_get_type_abort(
- req->private_data, struct async_connect_state);
-
- TALLOC_FREE(fde);
-
- /*
- * Stevens, Network Programming says that if there's a
- * successful connect, the socket is only writable. Upon an
- * error, it's both readable and writable.
- */
- if ((flags & (EVENT_FD_READ|EVENT_FD_WRITE))
- == (EVENT_FD_READ|EVENT_FD_WRITE)) {
- int sockerr;
- socklen_t err_len = sizeof(sockerr);
-
- if (getsockopt(state->fd, SOL_SOCKET, SO_ERROR,
- (void *)&sockerr, &err_len) == 0) {
- errno = sockerr;
- }
-
- state->sys_errno = errno;
-
- DEBUG(10, ("connect returned %s\n", strerror(errno)));
-
- sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
- async_req_error(req, map_nt_error_from_unix(state->sys_errno));
- return;
- }
-
- state->sys_errno = 0;
- async_req_done(req);
-}
-
-NTSTATUS async_connect_recv(struct async_req *req, int *perrno)
-{
- struct async_connect_state *state = talloc_get_type_abort(
- req->private_data, struct async_connect_state);
- NTSTATUS status;
-
- sys_fcntl_long(state->fd, F_SETFL, state->old_sockflags);
-
- *perrno = state->sys_errno;
-
- if (async_req_is_error(req, &status)) {
- return status;
- }
- if (state->sys_errno == 0) {
- return NT_STATUS_OK;
- }
- return map_nt_error_from_unix(state->sys_errno);
-}
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index f8dae8fbd6..88d82caab8 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -1177,45 +1177,75 @@ NTSTATUS ctdbd_traverse(uint32 db_id,
}
/*
+ This is used to canonicalize a ctdb_sock_addr structure.
+*/
+static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
+ struct sockaddr_storage *out)
+{
+ memcpy(out, in, sizeof (*out));
+
+#ifdef HAVE_IPV6
+ if (in->ss_family == AF_INET6) {
+ const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
+ const struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
+ struct sockaddr_in *out4 = (struct sockaddr_in *)out;
+ if (memcmp(&in6->sin6_addr, prefix, 12) == 0) {
+ memset(out, 0, sizeof(*out));
+#ifdef HAVE_SOCK_SIN_LEN
+ out4->sin_len = sizeof(*out);
+#endif
+ out4->sin_family = AF_INET;
+ out4->sin_port = in6->sin6_port;
+ memcpy(&out4->sin_addr, &in6->sin6_addr.s6_addr32[3], 4);
+ }
+ }
+#endif
+}
+
+/*
* Register us as a server for a particular tcp connection
*/
NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
- const struct sockaddr_storage *server,
- const struct sockaddr_storage *client,
+ const struct sockaddr_storage *_server,
+ const struct sockaddr_storage *_client,
void (*release_ip_handler)(const char *ip_addr,
void *private_data),
void *private_data)
{
- struct sockaddr *sock = (struct sockaddr *)client;
/*
* we still use ctdb_control_tcp for ipv4
* because we want to work against older ctdb
* versions at runtime
*/
struct ctdb_control_tcp p4;
-#ifdef HAVE_IPV6
+#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR
struct ctdb_control_tcp_addr p;
#endif
TDB_DATA data;
NTSTATUS status;
+ struct sockaddr_storage client;
+ struct sockaddr_storage server;
/*
* Only one connection so far
*/
SMB_ASSERT(conn->release_ip_handler == NULL);
- switch (sock->sa_family) {
+ smbd_ctdb_canonicalize_ip(_client, &client);
+ smbd_ctdb_canonicalize_ip(_server, &server);
+
+ switch (client.ss_family) {
case AF_INET:
- p4.dest = *(struct sockaddr_in *)server;
- p4.src = *(struct sockaddr_in *)client;
+ p4.dest = *(struct sockaddr_in *)&server;
+ p4.src = *(struct sockaddr_in *)&client;
data.dptr = (uint8_t *)&p4;
data.dsize = sizeof(p4);
break;
-#ifdef HAVE_IPV6
+#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR
case AF_INET6:
- p.dest.ip6 = *(struct sockaddr_in6 *)server;
- p.src.ip6 = *(struct sockaddr_in6 *)client;
+ p.dest.ip6 = *(struct sockaddr_in6 *)&server;
+ p.src.ip6 = *(struct sockaddr_in6 *)&client;
data.dptr = (uint8_t *)&p;
data.dsize = sizeof(p);
break;
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 4484d5323b..44b4562757 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -83,45 +83,24 @@ bool event_add_to_select_args(struct tevent_context *ev,
bool run_events(struct tevent_context *ev,
int selrtn, fd_set *read_fds, fd_set *write_fds)
{
- bool fired = false;
- struct tevent_fd *fde, *next;
+ struct tevent_fd *fde;
+ struct timeval now;
if (ev->signal_events &&
tevent_common_check_signal(ev)) {
return true;
}
- /* Run all events that are pending, not just one (as we
- did previously. */
-
- while (ev->timer_events) {
- struct timeval now;
- GetTimeOfDay(&now);
-
- if (timeval_compare(
- &now, &ev->timer_events->next_event) < 0) {
- /* Nothing to do yet */
- DEBUG(11, ("run_events: Nothing to do\n"));
- break;
- }
-
- DEBUG(10, ("Running event \"%s\" %p\n",
- ev->timer_events->handler_name,
- ev->timer_events));
+ GetTimeOfDay(&now);
- ev->timer_events->handler(
- ev,
- ev->timer_events, now,
- ev->timer_events->private_data);
+ if ((ev->timer_events != NULL)
+ && (timeval_compare(&now, &ev->timer_events->next_event) >= 0)) {
- fired = true;
- }
+ DEBUG(10, ("Running timed event \"%s\" %p\n",
+ ev->timer_events->handler_name, ev->timer_events));
- if (fired) {
- /*
- * We might have changed the socket status during the timed
- * events, return to run select again.
- */
+ ev->timer_events->handler(ev, ev->timer_events, now,
+ ev->timer_events->private_data);
return true;
}
@@ -129,23 +108,22 @@ bool run_events(struct tevent_context *ev,
/*
* No fd ready
*/
- return fired;
+ return false;
}
- for (fde = ev->fd_events; fde; fde = next) {
+ for (fde = ev->fd_events; fde; fde = fde->next) {
uint16 flags = 0;
- next = fde->next;
if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
if (flags & fde->flags) {
fde->handler(ev, fde, flags, fde->private_data);
- fired = true;
+ return true;
}
}
- return fired;
+ return false;
}
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 48fa4d32a9..b32ccb9c56 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -151,7 +151,8 @@ int iface_count_v4_nl(void)
}
/****************************************************************************
- Return a pointer to the in_addr of the first IPv4 interface.
+ Return a pointer to the in_addr of the first IPv4 interface that's
+ not 0.0.0.0.
**************************************************************************/
const struct in_addr *first_ipv4_iface(void)
@@ -159,7 +160,9 @@ const struct in_addr *first_ipv4_iface(void)
struct interface *i;
for (i=local_interfaces;i ;i=i->next) {
- if (i->ip.ss_family == AF_INET) {
+ if ((i->ip.ss_family == AF_INET) &&
+ (!is_zero_ip_v4(((struct sockaddr_in *)&i->ip)->sin_addr)))
+ {
break;
}
}
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index d5ef09d831..233255fed4 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -184,7 +184,7 @@ WERROR libnetapi_open_pipe(struct libnetapi_ctx *ctx,
status = pipe_cm_open(ctx, cli, interface, &result);
if (!NT_STATUS_IS_OK(status)) {
libnetapi_set_error_string(ctx, "failed to open PIPE %s: %s",
- cli_get_pipe_name_from_iface(debug_ctx(), interface),
+ get_pipe_name_from_iface(interface),
get_friendly_nt_error_msg(status));
return WERR_DEST_NOT_FOUND;
}
diff --git a/source3/lib/smbconf/testsuite.c b/source3/lib/smbconf/testsuite.c
index 3d3c2d0ff0..b31dec0438 100644
--- a/source3/lib/smbconf/testsuite.c
+++ b/source3/lib/smbconf/testsuite.c
@@ -41,11 +41,11 @@ static bool test_get_includes(struct smbconf_ctx *ctx)
char **includes = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- printf("test: get_includes\n");
+ printf("TEST: get_includes\n");
werr = smbconf_get_global_includes(ctx, mem_ctx,
&num_includes, &includes);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: get_includes - %s\n", win_errstr(werr));
+ printf("FAIL: get_includes - %s\n", win_errstr(werr));
goto done;
}
@@ -53,7 +53,7 @@ static bool test_get_includes(struct smbconf_ctx *ctx)
(num_includes > 0) ? ":" : ".");
print_strings("", num_includes, (const char **)includes);
- printf("success: get_includes\n");
+ printf("OK: get_includes\n");
ret = true;
done:
@@ -75,11 +75,11 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx)
uint32_t get_num_includes = 0;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- printf("test: set_get_includes\n");
+ printf("TEST: set_get_includes\n");
werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: get_set_includes (setting includes) - %s\n",
+ printf("FAIL: get_set_includes (setting includes) - %s\n",
win_errstr(werr));
goto done;
}
@@ -87,13 +87,13 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx)
werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
&get_includes);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: get_set_includes (getting includes) - %s\n",
+ printf("FAIL: get_set_includes (getting includes) - %s\n",
win_errstr(werr));
goto done;
}
if (get_num_includes != set_num_includes) {
- printf("failure: get_set_includes - set %d includes, got %d\n",
+ printf("FAIL: get_set_includes - set %d includes, got %d\n",
set_num_includes, get_num_includes);
goto done;
}
@@ -105,12 +105,12 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx)
printf("got: \n");
print_strings("* ", get_num_includes,
(const char **)get_includes);
- printf("failure: get_set_includes - data mismatch:\n");
+ printf("FAIL: get_set_includes - data mismatch:\n");
goto done;
}
}
- printf("success: set_includes\n");
+ printf("OK: set_includes\n");
ret = true;
done:
@@ -130,18 +130,18 @@ static bool test_delete_includes(struct smbconf_ctx *ctx)
uint32_t get_num_includes = 0;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- printf("test: delete_includes\n");
+ printf("TEST: delete_includes\n");
werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: delete_includes (setting includes) - %s\n",
+ printf("FAIL: delete_includes (setting includes) - %s\n",
win_errstr(werr));
goto done;
}
werr = smbconf_delete_global_includes(ctx);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: delete_includes (deleting includes) - %s\n",
+ printf("FAIL: delete_includes (deleting includes) - %s\n",
win_errstr(werr));
goto done;
}
@@ -149,24 +149,24 @@ static bool test_delete_includes(struct smbconf_ctx *ctx)
werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
&get_includes);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: delete_includes (getting includes) - %s\n",
+ printf("FAIL: delete_includes (getting includes) - %s\n",
win_errstr(werr));
goto done;
}
if (get_num_includes != 0) {
- printf("failure: delete_includes (not empty after delete)\n");
+ printf("FAIL: delete_includes (not empty after delete)\n");
goto done;
}
werr = smbconf_delete_global_includes(ctx);
if (!W_ERROR_IS_OK(werr)) {
- printf("failuer: delete_includes (delete empty includes) - "
+ printf("FAIL: delete_includes (delete empty includes) - "
"%s\n", win_errstr(werr));
goto done;
}
- printf("success: delete_includes\n");
+ printf("OK: delete_includes\n");
ret = true;
done:
@@ -177,7 +177,7 @@ static bool create_conf_file(const char *filename)
{
FILE *f;
- printf("creating file\n");
+ printf("TEST: creating file\n");
f = sys_fopen(filename, "w");
if (!f) {
printf("failure: failed to open %s for writing: %s\n",
@@ -192,7 +192,7 @@ static bool create_conf_file(const char *filename)
fclose(f);
- printf("success: create file\n");
+ printf("OK: create file\n");
return true;
}
@@ -211,30 +211,29 @@ static bool torture_smbconf_txt(void)
goto done;
}
- printf("test: init\n");
+ printf("TEST: init\n");
werr = smbconf_init_txt(mem_ctx, &conf_ctx, filename);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: init failed: %s\n", win_errstr(werr));
+ printf("FAIL: text backend\[ failed: %s\n", win_errstr(werr));
ret = false;
goto done;
}
- printf("success: init\n");
+ printf("OK: init\n");
ret &= test_get_includes(conf_ctx);
smbconf_shutdown(conf_ctx);
- printf("unlinking file\n");
+ printf("TEST: unlink file\n");
if (unlink(filename) != 0) {
- printf("failure: unlink failed: %s\n", strerror(errno));
+ printf("OK: unlink failed: %s\n", strerror(errno));
ret = false;
goto done;
}
- printf("success: unlink file\n");
-
- printf("%s: text backend\n", ret ? "success" : "failure");
+ printf("OK: unlink file\n");
done:
+ printf("%s: text backend\n", ret ? "success" : "failure");
talloc_free(mem_ctx);
return ret;
}
@@ -248,14 +247,14 @@ static bool torture_smbconf_reg(void)
printf("test: registry backend\n");
- printf("test: init\n");
+ printf("TEST: init\n");
werr = smbconf_init_reg(mem_ctx, &conf_ctx, NULL);
if (!W_ERROR_IS_OK(werr)) {
- printf("failure: init failed: %s\n", win_errstr(werr));
+ printf("FAIL: init failed: %s\n", win_errstr(werr));
ret = false;
goto done;
}
- printf("success: init\n");
+ printf("OK: init\n");
ret &= test_get_includes(conf_ctx);
ret &= test_set_get_includes(conf_ctx);
@@ -263,9 +262,8 @@ static bool torture_smbconf_reg(void)
smbconf_shutdown(conf_ctx);
- printf("%s: registry backend\n", ret ? "success" : "failure");
-
done:
+ printf("%s: registry backend\n", ret ? "success" : "failure");
talloc_free(mem_ctx);
return ret;
}
diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c
new file mode 100644
index 0000000000..1f5dfe4d25
--- /dev/null
+++ b/source3/lib/tdb_validate.c
@@ -0,0 +1,502 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * A general tdb content validation mechanism
+ *
+ * Copyright (C) Michael Adam 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tdb_validate.h"
+#include "includes.h"
+
+/*
+ * internal validation function, executed by the child.
+ */
+static int tdb_validate_child(struct tdb_context *tdb,
+ tdb_validate_data_func validate_fn)
+{
+ int ret = 1;
+ int num_entries = 0;
+ struct tdb_validation_status v_status;
+
+ v_status.tdb_error = False;
+ v_status.bad_freelist = False;
+ v_status.bad_entry = False;
+ v_status.unknown_key = False;
+ v_status.success = True;
+
+ if (!tdb) {
+ v_status.tdb_error = True;
+ v_status.success = False;
+ goto out;
+ }
+
+ /* Check if the tdb's freelist is good. */
+ if (tdb_validate_freelist(tdb, &num_entries) == -1) {
+ v_status.bad_freelist = True;
+ v_status.success = False;
+ goto out;
+ }
+
+ DEBUG(10,("tdb_validate_child: tdb %s freelist has %d entries\n",
+ tdb_name(tdb), num_entries));
+
+ /* Now traverse the tdb to validate it. */
+ num_entries = tdb_traverse(tdb, validate_fn, (void *)&v_status);
+ if (!v_status.success) {
+ goto out;
+ } else if (num_entries == -1) {
+ v_status.tdb_error = True;
+ v_status.success = False;
+ goto out;
+ }
+
+ DEBUG(10,("tdb_validate_child: tdb %s is good with %d entries\n",
+ tdb_name(tdb), num_entries));
+ ret = 0; /* Cache is good. */
+
+out:
+ DEBUG(10, ("tdb_validate_child: summary of validation status:\n"));
+ DEBUGADD(10,(" * tdb error: %s\n", v_status.tdb_error ? "yes" : "no"));
+ DEBUGADD(10,(" * bad freelist: %s\n",v_status.bad_freelist?"yes":"no"));
+ DEBUGADD(10,(" * bad entry: %s\n", v_status.bad_entry ? "yes" : "no"));
+ DEBUGADD(10,(" * unknown key: %s\n", v_status.unknown_key?"yes":"no"));
+ DEBUGADD(10,(" => overall success: %s\n", v_status.success?"yes":"no"));
+
+ return ret;
+}
+
+/*
+ * tdb validation function.
+ * returns 0 if tdb is ok, != 0 if it isn't.
+ * this function expects an opened tdb.
+ */
+int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
+{
+ pid_t child_pid = -1;
+ int child_status = 0;
+ int wait_pid = 0;
+ int ret = 1;
+
+ if (tdb == NULL) {
+ DEBUG(1, ("Error: tdb_validate called with tdb == NULL\n"));
+ return ret;
+ }
+
+ DEBUG(5, ("tdb_validate called for tdb '%s'\n", tdb_name(tdb)));
+
+ /* fork and let the child do the validation.
+ * benefit: no need to twist signal handlers and panic functions.
+ * just let the child panic. we catch the signal. */
+
+ DEBUG(10, ("tdb_validate: forking to let child do validation.\n"));
+ child_pid = sys_fork();
+ if (child_pid == 0) {
+ /* child code */
+ DEBUG(10, ("tdb_validate (validation child): created\n"));
+ DEBUG(10, ("tdb_validate (validation child): "
+ "calling tdb_validate_child\n"));
+ exit(tdb_validate_child(tdb, validate_fn));
+ }
+ else if (child_pid < 0) {
+ DEBUG(1, ("tdb_validate: fork for validation failed.\n"));
+ goto done;
+ }
+
+ /* parent */
+
+ DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid));
+
+ DEBUG(10, ("tdb_validate: waiting for child to finish...\n"));
+ while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
+ if (errno == EINTR) {
+ DEBUG(10, ("tdb_validate: got signal during waitpid, "
+ "retrying\n"));
+ errno = 0;
+ continue;
+ }
+ DEBUG(1, ("tdb_validate: waitpid failed with error '%s'.\n",
+ strerror(errno)));
+ goto done;
+ }
+ if (wait_pid != child_pid) {
+ DEBUG(1, ("tdb_validate: waitpid returned pid %d, "
+ "but %d was expected\n", wait_pid, child_pid));
+ goto done;
+ }
+
+ DEBUG(10, ("tdb_validate: validating child returned.\n"));
+ if (WIFEXITED(child_status)) {
+ DEBUG(10, ("tdb_validate: child exited, code %d.\n",
+ WEXITSTATUS(child_status)));
+ ret = WEXITSTATUS(child_status);
+ }
+ if (WIFSIGNALED(child_status)) {
+ DEBUG(10, ("tdb_validate: child terminated by signal %d\n",
+ WTERMSIG(child_status)));
+#ifdef WCOREDUMP
+ if (WCOREDUMP(child_status)) {
+ DEBUGADD(10, ("core dumped\n"));
+ }
+#endif
+ ret = WTERMSIG(child_status);
+ }
+ if (WIFSTOPPED(child_status)) {
+ DEBUG(10, ("tdb_validate: child was stopped by signal %d\n",
+ WSTOPSIG(child_status)));
+ ret = WSTOPSIG(child_status);
+ }
+
+done:
+ DEBUG(5, ("tdb_validate returning code '%d' for tdb '%s'\n", ret,
+ tdb_name(tdb)));
+
+ return ret;
+}
+
+/*
+ * tdb validation function.
+ * returns 0 if tdb is ok, != 0 if it isn't.
+ * this is a wrapper around the actual validation function that opens and closes
+ * the tdb.
+ */
+int tdb_validate_open(const char *tdb_path, tdb_validate_data_func validate_fn)
+{
+ TDB_CONTEXT *tdb = NULL;
+ int ret = 1;
+
+ DEBUG(5, ("tdb_validate_open called for tdb '%s'\n", tdb_path));
+
+ tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0);
+ if (!tdb) {
+ DEBUG(1, ("Error opening tdb %s\n", tdb_path));
+ return ret;
+ }
+
+ ret = tdb_validate(tdb, validate_fn);
+ tdb_close(tdb);
+ return ret;
+}
+
+/*
+ * tdb backup function and helpers for tdb_validate wrapper with backup
+ * handling.
+ */
+
+/* this structure eliminates the need for a global overall status for
+ * the traverse-copy */
+struct tdb_copy_data {
+ struct tdb_context *dst;
+ bool success;
+};
+
+static int traverse_copy_fn(struct tdb_context *tdb, TDB_DATA key,
+ TDB_DATA dbuf, void *private_data)
+{
+ struct tdb_copy_data *data = (struct tdb_copy_data *)private_data;
+
+ if (tdb_store(data->dst, key, dbuf, TDB_INSERT) != 0) {
+ DEBUG(4, ("Failed to insert into %s: %s\n", tdb_name(data->dst),
+ strerror(errno)));
+ data->success = False;
+ return 1;
+ }
+ return 0;
+}
+
+static int tdb_copy(struct tdb_context *src, struct tdb_context *dst)
+{
+ struct tdb_copy_data data;
+ int count;
+
+ data.dst = dst;
+ data.success = True;
+
+ count = tdb_traverse(src, traverse_copy_fn, (void *)(&data));
+ if ((count < 0) || (data.success == False)) {
+ return -1;
+ }
+ return count;
+}
+
+static int tdb_verify_basic(struct tdb_context *tdb)
+{
+ return tdb_traverse(tdb, NULL, NULL);
+}
+
+/* this backup function is essentially taken from lib/tdb/tools/tdbbackup.tdb
+ */
+static int tdb_backup(TALLOC_CTX *ctx, const char *src_path,
+ const char *dst_path, int hash_size)
+{
+ struct tdb_context *src_tdb = NULL;
+ struct tdb_context *dst_tdb = NULL;
+ char *tmp_path = NULL;
+ struct stat st;
+ int count1, count2;
+ int saved_errno = 0;
+ int ret = -1;
+
+ if (stat(src_path, &st) != 0) {
+ DEBUG(3, ("Could not stat '%s': %s\n", src_path,
+ strerror(errno)));
+ goto done;
+ }
+
+ /* open old tdb RDWR - so we can lock it */
+ src_tdb = tdb_open_log(src_path, 0, TDB_DEFAULT, O_RDWR, 0);
+ if (src_tdb == NULL) {
+ DEBUG(3, ("Failed to open tdb '%s'\n", src_path));
+ goto done;
+ }
+
+ if (tdb_lockall(src_tdb) != 0) {
+ DEBUG(3, ("Failed to lock tdb '%s'\n", src_path));
+ goto done;
+ }
+
+ tmp_path = talloc_asprintf(ctx, "%s%s", dst_path, ".tmp");
+ unlink(tmp_path);
+ dst_tdb = tdb_open_log(tmp_path,
+ hash_size ? hash_size : tdb_hash_size(src_tdb),
+ TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL,
+ st.st_mode & 0777);
+ if (dst_tdb == NULL) {
+ DEBUG(3, ("Error creating tdb '%s': %s\n", tmp_path,
+ strerror(errno)));
+ saved_errno = errno;
+ unlink(tmp_path);
+ goto done;
+ }
+
+ count1 = tdb_copy(src_tdb, dst_tdb);
+ if (count1 < 0) {
+ DEBUG(3, ("Failed to copy tdb '%s': %s\n", src_path,
+ strerror(errno)));
+ tdb_close(dst_tdb);
+ goto done;
+ }
+
+ /* reopen ro and do basic verification */
+ tdb_close(dst_tdb);
+ dst_tdb = tdb_open_log(tmp_path, 0, TDB_DEFAULT, O_RDONLY, 0);
+ if (!dst_tdb) {
+ DEBUG(3, ("Failed to reopen tdb '%s': %s\n", tmp_path,
+ strerror(errno)));
+ goto done;
+ }
+ count2 = tdb_verify_basic(dst_tdb);
+ if (count2 != count1) {
+ DEBUG(3, ("Failed to verify result of copying tdb '%s'.\n",
+ src_path));
+ tdb_close(dst_tdb);
+ goto done;
+ }
+
+ DEBUG(10, ("tdb_backup: successfully copied %d entries\n", count1));
+
+ /* make sure the new tdb has reached stable storage
+ * then rename it to its destination */
+ fsync(tdb_fd(dst_tdb));
+ tdb_close(dst_tdb);
+ unlink(dst_path);
+ if (rename(tmp_path, dst_path) != 0) {
+ DEBUG(3, ("Failed to rename '%s' to '%s': %s\n",
+ tmp_path, dst_path, strerror(errno)));
+ goto done;
+ }
+
+ /* success */
+ ret = 0;
+
+done:
+ if (src_tdb != NULL) {
+ tdb_close(src_tdb);
+ }
+ if (tmp_path != NULL) {
+ unlink(tmp_path);
+ TALLOC_FREE(tmp_path);
+ }
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
+}
+
+static int rename_file_with_suffix(TALLOC_CTX *ctx, const char *path,
+ const char *suffix)
+{
+ int ret = -1;
+ char *dst_path;
+
+ dst_path = talloc_asprintf(ctx, "%s%s", path, suffix);
+
+ ret = (rename(path, dst_path) != 0);
+
+ if (ret == 0) {
+ DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
+ } else if (errno == ENOENT) {
+ DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
+ ret = 0;
+ } else {
+ DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
+ strerror(errno)));
+ }
+
+ TALLOC_FREE(dst_path);
+ return ret;
+}
+
+/*
+ * do a backup of a tdb, moving the destination out of the way first
+ */
+static int tdb_backup_with_rotate(TALLOC_CTX *ctx, const char *src_path,
+ const char *dst_path, int hash_size,
+ const char *rotate_suffix,
+ bool retry_norotate_if_nospc,
+ bool rename_as_last_resort_if_nospc)
+{
+ int ret;
+
+ rename_file_with_suffix(ctx, dst_path, rotate_suffix);
+
+ ret = tdb_backup(ctx, src_path, dst_path, hash_size);
+
+ if (ret != 0) {
+ DEBUG(10, ("backup of %s failed: %s\n", src_path, strerror(errno)));
+ }
+ if ((ret != 0) && (errno == ENOSPC) && retry_norotate_if_nospc)
+ {
+ char *rotate_path = talloc_asprintf(ctx, "%s%s", dst_path,
+ rotate_suffix);
+ DEBUG(10, ("backup of %s failed due to lack of space\n",
+ src_path));
+ DEBUGADD(10, ("trying to free some space by removing rotated "
+ "dst %s\n", rotate_path));
+ if (unlink(rotate_path) == -1) {
+ DEBUG(10, ("unlink of %s failed: %s\n", rotate_path,
+ strerror(errno)));
+ } else {
+ ret = tdb_backup(ctx, src_path, dst_path, hash_size);
+ }
+ TALLOC_FREE(rotate_path);
+ }
+
+ if ((ret != 0) && (errno == ENOSPC) && rename_as_last_resort_if_nospc)
+ {
+ DEBUG(10, ("backup of %s failed due to lack of space\n",
+ src_path));
+ DEBUGADD(10, ("using 'rename' as a last resort\n"));
+ ret = rename(src_path, dst_path);
+ }
+
+ return ret;
+}
+
+/*
+ * validation function with backup handling:
+ *
+ * - calls tdb_validate
+ * - if the tdb is ok, create a backup "name.bak", possibly moving
+ * existing backup to name.bak.old,
+ * return 0 (success) even if the backup fails
+ * - if the tdb is corrupt:
+ * - move the tdb to "name.corrupt"
+ * - check if there is valid backup.
+ * if so, restore the backup.
+ * if restore is successful, return 0 (success),
+ * - otherwise return -1 (failure)
+ */
+int tdb_validate_and_backup(const char *tdb_path,
+ tdb_validate_data_func validate_fn)
+{
+ int ret = -1;
+ const char *backup_suffix = ".bak";
+ const char *corrupt_suffix = ".corrupt";
+ const char *rotate_suffix = ".old";
+ char *tdb_path_backup;
+ struct stat st;
+ TALLOC_CTX *ctx = NULL;
+
+ ctx = talloc_new(NULL);
+ if (ctx == NULL) {
+ DEBUG(0, ("tdb_validate_and_backup: out of memory\n"));
+ goto done;
+ }
+
+ tdb_path_backup = talloc_asprintf(ctx, "%s%s", tdb_path, backup_suffix);
+
+ ret = tdb_validate_open(tdb_path, validate_fn);
+
+ if (ret == 0) {
+ DEBUG(1, ("tdb '%s' is valid\n", tdb_path));
+ ret = tdb_backup_with_rotate(ctx, tdb_path, tdb_path_backup, 0,
+ rotate_suffix, True, False);
+ if (ret != 0) {
+ DEBUG(1, ("Error creating backup of tdb '%s'\n",
+ tdb_path));
+ /* the actual validation was successful: */
+ ret = 0;
+ } else {
+ DEBUG(1, ("Created backup '%s' of tdb '%s'\n",
+ tdb_path_backup, tdb_path));
+ }
+ } else {
+ DEBUG(1, ("tdb '%s' is invalid\n", tdb_path));
+
+ ret =stat(tdb_path_backup, &st);
+ if (ret != 0) {
+ DEBUG(5, ("Could not stat '%s': %s\n", tdb_path_backup,
+ strerror(errno)));
+ DEBUG(1, ("No backup found.\n"));
+ } else {
+ DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
+ ret = tdb_validate_open(tdb_path_backup, validate_fn);
+ if (ret != 0) {
+ DEBUG(1, ("Backup '%s' is invalid.\n",
+ tdb_path_backup));
+ }
+ }
+
+ if (ret != 0) {
+ int renamed = rename_file_with_suffix(ctx, tdb_path,
+ corrupt_suffix);
+ if (renamed != 0) {
+ DEBUG(1, ("Error moving tdb to '%s%s'\n",
+ tdb_path, corrupt_suffix));
+ } else {
+ DEBUG(1, ("Corrupt tdb stored as '%s%s'\n",
+ tdb_path, corrupt_suffix));
+ }
+ goto done;
+ }
+
+ DEBUG(1, ("valid backup '%s' found\n", tdb_path_backup));
+ ret = tdb_backup_with_rotate(ctx, tdb_path_backup, tdb_path, 0,
+ corrupt_suffix, True, True);
+ if (ret != 0) {
+ DEBUG(1, ("Error restoring backup from '%s'\n",
+ tdb_path_backup));
+ } else {
+ DEBUG(1, ("Restored tdb backup from '%s'\n",
+ tdb_path_backup));
+ }
+ }
+
+done:
+ TALLOC_FREE(ctx);
+ return ret;
+}
diff --git a/source3/lib/tdb_validate.h b/source3/lib/tdb_validate.h
new file mode 100644
index 0000000000..9eda79d7db
--- /dev/null
+++ b/source3/lib/tdb_validate.h
@@ -0,0 +1,79 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * A general tdb content validation mechanism
+ *
+ * Copyright (C) Michael Adam 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TDB_VALIDATE_H__
+#define __TDB_VALIDATE_H__
+
+#include "lib/replace/replace.h"
+#include "tdb.h"
+
+/**
+ * Flag field for keeping track of the status of a validation.
+ */
+struct tdb_validation_status {
+ bool tdb_error;
+ bool bad_freelist;
+ bool bad_entry;
+ bool unknown_key;
+ bool success;
+};
+
+/**
+ * Callback function type for the validation mechanism.
+ */
+typedef int (*tdb_validate_data_func)(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
+ TDB_DATA dbuf, void *state);
+
+/**
+ * tdb validation function.
+ * returns 0 if tdb is ok, != 0 if it isn't.
+ * this function expects an opened tdb.
+ */
+int tdb_validate(struct tdb_context *tdb,
+ tdb_validate_data_func validate_fn);
+
+/**
+ * tdb validation function.
+ * returns 0 if tdb is ok, != 0 if it isn't.
+ * This is a wrapper around the actual validation function that
+ * opens and closes the tdb.
+ */
+int tdb_validate_open(const char *tdb_path,
+ tdb_validate_data_func validate_fn);
+
+/**
+ * validation function with backup handling:
+ *
+ * - calls tdb_validate
+ * - if the tdb is ok, create a backup "name.bak", possibly moving
+ * existing backup to name.bak.old,
+ * return 0 (success) even if the backup fails
+ * - if the tdb is corrupt:
+ * - move the tdb to "name.corrupt"
+ * - check if there is valid backup.
+ * if so, restore the backup.
+ * if restore is successful, return 0 (success),
+ * - otherwise return -1 (failure)
+ */
+int tdb_validate_and_backup(const char *tdb_path,
+ tdb_validate_data_func validate_fn);
+
+#endif /* __TDB_VALIDATE_H__ */
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 7dd0da8fa8..e2cfe687b2 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -404,6 +404,16 @@ struct timespec get_atimespec(const SMB_STRUCT_STAT *pst)
ret.tv_sec = pst->st_atime;
ret.tv_nsec = pst->st_atimensec;
return ret;
+#elif defined(HAVE_STAT_ST_ATIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = pst->st_atime_n;
+ return ret;
+#elif defined(HAVE_STAT_ST_UATIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = pst->st_uatime * 1000;
+ return ret;
#elif defined(HAVE_STAT_ST_ATIMESPEC)
return pst->st_atimespec;
#else
@@ -422,7 +432,13 @@ void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
pst->st_atim = ts;
#elif defined(HAVE_STAT_ST_ATIMENSEC)
pst->st_atime = ts.tv_sec;
- pst->st_atimensec = ts.tv_nsec
+ pst->st_atimensec = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_ATIME_N)
+ pst->st_atime = ts.tv_sec;
+ pst->st_atime_n = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_UATIME)
+ pst->st_atime = ts.tv_sec;
+ pst->st_uatime = ts.tv_nsec / 1000;
#elif defined(HAVE_STAT_ST_ATIMESPEC)
pst->st_atimespec = ts;
#else
@@ -448,6 +464,16 @@ struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst)
ret.tv_sec = pst->st_mtime;
ret.tv_nsec = pst->st_mtimensec;
return ret;
+#elif defined(HAVE_STAT_ST_MTIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = pst->st_mtime_n;
+ return ret;
+#elif defined(HAVE_STAT_ST_UMTIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = pst->st_umtime * 1000;
+ return ret;
#elif defined(HAVE_STAT_ST_MTIMESPEC)
return pst->st_mtimespec;
#else
@@ -466,9 +492,15 @@ void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
pst->st_mtim = ts;
#elif defined(HAVE_STAT_ST_MTIMENSEC)
pst->st_mtime = ts.tv_sec;
- pst->st_mtimensec = ts.tv_nsec
-#elif defined(HAVE_STAT_ST_ATIMESPEC)
- pst->st_atimespec = ts;
+ pst->st_mtimensec = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_MTIME_N)
+ pst->st_mtime = ts.tv_sec;
+ pst->st_mtime_n = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_UMTIME)
+ pst->st_mtime = ts.tv_sec;
+ pst->st_umtime = ts.tv_nsec / 1000;
+#elif defined(HAVE_STAT_ST_MTIMESPEC)
+ pst->st_mtimespec = ts;
#else
#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
#endif
@@ -492,6 +524,16 @@ struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst)
ret.tv_sec = pst->st_ctime;
ret.tv_nsec = pst->st_ctimensec;
return ret;
+#elif defined(HAVE_STAT_ST_CTIME_N)
+ struct timespec ret;
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = pst->st_ctime_n;
+ return ret;
+#elif defined(HAVE_STAT_ST_UCTIME)
+ struct timespec ret;
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = pst->st_uctime * 1000;
+ return ret;
#elif defined(HAVE_STAT_ST_CTIMESPEC)
return pst->st_ctimespec;
#else
@@ -510,7 +552,13 @@ void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
pst->st_ctim = ts;
#elif defined(HAVE_STAT_ST_CTIMENSEC)
pst->st_ctime = ts.tv_sec;
- pst->st_ctimensec = ts.tv_nsec
+ pst->st_ctimensec = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_CTIME_N)
+ pst->st_ctime = ts.tv_sec;
+ pst->st_ctime_n = ts.tv_nsec;
+#elif defined(HAVE_STAT_ST_UCTIME)
+ pst->st_ctime = ts.tv_sec;
+ pst->st_uctime = ts.tv_nsec / 1000;
#elif defined(HAVE_STAT_ST_CTIMESPEC)
pst->st_ctimespec = ts;
#else
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 2485d1def5..df01c0306f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -57,9 +57,6 @@ extern unsigned int global_clobber_region_line;
enum protocol_types Protocol = PROTOCOL_COREPLUS;
-/* this is used by the chaining code */
-int chain_size = 0;
-
static enum remote_arch_types ra_type = RA_UNKNOWN;
/***********************************************************************
@@ -542,6 +539,15 @@ bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st)
}
/*******************************************************************
+ Returns the size in bytes of the named given the stat struct.
+********************************************************************/
+
+uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
+{
+ return sbuf->st_size;
+}
+
+/*******************************************************************
Returns the size in bytes of the named file.
********************************************************************/
@@ -551,7 +557,7 @@ SMB_OFF_T get_file_size(char *file_name)
buf.st_size = 0;
if(sys_stat(file_name,&buf) != 0)
return (SMB_OFF_T)-1;
- return(buf.st_size);
+ return get_file_size_stat(&buf);
}
/*******************************************************************
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index fdc10f20ab..0da7442d19 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -149,7 +149,9 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
}
/*
- the main entry point for access checking.
+ The main entry point for access checking. If returning ACCESS_DENIED
+ this function returns the denied bits in the uint32_t pointed
+ to by the access_granted pointer.
*/
NTSTATUS se_access_check(const struct security_descriptor *sd,
const NT_USER_TOKEN *token,
@@ -238,6 +240,7 @@ NTSTATUS se_access_check(const struct security_descriptor *sd,
done:
if (bits_remaining != 0) {
+ *access_granted = bits_remaining;
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 3ddc4342a7..78431d93c8 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -1036,7 +1036,7 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
return result;
post_status:
- if (!async_post_status(result, ev, status)) {
+ if (!async_post_ntstatus(result, ev, status)) {
goto fail;
}
return result;
@@ -1082,7 +1082,7 @@ static void open_socket_out_connected(struct async_req *subreq)
}
if (!async_req_set_timeout(subreq, state->ev,
timeval_set(0, state->wait_nsec))) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
subreq->async.fn = open_socket_out_connected;
@@ -1098,7 +1098,7 @@ static void open_socket_out_connected(struct async_req *subreq)
#endif
/* real error */
- async_req_error(req, map_nt_error_from_unix(sys_errno));
+ async_req_nterror(req, map_nt_error_from_unix(sys_errno));
}
NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
@@ -1107,7 +1107,7 @@ NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
req->private_data, struct open_socket_out_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*pfd = state->fd;
@@ -1183,7 +1183,7 @@ struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
return result;
post_status:
- if (!async_post_status(result, ev, status)) {
+ if (!async_post_ntstatus(result, ev, status)) {
goto fail;
}
return result;
@@ -1198,12 +1198,12 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
subreq->async.priv, struct async_req);
struct open_socket_out_defer_state *state = talloc_get_type_abort(
req->private_data, struct open_socket_out_defer_state);
- NTSTATUS status;
+ bool ret;
- status = async_wait_recv(subreq);
+ ret = async_wait_recv(subreq);
TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ if (!ret) {
+ async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return;
}
@@ -1227,7 +1227,7 @@ static void open_socket_out_defer_connected(struct async_req *subreq)
status = open_socket_out_recv(subreq, &state->fd);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -1239,7 +1239,7 @@ NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd)
req->private_data, struct open_socket_out_defer_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*pfd = state->fd;
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 2dbdd57947..78fa7cd0a1 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -630,487 +630,3 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
return NT_STATUS_INTERNAL_ERROR;
}
-
-
-/*********************************************************************
- * the following is a generic validation mechanism for tdbs.
- *********************************************************************/
-
-/*
- * internal validation function, executed by the child.
- */
-static int tdb_validate_child(struct tdb_context *tdb,
- tdb_validate_data_func validate_fn)
-{
- int ret = 1;
- int num_entries = 0;
- struct tdb_validation_status v_status;
-
- v_status.tdb_error = False;
- v_status.bad_freelist = False;
- v_status.bad_entry = False;
- v_status.unknown_key = False;
- v_status.success = True;
-
- if (!tdb) {
- v_status.tdb_error = True;
- v_status.success = False;
- goto out;
- }
-
- /* Check if the tdb's freelist is good. */
- if (tdb_validate_freelist(tdb, &num_entries) == -1) {
- v_status.bad_freelist = True;
- v_status.success = False;
- goto out;
- }
-
- DEBUG(10,("tdb_validate_child: tdb %s freelist has %d entries\n",
- tdb_name(tdb), num_entries));
-
- /* Now traverse the tdb to validate it. */
- num_entries = tdb_traverse(tdb, validate_fn, (void *)&v_status);
- if (!v_status.success) {
- goto out;
- } else if (num_entries == -1) {
- v_status.tdb_error = True;
- v_status.success = False;
- goto out;
- }
-
- DEBUG(10,("tdb_validate_child: tdb %s is good with %d entries\n",
- tdb_name(tdb), num_entries));
- ret = 0; /* Cache is good. */
-
-out:
- DEBUG(10, ("tdb_validate_child: summary of validation status:\n"));
- DEBUGADD(10,(" * tdb error: %s\n", v_status.tdb_error ? "yes" : "no"));
- DEBUGADD(10,(" * bad freelist: %s\n",v_status.bad_freelist?"yes":"no"));
- DEBUGADD(10,(" * bad entry: %s\n", v_status.bad_entry ? "yes" : "no"));
- DEBUGADD(10,(" * unknown key: %s\n", v_status.unknown_key?"yes":"no"));
- DEBUGADD(10,(" => overall success: %s\n", v_status.success?"yes":"no"));
-
- return ret;
-}
-
-/*
- * tdb validation function.
- * returns 0 if tdb is ok, != 0 if it isn't.
- * this function expects an opened tdb.
- */
-int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
-{
- pid_t child_pid = -1;
- int child_status = 0;
- int wait_pid = 0;
- int ret = 1;
-
- if (tdb == NULL) {
- DEBUG(1, ("Error: tdb_validate called with tdb == NULL\n"));
- return ret;
- }
-
- DEBUG(5, ("tdb_validate called for tdb '%s'\n", tdb_name(tdb)));
-
- /* fork and let the child do the validation.
- * benefit: no need to twist signal handlers and panic functions.
- * just let the child panic. we catch the signal. */
-
- DEBUG(10, ("tdb_validate: forking to let child do validation.\n"));
- child_pid = sys_fork();
- if (child_pid == 0) {
- /* child code */
- DEBUG(10, ("tdb_validate (validation child): created\n"));
- DEBUG(10, ("tdb_validate (validation child): "
- "calling tdb_validate_child\n"));
- exit(tdb_validate_child(tdb, validate_fn));
- }
- else if (child_pid < 0) {
- DEBUG(1, ("tdb_validate: fork for validation failed.\n"));
- goto done;
- }
-
- /* parent */
-
- DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid));
-
- DEBUG(10, ("tdb_validate: waiting for child to finish...\n"));
- while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
- if (errno == EINTR) {
- DEBUG(10, ("tdb_validate: got signal during waitpid, "
- "retrying\n"));
- errno = 0;
- continue;
- }
- DEBUG(1, ("tdb_validate: waitpid failed with error '%s'.\n",
- strerror(errno)));
- goto done;
- }
- if (wait_pid != child_pid) {
- DEBUG(1, ("tdb_validate: waitpid returned pid %d, "
- "but %d was expected\n", wait_pid, child_pid));
- goto done;
- }
-
- DEBUG(10, ("tdb_validate: validating child returned.\n"));
- if (WIFEXITED(child_status)) {
- DEBUG(10, ("tdb_validate: child exited, code %d.\n",
- WEXITSTATUS(child_status)));
- ret = WEXITSTATUS(child_status);
- }
- if (WIFSIGNALED(child_status)) {
- DEBUG(10, ("tdb_validate: child terminated by signal %d\n",
- WTERMSIG(child_status)));
-#ifdef WCOREDUMP
- if (WCOREDUMP(child_status)) {
- DEBUGADD(10, ("core dumped\n"));
- }
-#endif
- ret = WTERMSIG(child_status);
- }
- if (WIFSTOPPED(child_status)) {
- DEBUG(10, ("tdb_validate: child was stopped by signal %d\n",
- WSTOPSIG(child_status)));
- ret = WSTOPSIG(child_status);
- }
-
-done:
- DEBUG(5, ("tdb_validate returning code '%d' for tdb '%s'\n", ret,
- tdb_name(tdb)));
-
- return ret;
-}
-
-/*
- * tdb validation function.
- * returns 0 if tdb is ok, != 0 if it isn't.
- * this is a wrapper around the actual validation function that opens and closes
- * the tdb.
- */
-int tdb_validate_open(const char *tdb_path, tdb_validate_data_func validate_fn)
-{
- TDB_CONTEXT *tdb = NULL;
- int ret = 1;
-
- DEBUG(5, ("tdb_validate_open called for tdb '%s'\n", tdb_path));
-
- tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!tdb) {
- DEBUG(1, ("Error opening tdb %s\n", tdb_path));
- return ret;
- }
-
- ret = tdb_validate(tdb, validate_fn);
- tdb_close(tdb);
- return ret;
-}
-
-/*
- * tdb backup function and helpers for tdb_validate wrapper with backup
- * handling.
- */
-
-/* this structure eliminates the need for a global overall status for
- * the traverse-copy */
-struct tdb_copy_data {
- struct tdb_context *dst;
- bool success;
-};
-
-static int traverse_copy_fn(struct tdb_context *tdb, TDB_DATA key,
- TDB_DATA dbuf, void *private_data)
-{
- struct tdb_copy_data *data = (struct tdb_copy_data *)private_data;
-
- if (tdb_store(data->dst, key, dbuf, TDB_INSERT) != 0) {
- DEBUG(4, ("Failed to insert into %s: %s\n", tdb_name(data->dst),
- strerror(errno)));
- data->success = False;
- return 1;
- }
- return 0;
-}
-
-static int tdb_copy(struct tdb_context *src, struct tdb_context *dst)
-{
- struct tdb_copy_data data;
- int count;
-
- data.dst = dst;
- data.success = True;
-
- count = tdb_traverse(src, traverse_copy_fn, (void *)(&data));
- if ((count < 0) || (data.success == False)) {
- return -1;
- }
- return count;
-}
-
-static int tdb_verify_basic(struct tdb_context *tdb)
-{
- return tdb_traverse(tdb, NULL, NULL);
-}
-
-/* this backup function is essentially taken from lib/tdb/tools/tdbbackup.tdb
- */
-static int tdb_backup(TALLOC_CTX *ctx, const char *src_path,
- const char *dst_path, int hash_size)
-{
- struct tdb_context *src_tdb = NULL;
- struct tdb_context *dst_tdb = NULL;
- char *tmp_path = NULL;
- struct stat st;
- int count1, count2;
- int saved_errno = 0;
- int ret = -1;
-
- if (stat(src_path, &st) != 0) {
- DEBUG(3, ("Could not stat '%s': %s\n", src_path,
- strerror(errno)));
- goto done;
- }
-
- /* open old tdb RDWR - so we can lock it */
- src_tdb = tdb_open_log(src_path, 0, TDB_DEFAULT, O_RDWR, 0);
- if (src_tdb == NULL) {
- DEBUG(3, ("Failed to open tdb '%s'\n", src_path));
- goto done;
- }
-
- if (tdb_lockall(src_tdb) != 0) {
- DEBUG(3, ("Failed to lock tdb '%s'\n", src_path));
- goto done;
- }
-
- tmp_path = talloc_asprintf(ctx, "%s%s", dst_path, ".tmp");
- unlink(tmp_path);
- dst_tdb = tdb_open_log(tmp_path,
- hash_size ? hash_size : tdb_hash_size(src_tdb),
- TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL,
- st.st_mode & 0777);
- if (dst_tdb == NULL) {
- DEBUG(3, ("Error creating tdb '%s': %s\n", tmp_path,
- strerror(errno)));
- saved_errno = errno;
- unlink(tmp_path);
- goto done;
- }
-
- count1 = tdb_copy(src_tdb, dst_tdb);
- if (count1 < 0) {
- DEBUG(3, ("Failed to copy tdb '%s': %s\n", src_path,
- strerror(errno)));
- tdb_close(dst_tdb);
- goto done;
- }
-
- /* reopen ro and do basic verification */
- tdb_close(dst_tdb);
- dst_tdb = tdb_open_log(tmp_path, 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!dst_tdb) {
- DEBUG(3, ("Failed to reopen tdb '%s': %s\n", tmp_path,
- strerror(errno)));
- goto done;
- }
- count2 = tdb_verify_basic(dst_tdb);
- if (count2 != count1) {
- DEBUG(3, ("Failed to verify result of copying tdb '%s'.\n",
- src_path));
- tdb_close(dst_tdb);
- goto done;
- }
-
- DEBUG(10, ("tdb_backup: successfully copied %d entries\n", count1));
-
- /* make sure the new tdb has reached stable storage
- * then rename it to its destination */
- fsync(tdb_fd(dst_tdb));
- tdb_close(dst_tdb);
- unlink(dst_path);
- if (rename(tmp_path, dst_path) != 0) {
- DEBUG(3, ("Failed to rename '%s' to '%s': %s\n",
- tmp_path, dst_path, strerror(errno)));
- goto done;
- }
-
- /* success */
- ret = 0;
-
-done:
- if (src_tdb != NULL) {
- tdb_close(src_tdb);
- }
- if (tmp_path != NULL) {
- unlink(tmp_path);
- TALLOC_FREE(tmp_path);
- }
- if (saved_errno != 0) {
- errno = saved_errno;
- }
- return ret;
-}
-
-static int rename_file_with_suffix(TALLOC_CTX *ctx, const char *path,
- const char *suffix)
-{
- int ret = -1;
- char *dst_path;
-
- dst_path = talloc_asprintf(ctx, "%s%s", path, suffix);
-
- ret = (rename(path, dst_path) != 0);
-
- if (ret == 0) {
- DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
- } else if (errno == ENOENT) {
- DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
- ret = 0;
- } else {
- DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
- strerror(errno)));
- }
-
- TALLOC_FREE(dst_path);
- return ret;
-}
-
-/*
- * do a backup of a tdb, moving the destination out of the way first
- */
-static int tdb_backup_with_rotate(TALLOC_CTX *ctx, const char *src_path,
- const char *dst_path, int hash_size,
- const char *rotate_suffix,
- bool retry_norotate_if_nospc,
- bool rename_as_last_resort_if_nospc)
-{
- int ret;
-
- rename_file_with_suffix(ctx, dst_path, rotate_suffix);
-
- ret = tdb_backup(ctx, src_path, dst_path, hash_size);
-
- if (ret != 0) {
- DEBUG(10, ("backup of %s failed: %s\n", src_path, strerror(errno)));
- }
- if ((ret != 0) && (errno == ENOSPC) && retry_norotate_if_nospc)
- {
- char *rotate_path = talloc_asprintf(ctx, "%s%s", dst_path,
- rotate_suffix);
- DEBUG(10, ("backup of %s failed due to lack of space\n",
- src_path));
- DEBUGADD(10, ("trying to free some space by removing rotated "
- "dst %s\n", rotate_path));
- if (unlink(rotate_path) == -1) {
- DEBUG(10, ("unlink of %s failed: %s\n", rotate_path,
- strerror(errno)));
- } else {
- ret = tdb_backup(ctx, src_path, dst_path, hash_size);
- }
- TALLOC_FREE(rotate_path);
- }
-
- if ((ret != 0) && (errno == ENOSPC) && rename_as_last_resort_if_nospc)
- {
- DEBUG(10, ("backup of %s failed due to lack of space\n",
- src_path));
- DEBUGADD(10, ("using 'rename' as a last resort\n"));
- ret = rename(src_path, dst_path);
- }
-
- return ret;
-}
-
-/*
- * validation function with backup handling:
- *
- * - calls tdb_validate
- * - if the tdb is ok, create a backup "name.bak", possibly moving
- * existing backup to name.bak.old,
- * return 0 (success) even if the backup fails
- * - if the tdb is corrupt:
- * - move the tdb to "name.corrupt"
- * - check if there is valid backup.
- * if so, restore the backup.
- * if restore is successful, return 0 (success),
- * - otherwise return -1 (failure)
- */
-int tdb_validate_and_backup(const char *tdb_path,
- tdb_validate_data_func validate_fn)
-{
- int ret = -1;
- const char *backup_suffix = ".bak";
- const char *corrupt_suffix = ".corrupt";
- const char *rotate_suffix = ".old";
- char *tdb_path_backup;
- struct stat st;
- TALLOC_CTX *ctx = NULL;
-
- ctx = talloc_new(NULL);
- if (ctx == NULL) {
- DEBUG(0, ("tdb_validate_and_backup: out of memory\n"));
- goto done;
- }
-
- tdb_path_backup = talloc_asprintf(ctx, "%s%s", tdb_path, backup_suffix);
-
- ret = tdb_validate_open(tdb_path, validate_fn);
-
- if (ret == 0) {
- DEBUG(1, ("tdb '%s' is valid\n", tdb_path));
- ret = tdb_backup_with_rotate(ctx, tdb_path, tdb_path_backup, 0,
- rotate_suffix, True, False);
- if (ret != 0) {
- DEBUG(1, ("Error creating backup of tdb '%s'\n",
- tdb_path));
- /* the actual validation was successful: */
- ret = 0;
- } else {
- DEBUG(1, ("Created backup '%s' of tdb '%s'\n",
- tdb_path_backup, tdb_path));
- }
- } else {
- DEBUG(1, ("tdb '%s' is invalid\n", tdb_path));
-
- ret =stat(tdb_path_backup, &st);
- if (ret != 0) {
- DEBUG(5, ("Could not stat '%s': %s\n", tdb_path_backup,
- strerror(errno)));
- DEBUG(1, ("No backup found.\n"));
- } else {
- DEBUG(1, ("backup '%s' found.\n", tdb_path_backup));
- ret = tdb_validate_open(tdb_path_backup, validate_fn);
- if (ret != 0) {
- DEBUG(1, ("Backup '%s' is invalid.\n",
- tdb_path_backup));
- }
- }
-
- if (ret != 0) {
- int renamed = rename_file_with_suffix(ctx, tdb_path,
- corrupt_suffix);
- if (renamed != 0) {
- DEBUG(1, ("Error moving tdb to '%s%s'\n",
- tdb_path, corrupt_suffix));
- } else {
- DEBUG(1, ("Corrupt tdb stored as '%s%s'\n",
- tdb_path, corrupt_suffix));
- }
- goto done;
- }
-
- DEBUG(1, ("valid backup '%s' found\n", tdb_path_backup));
- ret = tdb_backup_with_rotate(ctx, tdb_path_backup, tdb_path, 0,
- corrupt_suffix, True, True);
- if (ret != 0) {
- DEBUG(1, ("Error restoring backup from '%s'\n",
- tdb_path_backup));
- } else {
- DEBUG(1, ("Restored tdb backup from '%s'\n",
- tdb_path_backup));
- }
- }
-
-done:
- TALLOC_FREE(ctx);
- return ret;
-}
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index 0e6e5d15c4..b56c0fd4d3 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -27,7 +27,7 @@
struct req_read_state {
struct winbindd_request *wb_req;
- struct event_context *ev;
+ struct tevent_context *ev;
size_t max_extra_data;
int fd;
};
@@ -37,7 +37,7 @@ static void wb_req_read_main(struct async_req *subreq);
static void wb_req_read_extra(struct async_req *subreq);
struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
int fd, size_t max_extra_data)
{
struct async_req *result, *subreq;
@@ -81,7 +81,7 @@ static void wb_req_read_len(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -89,7 +89,7 @@ static void wb_req_read_len(struct async_req *subreq)
DEBUG(0, ("wb_req_read_len: Invalid request size received: "
"%d (expected %d)\n", (int)state->wb_req->length,
(int)sizeof(struct winbindd_request)));
- async_req_error(req, NT_STATUS_INVALID_BUFFER_SIZE);
+ async_req_nterror(req, NT_STATUS_INVALID_BUFFER_SIZE);
return;
}
@@ -115,7 +115,7 @@ static void wb_req_read_main(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -124,7 +124,7 @@ static void wb_req_read_main(struct async_req *subreq)
DEBUG(3, ("Got request with %d bytes extra data on "
"unprivileged socket\n",
(int)state->wb_req->extra_len));
- async_req_error(req, NT_STATUS_INVALID_BUFFER_SIZE);
+ async_req_nterror(req, NT_STATUS_INVALID_BUFFER_SIZE);
return;
}
@@ -161,7 +161,7 @@ static void wb_req_read_extra(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -175,7 +175,7 @@ NTSTATUS wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct req_read_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*preq = talloc_move(mem_ctx, &state->wb_req);
@@ -184,7 +184,7 @@ NTSTATUS wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct req_write_state {
struct winbindd_request *wb_req;
- struct event_context *ev;
+ struct tevent_context *ev;
int fd;
};
@@ -192,7 +192,7 @@ static void wb_req_write_main(struct async_req *subreq);
static void wb_req_write_extra(struct async_req *subreq);
struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev, int fd,
+ struct tevent_context *ev, int fd,
struct winbindd_request *wb_req)
{
struct async_req *result, *subreq;
@@ -232,7 +232,7 @@ static void wb_req_write_main(struct async_req *subreq)
status = sendall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -261,7 +261,7 @@ static void wb_req_write_extra(struct async_req *subreq)
status = sendall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -270,12 +270,12 @@ static void wb_req_write_extra(struct async_req *subreq)
NTSTATUS wb_req_write_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
struct resp_read_state {
struct winbindd_response *wb_resp;
- struct event_context *ev;
+ struct tevent_context *ev;
size_t max_extra_data;
int fd;
};
@@ -285,7 +285,7 @@ static void wb_resp_read_main(struct async_req *subreq);
static void wb_resp_read_extra(struct async_req *subreq);
struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev, int fd)
+ struct tevent_context *ev, int fd)
{
struct async_req *result, *subreq;
struct resp_read_state *state;
@@ -327,7 +327,7 @@ static void wb_resp_read_len(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -336,7 +336,7 @@ static void wb_resp_read_len(struct async_req *subreq)
"%d (expected at least%d)\n",
(int)state->wb_resp->length,
(int)sizeof(struct winbindd_response)));
- async_req_error(req, NT_STATUS_INVALID_BUFFER_SIZE);
+ async_req_nterror(req, NT_STATUS_INVALID_BUFFER_SIZE);
return;
}
@@ -363,7 +363,7 @@ static void wb_resp_read_main(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -400,7 +400,7 @@ static void wb_resp_read_extra(struct async_req *subreq)
status = recvall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -414,7 +414,7 @@ NTSTATUS wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct resp_read_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*presp = talloc_move(mem_ctx, &state->wb_resp);
@@ -423,7 +423,7 @@ NTSTATUS wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct resp_write_state {
struct winbindd_response *wb_resp;
- struct event_context *ev;
+ struct tevent_context *ev;
int fd;
};
@@ -431,7 +431,7 @@ static void wb_resp_write_main(struct async_req *subreq);
static void wb_resp_write_extra(struct async_req *subreq);
struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev, int fd,
+ struct tevent_context *ev, int fd,
struct winbindd_response *wb_resp)
{
struct async_req *result, *subreq;
@@ -471,7 +471,7 @@ static void wb_resp_write_main(struct async_req *subreq)
status = sendall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -501,7 +501,7 @@ static void wb_resp_write_extra(struct async_req *subreq)
status = sendall_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -510,5 +510,5 @@ static void wb_resp_write_extra(struct async_req *subreq)
NTSTATUS wb_resp_write_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index ea0bcb512e..ae9a034cc8 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -155,7 +155,7 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
}
static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct wb_context *wb_ctx,
const char *dir)
{
@@ -232,7 +232,7 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
- if (async_post_status(req, ev, status)) {
+ if (async_post_ntstatus(req, ev, status)) {
return req;
}
TALLOC_FREE(req);
@@ -272,7 +272,7 @@ static struct winbindd_request *winbindd_request_copy(
}
struct wb_int_trans_state {
- struct event_context *ev;
+ struct tevent_context *ev;
int fd;
struct winbindd_request *wb_req;
struct winbindd_response *wb_resp;
@@ -282,7 +282,7 @@ static void wb_int_trans_write_done(struct async_req *subreq);
static void wb_int_trans_read_done(struct async_req *subreq);
static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev, int fd,
+ struct tevent_context *ev, int fd,
struct winbindd_request *wb_req)
{
struct async_req *result;
@@ -295,8 +295,8 @@ static struct async_req *wb_int_trans_send(TALLOC_CTX *mem_ctx,
}
if (winbind_closed_fd(fd)) {
- if (!async_post_status(result, ev,
- NT_STATUS_PIPE_DISCONNECTED)) {
+ if (!async_post_ntstatus(result, ev,
+ NT_STATUS_PIPE_DISCONNECTED)) {
goto fail;
}
return result;
@@ -334,13 +334,13 @@ static void wb_int_trans_write_done(struct async_req *subreq)
status = wb_req_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
subreq = wb_resp_read_send(state, state->ev, state->fd);
if (subreq == NULL) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
}
subreq->async.fn = wb_int_trans_read_done;
subreq->async.priv = req;
@@ -357,7 +357,7 @@ static void wb_int_trans_read_done(struct async_req *subreq)
status = wb_resp_read_recv(subreq, state, &state->wb_resp);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -372,7 +372,7 @@ static NTSTATUS wb_int_trans_recv(struct async_req *req,
req->private_data, struct wb_int_trans_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -396,7 +396,7 @@ static const char *winbindd_socket_dir(void)
struct wb_open_pipe_state {
struct wb_context *wb_ctx;
- struct event_context *ev;
+ struct tevent_context *ev;
bool need_priv;
struct winbindd_request wb_req;
};
@@ -407,7 +407,7 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq);
static void wb_open_pipe_connect_priv_done(struct async_req *subreq);
static struct async_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct wb_context *wb_ctx,
bool need_priv)
{
@@ -454,7 +454,7 @@ static void wb_open_pipe_connect_nonpriv_done(struct async_req *subreq)
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
state->wb_ctx->is_priv = true;
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -483,7 +483,7 @@ static void wb_open_pipe_ping_done(struct async_req *subreq)
status = wb_int_trans_recv(subreq, state, &wb_resp);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -516,7 +516,7 @@ static void wb_open_pipe_getpriv_done(struct async_req *subreq)
status = wb_int_trans_recv(subreq, state, &wb_resp);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -545,7 +545,7 @@ static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
status = wb_connect_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
state->wb_ctx->is_priv = true;
@@ -554,13 +554,13 @@ static void wb_open_pipe_connect_priv_done(struct async_req *subreq)
static NTSTATUS wb_open_pipe_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
struct wb_trans_state {
struct wb_trans_state *prev, *next;
struct wb_context *wb_ctx;
- struct event_context *ev;
+ struct tevent_context *ev;
struct winbindd_request *wb_req;
struct winbindd_response *wb_resp;
int num_retries;
@@ -599,7 +599,7 @@ static void wb_trigger_trans(struct async_req *req)
subreq->async.priv = req;
}
-struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+struct async_req *wb_trans_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct wb_context *wb_ctx, bool need_priv,
const struct winbindd_request *wb_req)
{
@@ -645,13 +645,13 @@ static bool wb_trans_retry(struct async_req *req,
* Winbind not around or we can't connect to the pipe. Fail
* immediately.
*/
- async_req_error(req, status);
+ async_req_nterror(req, status);
return true;
}
state->num_retries -= 1;
if (state->num_retries == 0) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return true;
}
@@ -680,12 +680,12 @@ static void wb_trans_retry_wait_done(struct async_req *subreq)
subreq->async.priv, struct async_req);
struct wb_trans_state *state = talloc_get_type_abort(
req->private_data, struct wb_trans_state);
- NTSTATUS status;
+ bool ret;
- status = async_wait_recv(subreq);
+ ret = async_wait_recv(subreq);
TALLOC_FREE(subreq);
- if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
- async_req_error(req, status);
+ if (ret) {
+ async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return;
}
@@ -748,7 +748,7 @@ NTSTATUS wb_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct wb_trans_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index de3fdeb9de..b903b2a6eb 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -31,6 +31,87 @@
const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int );
#endif
+static bool ads_dedicated_keytab_verify_ticket(krb5_context context,
+ krb5_auth_context auth_context,
+ const DATA_BLOB *ticket,
+ krb5_ticket **pp_tkt,
+ krb5_keyblock **keyblock,
+ krb5_error_code *perr)
+{
+ krb5_error_code ret = 0;
+ bool auth_ok = false;
+ krb5_keytab keytab = NULL;
+ krb5_keytab_entry kt_entry;
+ krb5_ticket *dec_ticket = NULL;
+
+ krb5_data packet;
+ krb5_kvno kvno = 0;
+ krb5_enctype enctype;
+
+ *pp_tkt = NULL;
+ *keyblock = NULL;
+ *perr = 0;
+
+ ZERO_STRUCT(kt_entry);
+
+ ret = smb_krb5_open_keytab(context, lp_dedicated_keytab_file(), true,
+ &keytab);
+ if (ret) {
+ DEBUG(1, ("smb_krb5_open_keytab failed (%s)\n",
+ error_message(ret)));
+ goto out;
+ }
+
+ packet.length = ticket->length;
+ packet.data = (char *)ticket->data;
+
+ ret = krb5_rd_req(context, &auth_context, &packet, NULL, keytab,
+ NULL, &dec_ticket);
+ if (ret) {
+ DEBUG(0, ("krb5_rd_req failed (%s)\n", error_message(ret)));
+ goto out;
+ }
+
+#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */
+ enctype = dec_ticket->ticket.key.keytype;
+#else /* MIT */
+ enctype = dec_ticket->enc_part.enctype;
+ kvno = dec_ticket->enc_part.kvno;
+#endif
+
+ /* Get the key for checking the pac signature */
+ ret = krb5_kt_get_entry(context, keytab, dec_ticket->server,
+ kvno, enctype, &kt_entry);
+ if (ret) {
+ DEBUG(0, ("krb5_kt_get_entry failed (%s)\n",
+ error_message(ret)));
+ goto out;
+ }
+
+ ret = krb5_copy_keyblock(context, KRB5_KT_KEY(&kt_entry), keyblock);
+ smb_krb5_kt_free_entry(context, &kt_entry);
+
+ if (ret) {
+ DEBUG(0, ("failed to copy key: %s\n",
+ error_message(ret)));
+ goto out;
+ }
+
+ auth_ok = true;
+ *pp_tkt = dec_ticket;
+ dec_ticket = NULL;
+
+ out:
+ if (dec_ticket)
+ krb5_free_ticket(context, dec_ticket);
+
+ if (keytab)
+ krb5_kt_close(context, keytab);
+
+ *perr = ret;
+ return auth_ok;
+}
+
/**********************************************************************************
Try to verify a ticket using the system keytab... the system keytab has kvno -1 entries, so
it's more like what microsoft does... see comment in utils/net_ads.c in the
@@ -437,22 +518,38 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
}
}
- /* Try secrets.tdb first and fallback to the krb5.keytab if
- necessary */
-
- auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ,
- ticket, &tkt, &keyblock, &ret);
-
- if (!auth_ok &&
- (ret == KRB5KRB_AP_ERR_TKT_NYV ||
- ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
- ret == KRB5KRB_AP_ERR_SKEW)) {
- goto auth_failed;
- }
-
- if (!auth_ok && lp_use_kerberos_keytab()) {
- auth_ok = ads_keytab_verify_ticket(context, auth_context,
- ticket, &tkt, &keyblock, &ret);
+ switch (lp_kerberos_method()) {
+ default:
+ case KERBEROS_VERIFY_SECRETS:
+ auth_ok = ads_secrets_verify_ticket(context, auth_context,
+ host_princ, ticket, &tkt, &keyblock, &ret);
+ break;
+ case KERBEROS_VERIFY_SYSTEM_KEYTAB:
+ auth_ok = ads_keytab_verify_ticket(context, auth_context,
+ ticket, &tkt, &keyblock, &ret);
+ break;
+ case KERBEROS_VERIFY_DEDICATED_KEYTAB:
+ auth_ok = ads_dedicated_keytab_verify_ticket(context,
+ auth_context, ticket, &tkt, &keyblock, &ret);
+ break;
+ case KERBEROS_VERIFY_SECRETS_AND_KEYTAB:
+ /* First try secrets.tdb and fallback to the krb5.keytab if
+ necessary. This is the pre 3.4 behavior when
+ "use kerberos keytab" was true.*/
+ auth_ok = ads_secrets_verify_ticket(context, auth_context,
+ host_princ, ticket, &tkt, &keyblock, &ret);
+
+ if (!auth_ok) {
+ /* Only fallback if we failed to decrypt the ticket */
+ if (ret != KRB5KRB_AP_ERR_TKT_NYV &&
+ ret != KRB5KRB_AP_ERR_TKT_EXPIRED &&
+ ret != KRB5KRB_AP_ERR_SKEW) {
+ auth_ok = ads_keytab_verify_ticket(context,
+ auth_context, ticket, &tkt, &keyblock,
+ &ret);
+ }
+ }
+ break;
}
if ( use_replay_cache ) {
@@ -465,7 +562,6 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
#endif
}
- auth_failed:
if (!auth_ok) {
DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
error_message(ret)));
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index f6da54f35b..edbd69392c 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -672,9 +672,11 @@ got_connection:
ldap_set_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version);
- status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version));
- if (!ADS_ERR_OK(status)) {
- goto out;
+ if ( lp_ldap_ssl_ads() ) {
+ status = ADS_ERROR(smb_ldap_start_tls(ads->ldap.ld, version));
+ if (!ADS_ERR_OK(status)) {
+ goto out;
+ }
}
/* fill in the current time and offsets */
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index be6943bad9..20f7b97745 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -504,7 +504,7 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX *mem_ctx,
static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
- if (!lp_use_kerberos_keytab()) {
+ if (!USE_SYSTEM_KEYTAB) {
return true;
}
@@ -790,7 +790,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
pipe_hnd->desthost,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
+ SAMR_ACCESS_ENUM_DOMAINS
+ | SAMR_ACCESS_OPEN_DOMAIN,
&sam_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
@@ -798,7 +799,9 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
&sam_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
+ SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
+ | SAMR_DOMAIN_ACCESS_CREATE_USER
+ | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
r->out.domain_sid,
&domain_pol);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index 3068f8d3eb..dc3bc75541 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -345,100 +345,129 @@ static NTSTATUS map_populate_groups(TALLOC_CTX *mem_ctx,
groupmap[0].sambaSID = talloc_asprintf(mem_ctx, "%s-512", sid);
groupmap[0].group_dn = talloc_asprintf(mem_ctx,
"cn=Domain Admins,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[0].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[0].group_dn);
+ if (groupmap[0].sambaSID == NULL || groupmap[0].group_dn == NULL) {
+ goto err;
+ }
accountmap[0].rid = 512;
accountmap[0].cn = talloc_strdup(mem_ctx, "Domain Admins");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[0].cn);
+ if (accountmap[0].cn == NULL) {
+ goto err;
+ }
groupmap[1].rid = 513;
groupmap[1].gidNumber = 513;
groupmap[1].sambaSID = talloc_asprintf(mem_ctx, "%s-513", sid);
groupmap[1].group_dn = talloc_asprintf(mem_ctx,
"cn=Domain Users,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[1].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[1].group_dn);
+ if (groupmap[1].sambaSID == NULL || groupmap[1].group_dn == NULL) {
+ goto err;
+ }
accountmap[1].rid = 513;
accountmap[1].cn = talloc_strdup(mem_ctx, "Domain Users");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[1].cn);
+ if (accountmap[1].cn == NULL) {
+ goto err;
+ }
groupmap[2].rid = 514;
groupmap[2].gidNumber = 514;
groupmap[2].sambaSID = talloc_asprintf(mem_ctx, "%s-514", sid);
groupmap[2].group_dn = talloc_asprintf(mem_ctx,
"cn=Domain Guests,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[2].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[2].group_dn);
+ if (groupmap[2].sambaSID == NULL || groupmap[2].group_dn == NULL) {
+ goto err;
+ }
accountmap[2].rid = 514;
accountmap[2].cn = talloc_strdup(mem_ctx, "Domain Guests");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[2].cn);
+ if (accountmap[2].cn == NULL) {
+ goto err;
+ }
groupmap[3].rid = 515;
groupmap[3].gidNumber = 515;
groupmap[3].sambaSID = talloc_asprintf(mem_ctx, "%s-515", sid);
groupmap[3].group_dn = talloc_asprintf(mem_ctx,
"cn=Domain Computers,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[3].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[3].group_dn);
+ if (groupmap[3].sambaSID == NULL || groupmap[3].group_dn == NULL) {
+ goto err;
+ }
accountmap[3].rid = 515;
accountmap[3].cn = talloc_strdup(mem_ctx, "Domain Computers");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[3].cn);
+ if (accountmap[3].cn == NULL) {
+ goto err;
+ }
groupmap[4].rid = 544;
groupmap[4].gidNumber = 544;
groupmap[4].sambaSID = talloc_asprintf(mem_ctx, "%s-544", builtin_sid);
groupmap[4].group_dn = talloc_asprintf(mem_ctx,
"cn=Administrators,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[4].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[4].group_dn);
+ if (groupmap[4].sambaSID == NULL || groupmap[4].group_dn == NULL) {
+ goto err;
+ }
accountmap[4].rid = 515;
accountmap[4].cn = talloc_strdup(mem_ctx, "Administrators");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[4].cn);
+ if (accountmap[4].cn == NULL) {
+ goto err;
+ }
groupmap[5].rid = 550;
groupmap[5].gidNumber = 550;
groupmap[5].sambaSID = talloc_asprintf(mem_ctx, "%s-550", builtin_sid);
groupmap[5].group_dn = talloc_asprintf(mem_ctx,
"cn=Print Operators,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[5].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[5].group_dn);
+ if (groupmap[5].sambaSID == NULL || groupmap[5].group_dn == NULL) {
+ goto err;
+ }
accountmap[5].rid = 550;
accountmap[5].cn = talloc_strdup(mem_ctx, "Print Operators");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[5].cn);
+ if (accountmap[5].cn == NULL) {
+ goto err;
+ }
groupmap[6].rid = 551;
groupmap[6].gidNumber = 551;
groupmap[6].sambaSID = talloc_asprintf(mem_ctx, "%s-551", builtin_sid);
groupmap[6].group_dn = talloc_asprintf(mem_ctx,
"cn=Backup Operators,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[6].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[6].group_dn);
+ if (groupmap[6].sambaSID == NULL || groupmap[6].group_dn == NULL) {
+ goto err;
+ }
accountmap[6].rid = 551;
accountmap[6].cn = talloc_strdup(mem_ctx, "Backup Operators");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[6].cn);
+ if (accountmap[6].cn == NULL) {
+ goto err;
+ }
groupmap[7].rid = 552;
groupmap[7].gidNumber = 552;
groupmap[7].sambaSID = talloc_asprintf(mem_ctx, "%s-552", builtin_sid);
groupmap[7].group_dn = talloc_asprintf(mem_ctx,
"cn=Replicators,ou=%s,%s", group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[7].sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap[7].group_dn);
+ if (groupmap[7].sambaSID == NULL || groupmap[7].group_dn == NULL) {
+ goto err;
+ }
accountmap[7].rid = 551;
accountmap[7].cn = talloc_strdup(mem_ctx, "Replicators");
- NT_STATUS_HAVE_NO_MEMORY(accountmap[7].cn);
+ if (accountmap[7].cn == NULL) {
+ goto err;
+ }
SAFE_FREE(group_attr);
return NT_STATUS_OK;
+
+ err:
+
+ SAFE_FREE(group_attr);
+ return NT_STATUS_NO_MEMORY;
}
/*
@@ -542,8 +571,10 @@ static NTSTATUS fetch_group_info_to_ldif(TALLOC_CTX *mem_ctx,
groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
groupmap->group_dn = talloc_asprintf(mem_ctx,
"cn=%s,ou=%s,%s", groupname, group_attr, suffix);
- NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
- NT_STATUS_HAVE_NO_MEMORY(groupmap->group_dn);
+ if (groupmap->sambaSID == NULL || groupmap->group_dn == NULL) {
+ SAFE_FREE(group_attr);
+ return NT_STATUS_NO_MEMORY;
+ }
/* Write the data to the temporary add ldif file */
fprintf(add_fd, "# %s, %s, %s\n", groupname, group_attr,
@@ -776,7 +807,10 @@ static NTSTATUS fetch_alias_info_to_ldif(TALLOC_CTX *mem_ctx,
g_rid = r->rid;
groupmap->gidNumber = ldif_gid;
groupmap->sambaSID = talloc_asprintf(mem_ctx, "%s-%d", sid, g_rid);
- NT_STATUS_HAVE_NO_MEMORY(groupmap->sambaSID);
+ if (groupmap->sambaSID == NULL) {
+ SAFE_FREE(group_attr);
+ return NT_STATUS_NO_MEMORY;
+ }
/* Write the data to the temporary add ldif file */
fprintf(add_fd, "# %s, %s, %s\n", aliasname, group_attr,
diff --git a/source3/librpc/ndr/ndr_string.c b/source3/librpc/ndr/ndr_string.c
index 86d7b26586..985d0f4daa 100644
--- a/source3/librpc/ndr/ndr_string.c
+++ b/source3/librpc/ndr/ndr_string.c
@@ -595,6 +595,29 @@ _PUBLIC_ void ndr_print_string_array(struct ndr_print *ndr, const char *name, co
ndr->depth--;
}
+_PUBLIC_ size_t ndr_size_string_array(const char **a, uint32_t count, int flags)
+{
+ uint32_t i;
+ size_t size = 0;
+
+ switch (flags & LIBNDR_STRING_FLAGS) {
+ case LIBNDR_FLAG_STR_NULLTERM:
+ for (i = 0; i < count; i++) {
+ size += strlen_m_term(a[i]);
+ }
+ break;
+ case LIBNDR_FLAG_STR_NOTERM:
+ for (i = 0; i < count; i++) {
+ size += strlen_m(a[i]);
+ }
+ break;
+ default:
+ return 0;
+ }
+
+ return size;
+}
+
/**
* Return number of elements in a string including the last (zeroed) element
*/
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index a1fcf8eb07..e579d1c9f0 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -152,32 +152,6 @@ bool cli_in_chain(struct cli_state *cli)
}
/**
- * Is the SMB command able to hold an AND_X successor
- * @param[in] cmd The SMB command in question
- * @retval Can we add a chained request after "cmd"?
- */
-
-static bool is_andx_req(uint8_t cmd)
-{
- switch (cmd) {
- case SMBtconX:
- case SMBlockingX:
- case SMBopenX:
- case SMBreadX:
- case SMBwriteX:
- case SMBsesssetupX:
- case SMBulogoffX:
- case SMBntcreateX:
- return true;
- break;
- default:
- break;
- }
-
- return false;
-}
-
-/**
* @brief Find the smb_cmd offset of the last command pushed
* @param[in] buf The buffer we're building up
* @retval Where can we put our next andx cmd?
@@ -1005,7 +979,7 @@ static void handle_incoming_pdu(struct cli_state *cli)
nt_errstr(status)));
for (req = cli->outstanding_requests; req; req = req->next) {
- async_req_error(req->async[0], status);
+ async_req_nterror(req->async[0], status);
}
return;
}
@@ -1022,7 +996,7 @@ static void cli_state_handler(struct event_context *event_ctx,
struct fd_event *event, uint16 flags, void *p)
{
struct cli_state *cli = (struct cli_state *)p;
- struct cli_request *req;
+ struct cli_request *req, *next;
NTSTATUS status;
DEBUG(11, ("cli_state_handler called with flags %d\n", flags));
@@ -1128,10 +1102,15 @@ static void cli_state_handler(struct event_context *event_ctx,
return;
sock_error:
- for (req = cli->outstanding_requests; req; req = req->next) {
- int i;
- for (i=0; i<req->num_async; i++) {
- async_req_error(req->async[i], status);
+
+ for (req = cli->outstanding_requests; req; req = next) {
+ int i, num_async;
+
+ next = req->next;
+ num_async = req->num_async;
+
+ for (i=0; i<num_async; i++) {
+ async_req_nterror(req->async[i], status);
}
}
TALLOC_FREE(cli->fd_event);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index bc690f2e02..a39e035d2a 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -161,50 +161,79 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
Do a NT1 guest session setup.
****************************************************************************/
-static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
+struct async_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli)
{
- char *p;
- uint32 capabilities = cli_session_setup_capabilities(cli);
+ struct async_req *result;
+ uint16_t vwv[13];
+ uint8_t *bytes;
- memset(cli->outbuf, '\0', smb_size);
- cli_set_message(cli->outbuf,13,0,True);
- SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
- cli_setup_packet(cli);
-
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
- SSVAL(cli->outbuf,smb_vwv3,2);
- SSVAL(cli->outbuf,smb_vwv4,cli->pid);
- SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
- SSVAL(cli->outbuf,smb_vwv7,0);
- SSVAL(cli->outbuf,smb_vwv8,0);
- SIVAL(cli->outbuf,smb_vwv11,capabilities);
- p = smb_buf(cli->outbuf);
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
- cli_setup_bcc(cli, p);
+ SCVAL(vwv+0, 0, 0xFF);
+ SCVAL(vwv+0, 1, 0);
+ SSVAL(vwv+1, 0, 0);
+ SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
+ SSVAL(vwv+3, 0, 2);
+ SSVAL(vwv+4, 0, cli->pid);
+ SIVAL(vwv+5, 0, cli->sesskey);
+ SSVAL(vwv+7, 0, 0);
+ SSVAL(vwv+8, 0, 0);
+ SSVAL(vwv+9, 0, 0);
+ SSVAL(vwv+10, 0, 0);
+ SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
+
+ bytes = talloc_array(talloc_tos(), uint8_t, 0);
+
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
+ NULL);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
+ NULL);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix",
+ strlen("Unix")+1, NULL);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba",
+ strlen("Samba")+1, NULL);
+
+ if (bytes == NULL) {
+ return NULL;
+ }
+
+ result = cli_request_send(mem_ctx, ev, cli, SMBsesssetupX, 0,
+ 13, vwv, 0, talloc_get_size(bytes), bytes);
+ TALLOC_FREE(bytes);
+ return result;
+}
- if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
- return cli_nt_error(cli);
+NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
+{
+ struct cli_request *cli_req = talloc_get_type_abort(
+ req->private_data, struct cli_request);
+ struct cli_state *cli = cli_req->cli;
+ uint8_t wct;
+ uint16_t *vwv;
+ uint16_t num_bytes;
+ uint8_t *bytes;
+ uint8_t *p;
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
}
-
- show_msg(cli->inbuf);
-
- if (cli_is_error(cli)) {
- return cli_nt_error(cli);
+
+ status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- cli->vuid = SVAL(cli->inbuf,smb_uid);
+ p = bytes;
- p = smb_buf(cli->inbuf);
- p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
- -1, STR_TERMINATE);
- p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
- -1, STR_TERMINATE);
- p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
- -1, STR_TERMINATE);
+ cli->vuid = SVAL(cli_req->inbuf, smb_uid);
+
+ p += clistr_pull(cli_req->inbuf, cli->server_os, (char *)p,
+ sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
+ p += clistr_pull(cli_req->inbuf, cli->server_type, (char *)p,
+ sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
+ p += clistr_pull(cli_req->inbuf, cli->server_domain, (char *)p,
+ sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
@@ -215,6 +244,43 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
return NT_STATUS_OK;
}
+static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ if (cli->fd_event != NULL) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_session_setup_guest_send(frame, ev, cli);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = cli_session_setup_guest_recv(req);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
/****************************************************************************
Do a NT1 plaintext session setup.
****************************************************************************/
@@ -1107,13 +1173,17 @@ bool cli_ulogoff(struct cli_state *cli)
Send a tconX.
****************************************************************************/
-bool cli_send_tconX(struct cli_state *cli,
- const char *share, const char *dev, const char *pass, int passlen)
+struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *share, const char *dev,
+ const char *pass, int passlen)
{
- fstring fullshare, pword;
- char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ fstring pword;
+ char *tmp = NULL;
+ struct async_req *result;
+ uint16_t vwv[4];
+ uint8_t *bytes;
fstrcpy(cli->share, share);
@@ -1121,9 +1191,10 @@ bool cli_send_tconX(struct cli_state *cli,
if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
passlen = 1;
pass = "";
- } else if (!pass) {
- DEBUG(1, ("Server not using user level security and no password supplied.\n"));
- return False;
+ } else if (pass == NULL) {
+ DEBUG(1, ("Server not using user level security and no "
+ "password supplied.\n"));
+ goto access_denied;
}
if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
@@ -1132,28 +1203,36 @@ bool cli_send_tconX(struct cli_state *cli,
DEBUG(1, ("Server requested LANMAN password "
"(share-level security) but "
"'client lanman auth' is disabled\n"));
- return False;
+ goto access_denied;
}
/*
- * Non-encrypted passwords - convert to DOS codepage before encryption.
+ * Non-encrypted passwords - convert to DOS codepage before
+ * encryption.
*/
passlen = 24;
- SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
+ SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
} else {
- if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
+ if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
+ |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
+ == 0) {
if (!lp_client_plaintext_auth() && (*pass)) {
DEBUG(1, ("Server requested plaintext "
"password but 'client plaintext "
"auth' is disabled\n"));
- return False;
+ goto access_denied;
}
/*
- * Non-encrypted passwords - convert to DOS codepage before using.
+ * Non-encrypted passwords - convert to DOS codepage
+ * before using.
*/
- passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
-
+ passlen = clistr_push(cli, pword, pass, sizeof(pword),
+ STR_TERMINATE);
+ if (passlen == -1) {
+ DEBUG(1, ("clistr_push(pword) failed\n"));
+ goto access_denied;
+ }
} else {
if (passlen) {
memcpy(pword, pass, passlen);
@@ -1161,52 +1240,139 @@ bool cli_send_tconX(struct cli_state *cli,
}
}
- slprintf(fullshare, sizeof(fullshare)-1,
- "\\\\%s\\%s", cli->desthost, share);
+ SCVAL(vwv+0, 0, 0xFF);
+ SCVAL(vwv+0, 1, 0);
+ SSVAL(vwv+1, 0, 0);
+ SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
+ SSVAL(vwv+3, 0, passlen);
- cli_set_message(cli->outbuf,4, 0, True);
- SCVAL(cli->outbuf,smb_com,SMBtconX);
- cli_setup_packet(cli);
+ if (passlen) {
+ bytes = (uint8_t *)talloc_memdup(talloc_tos(), pword, passlen);
+ } else {
+ bytes = talloc_array(talloc_tos(), uint8_t, 0);
+ }
- SSVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
- SSVAL(cli->outbuf,smb_vwv3,passlen);
+ /*
+ * Add the sharename
+ */
+ tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
+ cli->desthost, share);
+ if (tmp == NULL) {
+ TALLOC_FREE(bytes);
+ return NULL;
+ }
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
+ NULL);
+ TALLOC_FREE(tmp);
- p = smb_buf(cli->outbuf);
- if (passlen) {
- memcpy(p,pword,passlen);
+ /*
+ * Add the devicetype
+ */
+ tmp = talloc_strdup_upper(talloc_tos(), dev);
+ if (tmp == NULL) {
+ TALLOC_FREE(bytes);
+ return NULL;
}
- p += passlen;
- p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
- p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
+ bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
+ TALLOC_FREE(tmp);
- cli_setup_bcc(cli, p);
+ if (bytes == NULL) {
+ return NULL;
+ }
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ result = cli_request_send(mem_ctx, ev, cli, SMBtconX, 0,
+ 4, vwv, 0, talloc_get_size(bytes), bytes);
+ TALLOC_FREE(bytes);
+ return result;
- if (cli_is_error(cli))
- return False;
+ access_denied:
+ result = async_req_new(mem_ctx);
+ if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
+ return result;
+ }
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+NTSTATUS cli_tcon_andx_recv(struct async_req *req)
+{
+ struct cli_request *cli_req = talloc_get_type_abort(
+ req->private_data, struct cli_request);
+ struct cli_state *cli = cli_req->cli;
+ uint8_t wct;
+ uint16_t *vwv;
+ uint16_t num_bytes;
+ uint8_t *bytes;
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
- clistr_pull(cli->inbuf, cli->dev, smb_buf(cli->inbuf), sizeof(fstring),
- -1, STR_TERMINATE|STR_ASCII);
+ status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ clistr_pull(cli_req->inbuf, cli->dev, bytes, sizeof(fstring),
+ num_bytes, STR_TERMINATE|STR_ASCII);
- if (cli->protocol >= PROTOCOL_NT1 &&
- smb_buflen(cli->inbuf) == 3) {
+ if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
/* almost certainly win95 - enable bug fixes */
cli->win95 = True;
}
- /* Make sure that we have the optional support 16-bit field. WCT > 2 */
- /* Avoids issues when connecting to Win9x boxes sharing files */
+ /*
+ * Make sure that we have the optional support 16-bit field. WCT > 2.
+ * Avoids issues when connecting to Win9x boxes sharing files
+ */
+
+ cli->dfsroot = false;
- cli->dfsroot = False;
- if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
- cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
+ if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
+ cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
+ }
- cli->cnum = SVAL(cli->inbuf,smb_tid);
- return True;
+ cli->cnum = SVAL(cli_req->inbuf,smb_tid);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
+ const char *dev, const char *pass, int passlen)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ if (cli->fd_event != NULL) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = cli_tcon_andx_recv(req);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
}
/****************************************************************************
@@ -1294,7 +1460,10 @@ struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
if (bytes == NULL) {
return NULL;
}
- bytes = smb_bytes_push_str(bytes, false, prots[numprots].name);
+ bytes = smb_bytes_push_str(bytes, false,
+ prots[numprots].name,
+ strlen(prots[numprots].name)+1,
+ NULL);
if (bytes == NULL) {
return NULL;
}
@@ -1318,7 +1487,7 @@ NTSTATUS cli_negprot_recv(struct async_req *req)
NTSTATUS status;
uint16_t protnum;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -1887,8 +2056,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
}
if (service) {
- if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
- nt_status = cli_nt_error(cli);
+ nt_status = cli_tcon_andx(cli, service, service_type, password,
+ pw_len);
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
cli_shutdown(cli);
if (NT_STATUS_IS_OK(nt_status)) {
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index f853e4e670..e642f169f9 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -275,9 +275,10 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
/* must be a normal share */
- if (!cli_send_tconX(c, sharename, "?????",
- password, strlen(password)+1)) {
- d_printf("tree connect failed: %s\n", cli_errstr(c));
+ status = cli_tcon_andx(c, sharename, "?????",
+ password, strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("tree connect failed: %s\n", nt_errstr(status));
cli_shutdown(c);
return NULL;
}
@@ -1077,7 +1078,7 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
/* check for the referral */
- if (!cli_send_tconX(cli, "IPC$", "IPC", NULL, 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, "IPC$", "IPC", NULL, 0))) {
return false;
}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 0bec24202c..0382ef5fae 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -56,6 +56,16 @@ void cli_set_port(struct cli_state *cli, int port)
}
/****************************************************************************
+ convenience routine to find if we negotiated ucs2
+****************************************************************************/
+
+bool cli_ucs2(struct cli_state *cli)
+{
+ return ((cli->capabilities & CAP_UNICODE) != 0);
+}
+
+
+/****************************************************************************
Read an smb from a fd ignoring all keepalive packets.
The timeout is in milliseconds
@@ -640,7 +650,7 @@ static void cli_echo_recv_helper(struct async_req *req)
status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -649,7 +659,7 @@ static void cli_echo_recv_helper(struct async_req *req)
if ((num_bytes != cli_req->data.echo.data.length)
|| (memcmp(cli_req->data.echo.data.data, bytes,
num_bytes) != 0)) {
- async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
@@ -717,7 +727,7 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
NTSTATUS cli_echo_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
/**
@@ -765,3 +775,28 @@ NTSTATUS cli_echo(struct cli_state *cli, uint16_t num_echos, DATA_BLOB data)
TALLOC_FREE(frame);
return status;
}
+
+/**
+ * Is the SMB command able to hold an AND_X successor
+ * @param[in] cmd The SMB command in question
+ * @retval Can we add a chained request after "cmd"?
+ */
+bool is_andx_req(uint8_t cmd)
+{
+ switch (cmd) {
+ case SMBtconX:
+ case SMBlockingX:
+ case SMBopenX:
+ case SMBreadX:
+ case SMBwriteX:
+ case SMBsesssetupX:
+ case SMBulogoffX:
+ case SMBntcreateX:
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 02cd2108bf..0703f04c5f 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -771,6 +771,138 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
return SVAL(cli->inbuf,smb_vwv2 + 1);
}
+struct async_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ uint32_t CreatFlags,
+ uint32_t DesiredAccess,
+ uint32_t FileAttributes,
+ uint32_t ShareAccess,
+ uint32_t CreateDisposition,
+ uint32_t CreateOptions,
+ uint8_t SecurityFlags)
+{
+ struct async_req *result;
+ uint8_t *bytes;
+ size_t converted_len;
+ uint16_t vwv[24];
+
+ SCVAL(vwv+0, 0, 0xFF);
+ SCVAL(vwv+0, 1, 0);
+ SSVAL(vwv+1, 0, 0);
+ SCVAL(vwv+2, 0, 0);
+
+ if (cli->use_oplocks) {
+ CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
+ }
+ SIVAL(vwv+3, 1, CreatFlags);
+ SIVAL(vwv+5, 1, 0x0); /* RootDirectoryFid */
+ SIVAL(vwv+7, 1, DesiredAccess);
+ SIVAL(vwv+9, 1, 0x0); /* AllocationSize */
+ SIVAL(vwv+11, 1, 0x0); /* AllocationSize */
+ SIVAL(vwv+13, 1, FileAttributes);
+ SIVAL(vwv+15, 1, ShareAccess);
+ SIVAL(vwv+17, 1, CreateDisposition);
+ SIVAL(vwv+19, 1, CreateOptions);
+ SIVAL(vwv+21, 1, 0x02); /* ImpersonationLevel */
+ SCVAL(vwv+23, 1, SecurityFlags);
+
+ bytes = talloc_array(talloc_tos(), uint8_t, 0);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
+ fname, strlen(fname)+1,
+ &converted_len);
+
+ /* sigh. this copes with broken netapp filer behaviour */
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, NULL);
+
+ if (bytes == NULL) {
+ return NULL;
+ }
+
+ SIVAL(vwv+2, 1, converted_len);
+
+ result = cli_request_send(mem_ctx, ev, cli, SMBntcreateX, 0,
+ 24, vwv, 0, talloc_get_size(bytes), bytes);
+ TALLOC_FREE(bytes);
+ return result;
+}
+
+NTSTATUS cli_ntcreate_recv(struct async_req *req, uint16_t *pfnum)
+{
+ uint8_t wct;
+ uint16_t *vwv;
+ uint16_t num_bytes;
+ uint8_t *bytes;
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (wct < 3) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ *pfnum = SVAL(vwv+2, 1);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_ntcreate(struct cli_state *cli,
+ const char *fname,
+ uint32_t CreatFlags,
+ uint32_t DesiredAccess,
+ uint32_t FileAttributes,
+ uint32_t ShareAccess,
+ uint32_t CreateDisposition,
+ uint32_t CreateOptions,
+ uint8_t SecurityFlags,
+ uint16_t *pfid)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ if (cli->fd_event != NULL) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_ntcreate_send(frame, ev, cli, fname, CreatFlags,
+ DesiredAccess, FileAttributes, ShareAccess,
+ CreateDisposition, CreateOptions,
+ SecurityFlags);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = cli_ntcreate_recv(req, pfid);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
/****************************************************************************
Open a file.
****************************************************************************/
@@ -781,7 +913,9 @@ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0);
}
-uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str)
+uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
+ const char *str, size_t str_len,
+ size_t *pconverted_size)
{
size_t buflen;
char *converted;
@@ -806,7 +940,7 @@ uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str)
if (!convert_string_allocate(talloc_tos(), CH_UNIX,
ucs2 ? CH_UTF16LE : CH_DOS,
- str, strlen(str)+1, &converted,
+ str, str_len, &converted,
&converted_size, true)) {
return NULL;
}
@@ -821,6 +955,11 @@ uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str)
memcpy(buf + buflen, converted, converted_size);
TALLOC_FREE(converted);
+
+ if (pconverted_size) {
+ *pconverted_size = converted_size;
+ }
+
return buf;
}
@@ -890,12 +1029,8 @@ struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
bytes = talloc_array(talloc_tos(), uint8_t, 0);
- if (bytes == NULL) {
- return NULL;
- }
-
- bytes = smb_bytes_push_str(
- bytes, (cli->capabilities & CAP_UNICODE) != 0, fname);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
+ strlen(fname)+1, NULL);
if (bytes == NULL) {
return NULL;
}
@@ -914,7 +1049,7 @@ NTSTATUS cli_open_recv(struct async_req *req, int *fnum)
uint8_t *bytes;
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -992,7 +1127,7 @@ NTSTATUS cli_close_recv(struct async_req *req)
uint8_t *bytes;
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 1ba93d827d..9d17ff86a5 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -148,7 +148,7 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received,
NTSTATUS status;
size_t size;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -297,7 +297,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx,
state->top_req = 0;
if (size == 0) {
- if (!async_post_status(result, ev, NT_STATUS_OK)) {
+ if (!async_post_ntstatus(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
@@ -367,7 +367,7 @@ static void cli_pull_read_done(struct async_req *read_req)
status = cli_read_andx_recv(read_req, &read_state->data.read.received,
&read_state->data.read.rcvbuf);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(state->req, status);
+ async_req_nterror(state->req, status);
return;
}
@@ -404,7 +404,7 @@ static void cli_pull_read_done(struct async_req *read_req)
top_read->data.read.received,
state->priv);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(state->req, status);
+ async_req_nterror(state->req, status);
return;
}
state->pushed += top_read->data.read.received;
@@ -455,7 +455,7 @@ NTSTATUS cli_pull_recv(struct async_req *req, SMB_OFF_T *received)
req->private_data, struct cli_pull_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*received = state->pushed;
@@ -792,7 +792,7 @@ NTSTATUS cli_write_andx_recv(struct async_req *req, size_t *pwritten)
NTSTATUS status;
size_t written;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -879,14 +879,14 @@ static void cli_writeall_written(struct async_req *subreq)
status = cli_write_andx_recv(subreq, &written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
state->written += written;
if (state->written > state->size) {
- async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
@@ -902,7 +902,7 @@ static void cli_writeall_written(struct async_req *subreq)
state->buf + state->written,
state->offset + state->written, to_write);
if (subreq == NULL) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -912,7 +912,7 @@ static void cli_writeall_written(struct async_req *subreq)
static NTSTATUS cli_writeall_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
struct cli_push_state {
@@ -1018,7 +1018,7 @@ struct async_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
}
if (i == 0) {
- if (!async_post_status(result, ev, NT_STATUS_OK)) {
+ if (!async_post_ntstatus(result, ev, NT_STATUS_OK)) {
goto failed;
}
return result;
@@ -1047,7 +1047,7 @@ static void cli_push_written(struct async_req *req)
}
if (i == state->num_reqs) {
- async_req_error(state->req, NT_STATUS_INTERNAL_ERROR);
+ async_req_nterror(state->req, NT_STATUS_INTERNAL_ERROR);
return;
}
@@ -1055,7 +1055,7 @@ static void cli_push_written(struct async_req *req)
TALLOC_FREE(state->reqs[i]);
req = NULL;
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(state->req, status);
+ async_req_nterror(state->req, status);
return;
}
@@ -1081,7 +1081,7 @@ static void cli_push_written(struct async_req *req)
state->reqs, state->ev, state->cli, state->fnum,
state->mode, buf, state->start_offset + state->sent, to_write);
if (state->reqs[i] == NULL) {
- async_req_error(state->req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(state->req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1094,7 +1094,7 @@ static void cli_push_written(struct async_req *req)
NTSTATUS cli_push_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode,
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index baa73aeb14..69e2be3af7 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -765,9 +765,9 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx,
if (bytes == NULL) {
goto fail;
}
- bytes = smb_bytes_push_str(
- bytes, (state->cli->capabilities & CAP_UNICODE) != 0,
- state->pipe_name);
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(state->cli),
+ state->pipe_name,
+ strlen(state->pipe_name)+1, NULL);
if (bytes == NULL) {
goto fail;
}
@@ -962,7 +962,7 @@ static void cli_trans_ship_rest(struct async_req *req,
{
state->secondary_request_ctx = talloc_new(state);
if (state->secondary_request_ctx == NULL) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -972,7 +972,7 @@ static void cli_trans_ship_rest(struct async_req *req,
cli_req = cli_ship_trans(state->secondary_request_ctx, state);
if (cli_req == NULL) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
}
@@ -1133,7 +1133,7 @@ static void cli_trans_recv_helper(struct async_req *req)
*/
if (NT_STATUS_IS_ERR(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1154,7 +1154,7 @@ static void cli_trans_recv_helper(struct async_req *req)
state->rsetup = (uint16_t *)TALLOC_MEMDUP(
state, setup, sizeof(uint16_t) * num_setup);
if (state->rsetup == NULL) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
}
@@ -1165,7 +1165,7 @@ static void cli_trans_recv_helper(struct async_req *req)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("Pulling params failed: %s\n", nt_errstr(status)));
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1175,7 +1175,7 @@ static void cli_trans_recv_helper(struct async_req *req)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("Pulling data failed: %s\n", nt_errstr(status)));
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1318,7 +1318,7 @@ NTSTATUS cli_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
cli_req->recv_helper.priv, struct cli_trans_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c
index 9d33e6d93d..9ba460f869 100644
--- a/source3/libsmb/credentials.c
+++ b/source3/libsmb/credentials.c
@@ -146,7 +146,7 @@ static void creds_init_64(struct dcinfo *dc,
static void creds_step(struct dcinfo *dc)
{
- DOM_CHAL time_chal;
+ struct netr_Credential time_chal;
DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence ));
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 0ece5bb649..6d7a86241a 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -300,11 +300,11 @@ SMBC_server(TALLOC_CTX *ctx,
* tid.
*/
- if (!cli_send_tconX(srv->cli, share, "?????",
- *pp_password,
- strlen(*pp_password)+1)) {
-
- errno = SMBC_errno(context, srv->cli);
+ status = cli_tcon_andx(srv->cli, share, "?????",
+ *pp_password,
+ strlen(*pp_password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
cli_shutdown(srv->cli);
srv->cli = NULL;
smbc_getFunctionRemoveCachedServer(context)(context,
@@ -501,9 +501,10 @@ again:
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- *pp_password, strlen(*pp_password)+1)) {
- errno = SMBC_errno(context, c);
+ status = cli_tcon_andx(c, share, "?????", *pp_password,
+ strlen(*pp_password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
cli_shutdown(c);
return NULL;
}
diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
index ba706e5ee2..d3230cffef 100644
--- a/source3/libsmb/namecache.c
+++ b/source3/libsmb/namecache.c
@@ -62,27 +62,6 @@ bool namecache_enable(void)
}
/**
- * Shutdown namecache. Routine calls gencache close function
- * to safely close gencache file.
- *
- * @return true upon successful shutdown of the cache or
- * false on failure
- **/
-
-bool namecache_shutdown(void)
-{
- if (!gencache_shutdown()) {
- DEBUG(2, ("namecache_shutdown: "
- "Couldn't close namecache on top of gencache.\n"));
- return False;
- }
-
- DEBUG(5, ("namecache_shutdown: "
- "netbios namecache closed successfully.\n"));
- return True;
-}
-
-/**
* Generates a key for netbios name lookups on basis of
* netbios name and type.
* The caller must free returned key string when finished.
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 05679570d4..ac38d40271 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1502,7 +1502,7 @@ NTSTATUS internal_resolve_name(const char *name,
*return_count = 0;
DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
- name, name_type, sitename ? sitename : NULL));
+ name, name_type, sitename ? sitename : "(null)"));
if (is_ipaddress(name)) {
if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index 76b06088d6..f9ff4b3191 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -138,13 +138,13 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
cli_init_creds(cli, user_name, "", old_passwd);
}
- if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
- if (asprintf(err_str, "machine %s rejected the tconX on the IPC$ "
- "share. Error was : %s.\n",
- remote_machine, cli_errstr(cli)) == -1) {
+ result = cli_tcon_andx(cli, "IPC$", "IPC", "", 1);
+ if (!NT_STATUS_IS_OK(result)) {
+ if (asprintf(err_str, "machine %s rejected the tconX on the "
+ "IPC$ share. Error was : %s.\n",
+ remote_machine, nt_errstr(result))) {
*err_str = NULL;
}
- result = cli_nt_error(cli);
cli_shutdown(cli);
return result;
}
diff --git a/source3/m4/check_path.m4 b/source3/m4/check_path.m4
index 444ea1c401..0a61733870 100644
--- a/source3/m4/check_path.m4
+++ b/source3/m4/check_path.m4
@@ -215,19 +215,6 @@ AC_ARG_WITH(logfilebase,
#################################################
-# set ctdb source directory location
-AC_ARG_WITH(ctdb,
-[AS_HELP_STRING([--with-ctdb=DIR], [Where to find ctdb sources])],
-[ case "$withval" in
- yes|no)
- AC_MSG_WARN([--with-ctdb called without argument])
- ;;
- * )
- ctdbdir="$withval"
- ;;
- esac])
-
-#################################################
# set shared modules (internal lib) directory location
AC_ARG_WITH(modulesdir,
[AS_HELP_STRING([--with-modulesdir=DIR], [Where to put shared modules ($libdir)])],
@@ -297,7 +284,6 @@ AC_SUBST(lockdir)
AC_SUBST(piddir)
AC_SUBST(ncalrpcdir)
AC_SUBST(logfilebase)
-AC_SUBST(ctdbdir)
AC_SUBST(privatedir)
AC_SUBST(swatdir)
AC_SUBST(bindir)
@@ -337,7 +323,7 @@ AC_ARG_WITH(selftest-shrdir,
AC_MSG_WARN([--with-selftest-shrdir called without argument - will use default])
;;
* )
- selftest_shrdir="$withval"
+ selftest_shrdir="-s $withval"
;;
esac
])
@@ -346,6 +332,8 @@ AC_ARG_WITH(selftest-shrdir,
# set path of samba4's smbtorture
smbtorture4_path=""
AC_SUBST(smbtorture4_path)
+smbtorture4_option=""
+AC_SUBST(smbtorture4_option)
AC_ARG_WITH(smbtorture4_path,
[AS_HELP_STRING([--with-smbtorture4-path=PATH], [The path to a samba4 smbtorture for make test (none)])],
[ case "$withval" in
@@ -357,6 +345,27 @@ AC_ARG_WITH(smbtorture4_path,
if test -z "$smbtorture4_path" -a ! -f $smbtorture4_path; then
AC_MSG_ERROR(['$smbtorture_path' does not exist!])
fi
+ smbtorture4_option="-t $withval"
+ ;;
+ esac
+])
+
+#################################################
+# set custom conf for make test
+selftest_custom_conf=""
+AC_SUBST(selftest_custom_conf)
+AC_ARG_WITH(selftest_custom_conf,
+[AS_HELP_STRING([--with-selftest-custom-conf=PATH], [An optional custom smb.conf that is included in the server smb.conf during make test(none)])],
+[ case "$withval" in
+ yes|no)
+ AC_MSG_ERROR([--with-selftest-custom-conf should take a path])
+ ;;
+ * )
+ selftest_custom_conf="$withval"
+ if test -z "$selftest_custom_conf" -a ! -f $selftest_custom_conf; then
+ AC_MSG_ERROR(['$selftest_custom_conf' does not exist!])
+ fi
+ selftest_custom_conf="-c $withval"
;;
esac
])
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index b9ec2d68e0..14b27b80e0 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -667,7 +667,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
}
error = ifs_get_security_descriptor(fsp->fh->fd, security_info,
- &sd_size, sd);
+ sd_size, &sd_size, sd);
if (error && (errno != EMSGSIZE)) {
DEBUG(0, ("Failed getting size of security descriptor! "
"errno=%d\n", errno));
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index e9543e237f..78b0fd61bf 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -533,8 +533,8 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
if (!add_one_stream(state->mem_ctx,
&state->num_streams, &state->streams,
dp->d_name, stream_sbuf.st_size,
- get_allocation_size(conn, NULL,
- &stream_sbuf))) {
+ SMB_VFS_GET_ALLOC_SIZE(conn, NULL,
+ &stream_sbuf))) {
state->status = NT_STATUS_NO_MEMORY;
break;
}
@@ -594,8 +594,8 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
"", sbuf.st_size,
- get_allocation_size(handle->conn, fsp,
- &sbuf))) {
+ SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
+ &sbuf))) {
return NT_STATUS_NO_MEMORY;
}
}
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index 30b14f280f..e29ce5e7a8 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -406,8 +406,7 @@ static void handle_aio_completion(struct event_context *event_ctx,
DEBUG(10, ("mid %d finished\n", (int)mid));
- aio_request_done(mid);
- process_aio_queue();
+ smbd_aio_complete_mid(mid);
}
static int aio_child_destructor(struct aio_child *child)
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index a9aabab768..679be57558 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -551,6 +551,39 @@ int vfswrap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT
return result;
}
+/********************************************************************
+ Given a stat buffer return the allocated size on disk, taking into
+ account sparse files.
+********************************************************************/
+static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const SMB_STRUCT_STAT *sbuf)
+{
+ uint64_t result;
+
+ START_PROFILE(syscall_get_alloc_size);
+
+ if(S_ISDIR(sbuf->st_mode)) {
+ result = 0;
+ goto out;
+ }
+
+#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
+ result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
+#else
+ result = get_file_size_stat(sbuf);
+#endif
+
+ if (fsp && fsp->initial_allocation_size)
+ result = MAX(result,fsp->initial_allocation_size);
+
+ result = smb_roundup(handle->conn, result);
+
+ out:
+ END_PROFILE(syscall_get_alloc_size);
+ return result;
+}
+
static int vfswrap_unlink(vfs_handle_struct *handle, const char *path)
{
int result;
@@ -702,7 +735,7 @@ static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
struct utimbuf times;
times.actime = convert_timespec_to_time_t(ft->atime);
times.modtime = convert_timespec_to_time_t(ft->mtime);
- result = utime(path, times);
+ result = utime(path, &times);
} else {
result = utime(path, NULL);
}
@@ -1043,7 +1076,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
}
streams->size = sbuf.st_size;
- streams->alloc_size = get_allocation_size(handle->conn, fsp, &sbuf);
+ streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
streams->name = talloc_strdup(streams, "::$DATA");
if (streams->name == NULL) {
@@ -1443,6 +1476,8 @@ static vfs_op_tuple vfs_default_ops[] = {
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_lstat), SMB_VFS_OP_LSTAT,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_chmod), SMB_VFS_OP_CHMOD,
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 73758a2d9d..c6d62fdd87 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -155,6 +155,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf);
static int smb_full_audit_lstat(vfs_handle_struct *handle,
const char *path, SMB_STRUCT_STAT *sbuf);
+static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
+ files_struct *fsp, const SMB_STRUCT_STAT *sbuf);
static int smb_full_audit_unlink(vfs_handle_struct *handle,
const char *path);
static int smb_full_audit_chmod(vfs_handle_struct *handle,
@@ -403,6 +405,8 @@ static vfs_op_tuple audit_op_tuples[] = {
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_lstat), SMB_VFS_OP_LSTAT,
SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
+ SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_chmod), SMB_VFS_OP_CHMOD,
@@ -597,6 +601,7 @@ static struct {
{ SMB_VFS_OP_STAT, "stat" },
{ SMB_VFS_OP_FSTAT, "fstat" },
{ SMB_VFS_OP_LSTAT, "lstat" },
+ { SMB_VFS_OP_GET_ALLOC_SIZE, "get_alloc_size" },
{ SMB_VFS_OP_UNLINK, "unlink" },
{ SMB_VFS_OP_CHMOD, "chmod" },
{ SMB_VFS_OP_FCHMOD, "fchmod" },
@@ -1325,6 +1330,18 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle,
return result;
}
+static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
+ files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
+{
+ int result;
+
+ result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf);
+
+ do_log(SMB_VFS_OP_GET_ALLOC_SIZE, (result >= 0), handle, "%d", result);
+
+ return result;
+}
+
static int smb_full_audit_unlink(vfs_handle_struct *handle,
const char *path)
{
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index e048e89589..e2f272aa11 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -40,6 +40,31 @@ static int onefs_open(vfs_handle_struct *handle, const char *fname,
return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
}
+static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle, files_struct *fsp,
+ const SMB_STRUCT_STAT *sbuf)
+{
+ uint64_t result;
+
+ START_PROFILE(syscall_get_alloc_size);
+
+ if(S_ISDIR(sbuf->st_mode)) {
+ result = 0;
+ goto out;
+ }
+
+ /* Just use the file size since st_blocks is unreliable on OneFS. */
+ result = get_file_size_stat(sbuf);
+
+ if (fsp && fsp->initial_allocation_size)
+ result = MAX(result,fsp->initial_allocation_size);
+
+ result = smb_roundup(handle->conn, result);
+
+ out:
+ END_PROFILE(syscall_get_alloc_size);
+ return result;
+}
+
static int onefs_statvfs(vfs_handle_struct *handle, const char *path,
vfs_statvfs_struct *statbuf)
{
@@ -123,6 +148,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_lstat), SMB_VFS_OP_LSTAT,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_ntimes), SMB_VFS_OP_NTIMES,
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 54c17db1ce..77efb277de 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -648,8 +648,8 @@ static bool collect_one_stream(const char *dirname,
if (!add_one_stream(state->mem_ctx,
&state->num_streams, &state->streams,
dirent, sbuf.st_size,
- get_allocation_size(
- state->handle->conn, NULL, &sbuf))) {
+ SMB_VFS_GET_ALLOC_SIZE(state->handle->conn, NULL,
+ &sbuf))) {
state->status = NT_STATUS_NO_MEMORY;
return false;
}
@@ -693,8 +693,8 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
"::$DATA", sbuf.st_size,
- get_allocation_size(handle->conn, fsp,
- &sbuf))) {
+ SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
+ &sbuf))) {
return NT_STATUS_NO_MEMORY;
}
}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 1df4932167..37473439dd 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -732,8 +732,8 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
"::$DATA", sbuf.st_size,
- get_allocation_size(handle->conn, fsp,
- &sbuf))) {
+ SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
+ &sbuf))) {
return NT_STATUS_NO_MEMORY;
}
}
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index baa88bc44b..0736a66fb8 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -210,9 +210,6 @@ void run_dns_queue(void)
if (fd_in == -1)
return;
- /* Allow SIGTERM to kill us. */
- BlockSignals(False, SIGTERM);
-
if (!process_exists_by_pid(child_pid)) {
close(fd_in);
close(fd_out);
@@ -224,12 +221,9 @@ void run_dns_queue(void)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("read from child failed: %s\n", nt_errstr(status)));
fd_in = -1;
- BlockSignals(True, SIGTERM);
return;
}
- BlockSignals(True, SIGTERM);
-
namerec = add_dns_result(&r.name, r.result);
if (dns_current) {
@@ -338,14 +332,8 @@ bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
- /* Unblock TERM signal so we can be killed in DNS lookup. */
- BlockSignals(False, SIGTERM);
-
dns_ip.s_addr = interpret_addr(qname);
- /* Re-block TERM signal. */
- BlockSignals(True, SIGTERM);
-
namerec = add_dns_result(question, dns_ip);
if(namerec == NULL) {
send_wins_name_query_response(NAM_ERR, p, NULL);
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 0922e455a3..adefb7d94f 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -85,41 +85,80 @@ static void terminate(void)
exit(0);
}
-/**************************************************************************** **
- Handle a SHUTDOWN message from smbcontrol.
- **************************************************************************** */
-
-static void nmbd_terminate(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+static void nmbd_sig_term_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
{
terminate();
}
-/**************************************************************************** **
- Catch a SIGTERM signal.
- **************************************************************************** */
+static bool nmbd_setup_sig_term_handler(void)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(nmbd_event_context(),
+ nmbd_event_context(),
+ SIGTERM, 0,
+ nmbd_sig_term_handler,
+ NULL);
+ if (!se) {
+ DEBUG(0,("failed to setup SIGTERM handler"));
+ return false;
+ }
-static SIG_ATOMIC_T got_sig_term;
+ return true;
+}
+
+static void msg_reload_nmbd_services(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data);
+
+static void nmbd_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ DEBUG(0,("Got SIGHUP dumping debug info.\n"));
+ msg_reload_nmbd_services(nmbd_messaging_context(),
+ NULL, MSG_SMB_CONF_UPDATED,
+ procid_self(), NULL);
+}
-static void sig_term(int sig)
+static bool nmbd_setup_sig_hup_handler(void)
{
- got_sig_term = 1;
- sys_select_signal(SIGTERM);
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(nmbd_event_context(),
+ nmbd_event_context(),
+ SIGHUP, 0,
+ nmbd_sig_hup_handler,
+ NULL);
+ if (!se) {
+ DEBUG(0,("failed to setup SIGHUP handler"));
+ return false;
+ }
+
+ return true;
}
/**************************************************************************** **
- Catch a SIGHUP signal.
+ Handle a SHUTDOWN message from smbcontrol.
**************************************************************************** */
-static SIG_ATOMIC_T reload_after_sighup;
-
-static void sig_hup(int sig)
+static void nmbd_terminate(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
{
- reload_after_sighup = 1;
- sys_select_signal(SIGHUP);
+ terminate();
}
/**************************************************************************** **
@@ -282,6 +321,7 @@ static void reload_interfaces(time_t t)
/* We need to wait if there are no subnets... */
if (FIRST_SUBNET == NULL) {
+ void (*saved_handler)(int);
if (print_waiting_msg) {
DEBUG(0,("reload_interfaces: "
@@ -293,29 +333,20 @@ static void reload_interfaces(time_t t)
* Whilst we're waiting for an interface, allow SIGTERM to
* cause us to exit.
*/
-
- BlockSignals(false, SIGTERM);
+ saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
/* We only count IPv4, non-loopback interfaces here. */
- while (iface_count_v4_nl() == 0 && !got_sig_term) {
+ while (iface_count_v4_nl() == 0) {
sleep(5);
load_interfaces();
}
- /*
- * Handle termination inband.
- */
-
- if (got_sig_term) {
- got_sig_term = 0;
- terminate();
- }
+ CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
/*
* We got an interface, go back to blocking term.
*/
- BlockSignals(true, SIGTERM);
goto try_again;
}
}
@@ -460,15 +491,6 @@ static void process(void)
}
/*
- * Handle termination inband.
- */
-
- if (got_sig_term) {
- got_sig_term = 0;
- terminate();
- }
-
- /*
* Process all incoming packets
* read above. This calls the success and
* failure functions registered when response
@@ -637,19 +659,6 @@ static void process(void)
clear_unexpected(t);
- /*
- * Reload the services file if we got a sighup.
- */
-
- if(reload_after_sighup) {
- DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
- msg_reload_nmbd_services(nmbd_messaging_context(),
- NULL, MSG_SMB_CONF_UPDATED,
- procid_self(), NULL);
-
- reload_after_sighup = 0;
- }
-
/* check for new network interfaces */
reload_interfaces(t);
@@ -815,10 +824,7 @@ static bool open_sockets(bool isdaemon, int port)
BlockSignals(False, SIGHUP);
BlockSignals(False, SIGUSR1);
BlockSignals(False, SIGTERM);
-
- CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
- CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
-
+
#if defined(SIGFPE)
/* we are never interested in SIGFPE */
BlockSignals(True,SIGFPE);
@@ -913,6 +919,11 @@ static bool open_sockets(bool isdaemon, int port)
exit(1);
}
+ if (!nmbd_setup_sig_term_handler())
+ exit(1);
+ if (!nmbd_setup_sig_hup_handler())
+ exit(1);
+
/* get broadcast messages */
claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
@@ -977,9 +988,6 @@ static bool open_sockets(bool isdaemon, int port)
exit(1);
}
- /* We can only take signals in the select. */
- BlockSignals( True, SIGTERM );
-
TALLOC_FREE(frame);
process();
diff --git a/source3/nmbd/nmbd_become_dmb.c b/source3/nmbd/nmbd_become_dmb.c
index a0b2ef15f8..827d56cb06 100644
--- a/source3/nmbd/nmbd_become_dmb.c
+++ b/source3/nmbd/nmbd_become_dmb.c
@@ -128,7 +128,8 @@ in workgroup %s on subnet %s\n",
work->dmb_name = nmbname;
- /* Pick the first interface IPv4 address as the domain master browser ip. */
+ /* Pick the first interface IPv4 address as the domain master
+ * browser ip. */
nip = first_ipv4_iface();
if (!nip) {
DEBUG(0,("become_domain_master_stage2: "
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 489034899e..f69845b346 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1794,16 +1794,8 @@ bool listen_for_packets(bool run_election)
&r_fds, &w_fds, &timeout, &maxfd);
}
- /* Prepare for the select - allow certain signals. */
-
- BlockSignals(False, SIGTERM);
-
selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
- /* We can only take signals when we are in the select - block them again here. */
-
- BlockSignals(True, SIGTERM);
-
if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
return False;
}
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 61af0bb4a4..13bc931863 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -287,7 +287,8 @@ bool create_subnets(void)
}
if (lp_we_are_a_wins_server()) {
- /* Pick the first interface IPv4 address as the WINS server ip. */
+ /* Pick the first interface IPv4 address as the WINS server
+ * ip. */
const struct in_addr *nip = first_ipv4_iface();
if (!nip) {
diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c
index 3e672aef25..5da0da81e5 100644
--- a/source3/nmbd/nmbd_synclists.c
+++ b/source3/nmbd/nmbd_synclists.c
@@ -109,7 +109,7 @@ static void sync_child(char *name, int nm_type,
return;
}
- if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, "IPC$", "IPC", "", 1))) {
cli_shutdown(cli);
return;
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 6438888942..bc7d9974f4 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -250,6 +250,7 @@ struct global {
char *szLdapIdmapSuffix;
char *szLdapGroupSuffix;
int ldap_ssl;
+ bool ldap_ssl_ads;
char *szLdapSuffix;
char *szLdapAdminDn;
int ldap_debug_level;
@@ -322,7 +323,8 @@ struct global {
bool bHostnameLookups;
bool bUnixExtensions;
bool bDisableNetbios;
- bool bUseKerberosKeytab;
+ char * szDedicatedKeytabFile;
+ int iKerberosMethod;
bool bDeferSharingViolations;
bool bEnablePrivileges;
bool bASUSupport;
@@ -861,6 +863,17 @@ static const struct enum_list enum_config_backend[] = {
{-1, NULL}
};
+/* ADS kerberos ticket verification options */
+
+static const struct enum_list enum_kerberos_method[] = {
+ {KERBEROS_VERIFY_SECRETS, "default"},
+ {KERBEROS_VERIFY_SECRETS, "secrets only"},
+ {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
+ {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
+ {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
+ {-1, NULL}
+};
+
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
* The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
@@ -1745,14 +1758,24 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED | FLAG_GLOBAL,
},
{
- .label = "use kerberos keytab",
- .type = P_BOOL,
+ .label = "dedicated keytab file",
+ .type = P_STRING,
.p_class = P_GLOBAL,
- .ptr = &Globals.bUseKerberosKeytab,
+ .ptr = &Globals.szDedicatedKeytabFile,
.special = NULL,
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
+ {
+ .label = "kerberos method",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.iKerberosMethod,
+ .special = NULL,
+ .enum_list = enum_kerberos_method,
+ .flags = FLAG_ADVANCED,
+ },
+
{N_("Logging Options"), P_SEP, P_SEPARATOR},
@@ -3589,6 +3612,15 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
+ .label = "ldap ssl ads",
+ .type = P_BOOL,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.ldap_ssl_ads,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
+ {
.label = "ldap timeout",
.type = P_INTEGER,
.p_class = P_GLOBAL,
@@ -4900,6 +4932,7 @@ static void init_globals(bool first_time_only)
string_set(&Globals.szLdapAdminDn, "");
Globals.ldap_ssl = LDAP_SSL_START_TLS;
+ Globals.ldap_ssl_ads = False;
Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
Globals.ldap_delete_dn = False;
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
@@ -5244,6 +5277,7 @@ FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
+FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
@@ -5322,7 +5356,8 @@ FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
-FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
+FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
+FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index e677d429af..d26a667f44 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -7,17 +7,17 @@
Copyright (C) Andrew Bartlett 2001-2002
Copyright (C) Simo Sorce 2003
Copyright (C) Volker Lendecke 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -67,16 +67,16 @@ static int samu_destroy(struct samu *user)
struct samu *samu_new( TALLOC_CTX *ctx )
{
struct samu *user;
-
+
if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
DEBUG(0,("samuser_new: Talloc failed!\n"));
return NULL;
}
-
+
talloc_set_destructor( user, samu_destroy );
-
+
/* no initial methods */
-
+
user->methods = NULL;
/* Don't change these timestamp settings without a good reason.
@@ -98,7 +98,7 @@ struct samu *samu_new( TALLOC_CTX *ctx )
/* Some parts of samba strlen their pdb_get...() returns,
so this keeps the interface unchanged for now. */
-
+
user->username = "";
user->domain = "";
user->nt_username = "";
@@ -118,8 +118,7 @@ struct samu *samu_new( TALLOC_CTX *ctx )
asks for a filtered list of users. */
user->acct_ctrl = ACB_NORMAL;
-
-
+
return user;
}
@@ -140,7 +139,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
}
/* Basic properties based upon the Unix account information */
-
+
pdb_set_username(user, pwd->pw_name, PDB_SET);
pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
@@ -149,29 +148,29 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
will be rejected by other parts of the Samba code.
Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
--jerry */
-
+
gid_to_sid(&group_sid, pwd->pw_gid);
pdb_set_group_sid(user, &group_sid, PDB_SET);
#endif
-
+
/* save the password structure for later use */
-
+
user->unix_pw = tcopy_passwd( user, pwd );
/* Special case for the guest account which must have a RID of 501 */
-
+
if ( strequal( pwd->pw_name, guest_account ) ) {
if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
return NT_STATUS_NO_SUCH_USER;
}
return NT_STATUS_OK;
}
-
+
/* Non-guest accounts...Check for a workstation or user account */
if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
/* workstation */
-
+
if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
pwd->pw_name));
@@ -180,15 +179,15 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
}
else {
/* user */
-
+
if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
pwd->pw_name));
return NT_STATUS_INVALID_ACCOUNT_NAME;
}
-
+
/* set some basic attributes */
-
+
pdb_set_profile_path(user, talloc_sub_specified(user,
lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
PDB_DEFAULT);
@@ -202,7 +201,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
PDB_DEFAULT);
}
-
+
/* Now deal with the user SID. If we have a backend that can generate
RIDs, then do so. But sometimes the caller just wanted a structure
initialized and will fill in these fields later (such as from a
@@ -211,7 +210,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
if ( create && !pdb_rid_algorithm() ) {
uint32 user_rid;
DOM_SID user_sid;
-
+
if ( !pdb_new_rid( &user_rid ) ) {
DEBUG(3, ("Could not allocate a new RID\n"));
return NT_STATUS_ACCESS_DENIED;
@@ -224,18 +223,18 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
DEBUG(3, ("pdb_set_user_sid failed\n"));
return NT_STATUS_INTERNAL_ERROR;
}
-
+
return NT_STATUS_OK;
}
/* generate a SID for the user with the RID algorithm */
-
+
urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
-
+
if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
return NT_STATUS_INTERNAL_ERROR;
}
-
+
return NT_STATUS_OK;
}
@@ -365,10 +364,10 @@ bool pdb_gethexpwd(const char *p, unsigned char *pwd)
unsigned char lonybble, hinybble;
const char *hexchars = "0123456789ABCDEF";
char *p1, *p2;
-
+
if (!p)
return false;
-
+
for (i = 0; i < 32; i += 2) {
hinybble = toupper_ascii(p[i]);
lonybble = toupper_ascii(p[i + 1]);
@@ -554,16 +553,16 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
{
GROUP_MAP map;
bool ret;
-
+
/* Windows treats "MACHINE\None" as a special name for
rid 513 on non-DCs. You cannot create a user or group
name "None" on Windows. You will get an error that
the group already exists. */
-
+
if ( strequal( name, "None" ) ) {
*rid = DOMAIN_GROUP_RID_USERS;
*type = SID_NAME_DOM_GRP;
-
+
return True;
}
@@ -578,7 +577,7 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
if ( !(sam_account = samu_new( NULL )) ) {
return False;
}
-
+
become_root();
ret = pdb_getsampwnam(sam_account, name);
unbecome_root();
@@ -586,7 +585,7 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
if (ret) {
sid_copy(&user_sid, pdb_get_user_sid(sam_account));
}
-
+
TALLOC_FREE(sam_account);
if (ret) {
@@ -654,7 +653,7 @@ NTSTATUS local_password_change(const char *user_name,
if(!pdb_getsampwnam(sam_pass, user_name)) {
unbecome_root();
TALLOC_FREE(sam_pass);
-
+
if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
int tmp_debug = DEBUGLEVEL;
struct passwd *pwd;
@@ -754,7 +753,7 @@ NTSTATUS local_password_change(const char *user_name,
return NT_STATUS_UNSUCCESSFUL;
}
}
-
+
if (local_flags & LOCAL_SET_NO_PASSWORD) {
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
if (asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name) < 0) {
@@ -789,7 +788,7 @@ NTSTATUS local_password_change(const char *user_name,
TALLOC_FREE(sam_pass);
return NT_STATUS_UNSUCCESSFUL;
}
-
+
if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
if (asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name) < 0) {
*pp_err_str = NULL;
@@ -893,7 +892,7 @@ static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 bu
dir_drive_len, unknown_str_len, munged_dial_len,
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
-
+
uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
uint16 acct_ctrl, logon_divs;
uint16 bad_password_count, logon_count;
@@ -902,7 +901,7 @@ static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 bu
uint32 len = 0;
uint32 lm_pw_len, nt_pw_len, hourslen;
bool ret = True;
-
+
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
return False;
@@ -942,7 +941,7 @@ static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 bu
&bad_password_count, /* w */
&logon_count, /* w */
&unknown_6); /* d */
-
+
if (len == (uint32) -1) {
ret = False;
goto done;
@@ -987,7 +986,7 @@ static bool init_samu_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 bu
lp_logon_script()),
PDB_DEFAULT);
}
-
+
if (profile_path) {
pdb_set_profile_path(sampass, profile_path, PDB_SET);
} else {
@@ -1079,7 +1078,7 @@ static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 bu
dir_drive_len, unknown_str_len, munged_dial_len,
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
-
+
uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
uint16 acct_ctrl, logon_divs;
uint16 bad_password_count, logon_count;
@@ -1088,7 +1087,7 @@ static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 bu
uint32 len = 0;
uint32 lm_pw_len, nt_pw_len, hourslen;
bool ret = True;
-
+
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
return False;
@@ -1130,7 +1129,7 @@ static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 bu
&bad_password_count, /* w */
&logon_count, /* w */
&unknown_6); /* d */
-
+
if (len == (uint32) -1) {
ret = False;
goto done;
@@ -1178,7 +1177,7 @@ static bool init_samu_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 bu
lp_logon_script()),
PDB_DEFAULT);
}
-
+
if (profile_path) {
pdb_set_profile_path(sampass, profile_path, PDB_SET);
} else {
@@ -1268,7 +1267,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
dir_drive_len, unknown_str_len, munged_dial_len,
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
-
+
uint32 user_rid, group_rid, hours_len, unknown_6;
uint16 acct_ctrl, logon_divs;
uint16 bad_password_count, logon_count;
@@ -1280,12 +1279,12 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
bool ret = True;
fstring tmp_string;
bool expand_explicit = lp_passdb_expand_explicit();
-
+
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
return False;
}
-
+
/* SAMU_BUFFER_FORMAT_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
/* unpack the buffer into variables */
@@ -1323,7 +1322,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
&bad_password_count, /* w */
&logon_count, /* w */
&unknown_6); /* d */
-
+
if (len == (uint32) -1) {
ret = False;
goto done;
@@ -1376,7 +1375,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
lp_logon_script()),
PDB_DEFAULT);
}
-
+
if (profile_path) {
fstrcpy( tmp_string, profile_path );
if (expand_explicit) {
@@ -1503,7 +1502,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
dir_drive_len, unknown_str_len, munged_dial_len,
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
-
+
uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
uint16 logon_divs;
uint16 bad_password_count, logon_count;
@@ -1515,12 +1514,12 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
bool ret = True;
fstring tmp_string;
bool expand_explicit = lp_passdb_expand_explicit();
-
+
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
return False;
}
-
+
/* SAMU_BUFFER_FORMAT_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
/* unpack the buffer into variables */
@@ -1559,7 +1558,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
&bad_password_count, /* w */
&logon_count, /* w */
&unknown_6); /* d */
-
+
if (len == (uint32) -1) {
ret = False;
goto done;
@@ -1612,7 +1611,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
lp_logon_script()),
PDB_DEFAULT);
}
-
+
if (profile_path) {
fstrcpy( tmp_string, profile_path );
if (expand_explicit) {
@@ -1839,12 +1838,12 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool
} else {
profile_path_len = 0;
}
-
+
lm_pw = pdb_get_lanman_passwd(sampass);
if (!lm_pw) {
lm_pw_len = 0;
}
-
+
nt_pw = pdb_get_nt_passwd(sampass);
if (!nt_pw) {
nt_pw_len = 0;
@@ -1927,7 +1926,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool
DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
return (-1);
}
-
+
/* now for the real call to tdb_pack() */
buflen = tdb_pack(*buf, len, SAMU_BUFFER_FORMAT_V3,
logon_time, /* d */
@@ -1961,7 +1960,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool
pdb_get_bad_password_count(sampass), /* w */
pdb_get_logon_count(sampass), /* w */
pdb_get_unknown_6(sampass)); /* d */
-
+
/* check to make sure we got it correct */
if (buflen != len) {
DEBUG(0, ("init_buffer_from_samu_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
@@ -2038,7 +2037,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
}
dst->methods = src->methods;
-
+
if ( src->unix_pw ) {
dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
if (!dst->unix_pw) {
@@ -2127,7 +2126,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
return True;
}
-
+
LastBadPassword = pdb_get_bad_password_time(sampass);
DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
@@ -2150,7 +2149,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
*updated = True;
}
}
-
+
return True;
}
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index bb29380007..0721713c01 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -22,8 +22,6 @@
#include "includes.h"
#include "printing.h"
-extern SIG_ATOMIC_T got_sig_term;
-extern SIG_ATOMIC_T reload_after_sighup;
extern struct current_user current_user;
extern userdom_struct current_user_info;
@@ -1427,6 +1425,9 @@ void start_background_queue(void)
smb_panic("reinit_after_fork() failed");
}
+ smbd_setup_sig_term_handler();
+ smbd_setup_sig_hup_handler();
+
claim_connection( NULL, "smbd lpq backend",
FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
@@ -1483,19 +1484,6 @@ void start_background_queue(void)
exit_server_cleanly(NULL);
}
- /* check for some essential signals first */
-
- if (got_sig_term) {
- exit_server_cleanly(NULL);
- }
-
- if (reload_after_sighup) {
- change_to_root_user();
- DEBUG(1,("Reloading services after SIGHUP\n"));
- reload_services(False);
- reload_after_sighup = 0;
- }
-
if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) {
continue;
}
diff --git a/source3/registry/reg_init_basic.c b/source3/registry/reg_init_basic.c
index 60dcabdcf2..eab4ca7f9d 100644
--- a/source3/registry/reg_init_basic.c
+++ b/source3/registry/reg_init_basic.c
@@ -37,6 +37,14 @@ WERROR registry_init_common(void)
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0, ("Failed to initialize the reghook cache: %s\n",
win_errstr(werr)));
+ goto done;
+ }
+
+ /* setup the necessary keys and values */
+
+ werr = init_registry_data();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("Failed to initialize data in registry!\n"));
}
done:
diff --git a/source3/registry/reg_init_full.c b/source3/registry/reg_init_full.c
index 91e55d76b2..b5a06f2582 100644
--- a/source3/registry/reg_init_full.c
+++ b/source3/registry/reg_init_full.c
@@ -72,14 +72,6 @@ WERROR registry_init_full(void)
goto fail;
}
- /* setup the necessary keys and values */
-
- werr = init_registry_data();
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, ("Failed to initialize data in registry!\n"));
- goto fail;
- }
-
/* build the cache tree of registry hooks */
for ( i=0; reg_hooks[i].keyname; i++ ) {
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 5a53c0d940..2841ff08f6 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -81,9 +81,10 @@ static const struct pipe_id_info {
Return the pipe name from the interface.
****************************************************************************/
-const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
- const struct ndr_syntax_id *interface)
+const char *get_pipe_name_from_iface(const struct ndr_syntax_id *interface)
{
+ char *guid_str;
+ const char *result;
int i;
for (i = 0; pipe_names[i].client_pipe; i++) {
if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
@@ -97,7 +98,18 @@ const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx,
* interested in the known pipes mentioned in pipe_names[]
*/
- return NULL;
+ guid_str = GUID_string(talloc_tos(), &interface->uuid);
+ if (guid_str == NULL) {
+ return NULL;
+ }
+ result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
+ (int)interface->if_version);
+ TALLOC_FREE(guid_str);
+
+ if (result == NULL) {
+ return "PIPE";
+ }
+ return result;
}
/********************************************************************
@@ -243,7 +255,7 @@ static void rpc_read_done(struct async_req *subreq)
status = state->transport->read_recv(subreq, &received);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -266,7 +278,7 @@ static void rpc_read_done(struct async_req *subreq)
static NTSTATUS rpc_read_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
struct rpc_write_state {
@@ -323,7 +335,7 @@ static void rpc_write_done(struct async_req *subreq)
status = state->transport->write_recv(subreq, &written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -347,7 +359,7 @@ static void rpc_write_done(struct async_req *subreq)
static NTSTATUS rpc_write_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
@@ -458,7 +470,7 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
status = NT_STATUS_OK;
post_status:
- if (async_post_status(result, ev, status)) {
+ if (async_post_ntstatus(result, ev, status)) {
return result;
}
TALLOC_FREE(result);
@@ -476,18 +488,18 @@ static void get_complete_frag_got_header(struct async_req *subreq)
status = rpc_read_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
- async_req_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -516,7 +528,7 @@ static void get_complete_frag_got_rest(struct async_req *subreq)
status = rpc_read_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -524,7 +536,7 @@ static void get_complete_frag_got_rest(struct async_req *subreq)
static NTSTATUS get_complete_frag_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
/****************************************************************************
@@ -1084,7 +1096,7 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
status = NT_STATUS_INVALID_PARAMETER;
post_status:
- if (async_post_status(result, ev, status)) {
+ if (async_post_ntstatus(result, ev, status)) {
return result;
}
fail:
@@ -1104,7 +1116,7 @@ static void cli_api_pipe_trans_done(struct async_req *subreq)
&state->rdata_len);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -1121,7 +1133,7 @@ static void cli_api_pipe_write_done(struct async_req *subreq)
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1157,7 +1169,7 @@ static void cli_api_pipe_read_done(struct async_req *subreq)
status = state->transport->read_recv(subreq, &received);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
state->rdata_len = received;
@@ -1171,7 +1183,7 @@ static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct cli_api_pipe_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -1252,7 +1264,7 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
/* Make incoming_pdu dynamic with no memory. */
- prs_give_memory(&state->incoming_pdu, 0, 0, true);
+ prs_give_memory(&state->incoming_pdu, NULL, 0, true);
talloc_set_destructor(state, rpc_api_pipe_state_destructor);
@@ -1284,7 +1296,7 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
return result;
post_status:
- if (async_post_status(result, ev, status)) {
+ if (async_post_ntstatus(result, ev, status)) {
return result;
}
TALLOC_FREE(result);
@@ -1306,7 +1318,7 @@ 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_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1354,7 +1366,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_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1369,7 +1381,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq)
nt_errstr(status)));
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1393,13 +1405,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_error(req, NT_STATUS_INVALID_PARAMETER);
+ async_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_error(req, NT_STATUS_NO_MEMORY);
+ async_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1410,7 +1422,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_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -1438,7 +1450,7 @@ static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct rpc_api_pipe_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
@@ -2105,7 +2117,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
return result;
post_status:
- if (async_post_status(result, ev, status)) {
+ if (async_post_ntstatus(result, ev, status)) {
return result;
}
TALLOC_FREE(result);
@@ -2209,13 +2221,13 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq)
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
status = prepare_next_frag(state, &is_last_frag);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -2253,7 +2265,7 @@ static void rpc_api_pipe_req_done(struct async_req *subreq)
status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -2266,7 +2278,7 @@ NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct rpc_api_pipe_req_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
/*
* We always have to initialize to reply pdu, even if there is
* none. The rpccli_* caller routines expect this.
@@ -2573,7 +2585,7 @@ struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
return result;
post_status:
- if (async_post_status(result, ev, status)) {
+ if (async_post_ntstatus(result, ev, status)) {
return result;
}
TALLOC_FREE(result);
@@ -2597,27 +2609,30 @@ 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_error(req, status);
+ async_req_nterror(req, status);
return;
}
/* Unmarshall the RPC header */
if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
- async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL);
+ prs_mem_free(&reply_pdu);
+ async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
"RPC_HDR_BA.\n"));
- async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL);
+ prs_mem_free(&reply_pdu);
+ async_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"));
- async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL);
+ prs_mem_free(&reply_pdu);
+ async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
return;
}
@@ -2633,6 +2648,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
case PIPE_AUTH_TYPE_NONE:
case PIPE_AUTH_TYPE_SCHANNEL:
/* Bind complete. */
+ prs_mem_free(&reply_pdu);
async_req_done(req);
break;
@@ -2640,8 +2656,9 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
/* Need to send AUTH3 packet - no reply. */
status = rpc_finish_auth3_bind_send(req, state, &hdr,
&reply_pdu);
+ prs_mem_free(&reply_pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
}
break;
@@ -2649,8 +2666,9 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
/* Need to send alter context request and reply. */
status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
&reply_pdu);
+ prs_mem_free(&reply_pdu);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
}
break;
@@ -2660,7 +2678,8 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq)
default:
DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
(unsigned int)state->cli->auth->auth_type));
- async_req_error(req, NT_STATUS_INTERNAL_ERROR);
+ prs_mem_free(&reply_pdu);
+ async_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
}
}
@@ -2737,7 +2756,7 @@ static void rpc_bind_auth3_write_done(struct async_req *subreq)
status = rpc_write_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -2852,7 +2871,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_error(req, status);
+ async_req_nterror(req, status);
return;
}
@@ -2860,19 +2879,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_error(req, NT_STATUS_BUFFER_TOO_SMALL);
+ async_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_error(req, NT_STATUS_INVALID_PARAMETER);
+ async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
- async_req_error(req, NT_STATUS_INVALID_PARAMETER);
+ async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -2885,7 +2904,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_error(req, NT_STATUS_INVALID_PARAMETER);
+ async_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -2899,7 +2918,7 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq)
NTSTATUS rpc_pipe_bind_recv(struct async_req *req)
{
- return async_req_simple_recv(req);
+ return async_req_simple_recv_ntstatus(req);
}
NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
@@ -3511,6 +3530,61 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
return NT_STATUS_OK;
}
+NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *syntax,
+ struct rpc_pipe_client **presult)
+{
+ struct rpc_pipe_client *result;
+ struct cli_pipe_auth_data *auth;
+ NTSTATUS status;
+
+ result = talloc(mem_ctx, struct rpc_pipe_client);
+ if (result == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ result->abstract_syntax = *syntax;
+ result->transfer_syntax = ndr_transfer_syntax;
+ result->dispatch = cli_do_rpc_ndr;
+ result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
+ result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
+
+ result->desthost = talloc_strdup(result, global_myname());
+ result->srv_name_slash = talloc_asprintf_strupper_m(
+ result, "\\\\%s", global_myname());
+ if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = rpc_transport_smbd_init(result, conn, syntax,
+ &result->transport);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(result);
+ return status;
+ }
+
+ status = rpccli_anon_bind_data(result, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(result);
+ return status;
+ }
+
+ status = rpc_pipe_bind(result, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
+ TALLOC_FREE(result);
+ return status;
+ }
+
+ *presult = result;
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Open a pipe to a remote server.
****************************************************************************/
@@ -3587,8 +3661,7 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
}
DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
"%s failed with error %s\n",
- cli_get_pipe_name_from_iface(debug_ctx(),
- interface),
+ get_pipe_name_from_iface(interface),
nt_errstr(status) ));
TALLOC_FREE(result);
return status;
@@ -3596,8 +3669,7 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
"%s and bound anonymously.\n",
- cli_get_pipe_name_from_iface(debug_ctx(), interface),
- cli->desthost ));
+ get_pipe_name_from_iface(interface), cli->desthost));
*presult = result;
return NT_STATUS_OK;
@@ -3643,8 +3715,8 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
"machine %s and bound NTLMSSP as user %s\\%s.\n",
- cli_get_pipe_name_from_iface(debug_ctx(), interface),
- cli->desthost, domain, username ));
+ get_pipe_name_from_iface(interface), cli->desthost, domain,
+ username ));
*presult = result;
return NT_STATUS_OK;
@@ -3835,7 +3907,7 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
"for domain %s and bound using schannel.\n",
- cli_get_pipe_name_from_iface(debug_ctx(), interface),
+ get_pipe_name_from_iface(interface),
cli->desthost, domain ));
*presult = result;
@@ -4045,40 +4117,3 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-
-/**
- * Create a new RPC client context which uses a local dispatch function.
- */
-NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract_syntax,
- NTSTATUS (*dispatch) (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r),
- struct auth_serversupplied_info *serversupplied_info,
- struct rpc_pipe_client **presult)
-{
- struct rpc_pipe_client *result;
-
- result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- result->abstract_syntax = *abstract_syntax;
- result->transfer_syntax = ndr_transfer_syntax;
- result->dispatch = dispatch;
-
- result->pipes_struct = TALLOC_ZERO_P(mem_ctx, pipes_struct);
- if (result->pipes_struct == NULL) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
- }
- result->pipes_struct->mem_ctx = mem_ctx;
- result->pipes_struct->server_info = serversupplied_info;
- result->pipes_struct->pipe_bound = true;
-
- result->max_xmit_frag = -1;
- result->max_recv_frag = -1;
-
- *presult = result;
- return NT_STATUS_OK;
-}
-
-
diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c
index 6f7a541f72..793b9c7de5 100644
--- a/source3/rpc_client/init_netlogon.c
+++ b/source3/rpc_client/init_netlogon.c
@@ -144,7 +144,8 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
size_t num_sids,
const DOM_SID *sids,
- int *numgroups, DOM_GID **pgids)
+ int *numgroups,
+ struct samr_RidWithAttribute **pgids)
{
int i;
@@ -152,13 +153,14 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
*pgids = NULL;
for (i=0; i<num_sids; i++) {
- DOM_GID gid;
- if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.g_rid)) {
+ struct samr_RidWithAttribute gid;
+ if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
continue;
}
- gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
+ gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
SE_GROUP_ENABLED);
- ADD_TO_ARRAY(mem_ctx, DOM_GID, gid, pgids, numgroups);
+ ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
+ gid, pgids, numgroups);
if (*pgids == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -177,7 +179,7 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
struct netr_SamInfo3 *sam3)
{
struct samu *sampw;
- DOM_GID *gids = NULL;
+ struct samr_RidWithAttribute *gids = NULL;
const DOM_SID *user_sid = NULL;
const DOM_SID *group_sid = NULL;
DOM_SID domain_sid;
@@ -277,8 +279,8 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
}
for (i=0; i < groups.count; i++) {
- groups.rids[i].rid = gids[i].g_rid;
- groups.rids[i].attributes = gids[i].attr;
+ groups.rids[i].rid = gids[i].rid;
+ groups.rids[i].attributes = gids[i].attributes;
}
unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index e8a333e509..80ff384046 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -93,7 +93,7 @@ static void rpc_np_write_done(struct async_req *subreq)
status = cli_write_andx_recv(subreq, &state->written);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -105,7 +105,7 @@ static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten)
req->private_data, struct rpc_np_write_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*pwritten = state->written;
@@ -169,13 +169,13 @@ static void rpc_np_read_done(struct async_req *subreq)
}
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(subreq);
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
if (state->received > state->size) {
TALLOC_FREE(subreq);
- async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
@@ -189,7 +189,7 @@ static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived)
req->private_data, struct rpc_np_read_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*preceived = state->received;
@@ -251,7 +251,7 @@ static void rpc_np_trans_done(struct async_req *subreq)
&state->rdata, &state->rdata_len);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- async_req_error(req, status);
+ async_req_nterror(req, status);
return;
}
async_req_done(req);
@@ -264,7 +264,7 @@ static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
req->private_data, struct rpc_np_trans_state);
NTSTATUS status;
- if (async_req_is_error(req, &status)) {
+ if (async_req_is_nterror(req, &status)) {
return status;
}
*prdata = talloc_move(mem_ctx, &state->rdata);
@@ -272,49 +272,129 @@ static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+struct rpc_transport_np_init_state {
+ struct rpc_cli_transport *transport;
+ struct rpc_transport_np_state *transport_np;
+};
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq);
+
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const struct ndr_syntax_id *abstract_syntax)
+{
+ struct async_req *result, *subreq;
+ struct rpc_transport_np_init_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_transport_np_init_state)) {
+ return NULL;
+ }
+
+ state->transport = talloc(state, struct rpc_cli_transport);
+ if (state->transport == NULL) {
+ goto fail;
+ }
+ state->transport_np = talloc(state->transport,
+ struct rpc_transport_np_state);
+ if (state->transport_np == NULL) {
+ goto fail;
+ }
+ state->transport->priv = state->transport_np;
+
+ state->transport_np->pipe_name = get_pipe_name_from_iface(
+ abstract_syntax);
+ state->transport_np->cli = cli;
+
+ subreq = cli_ntcreate_send(
+ state, ev, cli, state->transport_np->pipe_name, 0,
+ DESIRED_ACCESS_PIPE, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN, 0, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = rpc_transport_np_init_pipe_open;
+ subreq->async.priv = result;
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_np_init_state);
+ NTSTATUS status;
+
+ status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+
+ talloc_set_destructor(state->transport_np,
+ rpc_transport_np_state_destructor);
+ async_req_done(req);
+}
+
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult)
+{
+ struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_np_init_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ state->transport->write_send = rpc_np_write_send;
+ state->transport->write_recv = rpc_np_write_recv;
+ state->transport->read_send = rpc_np_read_send;
+ state->transport->read_recv = rpc_np_read_recv;
+ state->transport->trans_send = rpc_np_trans_send;
+ state->transport->trans_recv = rpc_np_trans_recv;
+
+ *presult = talloc_move(mem_ctx, &state->transport);
+ return NT_STATUS_OK;
+}
+
NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
const struct ndr_syntax_id *abstract_syntax,
struct rpc_cli_transport **presult)
{
- struct rpc_cli_transport *result;
- struct rpc_transport_np_state *state;
- int fnum;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
- result = talloc(mem_ctx, struct rpc_cli_transport);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- state = talloc(result, struct rpc_transport_np_state);
- if (state == NULL) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
}
- result->priv = state;
-
- state->cli = cli;
- state->pipe_name = cli_get_pipe_name_from_iface(
- state, abstract_syntax);
-
- fnum = cli_nt_create(cli, state->pipe_name, DESIRED_ACCESS_PIPE);
- if (fnum == -1) {
- DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
- "to machine %s. Error was %s\n", state->pipe_name,
- cli->desthost, cli_errstr(cli)));
- TALLOC_FREE(result);
- return cli_get_nt_error(cli);
+
+ req = rpc_transport_np_init_send(frame, ev, cli, abstract_syntax);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
}
- state->fnum = fnum;
- talloc_set_destructor(state, rpc_transport_np_state_destructor);
- result->write_send = rpc_np_write_send;
- result->write_recv = rpc_np_write_recv;
- result->read_send = rpc_np_read_send;
- result->read_recv = rpc_np_read_recv;
- result->trans_send = rpc_np_trans_send;
- result->trans_recv = rpc_np_trans_recv;
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
- *presult = result;
- return NT_STATUS_OK;
+ status = rpc_transport_np_init_recv(req, mem_ctx, presult);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
}
struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c
new file mode 100644
index 0000000000..bf4aa65dae
--- /dev/null
+++ b/source3/rpc_client/rpc_transport_smbd.c
@@ -0,0 +1,694 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC client transport over named pipes to a child smbd
+ * 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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+/**
+ * struct rpc_cli_smbd_conn represents a forked smbd. This structure should
+ * exist only once per process which does the rpc calls.
+ *
+ * RPC pipe handles can be attached to this smbd connection with
+ * rpc_pipe_open_local().
+ *
+ * For this to work right, we can not use rpc_transport_np directly, because
+ * the child smbd wants to write its DEBUG output somewhere. We redirect the
+ * child's output to rpc_cli_smbd_conn->stdout_fd. While the RPC calls are
+ * active, we have an event context available and attach a fd event to the
+ * stdout_df.
+ */
+
+struct rpc_cli_smbd_conn {
+ /**
+ * The smb connection to handle the named pipe traffic over
+ */
+ struct cli_state *cli;
+
+ /**
+ * Attached to stdout in the forked smbd, this is where smbd will
+ * print its DEBUG.
+ */
+ int stdout_fd;
+
+ /**
+ * Custom callback provided by the owner of the
+ * rpc_cli_smbd_conn. Here we send the smbd DEBUG output. Can be NULL.
+ */
+ struct {
+ void (*fn)(char *buf, size_t len, void *priv);
+ void *priv;
+ } stdout_callback ;
+};
+
+/**
+ * Event handler to be called whenever the forked smbd prints debugging
+ * output.
+ */
+
+static void rpc_cli_smbd_stdout_reader(struct event_context *ev,
+ struct fd_event *fde,
+ uint16_t flags, void *priv)
+{
+ struct rpc_cli_smbd_conn *conn = talloc_get_type_abort(
+ priv, struct rpc_cli_smbd_conn);
+ char buf[1024];
+ ssize_t nread;
+
+ if ((flags & EVENT_FD_READ) == 0) {
+ return;
+ }
+
+ nread = read(conn->stdout_fd, buf, sizeof(buf)-1);
+ if (nread < 0) {
+ DEBUG(0, ("Could not read from smbd stdout: %s\n",
+ strerror(errno)));
+ TALLOC_FREE(fde);
+ return;
+ }
+ if (nread == 0) {
+ DEBUG(0, ("EOF from smbd stdout\n"));
+ TALLOC_FREE(fde);
+ return;
+ }
+
+ if (conn->stdout_callback.fn != NULL) {
+ conn->stdout_callback.fn(buf, nread,
+ conn->stdout_callback.priv);
+ }
+}
+
+/**
+ * struct rpc_transport_smbd_state is the link from a struct rpc_pipe_client
+ * to the rpc_cli_smbd_conn. We use a named pipe transport as a subtransport.
+ */
+
+struct rpc_transport_smbd_state {
+ struct rpc_cli_smbd_conn *conn;
+ struct rpc_cli_transport *sub_transp;
+};
+
+static int rpc_cli_smbd_conn_destructor(struct rpc_cli_smbd_conn *conn)
+{
+ if (conn->cli != NULL) {
+ cli_shutdown(conn->cli);
+ conn->cli = NULL;
+ }
+ if (conn->stdout_fd != -1) {
+ close(conn->stdout_fd);
+ conn->stdout_fd = -1;
+ }
+ return 0;
+}
+
+/*
+ * Do the negprot/sesssetup/tcon to an anonymous ipc$ connection
+ */
+
+struct get_anon_ipc_state {
+ struct event_context *ev;
+ struct cli_state *cli;
+};
+
+static void get_anon_ipc_negprot_done(struct async_req *subreq);
+static void get_anon_ipc_sesssetup_done(struct async_req *subreq);
+static void get_anon_ipc_tcon_done(struct async_req *subreq);
+
+static struct async_req *get_anon_ipc_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli)
+{
+ struct async_req *result, *subreq;
+ struct get_anon_ipc_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct get_anon_ipc_state)) {
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->cli = cli;
+
+ subreq = cli_negprot_send(state, ev, cli);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = get_anon_ipc_negprot_done;
+ subreq->async.priv = result;
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void get_anon_ipc_negprot_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct get_anon_ipc_state *state = talloc_get_type_abort(
+ req->private_data, struct get_anon_ipc_state);
+ NTSTATUS status;
+
+ status = cli_negprot_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+
+ subreq = cli_session_setup_guest_send(state, state->ev, state->cli);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = get_anon_ipc_sesssetup_done;
+ subreq->async.priv = req;
+}
+
+static void get_anon_ipc_sesssetup_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct get_anon_ipc_state *state = talloc_get_type_abort(
+ req->private_data, struct get_anon_ipc_state);
+ NTSTATUS status;
+
+ status = cli_session_setup_guest_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+
+ subreq = cli_tcon_andx_send(state, state->ev, state->cli,
+ "IPC$", "IPC", NULL, 0);
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+ subreq->async.fn = get_anon_ipc_tcon_done;
+ subreq->async.priv = req;
+}
+
+static void get_anon_ipc_tcon_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = cli_tcon_andx_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+ async_req_done(req);
+}
+
+static NTSTATUS get_anon_ipc_recv(struct async_req *req)
+{
+ return async_req_simple_recv_ntstatus(req);
+}
+
+struct rpc_cli_smbd_conn_init_state {
+ struct event_context *ev;
+ struct rpc_cli_smbd_conn *conn;
+};
+
+static void rpc_cli_smbd_conn_init_done(struct async_req *subreq);
+
+struct async_req *rpc_cli_smbd_conn_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ void (*stdout_callback)(char *buf,
+ size_t len,
+ void *priv),
+ void *priv)
+{
+ struct async_req *result, *subreq;
+ struct rpc_cli_smbd_conn_init_state *state;
+ int smb_sock[2];
+ int stdout_pipe[2];
+ NTSTATUS status;
+ pid_t pid;
+ int ret;
+
+ smb_sock[0] = smb_sock[1] = stdout_pipe[0] = stdout_pipe[1] = -1;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_cli_smbd_conn_init_state)) {
+ return NULL;
+ }
+ state->ev = ev;
+
+ state->conn = talloc(state, struct rpc_cli_smbd_conn);
+ if (state->conn == NULL) {
+ goto nomem;
+ }
+
+ state->conn->cli = cli_initialise();
+ if (state->conn->cli == NULL) {
+ goto nomem;
+ }
+ state->conn->stdout_fd = -1;
+ state->conn->stdout_callback.fn = stdout_callback;
+ state->conn->stdout_callback.priv = priv;
+ talloc_set_destructor(state->conn, rpc_cli_smbd_conn_destructor);
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, smb_sock);
+ if (ret == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto post_status;
+ }
+ ret = pipe(stdout_pipe);
+ if (ret == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto post_status;
+ }
+
+ pid = sys_fork();
+ if (pid == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto post_status;
+ }
+ if (pid == 0) {
+ char *smbd_cmd;
+
+ close(smb_sock[0]);
+ close(stdout_pipe[0]);
+ close(0);
+ if (dup(smb_sock[1]) == -1) {
+ exit(1);
+ }
+ close(smb_sock[1]);
+ close(1);
+ if (dup(stdout_pipe[1]) == -1) {
+ exit(1);
+ }
+ close(stdout_pipe[1]);
+
+ smbd_cmd = getenv("SMB_PATH");
+
+ if ((smbd_cmd == NULL)
+ && (asprintf(&smbd_cmd, "%s/smbd", get_dyn_SBINDIR())
+ == -1)) {
+ printf("no memory");
+ exit(1);
+ }
+ if (asprintf(&smbd_cmd, "%s -F -S", smbd_cmd) == -1) {
+ printf("no memory");
+ exit(1);
+ }
+
+ exit(system(smbd_cmd));
+ }
+
+ state->conn->cli->fd = smb_sock[0];
+ smb_sock[0] = -1;
+ close(smb_sock[1]);
+ smb_sock[1] = -1;
+
+ state->conn->stdout_fd = stdout_pipe[0];
+ stdout_pipe[0] = -1;
+ close(stdout_pipe[1]);
+ stdout_pipe[1] = -1;
+
+ subreq = get_anon_ipc_send(state, ev, state->conn->cli);
+ if (subreq == NULL) {
+ goto nomem;
+ }
+
+ if (event_add_fd(ev, subreq, state->conn->stdout_fd, EVENT_FD_READ,
+ rpc_cli_smbd_stdout_reader, state->conn) == NULL) {
+ goto nomem;
+ }
+
+ subreq->async.fn = rpc_cli_smbd_conn_init_done;
+ subreq->async.priv = result;
+ return result;
+
+ nomem:
+ status = NT_STATUS_NO_MEMORY;
+ post_status:
+ if (smb_sock[0] != -1) {
+ close(smb_sock[0]);
+ }
+ if (smb_sock[1] != -1) {
+ close(smb_sock[1]);
+ }
+ if (stdout_pipe[0] != -1) {
+ close(stdout_pipe[0]);
+ }
+ if (stdout_pipe[1] != -1) {
+ close(stdout_pipe[1]);
+ }
+ if (async_post_ntstatus(result, ev, status)) {
+ return result;
+ }
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_cli_smbd_conn_init_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = get_anon_ipc_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+ async_req_done(req);
+}
+
+NTSTATUS rpc_cli_smbd_conn_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn **pconn)
+{
+ struct rpc_cli_smbd_conn_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_cli_smbd_conn_init_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *pconn = talloc_move(mem_ctx, &state->conn);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS rpc_cli_smbd_conn_init(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn **pconn,
+ void (*stdout_callback)(char *buf,
+ size_t len,
+ void *priv),
+ void *priv)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = rpc_cli_smbd_conn_init_send(frame, ev, stdout_callback, priv);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = rpc_cli_smbd_conn_init_recv(req, mem_ctx, pconn);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
+struct rpc_smbd_write_state {
+ struct rpc_cli_transport *sub_transp;
+ ssize_t written;
+};
+
+static void rpc_smbd_write_done(struct async_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)
+{
+ struct rpc_transport_smbd_state *transp = talloc_get_type_abort(
+ priv, struct rpc_transport_smbd_state);
+ struct async_req *result, *subreq;
+ struct rpc_smbd_write_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_smbd_write_state)) {
+ return NULL;
+ }
+ state->sub_transp = transp->sub_transp;
+
+ subreq = transp->sub_transp->write_send(state, ev, data, size,
+ transp->sub_transp->priv);
+ if (subreq == NULL) {
+ goto fail;
+ }
+
+ if (event_add_fd(ev, subreq, transp->conn->stdout_fd, EVENT_FD_READ,
+ rpc_cli_smbd_stdout_reader, transp->conn) == NULL) {
+ goto fail;
+ }
+
+ subreq->async.fn = rpc_smbd_write_done;
+ subreq->async.priv = result;
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_smbd_write_done(struct async_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);
+ 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);
+ return;
+ }
+ async_req_done(req);
+}
+
+static NTSTATUS rpc_smbd_write_recv(struct async_req *req, ssize_t *pwritten)
+{
+ struct rpc_smbd_write_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_smbd_write_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *pwritten = state->written;
+ return NT_STATUS_OK;
+}
+
+struct rpc_smbd_read_state {
+ struct rpc_cli_transport *sub_transp;
+ ssize_t received;
+};
+
+static void rpc_smbd_read_done(struct async_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)
+{
+ struct rpc_transport_smbd_state *transp = talloc_get_type_abort(
+ priv, struct rpc_transport_smbd_state);
+ struct async_req *result, *subreq;
+ struct rpc_smbd_read_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_smbd_read_state)) {
+ return NULL;
+ }
+ state->sub_transp = transp->sub_transp;
+
+ subreq = transp->sub_transp->read_send(state, ev, data, size,
+ transp->sub_transp->priv);
+ if (subreq == NULL) {
+ goto fail;
+ }
+
+ if (event_add_fd(ev, subreq, transp->conn->stdout_fd, EVENT_FD_READ,
+ rpc_cli_smbd_stdout_reader, transp->conn) == NULL) {
+ goto fail;
+ }
+
+ subreq->async.fn = rpc_smbd_read_done;
+ subreq->async.priv = result;
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_smbd_read_done(struct async_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);
+ 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);
+ return;
+ }
+ async_req_done(req);
+}
+
+static NTSTATUS rpc_smbd_read_recv(struct async_req *req, ssize_t *preceived)
+{
+ struct rpc_smbd_read_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_smbd_read_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *preceived = state->received;
+ return NT_STATUS_OK;
+}
+
+struct rpc_transport_smbd_init_state {
+ struct rpc_cli_transport *transport;
+ struct rpc_transport_smbd_state *transport_smbd;
+};
+
+static void rpc_transport_smbd_init_done(struct async_req *subreq);
+
+struct async_req *rpc_transport_smbd_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *abstract_syntax)
+{
+ struct async_req *result, *subreq;
+ struct rpc_transport_smbd_init_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_transport_smbd_init_state)) {
+ return NULL;
+ }
+
+ state->transport = talloc(state, struct rpc_cli_transport);
+ if (state->transport == NULL) {
+ goto fail;
+ }
+ state->transport_smbd = talloc(state->transport,
+ struct rpc_transport_smbd_state);
+ if (state->transport_smbd == NULL) {
+ goto fail;
+ }
+ state->transport_smbd->conn = conn;
+ state->transport->priv = state->transport_smbd;
+
+ subreq = rpc_transport_np_init_send(state, ev, conn->cli,
+ abstract_syntax);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = rpc_transport_smbd_init_done;
+ subreq->async.priv = result;
+ return result;
+
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_transport_smbd_init_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct rpc_transport_smbd_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_smbd_init_state);
+ NTSTATUS status;
+
+ status = rpc_transport_np_init_recv(
+ subreq, state->transport_smbd,
+ &state->transport_smbd->sub_transp);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+ async_req_done(req);
+}
+
+NTSTATUS rpc_transport_smbd_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult)
+{
+ struct rpc_transport_smbd_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_smbd_init_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ state->transport->write_send = rpc_smbd_write_send;
+ state->transport->write_recv = rpc_smbd_write_recv;
+ state->transport->read_send = rpc_smbd_read_send;
+ state->transport->read_recv = rpc_smbd_read_recv;
+ state->transport->trans_send = NULL;
+ state->transport->trans_recv = NULL;
+
+ *presult = talloc_move(mem_ctx, &state->transport);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx,
+ struct rpc_cli_smbd_conn *conn,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_cli_transport **presult)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = rpc_transport_smbd_init_send(frame, ev, conn, abstract_syntax);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = rpc_transport_smbd_init_recv(req, mem_ctx, presult);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
diff --git a/source3/rpc_parse/parse_eventlog.c b/source3/rpc_parse/parse_eventlog.c
deleted file mode 100644
index 40930a2500..0000000000
--- a/source3/rpc_parse/parse_eventlog.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Marcin Krzysztof Porwit 2005.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_PARSE
-
-/********************************************************************
-********************************************************************/
-
-bool eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u,
- prs_struct *ps, int depth)
-{
- if(q_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "eventlog_io_q_read_eventlog");
- depth++;
-
- if(!(prs_align(ps)))
- return False;
-
- if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
- return False;
-
- if(!(prs_uint32("read flags", ps, depth, &(q_u->flags))))
- return False;
-
- if(!(prs_uint32("read offset", ps, depth, &(q_u->offset))))
- return False;
-
- if(!(prs_uint32("read buf size", ps, depth, &(q_u->max_read_size))))
- return False;
-
- return True;
-}
-
-static bool smb_io_eventlog_entry(const char *name, prs_struct *ps, int depth, Eventlog_entry *entry)
-{
- if(entry == NULL)
- return False;
-
- prs_debug(ps, depth, name, "smb_io_eventlog_entry");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!(prs_uint32("length", ps, depth, &(entry->record.length))))
- return False;
- if(!(prs_uint32("reserved", ps, depth, &(entry->record.reserved1))))
- return False;
- if(!(prs_uint32("record number", ps, depth, &(entry->record.record_number))))
- return False;
- if(!(prs_uint32("time generated", ps, depth, &(entry->record.time_generated))))
- return False;
- if(!(prs_uint32("time written", ps, depth, &(entry->record.time_written))))
- return False;
- if(!(prs_uint32("event id", ps, depth, &(entry->record.event_id))))
- return False;
- if(!(prs_uint16("event type", ps, depth, &(entry->record.event_type))))
- return False;
- if(!(prs_uint16("num strings", ps, depth, &(entry->record.num_strings))))
- return False;
- if(!(prs_uint16("event category", ps, depth, &(entry->record.event_category))))
- return False;
- if(!(prs_uint16("reserved2", ps, depth, &(entry->record.reserved2))))
- return False;
- if(!(prs_uint32("closing record", ps, depth, &(entry->record.closing_record_number))))
- return False;
- if(!(prs_uint32("string offset", ps, depth, &(entry->record.string_offset))))
- return False;
- if(!(prs_uint32("user sid length", ps, depth, &(entry->record.user_sid_length))))
- return False;
- if(!(prs_uint32("user sid offset", ps, depth, &(entry->record.user_sid_offset))))
- return False;
- if(!(prs_uint32("data length", ps, depth, &(entry->record.data_length))))
- return False;
- if(!(prs_uint32("data offset", ps, depth, &(entry->record.data_offset))))
- return False;
- if(!(prs_align(ps)))
- return False;
-
- /* Now encoding data */
-
- if(!(prs_uint8s(False, "buffer", ps, depth, entry->data,
- entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length))))
- {
- return False;
- }
-
- if(!(prs_align(ps)))
- return False;
-
- if(!(prs_uint32("length 2", ps, depth, &(entry->record.length))))
- return False;
-
- return True;
-}
-
-/** Structure of response seems to be:
- DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size
- for i=0..n
- EVENTLOGRECORD record
- DWORD sent_size -- sum of EVENTLOGRECORD lengths if records returned, 0 otherwise
- DWORD real_size -- 0 if records returned, otherwise length of next record to be returned
- WERROR status */
-bool eventlog_io_r_read_eventlog(const char *desc,
- EVENTLOG_Q_READ_EVENTLOG *q_u,
- EVENTLOG_R_READ_EVENTLOG *r_u,
- prs_struct *ps,
- int depth)
-{
- Eventlog_entry *entry;
- uint32 record_written = 0;
- uint32 record_total = 0;
-
- if(r_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "eventlog_io_r_read_eventlog");
- depth++;
-
- /* First, see if we've read more logs than we can output */
-
- if(r_u->num_bytes_in_resp > q_u->max_read_size) {
- entry = r_u->entry;
-
- /* remove the size of the last entry from the list */
-
- while(entry->next != NULL)
- entry = entry->next;
-
- r_u->num_bytes_in_resp -= entry->record.length;
-
- /* do not output the last log entry */
-
- r_u->num_records--;
- }
-
- entry = r_u->entry;
- record_total = r_u->num_records;
-
- if(r_u->num_bytes_in_resp != 0)
- r_u->sent_size = r_u->num_bytes_in_resp;
- else
- r_u->real_size = r_u->bytes_in_next_record;
-
- if(!(prs_align(ps)))
- return False;
- if(!(prs_uint32("bytes in resp", ps, depth, &(q_u->max_read_size))))
- return False;
-
- while(entry != NULL && record_written < record_total)
- {
- DEBUG(11, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total));
-
- /* Encode the actual eventlog record record */
-
- if (!(smb_io_eventlog_entry("entry", ps, depth, entry)))
- return false;
-
- entry = entry->next;
- record_written++;
-
- } /* end of encoding EVENTLOGRECORD */
-
- /* Now pad with whitespace until the end of the response buffer */
-
- if (q_u->max_read_size - r_u->num_bytes_in_resp) {
- r_u->end_of_entries_padding = PRS_ALLOC_MEM(ps, uint8_t, q_u->max_read_size - r_u->num_bytes_in_resp);
- if (!r_u->end_of_entries_padding) {
- return False;
- }
-
- if(!(prs_uint8s(False, "end of entries padding", ps,
- depth, r_u->end_of_entries_padding,
- (q_u->max_read_size - r_u->num_bytes_in_resp)))) {
- return False;
- }
- }
-
- /* We had better be DWORD aligned here */
-
- if(!(prs_uint32("sent size", ps, depth, &(r_u->sent_size))))
- return False;
- if(!(prs_uint32("real size", ps, depth, &(r_u->real_size))))
- return False;
- if(!(prs_ntstatus("status code", ps, depth, &r_u->status)))
- return False;
-
- return True;
-}
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 7d1d00a373..38d5b95376 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -26,27 +26,6 @@
#define DBGC_CLASS DBGC_RPC_PARSE
/*******************************************************************
- Reads or writes a UTIME type.
-********************************************************************/
-
-static bool smb_io_utime(const char *desc, UTIME *t, prs_struct *ps, int depth)
-{
- if (t == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_utime");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32 ("time", ps, depth, &t->time))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes an NTTIME structure.
********************************************************************/
@@ -89,53 +68,6 @@ bool smb_io_nttime(const char *desc, prs_struct *ps, int depth, NTTIME *nttime)
}
/*******************************************************************
- Gets an enumeration handle from an ENUM_HND structure.
-********************************************************************/
-
-uint32 get_enum_hnd(ENUM_HND *enh)
-{
- return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
-}
-
-/*******************************************************************
- Inits an ENUM_HND structure.
-********************************************************************/
-
-void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
-{
- DEBUG(5,("smb_io_enum_hnd\n"));
-
- enh->ptr_hnd = (hnd != 0) ? 1 : 0;
- enh->handle = hnd;
-}
-
-/*******************************************************************
- Reads or writes an ENUM_HND structure.
-********************************************************************/
-
-bool smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
-{
- if (hnd == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_enum_hnd");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
- return False;
-
- if (hnd->ptr_hnd != 0) {
- if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a DOM_SID structure.
********************************************************************/
@@ -174,67 +106,6 @@ bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
}
/*******************************************************************
- Inits a DOM_SID2 structure.
-********************************************************************/
-
-void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
-{
- sid2->sid = *sid;
- sid2->num_auths = sid2->sid.num_auths;
-}
-
-/*******************************************************************
- Reads or writes a DOM_SID2 structure.
-********************************************************************/
-
-bool smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2)
-{
- uint32 data_p;
-
- /* caputure the pointer value to stream */
-
- data_p = *sid2 ? 0xf000baaa : 0;
-
- if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
- return False;
-
- /* we're done if there is no data */
-
- if ( !data_p )
- return True;
-
- if (UNMARSHALLING(ps)) {
- if ( !(*sid2 = PRS_ALLOC_MEM(ps, DOM_SID2, 1)) )
- return False;
- }
-
- return True;
-}
-/*******************************************************************
- Reads or writes a DOM_SID2 structure.
-********************************************************************/
-
-bool smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
-{
- if (sid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_dom_sid2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
- return False;
-
- if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes a struct GUID
********************************************************************/
@@ -263,163 +134,6 @@ bool smb_io_uuid(const char *desc, struct GUID *uuid,
}
/*******************************************************************
-creates a STRHDR structure.
-********************************************************************/
-
-void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
-{
- hdr->str_max_len = max_len;
- hdr->str_str_len = len;
- hdr->buffer = buffer;
-}
-
-/*******************************************************************
- Reads or writes a STRHDR structure.
-********************************************************************/
-
-bool smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth)
-{
- if (hdr == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_strhdr");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
- return False;
- if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
- return False;
- if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a UNIHDR structure.
-********************************************************************/
-
-void init_uni_hdr(UNIHDR *hdr, UNISTR2 *str2)
-{
- hdr->uni_str_len = 2 * (str2->uni_str_len);
- hdr->uni_max_len = 2 * (str2->uni_max_len);
- hdr->buffer = (str2->uni_str_len != 0) ? 1 : 0;
-}
-
-/*******************************************************************
- Reads or writes a UNIHDR structure.
-********************************************************************/
-
-bool smb_io_unihdr(const char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
-{
- if (hdr == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_unihdr");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
- return False;
- if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
- return False;
- if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a BUFHDR structure.
-********************************************************************/
-
-void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
-{
- hdr->buf_max_len = max_len;
- hdr->buf_len = len;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool smb_io_hdrbuf_pre(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
-{
- (*offset) = prs_offset(ps);
- if (ps->io) {
-
- /* reading. */
-
- if(!smb_io_hdrbuf(desc, hdr, ps, depth))
- return False;
-
- } else {
-
- /* writing. */
-
- if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
- Does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
- uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
-{
- if (!ps->io) {
- /* writing: go back and do a retrospective job. i hate this */
-
- uint32 old_offset = prs_offset(ps);
-
- init_buf_hdr(hdr, max_len, len);
- if(!prs_set_offset(ps, ptr_hdrbuf))
- return False;
- if(!smb_io_hdrbuf(desc, hdr, ps, depth))
- return False;
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a BUFHDR structure.
-********************************************************************/
-
-bool smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
-{
- if (hdr == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_hdrbuf");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
- return False;
- if(!prs_uint32("buf_len ", ps, depth, &hdr->buf_len))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Inits a UNISTR structure.
********************************************************************/
@@ -458,82 +172,6 @@ bool smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
}
/*******************************************************************
- Allocate the RPC_DATA_BLOB memory.
-********************************************************************/
-
-static void create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
-{
- if (len) {
- str->buffer = (uint8 *)TALLOC_ZERO(talloc_tos(), len);
- if (str->buffer == NULL)
- smb_panic("create_rpc_blob: talloc fail");
- str->buf_len = len;
- } else {
- str->buffer = NULL;
- str->buf_len = 0;
- }
-}
-
-/*******************************************************************
- Inits a RPC_DATA_BLOB structure from a uint32
-********************************************************************/
-
-void init_rpc_blob_uint32(RPC_DATA_BLOB *str, uint32 val)
-{
- ZERO_STRUCTP(str);
-
- /* set up string lengths. */
- create_rpc_blob(str, sizeof(uint32));
- SIVAL(str->buffer, 0, val);
-}
-
-/*******************************************************************
- Inits a RPC_DATA_BLOB structure.
-********************************************************************/
-
-void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len)
-{
- ZERO_STRUCTP(str);
-
- /* set up string lengths. */
- if (len) {
- create_rpc_blob(str, len*2);
- rpcstr_push(str->buffer, buf, (size_t)str->buf_len, STR_TERMINATE);
- }
-}
-
-/*******************************************************************
- Inits a RPC_DATA_BLOB structure from a hex string.
-********************************************************************/
-
-void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf)
-{
- ZERO_STRUCTP(str);
- if (buf && *buf) {
- size_t len = strlen(buf);
- create_rpc_blob(str, len);
- str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len,
- buf, len);
- }
-}
-
-/*******************************************************************
- Inits a RPC_DATA_BLOB structure.
-********************************************************************/
-
-void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len)
-{
- ZERO_STRUCTP(str);
-
- /* max buffer size (allocated size) */
- if (buf != NULL && len) {
- create_rpc_blob(str, len);
- memcpy(str->buffer, buf, len);
- }
- str->buf_len = len;
-}
-
-/*******************************************************************
reads or writes a BUFFER5 structure.
the buf_len member tells you how large the buffer is.
********************************************************************/
@@ -609,77 +247,6 @@ void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
}
/*******************************************************************
- Creates a STRING2 structure.
-********************************************************************/
-
-void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len)
-{
- /* set up string lengths. */
- SMB_ASSERT(max_len >= str_len);
-
- /* Ensure buf is valid if str_len was set. Coverity check. */
- if (str_len && !buf) {
- return;
- }
-
- str->str_max_len = max_len;
- str->offset = 0;
- str->str_str_len = str_len;
-
- /* store the string */
- if(str_len != 0) {
- str->buffer = (uint8 *)TALLOC_ZERO(talloc_tos(),
- str->str_max_len);
- if (str->buffer == NULL)
- smb_panic("init_string2: malloc fail");
- memcpy(str->buffer, buf, str_len);
- }
-}
-
-/*******************************************************************
- Reads or writes a STRING2 structure.
- XXXX NOTE: STRING2 structures need NOT be null-terminated.
- the str_str_len member tells you how long the string is;
- the str_max_len member tells you how large the buffer is.
-********************************************************************/
-
-bool smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
-{
- if (str2 == NULL)
- return False;
-
- if (buffer) {
-
- prs_debug(ps, depth, desc, "smb_io_string2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
- return False;
- if(!prs_uint32("offset ", ps, depth, &str2->offset))
- return False;
- if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
- return False;
-
- /* buffer advanced by indicated length of string
- NOT by searching for null-termination */
- if(!prs_string2(True, "buffer ", ps, depth, str2))
- return False;
-
- } else {
-
- prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
- depth++;
- memset((char *)str2, '\0', sizeof(*str2));
-
- }
-
- return True;
-}
-
-/*******************************************************************
Inits a UNISTR2 structure.
********************************************************************/
@@ -735,36 +302,6 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
str->uni_max_len++;
}
-/*******************************************************************
- Inits a UNISTR4 structure.
-********************************************************************/
-
-void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
-{
- uni4->string = TALLOC_P( talloc_tos(), UNISTR2 );
- if (!uni4->string) {
- smb_panic("init_unistr4: talloc fail");
- return;
- }
- init_unistr2( uni4->string, buf, flags );
-
- uni4->length = 2 * (uni4->string->uni_str_len);
- uni4->size = 2 * (uni4->string->uni_max_len);
-}
-
-void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
-{
- uni4->string = TALLOC_P( ctx, UNISTR2 );
- if (!uni4->string) {
- smb_panic("init_unistr4_w: talloc fail");
- return;
- }
- init_unistr2_w( ctx, uni4->string, buf );
-
- uni4->length = 2 * (uni4->string->uni_str_len);
- uni4->size = 2 * (uni4->string->uni_max_len);
-}
-
/**
* Inits a UNISTR2 structure.
* @param ctx talloc context to allocate string on
@@ -970,583 +507,6 @@ bool smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *
}
/*******************************************************************
- now read/write UNISTR4
-********************************************************************/
-
-bool prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
-{
- void *ptr;
- prs_debug(ps, depth, desc, "prs_unistr4");
- depth++;
-
- if ( !prs_uint16("length", ps, depth, &uni4->length ))
- return False;
- if ( !prs_uint16("size", ps, depth, &uni4->size ))
- return False;
-
- ptr = uni4->string;
-
- if ( !prs_pointer( desc, ps, depth, &ptr, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
- return False;
-
- uni4->string = (UNISTR2 *)ptr;
-
- return True;
-}
-
-/*******************************************************************
- now read/write UNISTR4 header
-********************************************************************/
-
-bool prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
-{
- prs_debug(ps, depth, desc, "prs_unistr4_hdr");
- depth++;
-
- if ( !prs_uint16("length", ps, depth, &uni4->length) )
- return False;
- if ( !prs_uint16("size", ps, depth, &uni4->size) )
- return False;
- if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
- return False;
-
- return True;
-}
-
-/*******************************************************************
- now read/write UNISTR4 string
-********************************************************************/
-
-bool prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
-{
- prs_debug(ps, depth, desc, "prs_unistr4_str");
- depth++;
-
- if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a UNISTR4_ARRAY structure.
-********************************************************************/
-
-bool prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
-{
- unsigned int i;
-
- prs_debug(ps, depth, desc, "prs_unistr4_array");
- depth++;
-
- if(!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (array->count) {
- if ( !(array->strings = TALLOC_ZERO_ARRAY( talloc_tos(), UNISTR4, array->count)) )
- return False;
- } else {
- array->strings = NULL;
- }
- }
-
- /* write the headers and then the actual string buffer */
-
- for ( i=0; i<array->count; i++ ) {
- if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) )
- return False;
- }
-
- return True;
-}
-
-/********************************************************************
- initialise a UNISTR_ARRAY from a char**
-********************************************************************/
-
-bool init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
-{
- unsigned int i;
-
- array->count = count;
-
- /* allocate memory for the array of UNISTR4 objects */
-
- if (array->count) {
- if ( !(array->strings = TALLOC_ZERO_ARRAY(talloc_tos(), UNISTR4, count )) )
- return False;
- } else {
- array->strings = NULL;
- }
-
- for ( i=0; i<count; i++ )
- init_unistr4( &array->strings[i], strings[i], UNI_STR_TERMINATE );
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_RID structure.
-********************************************************************/
-
-void init_dom_rid(DOM_RID *prid, uint32 rid, uint16 type, uint32 idx)
-{
- prid->type = type;
- prid->rid = rid;
- prid->rid_idx = idx;
-}
-
-/*******************************************************************
- Reads or writes a DOM_RID structure.
-********************************************************************/
-
-bool smb_io_dom_rid(const char *desc, DOM_RID *rid, prs_struct *ps, int depth)
-{
- if (rid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_dom_rid");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint16("type ", ps, depth, &rid->type))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("rid ", ps, depth, &rid->rid))
- return False;
- if(!prs_uint32("rid_idx", ps, depth, &rid->rid_idx))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a DOM_RID2 structure.
-********************************************************************/
-
-bool smb_io_dom_rid2(const char *desc, DOM_RID2 *rid, prs_struct *ps, int depth)
-{
- if (rid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_dom_rid2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint16("type ", ps, depth, &rid->type))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("rid ", ps, depth, &rid->rid))
- return False;
- if(!prs_uint32("rid_idx", ps, depth, &rid->rid_idx))
- return False;
- if(!prs_uint32("unknown", ps, depth, &rid->unknown))
- return False;
-
- return True;
-}
-
-
-/*******************************************************************
-creates a DOM_RID3 structure.
-********************************************************************/
-
-void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
-{
- rid3->rid = rid;
- rid3->type1 = type;
- rid3->ptr_type = 0x1; /* non-zero, basically. */
- rid3->type2 = 0x1;
- rid3->unk = type;
-}
-
-/*******************************************************************
-reads or writes a DOM_RID3 structure.
-********************************************************************/
-
-bool smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
-{
- if (rid3 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_dom_rid3");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("rid ", ps, depth, &rid3->rid))
- return False;
- if(!prs_uint32("type1 ", ps, depth, &rid3->type1))
- return False;
- if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
- return False;
- if(!prs_uint32("type2 ", ps, depth, &rid3->type2))
- return False;
- if(!prs_uint32("unk ", ps, depth, &rid3->unk))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_RID4 structure.
-********************************************************************/
-
-void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
-{
- rid4->unknown = unknown;
- rid4->attr = attr;
- rid4->rid = rid;
-}
-
-/*******************************************************************
- Inits a DOM_CLNT_SRV structure.
-********************************************************************/
-
-void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv,
- const char *comp_name)
-{
- DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
-
- if (logon_srv != NULL) {
- logcln->undoc_buffer = 1;
- init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
- } else {
- logcln->undoc_buffer = 0;
- }
-
- if (comp_name != NULL) {
- logcln->undoc_buffer2 = 1;
- init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
- } else {
- logcln->undoc_buffer2 = 0;
- }
-}
-
-/*******************************************************************
- Inits or writes a DOM_CLNT_SRV structure.
-********************************************************************/
-
-bool smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
-{
- if (logcln == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_clnt_srv");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
- return False;
-
- if (logcln->undoc_buffer != 0) {
- if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
- return False;
- }
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
- return False;
-
- if (logcln->undoc_buffer2 != 0) {
- if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_LOG_INFO structure.
-********************************************************************/
-
-void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name)
-{
- DEBUG(5,("make_log_info %d\n", __LINE__));
-
- loginfo->undoc_buffer = 1;
-
- init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
- init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
-
- loginfo->sec_chan = sec_chan;
-
- init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
-}
-
-/*******************************************************************
- Reads or writes a DOM_LOG_INFO structure.
-********************************************************************/
-
-bool smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
-{
- if (loginfo == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_log_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
- return False;
-
- if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
- return False;
- if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
- return False;
-
- if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
- return False;
-
- if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a DOM_CHAL structure.
-********************************************************************/
-
-bool smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
-{
- if (chal == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_chal");
- depth++;
-
- if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a DOM_CRED structure.
-********************************************************************/
-
-bool smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
-{
- if (cred == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_cred");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_chal ("", &cred->challenge, ps, depth))
- return False;
-
- if(!smb_io_utime("", &cred->timestamp, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_CLNT_INFO2 structure.
-********************************************************************/
-
-void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
- const char *logon_srv, const char *comp_name,
- const DOM_CRED *clnt_cred)
-{
- DEBUG(5,("make_clnt_info: %d\n", __LINE__));
-
- init_clnt_srv(&clnt->login, logon_srv, comp_name);
-
- if (clnt_cred != NULL) {
- clnt->ptr_cred = 1;
- memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
- } else {
- clnt->ptr_cred = 0;
- }
-}
-
-/*******************************************************************
- Reads or writes a DOM_CLNT_INFO2 structure.
-********************************************************************/
-
-bool smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
-{
- if (clnt == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_clnt_info2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
- return False;
- if(!smb_io_cred("", &clnt->cred, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_CLNT_INFO structure.
-********************************************************************/
-
-void init_clnt_info(DOM_CLNT_INFO *clnt,
- const char *logon_srv, const char *acct_name,
- uint16 sec_chan, const char *comp_name,
- const DOM_CRED *cred)
-{
- DEBUG(5,("make_clnt_info\n"));
-
- init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
- memcpy(&clnt->cred, cred, sizeof(clnt->cred));
-}
-
-/*******************************************************************
- Reads or writes a DOM_CLNT_INFO structure.
-********************************************************************/
-
-bool smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
-{
- if (clnt == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_clnt_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_log_info("", &clnt->login, ps, depth))
- return False;
- if(!smb_io_cred("", &clnt->cred, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a DOM_LOGON_ID structure.
-********************************************************************/
-
-void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
-{
- DEBUG(5,("make_logon_id: %d\n", __LINE__));
-
- logonid->low = log_id_low;
- logonid->high = log_id_high;
-}
-
-/*******************************************************************
- Reads or writes a DOM_LOGON_ID structure.
-********************************************************************/
-
-bool smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
-{
- if (logonid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_logon_id");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("low ", ps, depth, &logonid->low ))
- return False;
- if(!prs_uint32("high", ps, depth, &logonid->high))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits an OWF_INFO structure.
-********************************************************************/
-
-void init_owf_info(OWF_INFO *hash, const uint8 data[16])
-{
- DEBUG(5,("init_owf_info: %d\n", __LINE__));
-
- if (data != NULL)
- memcpy(hash->data, data, sizeof(hash->data));
- else
- memset((char *)hash->data, '\0', sizeof(hash->data));
-}
-
-/*******************************************************************
- Reads or writes an OWF_INFO structure.
-********************************************************************/
-
-bool smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
-{
- if (hash == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_owf_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a DOM_GID structure.
-********************************************************************/
-
-bool smb_io_gid(const char *desc, DOM_GID *gid, prs_struct *ps, int depth)
-{
- if (gid == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_gid");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
- return False;
- if(!prs_uint32("attr ", ps, depth, &gid->attr))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Reads or writes an POLICY_HND structure.
********************************************************************/
@@ -1654,103 +614,6 @@ bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
}
/*******************************************************************
-reads or writes a BUFHDR2 structure.
-********************************************************************/
-bool smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_bufhdr2");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("info_level", ps, depth, &(hdr->info_level)))
- return False;
- if (!prs_uint32("length ", ps, depth, &(hdr->length )))
- return False;
- if (!prs_uint32("buffer ", ps, depth, &(hdr->buffer )))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a BUFHDR4 structure.
-********************************************************************/
-bool smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_bufhdr4");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("size", ps, depth, &hdr->size))
- return False;
- if (!prs_uint32("buffer", ps, depth, &hdr->buffer))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a RPC_DATA_BLOB structure.
-********************************************************************/
-
-bool smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_rpc_blob");
- depth++;
-
- if (!prs_align(ps))
- return False;
- if ( !prs_uint32("buf_len", ps, depth, &blob->buf_len) )
- return False;
-
- if ( blob->buf_len == 0 )
- return True;
-
- if (UNMARSHALLING(ps)) {
- blob->buffer = PRS_ALLOC_MEM(ps, uint8, blob->buf_len);
- if (!blob->buffer) {
- return False;
- }
- }
-
- if ( !prs_uint8s(True, "buffer", ps, depth, blob->buffer, blob->buf_len) )
- return False;
-
- return True;
-}
-
-/*******************************************************************
-creates a UNIHDR structure.
-********************************************************************/
-
-bool make_uni_hdr(UNIHDR *hdr, int len)
-{
- if (hdr == NULL)
- {
- return False;
- }
- hdr->uni_str_len = 2 * len;
- hdr->uni_max_len = 2 * len;
- hdr->buffer = len != 0 ? 1 : 0;
-
- return True;
-}
-
-/*******************************************************************
-creates a BUFHDR2 structure.
-********************************************************************/
-bool make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
-{
- hdr->info_level = info_level;
- hdr->length = length;
- hdr->buffer = buffer;
-
- return True;
-}
-
-/*******************************************************************
return the length of a UNISTR string.
********************************************************************/
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 1332a8311a..e8103ad866 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -1053,56 +1053,6 @@ bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUF
}
/******************************************************************
- Stream a string, length/buffer specified separately,
- in uint8 chars.
- ********************************************************************/
-
-bool prs_string2(bool charmode, const char *name, prs_struct *ps, int depth, STRING2 *str)
-{
- unsigned int i;
- char *q = prs_mem_get(ps, str->str_str_len);
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (str->str_str_len > str->str_max_len) {
- return False;
- }
- if (str->str_max_len) {
- str->buffer = PRS_ALLOC_MEM(ps,unsigned char, str->str_max_len);
- if (str->buffer == NULL)
- return False;
- } else {
- str->buffer = NULL;
- /* Return early to ensure Coverity isn't confused. */
- DEBUGADD(5,("%s%04x %s: \n", tab_depth(5,depth), ps->data_offset, name));
- return True;
- }
- }
-
- if (UNMARSHALLING(ps)) {
- for (i = 0; i < str->str_str_len; i++)
- str->buffer[i] = CVAL(q,i);
- } else {
- for (i = 0; i < str->str_str_len; i++)
- SCVAL(q, i, str->buffer[i]);
- }
-
- DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name));
- if (charmode)
- print_asc(5, (unsigned char*)str->buffer, str->str_str_len);
- else {
- for (i = 0; i < str->str_str_len; i++)
- DEBUG(5,("%02x ", str->buffer[i]));
- }
- DEBUGADD(5,("\n"));
-
- ps->data_offset += str->str_str_len;
-
- return True;
-}
-
-/******************************************************************
Stream a unicode string, length/buffer specified separately,
in uint16 chars. The unicode string is already in little-endian format.
********************************************************************/
diff --git a/source3/rpc_server/srv_eventlog.c b/source3/rpc_server/srv_eventlog.c
deleted file mode 100644
index 39e3115561..0000000000
--- a/source3/rpc_server/srv_eventlog.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Marcin Krzysztof Porwit 2005.
- * Copyright (C) Gerald Carter 2005 - 2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-#include "librpc/gen_ndr/srv_eventlog.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
-
-static bool proxy_eventlog_call(pipes_struct *p, uint8 opnum)
-{
- struct api_struct *fns;
- int n_fns;
-
- eventlog_get_pipe_fns(&fns, &n_fns);
-
- if (opnum >= n_fns)
- return False;
-
- if (fns[opnum].opnum != opnum) {
- smb_panic("EVENTLOG function table not sorted\n");
- }
-
- return fns[opnum].fn(p);
-}
-
-static bool api_eventlog_open_eventlog(pipes_struct *p)
-{
- return proxy_eventlog_call(p, NDR_EVENTLOG_OPENEVENTLOGW);
-}
-
-static bool api_eventlog_close_eventlog(pipes_struct *p)
-{
- return proxy_eventlog_call( p, NDR_EVENTLOG_CLOSEEVENTLOG );
-}
-
-static bool api_eventlog_get_num_records(pipes_struct *p)
-{
- return proxy_eventlog_call(p, NDR_EVENTLOG_GETNUMRECORDS);
-}
-
-static bool api_eventlog_get_oldest_entry(pipes_struct *p)
-{
- return proxy_eventlog_call(p, NDR_EVENTLOG_GETOLDESTRECORD);
-}
-
-static bool api_eventlog_read_eventlog(pipes_struct *p)
-{
- EVENTLOG_Q_READ_EVENTLOG q_u;
- EVENTLOG_R_READ_EVENTLOG r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if (!(eventlog_io_q_read_eventlog("", &q_u, data, 0))) {
- DEBUG(0, ("eventlog_io_q_read_eventlog: unable to unmarshall EVENTLOG_Q_READ_EVENTLOG.\n"));
- return False;
- }
-
- r_u.status = _eventlog_read_eventlog(p, &q_u, &r_u);
-
- if (!(eventlog_io_r_read_eventlog("", &q_u, &r_u, rdata, 0))) {
- DEBUG(0, ("eventlog_io_r_read_eventlog: unable to marshall EVENTLOG_R_READ_EVENTLOG.\n"));
- return False;
- }
-
- return True;
-}
-
-static bool api_eventlog_clear_eventlog(pipes_struct *p)
-{
- return proxy_eventlog_call(p, NDR_EVENTLOG_CLEAREVENTLOGW);
-}
-
-/*
- \pipe\eventlog commands
-*/
-struct api_struct api_eventlog_cmds[] =
-{
- {"EVENTLOG_OPENEVENTLOG", EVENTLOG_OPENEVENTLOG, api_eventlog_open_eventlog },
- {"EVENTLOG_CLOSEEVENTLOG", EVENTLOG_CLOSEEVENTLOG, api_eventlog_close_eventlog },
- {"EVENTLOG_GETNUMRECORDS", EVENTLOG_GETNUMRECORDS, api_eventlog_get_num_records },
- {"EVENTLOG_GETOLDESTENTRY", EVENTLOG_GETOLDESTENTRY, api_eventlog_get_oldest_entry },
- {"EVENTLOG_READEVENTLOG", EVENTLOG_READEVENTLOG, api_eventlog_read_eventlog },
- {"EVENTLOG_CLEAREVENTLOG", EVENTLOG_CLEAREVENTLOG, api_eventlog_clear_eventlog }
-};
-
-NTSTATUS rpc_eventlog2_init(void)
-{
- return rpc_srv_register(SMB_RPC_INTERFACE_VERSION,
- "eventlog", "eventlog", &ndr_table_eventlog,
- api_eventlog_cmds,
- sizeof(api_eventlog_cmds)/sizeof(struct api_struct));
-}
-
-void eventlog2_get_pipe_fns(struct api_struct **fns, int *n_fns)
-{
- *fns = api_eventlog_cmds;
- *n_fns = sizeof(api_eventlog_cmds) / sizeof(struct api_struct);
-}
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
index 8cbb319e9b..57b3be43ad 100644
--- a/source3/rpc_server/srv_eventlog_lib.c
+++ b/source3/rpc_server/srv_eventlog_lib.c
@@ -4,6 +4,7 @@
* Copyright (C) Marcin Krzysztof Porwit 2005,
* Copyright (C) Brian Moran 2005.
* Copyright (C) Gerald (Jerry) Carter 2005.
+ * Copyright (C) Guenther Deschner 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
@@ -269,7 +270,7 @@ bool prune_eventlog( TDB_CONTEXT * tdb )
/********************************************************************
********************************************************************/
-bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32_t needed )
+static bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32_t needed )
{
int calcd_size;
int MaxSize, Retention;
@@ -312,7 +313,7 @@ bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32_t needed )
/*******************************************************************
*******************************************************************/
-ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
+ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only )
{
TDB_CONTEXT *tdb = NULL;
uint32_t vers_id;
@@ -322,6 +323,13 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
char *eventlogdir;
TALLOC_CTX *ctx = talloc_tos();
+ /* check for invalid options */
+
+ if (force_clear && read_only) {
+ DEBUG(1,("elog_open_tdb: Invalid flags\n"));
+ return NULL;
+ }
+
/* first see if we have an open context */
for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
@@ -363,7 +371,7 @@ ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
if ( !force_clear ) {
- tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
+ tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, read_only ? O_RDONLY : O_RDWR , 0 );
if ( tdb ) {
vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
@@ -437,148 +445,6 @@ int elog_close_tdb( ELOG_TDB *etdb, bool force_close )
return 0;
}
-
-/*******************************************************************
- write an eventlog entry. Note that we have to lock, read next
- eventlog, increment, write, write the record, unlock
-
- coming into this, ee has the eventlog record, and the auxilliary date
- (computer name, etc.) filled into the other structure. Before packing
- into a record, this routine will calc the appropriate padding, etc.,
- and then blast out the record in a form that can be read back in
-*******************************************************************/
-
-#define MARGIN 512
-
-int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
-{
- int32 next_record;
- uint8 *packed_ee;
- TALLOC_CTX *mem_ctx = NULL;
- TDB_DATA kbuf, ebuf;
- uint32_t n_packed;
-
- if ( !ee )
- return 0;
-
- mem_ctx = talloc_init( "write_eventlog_tdb" );
-
- if ( mem_ctx == NULL )
- return 0;
-
- /* discard any entries that have bogus time, which usually indicates a bogus entry as well. */
- if ( ee->record.time_generated == 0 )
- return 0;
-
- /* todo - check for sanity in next_record */
-
- fixup_eventlog_entry( ee );
-
- if ( !can_write_to_eventlog( the_tdb, ee->record.length ) ) {
- DEBUG( 3, ( "Can't write to Eventlog, no room \n" ) );
- talloc_destroy( mem_ctx );
- return 0;
- }
-
- /* alloc mem for the packed version */
- packed_ee = (uint8 *)TALLOC( mem_ctx, ee->record.length + MARGIN );
- if ( !packed_ee ) {
- talloc_destroy( mem_ctx );
- return 0;
- }
-
- /* need to read the record number and insert it into the entry here */
-
- /* lock */
- tdb_lock_bystring_with_timeout( the_tdb, EVT_NEXT_RECORD, 1 );
- /* read */
- next_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
-
- n_packed =
- tdb_pack( (uint8 *)packed_ee, ee->record.length + MARGIN,
- "ddddddwwwwddddddBBdBBBd", ee->record.length,
- ee->record.reserved1, next_record,
- ee->record.time_generated, ee->record.time_written,
- ee->record.event_id, ee->record.event_type,
- ee->record.num_strings, ee->record.event_category,
- ee->record.reserved2,
- ee->record.closing_record_number,
- ee->record.string_offset,
- ee->record.user_sid_length,
- ee->record.user_sid_offset, ee->record.data_length,
- ee->record.data_offset,
- ee->data_record.source_name_len,
- ee->data_record.source_name,
- ee->data_record.computer_name_len,
- ee->data_record.computer_name,
- ee->data_record.sid_padding,
- ee->record.user_sid_length, ee->data_record.sid,
- ee->data_record.strings_len,
- ee->data_record.strings,
- ee->data_record.user_data_len,
- ee->data_record.user_data,
- ee->data_record.data_padding );
-
- /*DEBUG(3,("write_eventlog_tdb: packed into %d\n",n_packed)); */
-
- /* increment the record count */
-
- kbuf.dsize = sizeof( int32 );
- kbuf.dptr = (uint8 * ) & next_record;
-
- ebuf.dsize = n_packed;
- ebuf.dptr = (uint8 *)packed_ee;
-
- if ( tdb_store( the_tdb, kbuf, ebuf, 0 ) ) {
- /* DEBUG(1,("write_eventlog_tdb: Can't write record %d to eventlog\n",next_record)); */
- tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
- talloc_destroy( mem_ctx );
- return 0;
- }
- next_record++;
- tdb_store_int32( the_tdb, EVT_NEXT_RECORD, next_record );
- tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
- talloc_destroy( mem_ctx );
- return ( next_record - 1 );
-}
-
-/*******************************************************************
- calculate the correct fields etc for an eventlog entry
-*******************************************************************/
-
-void fixup_eventlog_entry( Eventlog_entry * ee )
-{
- /* fix up the eventlog entry structure as necessary */
-
- ee->data_record.sid_padding =
- ( ( 4 -
- ( ( ee->data_record.source_name_len +
- ee->data_record.computer_name_len ) % 4 ) ) % 4 );
- ee->data_record.data_padding =
- ( 4 -
- ( ( ee->data_record.strings_len +
- ee->data_record.user_data_len ) % 4 ) ) % 4;
- ee->record.length = sizeof( Eventlog_record );
- ee->record.length += ee->data_record.source_name_len;
- ee->record.length += ee->data_record.computer_name_len;
- if ( ee->record.user_sid_length == 0 ) {
- /* Should not pad to a DWORD boundary for writing out the sid if there is
- no SID, so just propagate the padding to pad the data */
- ee->data_record.data_padding += ee->data_record.sid_padding;
- ee->data_record.sid_padding = 0;
- }
- /* DEBUG(10, ("sid_padding is [%d].\n", ee->data_record.sid_padding)); */
- /* DEBUG(10, ("data_padding is [%d].\n", ee->data_record.data_padding)); */
-
- ee->record.length += ee->data_record.sid_padding;
- ee->record.length += ee->record.user_sid_length;
- ee->record.length += ee->data_record.strings_len;
- ee->record.length += ee->data_record.user_data_len;
- ee->record.length += ee->data_record.data_padding;
- /* need another copy of length at the end of the data */
- ee->record.length += sizeof( ee->record.length );
-}
-
/********************************************************************
Note that it's a pretty good idea to initialize the Eventlog_entry
structure to zero's before calling parse_logentry on an batch of
@@ -587,9 +453,8 @@ void fixup_eventlog_entry( Eventlog_entry * ee )
going in.
********************************************************************/
-bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
+bool parse_logentry( TALLOC_CTX *mem_ctx, char *line, struct eventlog_Record_tdb *entry, bool * eor )
{
- TALLOC_CTX *ctx = talloc_tos();
char *start = NULL, *stop = NULL;
start = line;
@@ -609,32 +474,32 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
if ( 0 == strncmp( start, "LEN", stop - start ) ) {
/* This will get recomputed later anyway -- probably not necessary */
- entry->record.length = atoi( stop + 1 );
+ entry->size = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "RS1", stop - start ) ) {
/* For now all these reserved entries seem to have the same value,
which can be hardcoded to int(1699505740) for now */
- entry->record.reserved1 = atoi( stop + 1 );
+ entry->reserved = talloc_strdup(mem_ctx, "eLfL");
} else if ( 0 == strncmp( start, "RCN", stop - start ) ) {
- entry->record.record_number = atoi( stop + 1 );
+ entry->record_number = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "TMG", stop - start ) ) {
- entry->record.time_generated = atoi( stop + 1 );
+ entry->time_generated = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "TMW", stop - start ) ) {
- entry->record.time_written = atoi( stop + 1 );
+ entry->time_written = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "EID", stop - start ) ) {
- entry->record.event_id = atoi( stop + 1 );
+ entry->event_id = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "ETP", stop - start ) ) {
if ( strstr( start, "ERROR" ) ) {
- entry->record.event_type = EVENTLOG_ERROR_TYPE;
+ entry->event_type = EVENTLOG_ERROR_TYPE;
} else if ( strstr( start, "WARNING" ) ) {
- entry->record.event_type = EVENTLOG_WARNING_TYPE;
+ entry->event_type = EVENTLOG_WARNING_TYPE;
} else if ( strstr( start, "INFO" ) ) {
- entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
+ entry->event_type = EVENTLOG_INFORMATION_TYPE;
} else if ( strstr( start, "AUDIT_SUCCESS" ) ) {
- entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
+ entry->event_type = EVENTLOG_AUDIT_SUCCESS;
} else if ( strstr( start, "AUDIT_FAILURE" ) ) {
- entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
+ entry->event_type = EVENTLOG_AUDIT_FAILURE;
} else if ( strstr( start, "SUCCESS" ) ) {
- entry->record.event_type = EVENTLOG_SUCCESS;
+ entry->event_type = EVENTLOG_SUCCESS;
} else {
/* some other eventlog type -- currently not defined in MSDN docs, so error out */
return False;
@@ -644,27 +509,26 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
/*
else if(0 == strncmp(start, "NST", stop - start))
{
- entry->record.num_strings = atoi(stop + 1);
+ entry->num_of_strings = atoi(stop + 1);
}
*/
else if ( 0 == strncmp( start, "ECT", stop - start ) ) {
- entry->record.event_category = atoi( stop + 1 );
+ entry->event_category = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "RS2", stop - start ) ) {
- entry->record.reserved2 = atoi( stop + 1 );
+ entry->reserved_flags = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "CRN", stop - start ) ) {
- entry->record.closing_record_number = atoi( stop + 1 );
+ entry->closing_record_number = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "USL", stop - start ) ) {
- entry->record.user_sid_length = atoi( stop + 1 );
+ entry->sid_length = atoi( stop + 1 );
} else if ( 0 == strncmp( start, "SRC", stop - start ) ) {
stop++;
while ( isspace( stop[0] ) ) {
stop++;
}
- entry->data_record.source_name_len = rpcstr_push_talloc(ctx,
- &entry->data_record.source_name,
- stop);
- if (entry->data_record.source_name_len == (uint32_t)-1 ||
- entry->data_record.source_name == NULL) {
+ entry->source_name_len = strlen_m_term(stop);
+ entry->source_name = talloc_strdup(mem_ctx, stop);
+ if (entry->source_name_len == (uint32_t)-1 ||
+ entry->source_name == NULL) {
return false;
}
} else if ( 0 == strncmp( start, "SRN", stop - start ) ) {
@@ -672,54 +536,43 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
while ( isspace( stop[0] ) ) {
stop++;
}
- entry->data_record.computer_name_len = rpcstr_push_talloc(ctx,
- &entry->data_record.computer_name,
- stop);
- if (entry->data_record.computer_name_len == (uint32_t)-1 ||
- entry->data_record.computer_name == NULL) {
+ entry->computer_name_len = strlen_m_term(stop);
+ entry->computer_name = talloc_strdup(mem_ctx, stop);
+ if (entry->computer_name_len == (uint32_t)-1 ||
+ entry->computer_name == NULL) {
return false;
}
} else if ( 0 == strncmp( start, "SID", stop - start ) ) {
+ smb_ucs2_t *dummy = NULL;
stop++;
while ( isspace( stop[0] ) ) {
stop++;
}
- entry->record.user_sid_length = rpcstr_push_talloc(ctx,
- &entry->data_record.sid,
+ entry->sid_length = rpcstr_push_talloc(mem_ctx,
+ &dummy,
stop);
- if (entry->record.user_sid_length == (uint32_t)-1 ||
- entry->data_record.sid == NULL) {
+ entry->sid = data_blob_talloc(mem_ctx, dummy, entry->sid_length);
+ if (entry->sid_length == (uint32_t)-1 ||
+ entry->sid.data == NULL) {
return false;
}
} else if ( 0 == strncmp( start, "STR", stop - start ) ) {
- smb_ucs2_t *temp = NULL;
size_t tmp_len;
- uint32_t old_len;
/* skip past initial ":" */
stop++;
/* now skip any other leading whitespace */
while ( isspace(stop[0])) {
stop++;
}
- tmp_len = rpcstr_push_talloc(ctx,
- &temp,
- stop);
- if (tmp_len == (size_t)-1 || !temp) {
+ tmp_len = strlen_m_term(stop);
+ if (tmp_len == (size_t)-1) {
return false;
}
- old_len = entry->data_record.strings_len;
- entry->data_record.strings = (smb_ucs2_t *)TALLOC_REALLOC_ARRAY(ctx,
- entry->data_record.strings,
- char,
- old_len + tmp_len);
- if (!entry->data_record.strings) {
+ if (!add_string_to_array(mem_ctx, stop, &entry->strings,
+ (int *)&entry->num_of_strings)) {
return false;
}
- memcpy(((char *)entry->data_record.strings) + old_len,
- temp,
- tmp_len);
- entry->data_record.strings_len += tmp_len;
- entry->record.num_strings++;
+ entry->strings_len += tmp_len;
} else if ( 0 == strncmp( start, "DAT", stop - start ) ) {
/* skip past initial ":" */
stop++;
@@ -727,10 +580,9 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
while ( isspace( stop[0] ) ) {
stop++;
}
- entry->data_record.user_data_len = strlen(stop);
- entry->data_record.user_data = talloc_strdup(ctx,
- stop);
- if (!entry->data_record.user_data) {
+ entry->data_length = strlen_m(stop);
+ entry->data = data_blob_talloc(mem_ctx, stop, entry->data_length);
+ if (!entry->data.data) {
return false;
}
} else {
@@ -742,3 +594,359 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor )
}
return true;
}
+
+/*******************************************************************
+ calculate the correct fields etc for an eventlog entry
+*******************************************************************/
+
+size_t fixup_eventlog_record_tdb(struct eventlog_Record_tdb *r)
+{
+ size_t size = 56; /* static size of integers before buffers start */
+
+ r->source_name_len = strlen_m_term(r->source_name) * 2;
+ r->computer_name_len = strlen_m_term(r->computer_name) * 2;
+ r->strings_len = ndr_size_string_array(r->strings,
+ r->num_of_strings, LIBNDR_FLAG_STR_NULLTERM) * 2;
+
+ /* fix up the eventlog entry structure as necessary */
+ r->sid_padding = ( ( 4 - ( ( r->source_name_len + r->computer_name_len ) % 4 ) ) % 4 );
+ r->padding = ( 4 - ( ( r->strings_len + r->data_length ) % 4 ) ) % 4;
+
+ if (r->sid_length == 0) {
+ /* Should not pad to a DWORD boundary for writing out the sid if there is
+ no SID, so just propagate the padding to pad the data */
+ r->padding += r->sid_padding;
+ r->sid_padding = 0;
+ }
+
+ size += r->source_name_len;
+ size += r->computer_name_len;
+ size += r->sid_padding;
+ size += r->sid_length;
+ size += r->strings_len;
+ size += r->data_length;
+ size += r->padding;
+ /* need another copy of length at the end of the data */
+ size += sizeof(r->size);
+
+ r->size = size;
+
+ return size;
+}
+
+
+/********************************************************************
+ ********************************************************************/
+
+struct eventlog_Record_tdb *evlog_pull_record_tdb(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ uint32_t record_number)
+{
+ struct eventlog_Record_tdb *r;
+ TDB_DATA data, key;
+
+ int32_t srecno;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+
+ srecno = record_number;
+ key.dptr = (unsigned char *)&srecno;
+ key.dsize = sizeof(int32_t);
+
+ data = tdb_fetch(tdb, key);
+ if (data.dsize == 0) {
+ DEBUG(8,("evlog_pull_record_tdb: "
+ "Can't find a record for the key, record %d\n",
+ record_number));
+ return NULL;
+ }
+
+ r = talloc_zero(mem_ctx, struct eventlog_Record_tdb);
+ if (!r) {
+ goto done;
+ }
+
+ blob = data_blob_const(data.dptr, data.dsize);
+
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, r,
+ (ndr_pull_flags_fn_t)ndr_pull_eventlog_Record_tdb);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10,("evlog_pull_record_tdb: failed to decode record %d\n",
+ record_number));
+ TALLOC_FREE(r);
+ goto done;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(eventlog_Record_tdb, r);
+ }
+
+ DEBUG(10,("evlog_pull_record_tdb: retrieved entry for record %d\n",
+ record_number));
+ done:
+ SAFE_FREE(data.dptr);
+
+ return r;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+struct EVENTLOGRECORD *evlog_pull_record(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ uint32_t record_number)
+{
+ struct eventlog_Record_tdb *t;
+ struct EVENTLOGRECORD *r;
+ NTSTATUS status;
+
+ r = talloc_zero(mem_ctx, struct EVENTLOGRECORD);
+ if (!r) {
+ return NULL;
+ }
+
+ t = evlog_pull_record_tdb(r, tdb, record_number);
+ if (!t) {
+ talloc_free(r);
+ return NULL;
+ }
+
+ status = evlog_tdb_entry_to_evt_entry(r, t, r);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(r);
+ return NULL;
+ }
+
+ r->Length = r->Length2 = ndr_size_EVENTLOGRECORD(r, NULL, 0);
+
+ return r;
+}
+
+/********************************************************************
+ write an eventlog entry. Note that we have to lock, read next
+ eventlog, increment, write, write the record, unlock
+
+ coming into this, ee has the eventlog record, and the auxilliary date
+ (computer name, etc.) filled into the other structure. Before packing
+ into a record, this routine will calc the appropriate padding, etc.,
+ and then blast out the record in a form that can be read back in
+ ********************************************************************/
+
+NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ struct eventlog_Record_tdb *r,
+ uint32_t *record_number)
+{
+ TDB_DATA kbuf, ebuf;
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ int ret;
+
+ if (!r) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!can_write_to_eventlog(tdb, r->size)) {
+ return NT_STATUS_EVENTLOG_CANT_START;
+ }
+
+ /* need to read the record number and insert it into the entry here */
+
+ /* lock */
+ ret = tdb_lock_bystring_with_timeout(tdb, EVT_NEXT_RECORD, 1);
+ if (ret == -1) {
+ return NT_STATUS_LOCK_NOT_GRANTED;
+ }
+
+ /* read */
+ r->record_number = tdb_fetch_int32(tdb, EVT_NEXT_RECORD);
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, r,
+ (ndr_push_flags_fn_t)ndr_push_eventlog_Record_tdb);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ /* increment the record count */
+
+ kbuf.dsize = sizeof(int32_t);
+ kbuf.dptr = (uint8_t *)&r->record_number;
+
+ ebuf.dsize = blob.length;
+ ebuf.dptr = blob.data;
+
+ ret = tdb_store(tdb, kbuf, ebuf, 0);
+ if (ret == -1) {
+ tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
+ return NT_STATUS_EVENTLOG_FILE_CORRUPT;
+ }
+
+ ret = tdb_store_int32(tdb, EVT_NEXT_RECORD, r->record_number + 1);
+ if (ret == -1) {
+ tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
+ return NT_STATUS_EVENTLOG_FILE_CORRUPT;
+ }
+ tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
+
+ if (record_number) {
+ *record_number = r->record_number;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+NTSTATUS evlog_push_record(TALLOC_CTX *mem_ctx,
+ TDB_CONTEXT *tdb,
+ struct EVENTLOGRECORD *r,
+ uint32_t *record_number)
+{
+ struct eventlog_Record_tdb *t;
+ NTSTATUS status;
+
+ t = talloc_zero(mem_ctx, struct eventlog_Record_tdb);
+ if (!t) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = evlog_evt_entry_to_tdb_entry(t, r, t);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(t);
+ return status;
+ }
+
+ status = evlog_push_record_tdb(mem_ctx, tdb, t, record_number);
+ talloc_free(t);
+
+ return status;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+NTSTATUS evlog_evt_entry_to_tdb_entry(TALLOC_CTX *mem_ctx,
+ const struct EVENTLOGRECORD *e,
+ struct eventlog_Record_tdb *t)
+{
+ uint32_t i;
+
+ ZERO_STRUCTP(t);
+
+ t->size = e->Length;
+ t->reserved = e->Reserved;
+ t->record_number = e->RecordNumber;
+ t->time_generated = e->TimeGenerated;
+ t->time_written = e->TimeWritten;
+ t->event_id = e->EventID;
+ t->event_type = e->EventType;
+ t->num_of_strings = e->NumStrings;
+ t->event_category = e->EventCategory;
+ t->reserved_flags = e->ReservedFlags;
+ t->closing_record_number = e->ClosingRecordNumber;
+
+ t->stringoffset = e->StringOffset;
+ t->sid_length = e->UserSidLength;
+ t->sid_offset = e->UserSidOffset;
+ t->data_length = e->DataLength;
+ t->data_offset = e->DataOffset;
+
+ t->source_name_len = 2 * strlen_m_term(e->SourceName);
+ t->source_name = talloc_strdup(mem_ctx, e->SourceName);
+ NT_STATUS_HAVE_NO_MEMORY(t->source_name);
+
+ t->computer_name_len = 2 * strlen_m_term(e->Computername);
+ t->computer_name = talloc_strdup(mem_ctx, e->Computername);
+ NT_STATUS_HAVE_NO_MEMORY(t->computer_name);
+
+ /* t->sid_padding; */
+ if (e->UserSidLength > 0) {
+ const char *sid_str = NULL;
+ smb_ucs2_t *dummy = NULL;
+ sid_str = sid_string_talloc(mem_ctx, &e->UserSid);
+ t->sid_length = rpcstr_push_talloc(mem_ctx, &dummy, sid_str);
+ if (t->sid_length == -1) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ t->sid = data_blob_talloc(mem_ctx, (uint8_t *)dummy, t->sid_length);
+ NT_STATUS_HAVE_NO_MEMORY(t->sid.data);
+ }
+
+ t->strings = talloc_array(mem_ctx, const char *, e->NumStrings);
+ for (i=0; i < e->NumStrings; i++) {
+ t->strings[i] = talloc_strdup(t->strings, e->Strings[i]);
+ NT_STATUS_HAVE_NO_MEMORY(t->strings[i]);
+ }
+
+ t->strings_len = 2 * ndr_size_string_array(t->strings, t->num_of_strings, LIBNDR_FLAG_STR_NULLTERM);
+ t->data = data_blob_talloc(mem_ctx, e->Data, e->DataLength);
+ /* t->padding = r->Pad; */
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx,
+ const struct eventlog_Record_tdb *t,
+ struct EVENTLOGRECORD *e)
+{
+ uint32_t i;
+
+ ZERO_STRUCTP(e);
+
+ e->Length = t->size;
+ e->Reserved = t->reserved;
+ e->RecordNumber = t->record_number;
+ e->TimeGenerated = t->time_generated;
+ e->TimeWritten = t->time_written;
+ e->EventID = t->event_id;
+ e->EventType = t->event_type;
+ e->NumStrings = t->num_of_strings;
+ e->EventCategory = t->event_category;
+ e->ReservedFlags = t->reserved_flags;
+ e->ClosingRecordNumber = t->closing_record_number;
+
+ e->StringOffset = t->stringoffset;
+ e->UserSidLength = t->sid_length;
+ e->UserSidOffset = t->sid_offset;
+ e->DataLength = t->data_length;
+ e->DataOffset = t->data_offset;
+
+ e->SourceName = talloc_strdup(mem_ctx, t->source_name);
+ NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
+
+ e->Computername = talloc_strdup(mem_ctx, t->computer_name);
+ NT_STATUS_HAVE_NO_MEMORY(e->Computername);
+
+ if (t->sid_length > 0) {
+ const char *sid_str = NULL;
+ size_t len;
+ if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
+ t->sid.data, t->sid.length,
+ &sid_str, &len, false)) {
+ return NT_STATUS_INVALID_SID;
+ }
+ if (len > 0) {
+ e->UserSid = *string_sid_talloc(mem_ctx, sid_str);
+ }
+ }
+
+ e->Strings = talloc_array(mem_ctx, const char *, t->num_of_strings);
+ for (i=0; i < t->num_of_strings; i++) {
+ e->Strings[i] = talloc_strdup(e->Strings, t->strings[i]);
+ NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
+ }
+
+ e->Data = (uint8_t *)talloc_memdup(mem_ctx, t->data.data, t->data_length);
+ e->Pad = talloc_strdup(mem_ctx, "");
+ NT_STATUS_HAVE_NO_MEMORY(e->Pad);
+
+ e->Length2 = t->size;
+
+ return NT_STATUS_OK;
+}
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index a687025ba6..697457888e 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -4,6 +4,7 @@
* Copyright (C) Marcin Krzysztof Porwit 2005,
* Copyright (C) Brian Moran 2005,
* Copyright (C) Gerald (Jerry) Carter 2005.
+ * Copyright (C) Guenther Deschner 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
@@ -194,7 +195,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
in a single process */
become_root();
- elog->etdb = elog_open_tdb( elog->logname, False );
+ elog->etdb = elog_open_tdb( elog->logname, False, False );
unbecome_root();
if ( !elog->etdb ) {
@@ -214,7 +215,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
}
become_root();
- elog->etdb = elog_open_tdb( elog->logname, False );
+ elog->etdb = elog_open_tdb( elog->logname, False, False );
unbecome_root();
}
@@ -276,140 +277,6 @@ static int elog_size( EVENTLOG_INFO *info )
}
/********************************************************************
- For the given tdb, get the next eventlog record into the passed
- Eventlog_entry. returns NULL if it can't get the record for some reason.
- ********************************************************************/
-
-static Eventlog_entry *get_eventlog_record(TALLOC_CTX *mem_ctx,
- TDB_CONTEXT *tdb,
- int recno)
-{
- Eventlog_entry *ee = NULL;
- TDB_DATA ret, key;
-
- int32_t srecno;
- int32_t reclen;
- int len;
-
- char *wpsource = NULL;
- char *wpcomputer = NULL;
- char *wpsid = NULL;
- char *wpstrs = NULL;
- char *puserdata = NULL;
-
- key.dsize = sizeof(int32_t);
-
- srecno = recno;
- key.dptr = (unsigned char *)&srecno;
-
- ret = tdb_fetch( tdb, key );
-
- if ( ret.dsize == 0 ) {
- DEBUG( 8,
- ( "Can't find a record for the key, record %d\n",
- recno ) );
- return NULL;
- }
-
- len = tdb_unpack( ret.dptr, ret.dsize, "d", &reclen );
-
- DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno, len ) );
-
- if ( !len )
- return NULL;
-
- ee = TALLOC_ARRAY(mem_ctx, Eventlog_entry, 1);
- if (!ee) {
- return NULL;
- }
- ZERO_STRUCTP(ee);
-
- len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd",
- &ee->record.length, &ee->record.reserved1,
- &ee->record.record_number,
- &ee->record.time_generated,
- &ee->record.time_written, &ee->record.event_id,
- &ee->record.event_type, &ee->record.num_strings,
- &ee->record.event_category, &ee->record.reserved2,
- &ee->record.closing_record_number,
- &ee->record.string_offset,
- &ee->record.user_sid_length,
- &ee->record.user_sid_offset,
- &ee->record.data_length, &ee->record.data_offset,
- &ee->data_record.source_name_len, &wpsource,
- &ee->data_record.computer_name_len, &wpcomputer,
- &ee->data_record.sid_padding,
- &ee->record.user_sid_length, &wpsid,
- &ee->data_record.strings_len, &wpstrs,
- &ee->data_record.user_data_len, &puserdata,
- &ee->data_record.data_padding );
- DEBUG( 10,
- ( "Read record %d, len in tdb was %d\n",
- ee->record.record_number, len ) );
-
- /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
- into it's 2nd argment for 'B' */
-
- if (wpcomputer) {
- ee->data_record.computer_name = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpcomputer, ee->data_record.computer_name_len);
- if (!ee->data_record.computer_name) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
- if (wpsource) {
- ee->data_record.source_name = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpsource, ee->data_record.source_name_len);
- if (!ee->data_record.source_name) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- if (wpsid) {
- ee->data_record.sid = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpsid, ee->record.user_sid_length);
- if (!ee->data_record.sid) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
- if (wpstrs) {
- ee->data_record.strings = (smb_ucs2_t *)TALLOC_MEMDUP(
- ee, wpstrs, ee->data_record.strings_len);
- if (!ee->data_record.strings) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- if (puserdata) {
- ee->data_record.user_data = (char *)TALLOC_MEMDUP(
- ee, puserdata, ee->data_record.user_data_len);
- if (!ee->data_record.user_data) {
- TALLOC_FREE(ee);
- goto out;
- }
- }
-
- out:
-
- SAFE_FREE(wpcomputer);
- SAFE_FREE(wpsource);
- SAFE_FREE(wpsid);
- SAFE_FREE(wpstrs);
- SAFE_FREE(puserdata);
-
- DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) );
- DEBUG( 10,
- ( "get_eventlog_record: computer_name %d is ",
- ee->data_record.computer_name_len ) );
- SAFE_FREE(ret.dptr);
- return ee;
-}
-
-/********************************************************************
note that this can only be called AFTER the table is constructed,
since it uses the table to find the tdb handle
********************************************************************/
@@ -484,124 +351,6 @@ done:
}
/********************************************************************
- ********************************************************************/
-
-static Eventlog_entry *read_package_entry( TALLOC_CTX *mem_ctx,
- Eventlog_entry * entry )
-{
- uint8 *offset;
- Eventlog_entry *ee_new = NULL;
-
- ee_new = TALLOC_ZERO_ARRAY(mem_ctx, Eventlog_entry, 1 );
- if ( ee_new == NULL ) {
- return NULL;
- }
-
- entry->data_record.sid_padding =
- ( ( 4 -
- ( ( entry->data_record.source_name_len +
- entry->data_record.computer_name_len ) % 4 ) ) % 4 );
- entry->data_record.data_padding =
- ( 4 -
- ( ( entry->data_record.strings_len +
- entry->data_record.user_data_len ) % 4 ) ) % 4;
- entry->record.length = sizeof( Eventlog_record );
- entry->record.length += entry->data_record.source_name_len;
- entry->record.length += entry->data_record.computer_name_len;
- if ( entry->record.user_sid_length == 0 ) {
- /* Should not pad to a DWORD boundary for writing out the sid if there is
- no SID, so just propagate the padding to pad the data */
- entry->data_record.data_padding +=
- entry->data_record.sid_padding;
- entry->data_record.sid_padding = 0;
- }
- DEBUG( 10,
- ( "sid_padding is [%d].\n", entry->data_record.sid_padding ) );
- DEBUG( 10,
- ( "data_padding is [%d].\n",
- entry->data_record.data_padding ) );
-
- entry->record.length += entry->data_record.sid_padding;
- entry->record.length += entry->record.user_sid_length;
- entry->record.length += entry->data_record.strings_len;
- entry->record.length += entry->data_record.user_data_len;
- entry->record.length += entry->data_record.data_padding;
- /* need another copy of length at the end of the data */
- entry->record.length += sizeof( entry->record.length );
- DEBUG( 10,
- ( "entry->record.length is [%d].\n", entry->record.length ) );
- entry->data =
- TALLOC_ZERO_ARRAY(mem_ctx, uint8_t,
- entry->record.length -
- sizeof( Eventlog_record ) -
- sizeof( entry->record.length ));
- if ( entry->data == NULL ) {
- return NULL;
- }
- offset = entry->data;
- memcpy( offset, entry->data_record.source_name,
- entry->data_record.source_name_len );
- offset += entry->data_record.source_name_len;
- memcpy( offset, entry->data_record.computer_name,
- entry->data_record.computer_name_len );
- offset += entry->data_record.computer_name_len;
- /* SID needs to be DWORD-aligned */
- offset += entry->data_record.sid_padding;
- entry->record.user_sid_offset =
- sizeof( Eventlog_record ) + ( offset - entry->data );
- memcpy( offset, entry->data_record.sid,
- entry->record.user_sid_length );
- offset += entry->record.user_sid_length;
- /* Now do the strings */
- entry->record.string_offset =
- sizeof( Eventlog_record ) + ( offset - entry->data );
- memcpy( offset, entry->data_record.strings,
- entry->data_record.strings_len );
- offset += entry->data_record.strings_len;
- /* Now do the data */
- entry->record.data_length = entry->data_record.user_data_len;
- entry->record.data_offset =
- sizeof( Eventlog_record ) + ( offset - entry->data );
- memcpy( offset, entry->data_record.user_data,
- entry->data_record.user_data_len );
- offset += entry->data_record.user_data_len;
-
- memcpy( &( ee_new->record ), &entry->record,
- sizeof( Eventlog_record ) );
- memcpy( &( ee_new->data_record ), &entry->data_record,
- sizeof( Eventlog_data_record ) );
- ee_new->data = entry->data;
-
- return ee_new;
-}
-
-/********************************************************************
- ********************************************************************/
-
-static bool add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u,
- Eventlog_entry * ee_new )
-{
- Eventlog_entry *insert_point;
-
- insert_point = r_u->entry;
-
- if ( NULL == insert_point ) {
- r_u->entry = ee_new;
- ee_new->next = NULL;
- } else {
- while ( ( NULL != insert_point->next ) ) {
- insert_point = insert_point->next;
- }
- ee_new->next = NULL;
- insert_point->next = ee_new;
- }
- r_u->num_records++;
- r_u->num_bytes_in_resp += ee_new->record.length;
-
- return True;
-}
-
-/********************************************************************
_eventlog_OpenEventLogW
********************************************************************/
@@ -677,7 +426,7 @@ NTSTATUS _eventlog_ClearEventLogW(pipes_struct *p,
elog_close_tdb( info->etdb, True );
become_root();
- info->etdb = elog_open_tdb( info->logname, True );
+ info->etdb = elog_open_tdb( info->logname, True, False );
unbecome_root();
if ( !info->etdb )
@@ -706,98 +455,117 @@ NTSTATUS _eventlog_CloseEventLog(pipes_struct * p,
}
/********************************************************************
+ _eventlog_ReadEventLogW
********************************************************************/
-NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
- EVENTLOG_Q_READ_EVENTLOG * q_u,
- EVENTLOG_R_READ_EVENTLOG * r_u )
+NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p,
+ struct eventlog_ReadEventLogW *r)
{
- EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
- Eventlog_entry *entry = NULL, *ee_new = NULL;
- uint32 num_records_read = 0;
+ EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
+ uint32_t num_records_read = 0;
int bytes_left, record_number;
- uint32 elog_read_type, elog_read_dir;
+ uint32_t elog_read_type, elog_read_dir;
- if (info == NULL) {
+ if (!info) {
return NT_STATUS_INVALID_HANDLE;
}
- info->flags = q_u->flags;
+ info->flags = r->in.flags;
+ bytes_left = r->in.number_of_bytes;
- bytes_left = q_u->max_read_size;
-
- if ( !info->etdb )
+ if (!info->etdb) {
return NT_STATUS_ACCESS_DENIED;
+ }
/* check for valid flags. Can't use the sequential and seek flags together */
- elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
- elog_read_dir = q_u->flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
+ elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
+ elog_read_dir = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
- if ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ)
- || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ) )
+ if (r->in.flags == 0 ||
+ elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
+ elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
{
- DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->flags));
+ DEBUG(3,("_eventlog_ReadEventLogW: "
+ "Invalid flags [0x%08x] for ReadEventLog\n",
+ r->in.flags));
return NT_STATUS_INVALID_PARAMETER;
}
/* a sequential read should ignore the offset */
- if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ )
+ if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
record_number = info->current_record;
- else
- record_number = q_u->offset;
+ } else {
+ record_number = r->in.offset;
+ }
+
+ if (r->in.number_of_bytes == 0) {
+ struct EVENTLOGRECORD *e;
+ e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
+ record_number);
+ if (!e) {
+ return NT_STATUS_END_OF_FILE;
+ }
+ *r->out.real_size = e->Length;
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- while ( bytes_left > 0 ) {
+ while (bytes_left > 0) {
- /* assume that when the record fetch fails, that we are done */
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct EVENTLOGRECORD *e;
- entry = get_eventlog_record (p->mem_ctx, ELOG_TDB_CTX(info->etdb), record_number);
- if (!entry) {
+ e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
+ record_number);
+ if (!e) {
break;
}
- DEBUG( 8, ( "Retrieved record %d\n", record_number ) );
-
- /* Now see if there is enough room to add */
-
- if ( !(ee_new = read_package_entry( p->mem_ctx, entry )) )
- return NT_STATUS_NO_MEMORY;
+ ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL, e,
+ (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
- if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) {
- r_u->bytes_in_next_record = ee_new->record.length;
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
+ }
- /* response would be too big to fit in client-size buffer */
+ if (blob.length > r->in.number_of_bytes) {
+ *r->out.real_size = blob.length;
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- bytes_left = 0;
+ if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
break;
}
- add_record_to_resp( r_u, ee_new );
- bytes_left -= ee_new->record.length;
- TALLOC_FREE(entry);
- num_records_read = r_u->num_records - num_records_read;
+ bytes_left -= blob.length;
- DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
- "of [%d] records using [%d] bytes out of a max of [%d].\n",
- num_records_read, r_u->num_records,
- r_u->num_bytes_in_resp,
- q_u->max_read_size ) );
-
- if ( info->flags & EVENTLOG_FORWARDS_READ )
+ if (info->flags & EVENTLOG_FORWARDS_READ) {
record_number++;
- else
+ } else {
record_number--;
+ }
/* update the eventlog record pointer */
info->current_record = record_number;
+
+ memcpy(&r->out.data[*(r->out.sent_size)],
+ blob.data, blob.length);
+ *(r->out.sent_size) += blob.length;
+
+ num_records_read++;
}
- /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
- say when there are no more records */
+ if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
+ return NT_STATUS_END_OF_FILE;
+ }
- return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);
+ return NT_STATUS_OK;
}
/********************************************************************
@@ -872,12 +640,6 @@ NTSTATUS _eventlog_OpenBackupEventLogW(pipes_struct *p, struct eventlog_OpenBack
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p, struct eventlog_ReadEventLogW *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _eventlog_ReportEventW(pipes_struct *p, struct eventlog_ReportEventW *r)
{
p->rng_fault_state = True;
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index 5f7c8d9f1a..2779b8aa18 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -34,9 +34,10 @@
pipe is open. JRA.
****************************************************************************/
-static bool is_samr_lsa_pipe(const char *pipe_name)
+static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
{
- return (strstr(pipe_name, "samr") || strstr(pipe_name, "lsa"));
+ return (ndr_syntax_id_equal(syntax, &ndr_table_samr.syntax_id)
+ || ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
}
/****************************************************************************
@@ -44,7 +45,7 @@ static bool is_samr_lsa_pipe(const char *pipe_name)
pipes of the same name.
****************************************************************************/
-bool init_pipe_handle_list(pipes_struct *p, const char *pipe_name)
+bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
{
pipes_struct *plist;
struct handle_list *hl;
@@ -52,11 +53,11 @@ bool init_pipe_handle_list(pipes_struct *p, const char *pipe_name)
for (plist = get_first_internal_pipe();
plist;
plist = get_next_internal_pipe(plist)) {
- if (strequal(plist->name, pipe_name)) {
+ if (ndr_syntax_id_equal(syntax, &plist->syntax)) {
break;
}
- if (is_samr_lsa_pipe(plist->name)
- && is_samr_lsa_pipe(pipe_name)) {
+ if (is_samr_lsa_pipe(&plist->syntax)
+ && is_samr_lsa_pipe(syntax)) {
/*
* samr and lsa share a handle space (same process
* under Windows?)
@@ -80,7 +81,8 @@ bool init_pipe_handle_list(pipes_struct *p, const char *pipe_name)
}
ZERO_STRUCTP(hl);
- DEBUG(10,("init_pipe_handles: created handle list for pipe %s\n", pipe_name ));
+ DEBUG(10,("init_pipe_handles: created handle list for "
+ "pipe %s\n", get_pipe_name_from_iface(syntax)));
}
/*
@@ -96,7 +98,8 @@ bool init_pipe_handle_list(pipes_struct *p, const char *pipe_name)
p->pipe_handles = hl;
DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
- (unsigned long)p->pipe_handles->pipe_ref_count, pipe_name ));
+ (unsigned long)p->pipe_handles->pipe_ref_count,
+ get_pipe_name_from_iface(syntax)));
return True;
}
@@ -242,7 +245,8 @@ void close_policy_by_pipe(pipes_struct *p)
p->pipe_handles->count = 0;
SAFE_FREE(p->pipe_handles);
- DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name ));
+ DEBUG(10,("close_policy_by_pipe: deleted handle list for "
+ "pipe %s\n", get_pipe_name_from_iface(&p->syntax)));
}
}
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 343342a06c..924226bc4f 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -610,7 +610,8 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
bool ret;
- DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n", p->name));
+ DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n",
+ get_pipe_name_from_iface(&p->syntax)));
ZERO_STRUCT(reply);
@@ -634,7 +635,7 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
"but client declined signing.\n",
- p->name ));
+ get_pipe_name_from_iface(&p->syntax)));
return False;
}
}
@@ -642,7 +643,7 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
"but client declined sealing.\n",
- p->name ));
+ get_pipe_name_from_iface(&p->syntax)));
return False;
}
}
@@ -962,14 +963,14 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
int i=0;
struct pipe_rpc_fns *context_fns;
- DEBUG(3,("check_bind_req for %s\n", p->name));
+ DEBUG(3,("check_bind_req for %s\n",
+ get_pipe_name_from_iface(&p->syntax)));
/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
for (i=0; i<rpc_lookup_size; i++) {
DEBUGADD(10, ("checking %s\n", rpc_lookup[i].pipe.clnt));
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)
- && ndr_syntax_id_equal(
+ if (ndr_syntax_id_equal(
abstract, &rpc_lookup[i].rpc_interface)
&& ndr_syntax_id_equal(
transfer, &ndr_transfer_syntax)) {
@@ -1056,7 +1057,7 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
* @param[in] cli_filename The pipe name requested by the client
* @result Do we want to serve this?
*/
-bool is_known_pipename(const char *cli_filename)
+bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
{
const char *pipename = cli_filename;
int i;
@@ -1076,6 +1077,7 @@ bool is_known_pipename(const char *cli_filename)
for (i=0; i<rpc_lookup_size; i++) {
if (strequal(pipename, rpc_lookup[i].pipe.clnt)) {
+ *syntax = rpc_lookup[i].rpc_interface;
return true;
}
}
@@ -1145,7 +1147,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_
}
DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
- if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
+ if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
bool ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth);
data_blob_free(&secblob);
data_blob_free(&blob);
@@ -1530,7 +1532,8 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
/* No rebinds on a bound pipe - use alter context. */
if (p->pipe_bound) {
- DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound pipe %s.\n", p->pipe_srv_name));
+ DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
+ "pipe %s.\n", get_pipe_name_from_iface(&p->syntax)));
return setup_bind_nak(p);
}
@@ -1589,16 +1592,20 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
&hdr_rb.rpc_context[0].abstract)) {
DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- fstrcpy(p->name, rpc_lookup[i].pipe.clnt);
- fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
break;
}
}
if (i == rpc_lookup_size) {
- if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
+ NTSTATUS status;
+
+ status = smb_probe_module(
+ "rpc", get_pipe_name_from_iface(
+ &hdr_rb.rpc_context[0].abstract));
+
+ if (NT_STATUS_IS_ERR(status)) {
DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
- p->name ));
+ get_pipe_name_from_iface(&hdr_rb.rpc_context[0].abstract)));
prs_mem_free(&outgoing_rpc);
prs_mem_free(&out_hdr_ba);
prs_mem_free(&out_auth);
@@ -1607,23 +1614,26 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
}
for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
+ if (strequal(rpc_lookup[i].pipe.clnt,
+ get_pipe_name_from_iface(&p->syntax))) {
DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
break;
}
}
if (i == rpc_lookup_size) {
- DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
+ DEBUG(0, ("module %s doesn't provide functions for "
+ "pipe %s!\n",
+ get_pipe_name_from_iface(&p->syntax),
+ get_pipe_name_from_iface(&p->syntax)));
goto err_exit;
}
}
/* name has to be \PIPE\xxxxx */
fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, p->pipe_srv_name);
+ fstrcat(ack_pipe_name, rpc_lookup[i].pipe.srv);
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
@@ -2233,7 +2243,7 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list )
return;
}
-static bool api_rpcTNP(pipes_struct *p, const char *rpc_name,
+static bool api_rpcTNP(pipes_struct *p,
const struct api_struct *api_rpc_cmds, int n_cmds);
/****************************************************************************
@@ -2258,7 +2268,8 @@ bool api_pipe_request(pipes_struct *p)
changed_user = True;
}
- DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
+ DEBUG(5, ("Requested \\PIPE\\%s\n",
+ get_pipe_name_from_iface(&p->syntax)));
/* get the set of RPC functions for this context */
@@ -2266,12 +2277,13 @@ bool api_pipe_request(pipes_struct *p)
if ( pipe_fns ) {
TALLOC_CTX *frame = talloc_stackframe();
- ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
+ ret = api_rpcTNP(p, pipe_fns->cmds, pipe_fns->n_cmds);
TALLOC_FREE(frame);
}
else {
DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
- p->hdr_req.context_id, p->name));
+ p->hdr_req.context_id,
+ get_pipe_name_from_iface(&p->syntax)));
}
if (changed_user) {
@@ -2285,18 +2297,22 @@ bool api_pipe_request(pipes_struct *p)
Calls the underlying RPC function for a named pipe.
********************************************************************/
-static bool api_rpcTNP(pipes_struct *p, const char *rpc_name,
+static bool api_rpcTNP(pipes_struct *p,
const struct api_struct *api_rpc_cmds, int n_cmds)
{
int fn_num;
- fstring name;
uint32 offset1, offset2;
/* interpret the command */
- DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
+ DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
+ get_pipe_name_from_iface(&p->syntax), p->hdr_req.opnum));
- slprintf(name, sizeof(name)-1, "in_%s", rpc_name);
- prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
+ if (DEBUGLEVEL >= 50) {
+ fstring name;
+ slprintf(name, sizeof(name)-1, "in_%s",
+ get_pipe_name_from_iface(&p->syntax));
+ prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
+ }
for (fn_num = 0; fn_num < n_cmds; fn_num++) {
if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
@@ -2322,7 +2338,9 @@ static bool api_rpcTNP(pipes_struct *p, const char *rpc_name,
fn_num, api_rpc_cmds[fn_num].fn));
/* do the actual command */
if(!api_rpc_cmds[fn_num].fn(p)) {
- DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
+ DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
+ get_pipe_name_from_iface(&p->syntax),
+ api_rpc_cmds[fn_num].name));
prs_mem_free(&p->out_data.rdata);
return False;
}
@@ -2341,13 +2359,18 @@ static bool api_rpcTNP(pipes_struct *p, const char *rpc_name,
return True;
}
- slprintf(name, sizeof(name)-1, "out_%s", rpc_name);
offset2 = prs_offset(&p->out_data.rdata);
prs_set_offset(&p->out_data.rdata, offset1);
- prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);
+ if (DEBUGLEVEL >= 50) {
+ fstring name;
+ slprintf(name, sizeof(name)-1, "out_%s",
+ get_pipe_name_from_iface(&p->syntax));
+ prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);
+ }
prs_set_offset(&p->out_data.rdata, offset2);
- DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
+ DEBUG(5,("api_rpcTNP: called %s successfully\n",
+ get_pipe_name_from_iface(&p->syntax)));
/* Check for buffer underflow in rpc parsing */
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 0753476230..4cbe8d67a3 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -90,13 +90,14 @@ static bool pipe_init_outgoing_data(pipes_struct *p)
****************************************************************************/
static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
- const char *pipe_name,
+ const struct ndr_syntax_id *syntax,
const char *client_address,
struct auth_serversupplied_info *server_info)
{
pipes_struct *p;
- DEBUG(4,("Create pipe requested %s\n", pipe_name));
+ DEBUG(4,("Create pipe requested %s\n",
+ get_pipe_name_from_iface(syntax)));
p = TALLOC_ZERO_P(mem_ctx, struct pipes_struct);
@@ -105,13 +106,15 @@ static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
return NULL;
}
- if ((p->mem_ctx = talloc_init("pipe %s %p", pipe_name, p)) == NULL) {
+ if ((p->mem_ctx = talloc_init("pipe %s %p",
+ get_pipe_name_from_iface(syntax),
+ p)) == NULL) {
DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
TALLOC_FREE(p);
return NULL;
}
- if (!init_pipe_handle_list(p, pipe_name)) {
+ if (!init_pipe_handle_list(p, syntax)) {
DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
talloc_destroy(p->mem_ctx);
TALLOC_FREE(p);
@@ -152,11 +155,11 @@ static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
* Initialize the outgoing RPC data buffer with no memory.
*/
prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);
-
- fstrcpy(p->name, pipe_name);
-
+
+ p->syntax = *syntax;
+
DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n",
- pipe_name, pipes_open));
+ get_pipe_name_from_iface(syntax), pipes_open));
talloc_set_destructor(p, close_internal_rpc_pipe_hnd);
@@ -174,7 +177,7 @@ static void set_incoming_fault(pipes_struct *p)
p->in_data.pdu_received_len = 0;
p->fault_state = True;
DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
- p->name));
+ get_pipe_name_from_iface(&p->syntax)));
}
/****************************************************************************
@@ -324,7 +327,8 @@ static void free_pipe_context(pipes_struct *p)
"%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
talloc_free_children(p->mem_ctx);
} else {
- p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
+ p->mem_ctx = talloc_init(
+ "pipe %s %p", get_pipe_name_from_iface(&p->syntax), p);
if (p->mem_ctx == NULL) {
p->fault_state = True;
}
@@ -492,7 +496,7 @@ static void process_complete_pdu(pipes_struct *p)
if(p->fault_state) {
DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
- p->name ));
+ get_pipe_name_from_iface(&p->syntax)));
set_incoming_fault(p);
setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
return;
@@ -520,12 +524,13 @@ static void process_complete_pdu(pipes_struct *p)
case RPC_PING: /* CL request - ignore... */
DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
- (unsigned int)p->hdr.pkt_type, p->name));
+ (unsigned int)p->hdr.pkt_type,
+ get_pipe_name_from_iface(&p->syntax)));
break;
case RPC_RESPONSE: /* No responses here. */
DEBUG(0,("process_complete_pdu: Error. RPC_RESPONSE received from client on pipe %s.\n",
- p->name ));
+ get_pipe_name_from_iface(&p->syntax)));
break;
case RPC_FAULT:
@@ -537,7 +542,8 @@ static void process_complete_pdu(pipes_struct *p)
case RPC_FACK:
case RPC_CANCEL_ACK:
DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
- (unsigned int)p->hdr.pkt_type, p->name));
+ (unsigned int)p->hdr.pkt_type,
+ get_pipe_name_from_iface(&p->syntax)));
break;
case RPC_BIND:
@@ -552,7 +558,8 @@ static void process_complete_pdu(pipes_struct *p)
case RPC_BINDACK:
case RPC_BINDNACK:
DEBUG(0,("process_complete_pdu: Error. RPC_BINDACK/RPC_BINDNACK packet type %u received on pipe %s.\n",
- (unsigned int)p->hdr.pkt_type, p->name));
+ (unsigned int)p->hdr.pkt_type,
+ get_pipe_name_from_iface(&p->syntax)));
break;
@@ -567,7 +574,7 @@ static void process_complete_pdu(pipes_struct *p)
case RPC_ALTCONTRESP:
DEBUG(0,("process_complete_pdu: Error. RPC_ALTCONTRESP on pipe %s: Should only be server -> client.\n",
- p->name));
+ get_pipe_name_from_iface(&p->syntax)));
break;
case RPC_AUTH3:
@@ -581,7 +588,7 @@ static void process_complete_pdu(pipes_struct *p)
case RPC_SHUTDOWN:
DEBUG(0,("process_complete_pdu: Error. RPC_SHUTDOWN on pipe %s: Should only be server -> client.\n",
- p->name));
+ get_pipe_name_from_iface(&p->syntax)));
break;
case RPC_CO_CANCEL:
@@ -619,7 +626,8 @@ static void process_complete_pdu(pipes_struct *p)
prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);
if (!reply) {
- DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
+ DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
+ "pipe %s\n", get_pipe_name_from_iface(&p->syntax)));
set_incoming_fault(p);
setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
prs_mem_free(&rpc_in);
@@ -773,7 +781,8 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_
return -1;
}
- DEBUG(6,(" name: %s len: %u\n", p->name, (unsigned int)n));
+ DEBUG(6,(" name: %s len: %u\n", get_pipe_name_from_iface(&p->syntax),
+ (unsigned int)n));
/*
* We cannot return more than one PDU length per
@@ -787,8 +796,10 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_
*/
if(n > RPC_MAX_PDU_FRAG_LEN) {
- DEBUG(5,("read_from_pipe: too large read (%u) requested on \
-pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, RPC_MAX_PDU_FRAG_LEN ));
+ DEBUG(5,("read_from_pipe: too large read (%u) requested on "
+ "pipe %s. We can only service %d sized reads.\n",
+ (unsigned int)n, get_pipe_name_from_iface(&p->syntax),
+ RPC_MAX_PDU_FRAG_LEN ));
n = RPC_MAX_PDU_FRAG_LEN;
}
@@ -803,9 +814,12 @@ pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, RPC_M
if((pdu_remaining = p->out_data.current_pdu_len - p->out_data.current_pdu_sent) > 0) {
data_returned = (ssize_t)MIN(n, pdu_remaining);
- DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
-returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
- (unsigned int)p->out_data.current_pdu_sent, (int)data_returned));
+ DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
+ "current_pdu_sent = %u returning %d bytes.\n",
+ get_pipe_name_from_iface(&p->syntax),
+ (unsigned int)p->out_data.current_pdu_len,
+ (unsigned int)p->out_data.current_pdu_sent,
+ (int)data_returned));
memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);
p->out_data.current_pdu_sent += (uint32)data_returned;
@@ -817,9 +831,11 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
* may of course be zero if this is the first return fragment.
*/
- DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length \
-= %u, prs_offset(&p->out_data.rdata) = %u.\n",
- p->name, (int)p->fault_state, (unsigned int)p->out_data.data_sent_length, (unsigned int)prs_offset(&p->out_data.rdata) ));
+ DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length "
+ "= %u, prs_offset(&p->out_data.rdata) = %u.\n",
+ get_pipe_name_from_iface(&p->syntax), (int)p->fault_state,
+ (unsigned int)p->out_data.data_sent_length,
+ (unsigned int)prs_offset(&p->out_data.rdata) ));
if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
/*
@@ -837,7 +853,8 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
*/
if(!create_next_pdu(p)) {
- DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n", p->name));
+ DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
+ get_pipe_name_from_iface(&p->syntax)));
return -1;
}
@@ -1086,13 +1103,14 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
handle->private_data = p;
} else {
struct pipes_struct *p;
+ struct ndr_syntax_id syntax;
- if (!is_known_pipename(name)) {
+ if (!is_known_pipename(name, &syntax)) {
TALLOC_FREE(handle);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- p = make_internal_rpc_pipe_p(handle, name, client_address,
+ p = make_internal_rpc_pipe_p(handle, &syntax, client_address,
server_info);
handle->type = FAKE_FILE_TYPE_NAMED_PIPE;
@@ -1109,66 +1127,235 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
return NT_STATUS_OK;
}
-NTSTATUS np_write(struct fake_file_handle *handle, const uint8_t *data,
- size_t len, ssize_t *nwritten)
+struct np_write_state {
+ ssize_t nwritten;
+};
+
+static void np_write_done(struct async_req *subreq);
+
+struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ const uint8_t *data, size_t len)
{
- DEBUG(6, ("np_write: len: %d\n", (int)len));
+ struct async_req *result, *subreq;
+ struct np_write_state *state;
+ NTSTATUS status;
+
+ DEBUG(6, ("np_write_send: len: %d\n", (int)len));
dump_data(50, data, len);
- switch (handle->type) {
- case FAKE_FILE_TYPE_NAMED_PIPE: {
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct np_write_state)) {
+ return NULL;
+ }
+
+ if (len == 0) {
+ state->nwritten = 0;
+ status = NT_STATUS_OK;
+ goto post_status;
+ }
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
struct pipes_struct *p = talloc_get_type_abort(
handle->private_data, struct pipes_struct);
- *nwritten = write_to_internal_pipe(p, (char *)data, len);
- break;
+
+ state->nwritten = write_to_internal_pipe(p, (char *)data, len);
+
+ status = (state->nwritten >= 0)
+ ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+ goto post_status;
}
- case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
struct np_proxy_state *p = talloc_get_type_abort(
handle->private_data, struct np_proxy_state);
- *nwritten = write_data(p->fd, (char *)data, len);
- break;
+
+ state->nwritten = len;
+
+ subreq = sendall_send(state, ev, p->fd, data, len, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = np_write_done;
+ subreq->async.priv = result;
+ return result;
}
- default:
- return NT_STATUS_INVALID_HANDLE;
- break;
+
+ status = NT_STATUS_INVALID_HANDLE;
+ post_status:
+ if (async_post_ntstatus(result, ev, status)) {
+ return result;
}
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void np_write_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = sendall_recv(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_nterror(req, status);
+ return;
+ }
+ async_req_done(req);
+}
+
+NTSTATUS np_write_recv(struct async_req *req, ssize_t *pnwritten)
+{
+ struct np_write_state *state = talloc_get_type_abort(
+ req->private_data, struct np_write_state);
+ NTSTATUS status;
- return ((*nwritten) >= 0)
- ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *pnwritten = state->nwritten;
+ return NT_STATUS_OK;
}
-NTSTATUS np_read(struct fake_file_handle *handle, uint8_t *data, size_t len,
- ssize_t *nread, bool *is_data_outstanding)
+struct np_read_state {
+ ssize_t nread;
+ bool is_data_outstanding;
+ int fd;
+};
+
+static void np_read_done(struct async_req *subreq);
+
+struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+ struct fake_file_handle *handle,
+ uint8_t *data, size_t len)
{
- switch (handle->type) {
- case FAKE_FILE_TYPE_NAMED_PIPE: {
+ struct async_req *result, *subreq;
+ struct np_read_state *state;
+ NTSTATUS status;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct np_read_state)) {
+ return NULL;
+ }
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE) {
struct pipes_struct *p = talloc_get_type_abort(
handle->private_data, struct pipes_struct);
- *nread = read_from_internal_pipe(p, (char *)data, len,
- is_data_outstanding);
- break;
+
+ state->nread = read_from_internal_pipe(
+ p, (char *)data, len, &state->is_data_outstanding);
+
+ status = (state->nread >= 0)
+ ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+ goto post_status;
}
- case FAKE_FILE_TYPE_NAMED_PIPE_PROXY: {
+
+ if (handle->type == FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
struct np_proxy_state *p = talloc_get_type_abort(
handle->private_data, struct np_proxy_state);
- int available = 0;
- *nread = sys_read(p->fd, (char *)data, len);
+ state->fd = p->fd;
- /*
- * We don't look at the ioctl result. We don't really care
- * if there is data available, because this is racy anyway.
- */
- ioctl(p->fd, FIONREAD, &available);
- *is_data_outstanding = (available > 0);
+ subreq = async_recv(state, ev, p->fd, data, len, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = np_read_done;
+ subreq->async.priv = result;
+ return result;
+ }
+
+ status = NT_STATUS_INVALID_HANDLE;
+ post_status:
+ if (async_post_ntstatus(result, ev, status)) {
+ return result;
+ }
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void np_read_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct np_read_state *state = talloc_get_type_abort(
+ req->private_data, struct np_read_state);
+ ssize_t result;
+ int sys_errno;
+ int available = 0;
+
+ result = async_syscall_result_ssize_t(subreq, &sys_errno);
+ if (result == -1) {
+ async_req_nterror(req, map_nt_error_from_unix(sys_errno));
+ return;
+ }
+ if (result == 0) {
+ async_req_nterror(req, NT_STATUS_END_OF_FILE);
+ return;
+ }
+
+ state->nread = result;
- break;
+ /*
+ * We don't look at the ioctl result. We don't really care if there is
+ * data available, because this is racy anyway.
+ */
+ ioctl(state->fd, FIONREAD, &available);
+ state->is_data_outstanding = (available > 0);
+
+ async_req_done(req);
+}
+
+NTSTATUS np_read_recv(struct async_req *req, ssize_t *nread,
+ bool *is_data_outstanding)
+{
+ struct np_read_state *state = talloc_get_type_abort(
+ req->private_data, struct np_read_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *nread = state->nread;
+ *is_data_outstanding = state->is_data_outstanding;
+ return NT_STATUS_OK;
+}
+
+/**
+ * Create a new RPC client context which uses a local dispatch function.
+ */
+NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
+ const struct ndr_syntax_id *abstract_syntax,
+ NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const struct ndr_interface_table *table,
+ uint32_t opnum, void *r),
+ struct auth_serversupplied_info *serversupplied_info,
+ struct rpc_pipe_client **presult)
+{
+ struct rpc_pipe_client *result;
+
+ result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
+ if (result == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- default:
- return NT_STATUS_INVALID_HANDLE;
- break;
+
+ result->abstract_syntax = *abstract_syntax;
+ result->transfer_syntax = ndr_transfer_syntax;
+ result->dispatch = dispatch;
+
+ result->pipes_struct = make_internal_rpc_pipe_p(
+ result, abstract_syntax, "", serversupplied_info);
+ if (result->pipes_struct == NULL) {
+ TALLOC_FREE(result);
+ return NT_STATUS_NO_MEMORY;
}
- return ((*nread) >= 0)
- ? NT_STATUS_OK : NT_STATUS_UNEXPECTED_IO_ERROR;
+ result->max_xmit_frag = -1;
+ result->max_recv_frag = -1;
+
+ *presult = result;
+ return NT_STATUS_OK;
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index ba2fe774b8..e61d343731 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -1701,7 +1701,7 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
/* check smb.conf parameters and the the sec_desc */
- if ( !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
+ if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c
index 905b147ce6..e212452e5d 100644
--- a/source3/rpcclient/cmd_eventlog.c
+++ b/source3/rpcclient/cmd_eventlog.c
@@ -55,7 +55,7 @@ static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
int argc,
const char **argv)
{
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
struct policy_handle handle;
uint32_t flags = EVENTLOG_BACKWARDS_READ |
@@ -67,7 +67,7 @@ static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
uint32_t real_size = 0;
if (argc < 2 || argc > 4) {
- printf("Usage: %s logname [offset]\n", argv[0]);
+ printf("Usage: %s logname [offset] [number_of_bytes]\n", argv[0]);
return NT_STATUS_OK;
}
@@ -75,12 +75,27 @@ static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
offset = atoi(argv[2]);
}
+ if (argc >= 4) {
+ number_of_bytes = atoi(argv[3]);
+ data = talloc_array(mem_ctx, uint8_t, number_of_bytes);
+ if (!data) {
+ goto done;
+ }
+ }
+
status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- while (1) {
+ do {
+
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ struct EVENTLOGRECORD r;
+ uint32_t size = 0;
+ uint32_t pos = 0;
+
status = rpccli_eventlog_ReadEventLogW(cli, mem_ctx,
&handle,
flags,
@@ -93,35 +108,53 @@ static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
real_size > 0 ) {
number_of_bytes = real_size;
data = talloc_array(mem_ctx, uint8_t, real_size);
- continue;
+ if (!data) {
+ goto done;
+ }
+ status = rpccli_eventlog_ReadEventLogW(cli, mem_ctx,
+ &handle,
+ flags,
+ offset,
+ number_of_bytes,
+ data,
+ &sent_size,
+ &real_size);
}
- number_of_bytes = 0;
-
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE) &&
+ !NT_STATUS_IS_OK(status)) {
goto done;
}
- {
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- struct eventlog_Record rec;
+ number_of_bytes = 0;
+
+ size = IVAL(data, pos);
- blob = data_blob_const(data, sent_size);
+ while (size > 0) {
- ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, NULL,
- &rec,
- (ndr_pull_flags_fn_t)ndr_pull_eventlog_Record);
+ blob = data_blob_const(data + pos, size);
+ /* dump_data(0, blob.data, blob.length); */
+ ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, NULL, &r,
+ (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
goto done;
}
- NDR_PRINT_DEBUG(eventlog_Record, &rec);
+ NDR_PRINT_DEBUG(EVENTLOGRECORD, &r);
+
+ pos += size;
+
+ if (pos + 4 > sent_size) {
+ break;
+ }
+
+ size = IVAL(data, pos);
}
offset++;
- }
+
+ } while (NT_STATUS_IS_OK(status));
done:
rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 050e78d274..9a02c129b5 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -619,16 +619,14 @@ static NTSTATUS do_cmd(struct cli_state *cli,
default:
DEBUG(0, ("Could not initialise %s. Invalid "
"auth type %u\n",
- cli_get_pipe_name_from_iface(
- debug_ctx(),
+ get_pipe_name_from_iface(
cmd_entry->interface),
pipe_default_auth_type ));
return NT_STATUS_UNSUCCESSFUL;
}
if (!NT_STATUS_IS_OK(ntresult)) {
DEBUG(0, ("Could not initialise %s. Error was %s\n",
- cli_get_pipe_name_from_iface(
- debug_ctx(),
+ get_pipe_name_from_iface(
cmd_entry->interface),
nt_errstr(ntresult) ));
return ntresult;
@@ -657,8 +655,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
if (!NT_STATUS_IS_OK(ntresult)) {
DEBUG(0, ("Could not initialise credentials for %s.\n",
- cli_get_pipe_name_from_iface(
- debug_ctx(),
+ get_pipe_name_from_iface(
cmd_entry->interface)));
return ntresult;
}
diff --git a/source3/samba4-templates.mk b/source3/samba4-templates.mk
index ecebce6d1d..0024a7531f 100644
--- a/source3/samba4-templates.mk
+++ b/source3/samba4-templates.mk
@@ -19,9 +19,9 @@ endef
# Link a binary
# Arguments: target file, depends, flags
define binary_link_template
-$(1)4: $(2) $(LIBREPLACE_OBJ) ;
+$(1)4: $(2) ;
@echo Linking $$@
- @$$(BNLD) $$(BNLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) $(3) $$(LIBS) $$(LIBREPLACE_OBJ)
+ @$$(BNLD) $$(BNLD_FLAGS) $$(INTERN_LDFLAGS) -o $$@ $$(INSTALL_LINK_FLAGS) $(3) $$(LIBS)
clean::
@rm -f $(1)
@@ -32,9 +32,9 @@ endef
# Link a host-machine binary
# Arguments: target file, depends, flags
define host_binary_link_template
-$(1)4: $(2) $(LIBREPLACE_OBJ) ;
+$(1)4: $(2) ;
@echo Linking $$@
- @$$(HOSTLD) $$(HOSTLD_FLAGS) -L$${builddir}/bin/static -o $$@ $$(INSTALL_LINK_FLAGS) $(3) $$(LIBREPLACE_OBJ)
+ @$$(HOSTLD) $$(HOSTLD_FLAGS) -L$${builddir}/bin/static -o $$@ $$(INSTALL_LINK_FLAGS) $(3)
clean::
rm -f $(1)
diff --git a/source3/samba4.m4 b/source3/samba4.m4
index 421ace0dbb..8107f816ad 100644
--- a/source3/samba4.m4
+++ b/source3/samba4.m4
@@ -1,5 +1,6 @@
AC_SUBST(BLDSHARED)
-smbtorture4_path=bin/smbtorture4
+smbtorture4_path="bin/smbtorture4"
+smbtorture4_option="-t bin/smbtorture4"
m4_include(build/m4/public.m4)
m4_include(../m4/check_python.m4)
@@ -18,6 +19,24 @@ AC_MSG_RESULT($pythondir)
AC_SUBST(pythondir)
+SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL} ${CRYPT_LIBS}])
+SMB_ENABLE(LIBREPLACE_EXT)
+
+SMB_EXT_LIB(LIBREPLACE_NETWORK, [${LIBREPLACE_NETWORK_LIBS}])
+SMB_ENABLE(LIBREPLACE_NETWORK)
+
+SMB_SUBSYSTEM(LIBREPLACE,
+ [${LIBREPLACE_OBJS}],
+ [LIBREPLACE_EXT LIBREPLACE_NETWORK],
+ [-I../lib/replace])
+
+LIBREPLACE_HOSTCC_OBJS=`echo ${LIBREPLACE_OBJS} |sed -e 's/\.o/\.ho/g'`
+
+SMB_SUBSYSTEM(LIBREPLACE_HOSTCC,
+ [${LIBREPLACE_HOSTCC_OBJS}],
+ [],
+ [-I../lib/replace])
+
m4_include(lib/smbreadline/readline.m4)
m4_include(heimdal_build/internal.m4)
m4_include(../lib/util/fault.m4)
@@ -71,7 +90,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent >= 0.9.2,
SMB_INCLUDE_MK(../lib/tevent/python.mk)
-SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.1,
+SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.3,
[
SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk)
SMB_INCLUDE_MK(lib/ldb/tools/config.mk)
diff --git a/source3/samba4.mk b/source3/samba4.mk
index 49afa3a2e2..b7df7a58da 100644
--- a/source3/samba4.mk
+++ b/source3/samba4.mk
@@ -111,6 +111,7 @@ ntptrsrcdir := $(samba4srcdir)/ntptr
clientsrcdir := $(samba4srcdir)/client
libclisrcdir := $(samba4srcdir)/libcli
libclinbtsrcdir := $(samba4srcdir)/../libcli/nbt
+libclicommonsrcdir := $(samba4srcdir)/../libcli
pyscriptsrcdir := $(samba4srcdir)/scripting/python
kdcsrcdir := $(samba4srcdir)/kdc
smbreadlinesrcdir := $(samba4srcdir)/lib/smbreadline
@@ -170,9 +171,9 @@ everything:: $(patsubst %,%4,$(BINARIES))
setup:
@ln -sf ../source4/setup setup
-LD_LIBPATH_OVERRIDE = $(LIB_PATH_VAR)="$(builddir)/bin/shared"
+S4_LD_LIBPATH_OVERRIDE = $(LIB_PATH_VAR)="$(builddir)/bin/shared"
-SELFTEST4 = $(LD_LIBPATH_OVERRIDE) EXEEXT="4" $(PERL) $(selftestdir)/selftest.pl --prefix=st4 \
+SELFTEST4 = $(S4_LD_LIBPATH_OVERRIDE) EXEEXT="4" $(PERL) $(selftestdir)/selftest.pl --prefix=st4 \
--builddir=$(builddir) --srcdir=$(samba4srcdir) \
--exeext=4 \
--expected-failures=$(samba4srcdir)/selftest/knownfail \
diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh
index 94fd791b51..94621841f5 100755
--- a/source3/script/tests/selftest.sh
+++ b/source3/script/tests/selftest.sh
@@ -1,17 +1,44 @@
#!/bin/sh
-if [ $# != 3 -a $# != 4 ]; then
- echo "$0 <directory> <all | quick> <smbtorture4> [<shrdir>]"
+if [ $# -lt 2 ]; then
+ echo "$0 <directory> <all | quick> [-t <smbtorture4>] [-s <shrdir>] " \
+ "[-c <custom conf>]"
exit 1
fi
-SMBTORTURE4=$3
-SUBTESTS=$2
+##
+## Setup the required args
+##
+DIRECTORY=$1; shift;
+SUBTESTS=$1; shift;
+
+##
+## Parse oprtional args
+##
+while getopts s:c:t: f
+do
+ case $f in
+ t) SMBTORTURE4=$OPTARG;;
+ s) ALT_SHRDIR_ARG=$OPTARG;;
+ c) CUSTOM_CONF_ARG=$OPTARG;;
+ esac
+done
+
+echo "Running selftest with the following"
+echo "Selftest Directory: $DIRECTORY"
+echo "Subtests to Run: $SUBTESTS"
+echo "smbtorture4 Path: $SMBTORTURE4"
+echo "Alternative Share Dir: $ALT_SHRDIR_ARG"
+echo "Custom Configuration: $CUSTOM_CONF_ARG"
+
+if [ $CUSTOM_CONF_ARG ]; then
+ INCLUDE_CUSTOM_CONF="include = $CUSTOM_CONF_ARG"
+fi
##
## create the test directory
##
-PREFIX=`echo $1 | sed s+//+/+`
+PREFIX=`echo $DIRECTORY | sed s+//+/+`
mkdir -p $PREFIX || exit $?
OLD_PWD=`pwd`
cd $PREFIX || exit $?
@@ -68,7 +95,10 @@ export WINBINDD_SOCKET_DIR WINBINDD_PRIV_PIPE_DIR
PATH=bin:$PATH
export PATH
-SAMBA4BINDIR=`dirname $SMBTORTURE4`
+if [ $SMBTORTURE4 ]; then
+ SAMBA4BINDIR=`dirname $SMBTORTURE4`
+fi
+
SAMBA4SHAREDDIR="$SAMBA4BINDIR/shared"
export SAMBA4SHAREDDIR
@@ -116,8 +146,8 @@ chmod 755 $WINBINDD_SOCKET_DIR
##
## Create an alternate shrdir if one was specified.
##
-if [ $# = 4 ]; then
- ALT_SHRDIR=`echo $4 | sed s+//+/+`
+if [ $ALT_SHRDIR_ARG ]; then
+ ALT_SHRDIR=`echo $ALT_SHRDIR_ARG | sed s+//+/+`
mkdir -p $ALT_SHRDIR || exit $?
OLD_PWD=`pwd`
cd $ALT_SHRDIR || exit $?
@@ -140,8 +170,6 @@ cat >$COMMONCONFFILE<<EOF
private dir = $PRIVATEDIR
pid directory = $PIDDIR
lock directory = $LOCKDIR
- state directory = $LOCKDIR
- cache directory = $LOCKDIR
log file = $LOGDIR/log.%m
log level = 0
@@ -177,6 +205,9 @@ cat >$SERVERCONFFILE<<EOF
panic action = $SCRIPTDIR/gdb_backtrace %d %\$(MAKE_TEST_BINARY)
include = $COMMONCONFFILE
+ state directory = $LOCKDIR
+ cache directory = $LOCKDIR
+
passdb backend = tdbsam
domain master = yes
@@ -200,8 +231,6 @@ cat >$SERVERCONFFILE<<EOF
# min receivefile size = 4000
-[tmp]
- path = $SHRDIR
read only = no
smbd:sharedelay = 100000
smbd:writetimeupdatedelay = 500000
@@ -209,6 +238,12 @@ cat >$SERVERCONFFILE<<EOF
map system = yes
create mask = 755
vfs objects = $BINDIR/xattr_tdb.so $BINDIR/streams_depot.so
+
+ #Include user defined custom parameters if set
+ $INCLUDE_CUSTOM_CONF
+
+[tmp]
+ path = $SHRDIR
[hideunread]
copy = tmp
hide unreadable = yes
diff --git a/source3/script/tests/test_functions.sh b/source3/script/tests/test_functions.sh
index 407d46aa9e..bddae18c10 100644
--- a/source3/script/tests/test_functions.sh
+++ b/source3/script/tests/test_functions.sh
@@ -1,3 +1,4 @@
+TEST_FUNCTIONS_SH="INCLUDED"
samba3_stop_sig_term() {
RET=0
@@ -197,13 +198,13 @@ testit() {
TEST_PCAP="$PREFIX/test_${shname}_${UNIQUE_PID}.pcap"
trap "rm -f $TEST_LOG $TEST_PCAP" EXIT
- if [ -z "$nmbd_log_size" ]; then
+ samba3_nmbd_test_log && if [ -z "$nmbd_log_size" ]; then
nmbd_log_size=`wc -l < $NMBD_TEST_LOG`;
fi
- if [ -z "$winbindd_log_size" ]; then
+ samba3_winbindd_test_log && if [ -z "$winbindd_log_size" ]; then
winbindd_log_size=`wc -l < $WINBINDD_TEST_LOG`;
fi
- if [ -z "$smbd_log_size" ]; then
+ samba3_smbd_test_log && if [ -z "$smbd_log_size" ]; then
smbd_log_size=`wc -l < $SMBD_TEST_LOG`;
fi
diff --git a/source3/script/tests/test_local_s3.sh b/source3/script/tests/test_local_s3.sh
index aed8637abd..1840779085 100755
--- a/source3/script/tests/test_local_s3.sh
+++ b/source3/script/tests/test_local_s3.sh
@@ -9,8 +9,10 @@ EOF
exit 1;
fi
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
diff --git a/source3/script/tests/test_net_misc.sh b/source3/script/tests/test_net_misc.sh
index 0a0636ac8a..8d092f4fe1 100755
--- a/source3/script/tests/test_net_misc.sh
+++ b/source3/script/tests/test_net_misc.sh
@@ -7,8 +7,10 @@ NET="$VALGRIND ${NET:-$BINDIR/net} $CONFIGURATION"
NETTIME="${NET} time"
NETLOOKUP="${NET} lookup"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
@@ -16,7 +18,7 @@ test_time()
{
PARAM="$1"
- ${NETTIME} ${PARAM} -S localhost2
+ ${NETTIME} -S ${SERVER} ${PARAM}
}
test_lookup()
diff --git a/source3/script/tests/test_net_registry.sh b/source3/script/tests/test_net_registry.sh
index 5edcb061ee..52a78bc339 100755
--- a/source3/script/tests/test_net_registry.sh
+++ b/source3/script/tests/test_net_registry.sh
@@ -13,8 +13,10 @@ else
NETREG="${NET} registry"
fi
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
@@ -361,8 +363,11 @@ take_administrative_rights()
if test "x${RPC}" = "xrpc" ; then
testit "giving user ${USERNAME} administrative rights" \
- give_administrative_rights || \
- failed=`expr $failed + 1`
+ give_administrative_rights
+ if [ "x$?" != "x0" ] ; then
+ failed=`expr $failed + 1`
+ testok $0 $failed
+ fi
fi
testit "enumerate HKLM" \
diff --git a/source3/script/tests/test_net_s3.sh b/source3/script/tests/test_net_s3.sh
index f7dc2b7e10..a0e83a65b1 100755
--- a/source3/script/tests/test_net_s3.sh
+++ b/source3/script/tests/test_net_s3.sh
@@ -2,8 +2,10 @@
# tests for the "net" command
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
diff --git a/source3/script/tests/test_ntlm_auth_s3.sh b/source3/script/tests/test_ntlm_auth_s3.sh
index 6c97f2e650..c7ebc03c80 100755
--- a/source3/script/tests/test_ntlm_auth_s3.sh
+++ b/source3/script/tests/test_ntlm_auth_s3.sh
@@ -1,7 +1,9 @@
#!/bin/sh
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh
index 3e9998666c..0885b139bb 100755
--- a/source3/script/tests/test_posix_s3.sh
+++ b/source3/script/tests/test_posix_s3.sh
@@ -16,8 +16,10 @@ start="$4"
shift 4
ADDARGS="$*"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
base="BASE-ATTR BASE-CHARSET BASE-CHKPATH BASE-DEFER_OPEN BASE-DELAYWRITE BASE-DELETE"
base="$base BASE-DENY1 BASE-DENY2 BASE-DENY3 BASE-DENYDOS BASE-DIR1 BASE-DIR2"
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index c10aed0ee6..f60c7d7c0b 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -2,21 +2,25 @@
# this runs the file serving tests that are expected to pass with samba3
-if [ $# -lt 2 ]; then
+if [ $# -lt 4 ]; then
cat <<EOF
-Usage: test_smbclient_s3.sh SERVER SERVER_IP
+Usage: test_smbclient_s3.sh SERVER SERVER_IP USERNAME PASSWORD
EOF
exit 1;
fi
SERVER="$1"
SERVER_IP="$2"
+USERNAME="$3"
+PASSWORD="$4"
SMBCLIENT="$VALGRIND ${SMBCLIENT:-$BINDIR/smbclient} $CONFIGURATION"
-shift 2
+shift 4
ADDARGS="$*"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
@@ -25,9 +29,18 @@ test_noninteractive_no_prompt()
{
prompt="smb"
- echo du | \
- $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I SERVER_IP $ADDARGS 2>&1 | \
- grep $prompt
+ cmd='echo du | $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP $ADDARGS 2>&1'
+ eval echo "$cmd"
+ out=`eval $cmd`
+
+ if [ $? != 0 ] ; then
+ echo "$out"
+ echo "command failed"
+ false
+ return
+ fi
+
+ echo "$out" | grep $prompt >/dev/null 2>&1
if [ $? = 0 ] ; then
# got a prompt .. fail
@@ -49,18 +62,26 @@ du
quit
EOF
- CLI_FORCE_INTERACTIVE=yes \
- $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP \
- $ADDARGS < $tmpfile 2>/dev/null | \
- grep $prompt
+ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+ eval echo "$cmd"
+ out=`eval $cmd`
+ ret=$?
+ rm -f $tmpfile
+
+ if [ $ret != 0 ] ; then
+ echo "$out"
+ echo "command failed"
+ false
+ return
+ fi
+
+ echo "$out" | grep $prompt >/dev/null 2>&1
if [ $? = 0 ] ; then
# got a prompt .. succeed
- rm -f $tmpfile
true
else
echo failed to match interactive prompt on stdout
- rm -f $tmpfile
false
fi
}
diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh
index 2ec20dc6ac..842277b357 100755
--- a/source3/script/tests/test_smbtorture_s3.sh
+++ b/source3/script/tests/test_smbtorture_s3.sh
@@ -16,8 +16,10 @@ start="$4"
shift 4
ADDARGS="$*"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7"
#tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE "
diff --git a/source3/script/tests/test_testparm_s3.sh b/source3/script/tests/test_testparm_s3.sh
index 6ea2794537..c88fc2d9d5 100755
--- a/source3/script/tests/test_testparm_s3.sh
+++ b/source3/script/tests/test_testparm_s3.sh
@@ -8,8 +8,10 @@
TEMP_CONFFILE=${LIBDIR}/smb.conf.tmp
TESTPARM="$VALGRIND ${TESTPARM:-$BINDIR/testparm} --suppress-prompt --skip-logic-checks"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
failed=0
diff --git a/source3/script/tests/test_wbinfo_s3.sh b/source3/script/tests/test_wbinfo_s3.sh
index e3bf1b9e70..fa6e20fc72 100755
--- a/source3/script/tests/test_wbinfo_s3.sh
+++ b/source3/script/tests/test_wbinfo_s3.sh
@@ -14,8 +14,10 @@ password="$4"
shift 4
ADDARGS="$*"
+test x"$TEST_FUNCTIONS_SH" != x"INCLUDED" && {
incdir=`dirname $0`
. $incdir/test_functions.sh
+}
OLDIFS=$IFS;
diff --git a/source3/script/tests/tests_all.sh b/source3/script/tests/tests_all.sh
index 2b46da0e77..11d315b198 100755
--- a/source3/script/tests/tests_all.sh
+++ b/source3/script/tests/tests_all.sh
@@ -20,13 +20,13 @@ smbtorture_s3_encrypted() {
smbclient_s3() {
echo "RUNNING TESTS smbclient_s3"
- $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP \
+ $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP $USERNAME $PASSWORD \
|| failed=`expr $failed + $?`
}
smbclient_s3_encrypted() {
echo "RUNNING TESTS smbclient_s3_encrypted"
- $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP "-e" \
+ $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP $USERNAME $PASSWORD "-e" \
|| failed=`expr $failed + $?`
}
diff --git a/source3/script/tests/tests_smbclient_s3.sh b/source3/script/tests/tests_smbclient_s3.sh
index d48a692d4b..40edf2296f 100644
--- a/source3/script/tests/tests_smbclient_s3.sh
+++ b/source3/script/tests/tests_smbclient_s3.sh
@@ -1 +1 @@
-. $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP
+. $SCRIPTDIR/test_smbclient_s3.sh $SERVER $SERVER_IP $USERNAME $PASSWORD
diff --git a/source3/selftest/tests.sh b/source3/selftest/tests.sh
index 98568b6bb3..f88dab0337 100755
--- a/source3/selftest/tests.sh
+++ b/source3/selftest/tests.sh
@@ -44,27 +44,127 @@ normalize_testname() {
echo $name | tr "A-Z-" "a-z."
}
+TEST_FUNCTIONS_SH="INCLUDED"
+testit() {
+ name=$1
+ shift 1
+ cmdline="$*"
+
+ plantest "`normalize_testname $testitprefix$name`" $testitenv $cmdline
+ return
+}
+
+testok() {
+ true
+ return
+}
+
BINDIR=`dirname $0`/../bin
+export BINDIR
+
SCRIPTDIR=`dirname $0`/../script/tests
export SCRIPTDIR
-plantest "talloctort" none $VALGRIND $BINDIR/talloctort
-plantest "replacetort" none $VALGRIND $BINDIR/replacetort
-plantest "tdbtorture" none $VALGRIND $BINDIR/tdbtorture
-plantest "smbconftort" none $VALGRIND $BINDIR/smbconftort $CONFIGURATION
-
-tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7"
-tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE "
-tests="$tests OPLOCK1 OPLOCK2 OPLOCK3"
-tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3"
-tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K"
-tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE"
-
-for t in $tests; do
- name=`normalize_testname $t`
- plantest "$name" dc $VALGRIND $BINDIR/smbtorture //\$SERVER/tmp -U\$USERNAME%\$PASSWORD $t
-done
-
-plantest "blackbox.smbclient" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP
-plantest "blackbox.wbinfo" dc BINDIR="$BINDIR" script/tests/test_wbinfo_s3.sh \$DOMAIN \$SERVER \$USERNAME \$PASSWORD
-plantest "blackbox.net" dc BINDIR="$BINDIR" SCRIPTDIR="$SCRIPTDIR" script/tests/test_net_s3.sh
+CONFIGURATION="--configfile \$SMB_CONF_PATH"
+export CONFIGURATION
+
+CONFFILE="\$SMB_CONF_PATH"
+export CONFFILE
+
+SERVER="\$SERVER"
+export SERVER
+
+USERNAME="\$USERNAME"
+export USERNAME
+
+PASSWORD="\$PASSWORD"
+export PASSWORD
+
+(
+ shift $#
+ testitprefix="local_s3."
+ testitenv="none"
+ . $SCRIPTDIR/test_local_s3.sh
+)
+
+(
+ shift $#
+ testitprefix="smbtorture_s3.plain."
+ testitenv="dc"
+ . $SCRIPTDIR/test_smbtorture_s3.sh //\$SERVER_IP/tmp \$USERNAME \$PASSWORD "" ""
+)
+
+(
+ shift $#
+ testitprefix="smbtorture_s3.crypt."
+ testitenv="dc"
+ . $SCRIPTDIR/test_smbtorture_s3.sh //\$SERVER_IP/tmp \$USERNAME \$PASSWORD "" "-e"
+)
+
+(
+ shift $#
+ testitprefix="wbinfo_s3."
+ testitenv="dc:local"
+ . $SCRIPTDIR/test_wbinfo_s3.sh \$WORKGROUP \$SERVER \$USERNAME \$PASSWORD
+)
+
+(
+ shift $#
+ testitprefix="ntlm_auth_s3."
+ testitenv="dc:local"
+ . $SCRIPTDIR/test_ntlm_auth_s3.sh
+)
+
+# plain
+plantest "blackbox.smbclient_s3.plain" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$USERNAME \$PASSWORD
+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
+
+# encrypted
+plantest "blackbox.smbclient_s3.crypt" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$USERNAME \$PASSWORD "-e"
+
+# these don't work yet
+#plantest "blackbox.smbclient_s3.crypt member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD "-e"
+#plantest "blackbox.smbclient_s3.crypt domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD "-e"
+
+plantest "blackbox.net_s3" dc:local BINDIR="$BINDIR" SCRIPTDIR="$SCRIPTDIR" SERVERCONFFILE="\$SMB_CONF_PATH" script/tests/test_net_s3.sh
+
+(
+ shift $#
+ testitprefix="posix_s3."
+ testitenv="dc:local"
+
+ SMBTORTURE4BINARY=$SMBTORTURE4
+ TORTURE4_OPTIONS=""
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --configfile=\$SMB_CONF_PATH"
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --maximum-runtime=$SELFTEST_MAXTIME"
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --target=$SELFTEST_TARGET"
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --basedir=$SELFTEST_PREFIX"
+ if [ -n "$SELFTEST_VERBOSE" ]; then
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --option=torture:progress=no"
+ fi
+ TORTURE_OPTIONS="$TORTURE4_OPTIONS --format=subunit"
+ if [ -n "$SELFTEST_QUICK" ]; then
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --option=torture:quick=yes"
+ fi
+
+ # This is an ugly hack...
+ TORTURE4_OPTIONS="$TORTURE4_OPTIONS --option=torture:localdir=$SELFTEST_PREFIX/dc/share"
+
+ if [ -x "$SMBTORTURE4" ]; then
+ LIB_PATH_VAR_VAR="\$`echo $LIB_PATH_VAR`"
+ S4_LIB_PREFIX=`eval echo "$LIB_PATH_VAR=\"$SAMBA4SHAREDDIR:$LIB_PATH_VAR_VAR\""`
+ SMBTORTURE4="$S4_LIB_PREFIX $SMBTORTURE4"
+ SMBTORTURE4VERSION=`eval $SMBTORTURE4 --version`
+ fi
+ if [ -n "$SMBTORTURE4" -a -n "$SMBTORTURE4VERSION" ];then
+ echo "Using SMBTORTURE4: $SMBTORTURE4BINARY"
+ echo "Version: $SMBTORTURE4VERSION"
+ . $SCRIPTDIR/test_posix_s3.sh //\$SERVER_IP/tmp \$USERNAME \$PASSWORD "" ""
+ else
+ echo "Skip Tests with Samba4's smbtorture"
+ echo "Try to compile with --with-smbtorture4-path=PATH to enable"
+ fi
+
+)
+
diff --git a/source3/services/services_db.c b/source3/services/services_db.c
index e41524851f..6d1b5d5b95 100644
--- a/source3/services/services_db.c
+++ b/source3/services/services_db.c
@@ -567,7 +567,8 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc,
WERROR wresult;
char *path = NULL;
REGVAL_CTR *values = NULL;
- prs_struct ps;
+ DATA_BLOB blob;
+ NTSTATUS status;
bool ret = False;
/* now add the security descriptor */
@@ -593,21 +594,18 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc,
/* stream the printer security descriptor */
- if (!prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key, MARSHALL)) {
- DEBUG(0,("svcctl_set_secdesc: prs_init() failed!\n"));
+ status = marshall_sec_desc(ctx, sec_desc, &blob.data, &blob.length);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("svcctl_set_secdesc: ndr_push_struct_blob() failed!\n"));
TALLOC_FREE( key );
return False;
}
- if ( sec_io_desc("sec_desc", &sec_desc, &ps, 0 ) ) {
- uint32 offset = prs_offset( &ps );
- regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset );
- ret = store_reg_values( key, values );
- }
+ regval_ctr_addvalue( values, "Security", REG_BINARY, (const char *)blob.data, blob.length);
+ ret = store_reg_values( key, values );
/* cleanup */
- prs_mem_free( &ps );
TALLOC_FREE( key);
return ret;
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 54ae45a789..64d512d675 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -109,58 +109,6 @@ static struct aio_extra *find_aio_ex(uint16 mid)
*****************************************************************************/
/****************************************************************************
- Signal handler when an aio request completes.
-*****************************************************************************/
-
-void aio_request_done(uint16_t mid)
-{
- if (aio_signals_received < aio_pending_size) {
- aio_pending_array[aio_signals_received] = mid;
- aio_signals_received++;
- }
- /* Else signal is lost. */
-}
-
-static void signal_handler(int sig, siginfo_t *info, void *unused)
-{
- aio_request_done(info->si_value.sival_int);
- sys_select_signal(RT_SIGNAL_AIO);
-}
-
-/****************************************************************************
- Is there a signal waiting ?
-*****************************************************************************/
-
-bool aio_finished(void)
-{
- return (aio_signals_received != 0);
-}
-
-/****************************************************************************
- Initialize the signal handler for aio read/write.
-*****************************************************************************/
-
-void initialize_async_io_handler(void)
-{
- struct sigaction act;
-
- aio_pending_size = lp_maxmux();
- aio_pending_array = SMB_MALLOC_ARRAY(uint16, aio_pending_size);
- SMB_ASSERT(aio_pending_array != NULL);
-
- ZERO_STRUCT(act);
- act.sa_sigaction = signal_handler;
- act.sa_flags = SA_SIGINFO;
- sigemptyset( &act.sa_mask );
- if (sigaction(RT_SIGNAL_AIO, &act, NULL) != 0) {
- DEBUG(0,("Failed to setup RT_SIGNAL_AIO handler\n"));
- }
-
- /* the signal can start off blocked due to a bug in bash */
- BlockSignals(False, RT_SIGNAL_AIO);
-}
-
-/****************************************************************************
Set up an aio request from a SMBreadX call.
*****************************************************************************/
@@ -193,8 +141,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF)
- || (lp_write_cache_size(SNUM(conn)) != 0) ) {
+ if (req_is_in_chain(req) || (lp_write_cache_size(SNUM(conn)) != 0)) {
return False;
}
@@ -290,8 +237,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF)
- || (lp_write_cache_size(SNUM(conn)) != 0) ) {
+ if (req_is_in_chain(req) || (lp_write_cache_size(SNUM(conn)) != 0)) {
return False;
}
@@ -573,57 +519,47 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
Returns non-zero errno if fail or zero if all ok.
*****************************************************************************/
-int process_aio_queue(void)
+void smbd_aio_complete_mid(unsigned int mid)
{
- int i;
+ files_struct *fsp = NULL;
+ struct aio_extra *aio_ex = find_aio_ex(mid);
int ret = 0;
- BlockSignals(True, RT_SIGNAL_AIO);
-
- DEBUG(10,("process_aio_queue: signals_received = %d\n",
- (int)aio_signals_received));
- DEBUG(10,("process_aio_queue: outstanding_aio_calls = %d\n",
- outstanding_aio_calls));
+ DEBUG(10,("smbd_aio_complete_mid: mid[%u]\n", mid));
- if (!aio_signals_received) {
- BlockSignals(False, RT_SIGNAL_AIO);
- return 0;
+ if (!aio_ex) {
+ DEBUG(3,("smbd_aio_complete_mid: Can't find record to "
+ "match mid %u.\n", mid));
+ srv_cancel_sign_response(mid);
+ return;
}
- /* Drain all the complete aio_reads. */
- for (i = 0; i < aio_signals_received; i++) {
- uint16 mid = aio_pending_array[i];
- files_struct *fsp = NULL;
- struct aio_extra *aio_ex = find_aio_ex(mid);
-
- if (!aio_ex) {
- DEBUG(3,("process_aio_queue: Can't find record to "
- "match mid %u.\n", (unsigned int)mid));
- srv_cancel_sign_response(mid);
- continue;
- }
+ fsp = aio_ex->fsp;
+ if (fsp == NULL) {
+ /* file was closed whilst I/O was outstanding. Just
+ * ignore. */
+ DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst "
+ "aio outstanding (mid[%u]).\n", mid));
+ srv_cancel_sign_response(mid);
+ return;
+ }
- fsp = aio_ex->fsp;
- if (fsp == NULL) {
- /* file was closed whilst I/O was outstanding. Just
- * ignore. */
- DEBUG( 3,( "process_aio_queue: file closed whilst "
- "aio outstanding.\n"));
- srv_cancel_sign_response(mid);
- continue;
- }
+ if (!handle_aio_completed(aio_ex, &ret)) {
+ return;
+ }
- if (!handle_aio_completed(aio_ex, &ret)) {
- continue;
- }
+ TALLOC_FREE(aio_ex);
+}
- TALLOC_FREE(aio_ex);
- }
+static void smbd_aio_signal_handler(struct tevent_context *ev_ctx,
+ struct tevent_signal *se,
+ int signum, int count,
+ void *_info, void *private_data)
+{
+ siginfo_t *info = (siginfo_t *)_info;
+ unsigned int mid = (unsigned int)info->si_value.sival_int;
- outstanding_aio_calls -= aio_signals_received;
- aio_signals_received = 0;
- BlockSignals(False, RT_SIGNAL_AIO);
- return ret;
+ smbd_aio_complete_mid(mid);
}
/****************************************************************************
@@ -755,19 +691,28 @@ void cancel_aio_by_fsp(files_struct *fsp)
}
}
-#else
-bool aio_finished(void)
-{
- return False;
-}
+/****************************************************************************
+ Initialize the signal handler for aio read/write.
+*****************************************************************************/
void initialize_async_io_handler(void)
{
+ aio_signal_event = tevent_add_signal(smbd_event_context(),
+ smbd_event_context(),
+ RT_SIGNAL_AIO, SA_SIGINFO,
+ smbd_aio_signal_handler,
+ NULL);
+ if (!aio_signal_event) {
+ exit_server("Failed to setup RT_SIGNAL_AIO handler");
+ }
+
+ /* tevent supports 100 signal with SA_SIGINFO */
+ aio_pending_size = 100;
}
-int process_aio_queue(void)
+#else
+void initialize_async_io_handler(void)
{
- return False;
}
bool schedule_aio_read_and_X(connection_struct *conn,
@@ -795,4 +740,7 @@ int wait_for_aio_completion(files_struct *fsp)
{
return ENOSYS;
}
+
+void smbd_aio_complete_mid(unsigned int mid);
+
#endif
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 9936fb219f..ac1ff00858 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -47,11 +47,6 @@ typedef struct blocking_lock_record {
Determine if this is a secondary element of a chained SMB.
**************************************************************************/
-static bool in_chained_smb(void)
-{
- return (chain_size != 0);
-}
-
static void received_unlock_msg(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -144,7 +139,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blocking_lock_record *blr;
NTSTATUS status;
- if(in_chained_smb() ) {
+ if(req_is_in_chain(req)) {
DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
return False;
}
diff --git a/source3/smbd/dnsregister.c b/source3/smbd/dnsregister.c
index c092251fee..2fd95f9fb7 100644
--- a/source3/smbd/dnsregister.c
+++ b/source3/smbd/dnsregister.c
@@ -35,18 +35,16 @@
#include <dns_sd.h>
struct dns_reg_state {
+ struct tevent_context *event_ctx;
+ uint16_t port;
DNSServiceRef srv_ref;
- struct timed_event *retry_handler;
+ struct tevent_timer *te;
+ int fd;
+ struct tevent_fd *fde;
};
-void dns_register_close(struct dns_reg_state **dns_state_ptr)
+static int dns_reg_state_destructor(struct dns_reg_state *dns_state)
{
- struct dns_reg_state *dns_state = *dns_state_ptr;
-
- if (dns_state == NULL) {
- return;
- }
-
if (dns_state->srv_ref != NULL) {
/* Close connection to the mDNS daemon */
DNSServiceRefDeallocate(dns_state->srv_ref);
@@ -54,81 +52,52 @@ void dns_register_close(struct dns_reg_state **dns_state_ptr)
}
/* Clear event handler */
- if (dns_state->retry_handler != NULL) {
- TALLOC_FREE(dns_state->retry_handler);
- dns_state->retry_handler = NULL;
- }
+ TALLOC_FREE(dns_state->te);
+ TALLOC_FREE(dns_state->fde);
+ dns_state->fd = -1;
- talloc_free(dns_state);
- *dns_state_ptr = NULL;
+ return 0;
}
-static void dns_register_smbd_retry(struct event_context *ctx,
- struct timed_event *te,
- const struct timeval *now,
- void *private_data)
+static void dns_register_smbd_retry(struct tevent_context *ctx,
+ struct tevent_timer *te,
+ struct timeval now,
+ void *private_data);
+static void dns_register_smbd_fde_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
+static bool dns_register_smbd_schedule(struct dns_reg_state *dns_state,
+ struct timeval tval)
{
- struct dns_reg_state *dns_state = (struct dns_reg_state *)private_data;
-
- /* Clear previous registration state to force new
- * registration attempt. Clears event handler.
- */
- dns_register_close(&dns_state);
-}
-
-static void schedule_dns_register_smbd_retry(struct dns_reg_state *dns_state,
- struct timeval *timeout)
-{
- struct timed_event * event;
-
- dns_state->srv_ref = NULL;
- event= event_add_timed(smbd_event_context(),
- NULL,
- timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0),
- dns_register_smbd_retry,
- dns_state);
+ dns_reg_state_destructor(dns_state);
+
+ dns_state->te = tevent_add_timer(dns_state->event_ctx,
+ dns_state,
+ tval,
+ dns_register_smbd_retry,
+ dns_state);
+ if (!dns_state->te) {
+ return false;
+ }
- dns_state->retry_handler = event;
- get_timed_events_timeout(smbd_event_context(), timeout);
+ return true;
}
-/* Kick off a mDNS request to register the "_smb._tcp" on the specified port.
- * We really ought to register on all the ports we are listening on. This will
- * have to be an exercise for some-one who knows the DNS registration API a bit
- * better.
- */
-void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
- unsigned port,
- int *maxfd,
- fd_set *listen_set,
- struct timeval *timeout)
+static void dns_register_smbd_retry(struct tevent_context *ctx,
+ struct tevent_timer *te,
+ struct timeval now,
+ void *private_data)
{
- int mdnsd_conn_fd;
+ struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
+ struct dns_reg_state);
DNSServiceErrorType err;
- struct dns_reg_state *dns_state = *dns_state_ptr;
-
- if (dns_state == NULL) {
- *dns_state_ptr = dns_state = talloc(NULL, struct dns_reg_state);
- if (dns_state == NULL) {
- return;
- }
- }
-
- /* Quit if a re-try attempt has been scheduled. */
- if (dns_state->retry_handler != NULL) {
- return;
- }
- /* If a registration is active add conn
- * fd to select listen_set and return
- */
- if (dns_state->srv_ref != NULL) {
- mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
- FD_SET(mdnsd_conn_fd, listen_set);
- return;
- }
+ dns_reg_state_destructor(dns_state);
- DEBUG(6, ("registering _smb._tcp service on port %d\n", port));
+ DEBUG(6, ("registering _smb._tcp service on port %d\n",
+ dns_state->port));
/* Register service with DNS. Connects with the mDNS
* daemon running on the local system to perform DNS
@@ -140,7 +109,7 @@ void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
"_smb._tcp" /* service type */,
NULL /* domain */,
"" /* SRV target host name */,
- htons(port),
+ htons(dns_state->port),
0 /* TXT record len */,
NULL /* TXT record data */,
NULL /* callback func */,
@@ -150,62 +119,81 @@ void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
/* Failed to register service. Schedule a re-try attempt.
*/
DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
- schedule_dns_register_smbd_retry(dns_state, timeout);
- return;
+ goto retry;
+ }
+
+ dns_state->fd = DNSServiceRefSockFD(dns_state->srv_ref);
+ if (dns_state->fd == -1) {
+ goto retry;
}
- mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
- FD_SET(mdnsd_conn_fd, listen_set);
- *maxfd = MAX(*maxfd, mdnsd_conn_fd);
- *timeout = timeval_zero();
+ dns_state->fde = tevent_add_fd(dns_state->event_ctx,
+ dns_state,
+ dns_state->fd,
+ TEVENT_FD_READ,
+ dns_register_smbd_fde_handler,
+ dns_state);
+ if (!dns_state->fde) {
+ goto retry;
+ }
+ return;
+ retry:
+ dns_register_smbd_schedule(dns_state,
+ timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
}
/* Processes reply from mDNS daemon. Returns true if a reply was received */
-bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
- fd_set *lfds, struct timeval *timeout)
+static void dns_register_smbd_fde_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
{
- int mdnsd_conn_fd = -1;
+ struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
+ struct dns_reg_state);
+ DNSServiceErrorType err;
- if (dns_state->srv_ref == NULL) {
- return false;
+ err = DNSServiceProcessResult(dns_state->srv_ref);
+ if (err != kDNSServiceErr_NoError) {
+ DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
+ err));
+ goto retry;
}
- mdnsd_conn_fd = DNSServiceRefSockFD(dns_state->srv_ref);
+ talloc_free(dns_state);
+ return;
- /* Process reply from daemon. Handles any errors. */
- if ((mdnsd_conn_fd != -1) && (FD_ISSET(mdnsd_conn_fd,lfds)) ) {
- DNSServiceErrorType err;
-
- err = DNSServiceProcessResult(dns_state->srv_ref);
- if (err != kDNSServiceErr_NoError) {
- DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
- err));
- schedule_dns_register_smbd_retry(dns_state, timeout);
- }
+ retry:
+ dns_register_smbd_schedule(dns_state,
+ timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
+}
- return true;
+bool smbd_setup_mdns_registration(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ uint16_t port)
+{
+ struct dns_reg_state *dns_state;
+
+ dns_state = talloc_zero(mem_ctx, struct dns_reg_state);
+ if (dns_state == NULL) {
+ return false;
}
+ dns_state->event_ctx = ev;
+ dns_state->port = port;
+ dns_state->fd = -1;
+
+ talloc_set_destructor(dns_state, dns_reg_state_destructor);
- return false;
+ return dns_register_smbd_schedule(dns_state, timeval_zero());
}
#else /* WITH_DNSSD_SUPPORT */
- void dns_register_smbd(struct dns_reg_state ** dns_state_ptr,
- unsigned port,
- int *maxfd,
- fd_set *listen_set,
- struct timeval *timeout)
-{}
-
- void dns_register_close(struct dns_reg_state ** dns_state_ptr)
-{}
-
- bool dns_register_smbd_reply(struct dns_reg_state *dns_state,
- fd_set *lfds, struct timeval *timeout)
+bool smbd_setup_mdns_registration(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ uint16_t port)
{
- return false;
+ return true;
}
#endif /* WITH_DNSSD_SUPPORT */
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index d44e63a89a..fe7ba1cc46 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -113,16 +113,11 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
* having the DELETE bit on the file itself and second if that does
* not help, by the DELETE_CHILD bit on the containing directory.
*
- * Here we check the other way round because with just posix
- * permissions looking at the file itself will never grant DELETE, so
- * by looking at the directory first we save one get_acl call.
+ * Here we only check the directory permissions, we will
+ * check the file DELETE permission separately.
*/
- if (can_access_file_acl(conn, dname, FILE_DELETE_CHILD)) {
- return true;
- }
-
- return can_access_file_acl(conn, fname, DELETE_ACCESS);
+ return can_access_file_acl(conn, dname, FILE_DELETE_CHILD);
}
/****************************************************************************
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index d240ecfa64..003cb0ffd4 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -126,7 +126,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
char *stream = NULL;
bool component_was_mangled = False;
bool name_has_wildcard = False;
+ bool posix_pathnames = false;
NTSTATUS result;
+ int ret = -1;
SET_STAT_INVALID(*pst);
*pp_conv_path = NULL;
@@ -225,7 +227,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
}
}
- if (!lp_posix_pathnames()) {
+ posix_pathnames = lp_posix_pathnames();
+
+ if (!posix_pathnames) {
stream = strchr_m(name, ':');
if (stream != NULL) {
@@ -268,7 +272,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* stat the name - if it exists then we are all done!
*/
- if (SMB_VFS_STAT(conn,name,&st) == 0) {
+ if (posix_pathnames) {
+ ret = SMB_VFS_LSTAT(conn,name,&st);
+ } else {
+ ret = SMB_VFS_STAT(conn,name,&st);
+ }
+
+ if (ret == 0) {
/* Ensure we catch all names with in "/."
this is disallowed under Windows. */
const char *p = strstr(name, "/."); /* mb safe. */
@@ -380,7 +390,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* Check if the name exists up to this point.
*/
- if (SMB_VFS_STAT(conn,name, &st) == 0) {
+ if (posix_pathnames) {
+ ret = SMB_VFS_LSTAT(conn,name, &st);
+ } else {
+ ret = SMB_VFS_STAT(conn,name, &st);
+ }
+
+ if (ret == 0) {
/*
* It exists. it must either be a directory or this must
* be the last part of the path for it to be OK.
@@ -598,7 +614,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* if it exists. JRA.
*/
- if (SMB_VFS_STAT(conn,name, &st) == 0) {
+ if (posix_pathnames) {
+ ret = SMB_VFS_LSTAT(conn,name, &st);
+ } else {
+ ret = SMB_VFS_STAT(conn,name, &st);
+ }
+
+ if (ret == 0) {
*pst = st;
} else {
SET_STAT_INVALID(st);
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index c5681223f9..3f8cb411e5 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -22,10 +22,9 @@
#if defined(WITH_AIO)
struct aio_extra *aio_list_head = NULL;
+struct tevent_signal *aio_signal_event = NULL;
int aio_pending_size = 0;
-sig_atomic_t aio_signals_received = 0;
int outstanding_aio_calls = 0;
-uint16 *aio_pending_array = NULL;
#endif
/* dlink list we store pending lock records on. */
@@ -125,8 +124,6 @@ int max_send = BUFFER_SIZE;
* Can be modified by the max xmit parameter.
*/
int max_recv = BUFFER_SIZE;
-SIG_ATOMIC_T reload_after_sighup = 0;
-SIG_ATOMIC_T got_sig_term = 0;
uint16 last_session_tag = UID_FIELD_INVALID;
int trans_num = 0;
char *orig_inbuf = NULL;
@@ -172,11 +169,6 @@ struct vfs_init_function_entry *backends = NULL;
char *sparse_buf = NULL;
char *LastDir = NULL;
-#if HAVE_KERNEL_OPLOCKS_LINUX
-SIG_ATOMIC_T oplock_signals_received = 0;
-SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
-#endif
-
/* Current number of oplocks we have outstanding. */
int32_t exclusive_oplocks_open = 0;
int32_t level_II_oplocks_open = 0;
@@ -186,7 +178,6 @@ struct kernel_oplocks *koplocks = NULL;
struct notify_mid_map *notify_changes_by_mid = NULL;
int am_parent = 1;
-SIG_ATOMIC_T got_sig_cld = 0;
int server_fd = -1;
struct event_context *smbd_event_ctx = NULL;
struct messaging_context *smbd_msg_ctx = NULL;
@@ -205,8 +196,4 @@ void smbd_init_globals(void)
ZERO_STRUCT(conn_ctx_stack);
ZERO_STRUCT(sec_ctx_stack);
-
-#if HAVE_KERNEL_OPLOCKS_LINUX
- ZERO_STRUCT(fd_pending_array);
-#endif
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 2c4f8b5821..6ac92ed3dd 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -20,10 +20,9 @@
#if defined(WITH_AIO)
struct aio_extra;
extern struct aio_extra *aio_list_head;
+extern struct tevent_signal *aio_signal_event;
extern int aio_pending_size;
-extern sig_atomic_t aio_signals_received;
extern int outstanding_aio_calls;
-extern uint16_t *aio_pending_array;
#endif
/* dlink list we store pending lock records on. */
@@ -124,8 +123,6 @@ extern int max_send;
* Can be modified by the max xmit parameter.
*/
extern int max_recv;
-extern SIG_ATOMIC_T reload_after_sighup;
-extern SIG_ATOMIC_T got_sig_term;
extern uint16 last_session_tag;
extern int trans_num;
extern char *orig_inbuf;
@@ -184,12 +181,6 @@ extern struct vfs_init_function_entry *backends;
extern char *sparse_buf;
extern char *LastDir;
-#if HAVE_KERNEL_OPLOCKS_LINUX
-extern SIG_ATOMIC_T oplock_signals_received;
-#define FD_PENDING_SIZE 100
-extern SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
-#endif
-
/* Current number of oplocks we have outstanding. */
extern int32_t exclusive_oplocks_open;
extern int32_t level_II_oplocks_open;
@@ -199,7 +190,6 @@ extern struct kernel_oplocks *koplocks;
extern struct notify_mid_map *notify_changes_by_mid;
extern int am_parent;
-extern SIG_ATOMIC_T got_sig_cld;
extern int server_fd;
extern struct event_context *smbd_event_ctx;
extern struct messaging_context *smbd_msg_ctx;
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 7c150561b1..9c7528dfa7 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -204,40 +204,137 @@ void send_trans_reply(connection_struct *conn,
Start the first part of an RPC reply which began with an SMBtrans request.
****************************************************************************/
-static void api_rpc_trans_reply(connection_struct *conn,
- struct smb_request *req,
- files_struct *fsp,
- int max_trans_reply)
+struct dcerpc_cmd_state {
+ struct fake_file_handle *handle;
+ uint8_t *data;
+ size_t num_data;
+ size_t max_read;
+};
+
+static void api_dcerpc_cmd_write_done(struct async_req *subreq);
+static void api_dcerpc_cmd_read_done(struct async_req *subreq);
+
+static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
+ files_struct *fsp, uint8_t *data, size_t length,
+ size_t max_read)
{
- bool is_data_outstanding;
- uint8_t *rdata = SMB_MALLOC_ARRAY(uint8_t, max_trans_reply);
- ssize_t data_len;
- NTSTATUS status;
+ struct async_req *subreq;
+ struct dcerpc_cmd_state *state;
+
+ if (!fsp_is_np(fsp)) {
+ api_no_reply(conn, req);
+ return;
+ }
- if(rdata == NULL) {
- DEBUG(0,("api_rpc_trans_reply: malloc fail.\n"));
+ state = talloc(req, struct dcerpc_cmd_state);
+ if (state == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
+ req->async_priv = state;
- if (!fsp_is_np(fsp)) {
- SAFE_FREE(rdata);
- api_no_reply(conn,req);
+ state->handle = fsp->fake_file_handle;
+
+ /*
+ * This memdup severely sucks. But doing it properly essentially means
+ * to rewrite lanman.c, something which I don't really want to do now.
+ */
+ state->data = (uint8_t *)talloc_memdup(state, data, length);
+ if (state->data == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
+ state->num_data = length;
+ state->max_read = max_read;
+
+ subreq = np_write_send(state, smbd_event_context(), state->handle,
+ state->data, length);
+ if (subreq == NULL) {
+ TALLOC_FREE(state);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ subreq->async.fn = api_dcerpc_cmd_write_done;
+ subreq->async.priv = talloc_move(conn, &req);
+}
+
+static void api_dcerpc_cmd_write_done(struct async_req *subreq)
+{
+ struct smb_request *req = talloc_get_type_abort(
+ subreq->async.priv, struct smb_request);
+ struct dcerpc_cmd_state *state = talloc_get_type_abort(
+ req->async_priv, struct dcerpc_cmd_state);
+ NTSTATUS status;
+ ssize_t nwritten = -1;
+
+ status = np_write_recv(subreq, &nwritten);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status) || (nwritten != state->num_data)) {
+ DEBUG(10, ("Could not write to pipe: %s (%d/%d)\n",
+ nt_errstr(status), (int)state->num_data,
+ (int)nwritten));
+ reply_nterror(req, NT_STATUS_PIPE_NOT_AVAILABLE);
+ goto send;
+ }
+
+ state->data = TALLOC_REALLOC_ARRAY(state, state->data, uint8_t,
+ state->max_read);
+ if (state->data == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ goto send;
+ }
+
+ subreq = np_read_send(req->conn, smbd_event_context(),
+ state->handle, state->data, state->max_read);
+ if (subreq == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ goto send;
+ }
+
+ subreq->async.fn = api_dcerpc_cmd_read_done;
+ subreq->async.priv = req;
+ return;
+
+ send:
+ if (!srv_send_smb(
+ smbd_server_fd(), (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(req->conn) || req->encrypted)) {
+ exit_server_cleanly("construct_reply: srv_send_smb failed.");
+ }
+ TALLOC_FREE(req);
+}
+
+static void api_dcerpc_cmd_read_done(struct async_req *subreq)
+{
+ struct smb_request *req = talloc_get_type_abort(
+ subreq->async.priv, struct smb_request);
+ struct dcerpc_cmd_state *state = talloc_get_type_abort(
+ req->async_priv, struct dcerpc_cmd_state);
+ NTSTATUS status;
+ ssize_t nread;
+ bool is_data_outstanding;
+
+ status = np_read_recv(subreq, &nread, &is_data_outstanding);
+ TALLOC_FREE(subreq);
- status = np_read(fsp->fake_file_handle, rdata, max_trans_reply,
- &data_len, &is_data_outstanding);
if (!NT_STATUS_IS_OK(status)) {
- SAFE_FREE(rdata);
- api_no_reply(conn,req);
+ DEBUG(10, ("Could not read from to pipe: %s\n",
+ nt_errstr(status)));
+ reply_nterror(req, status);
+
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(req->conn)
+ ||req->encrypted)) {
+ exit_server_cleanly("construct_reply: srv_send_smb "
+ "failed.");
+ }
+ TALLOC_FREE(req);
return;
}
- send_trans_reply(conn, req, NULL, 0, (char *)rdata, data_len,
+ send_trans_reply(req->conn, req, NULL, 0, (char *)state->data, nread,
is_data_outstanding);
- SAFE_FREE(rdata);
- return;
+ TALLOC_FREE(req);
}
/****************************************************************************
@@ -310,7 +407,6 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
struct files_struct *fsp;
int pnum;
int subcommand;
- NTSTATUS status;
DEBUG(5,("api_fd_reply\n"));
@@ -360,14 +456,8 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
switch (subcommand) {
case TRANSACT_DCERPCCMD: {
/* dce/rpc command */
- ssize_t nwritten;
- status = np_write(fsp->fake_file_handle, data, tdscnt,
- &nwritten);
- if (!NT_STATUS_IS_OK(status)) {
- api_no_reply(conn, req);
- return;
- }
- api_rpc_trans_reply(conn, req, fsp, mdrcnt);
+ api_dcerpc_cmd(conn, req, fsp, (uint8_t *)data, tdscnt,
+ mdrcnt);
break;
}
case TRANSACT_WAITNAMEDPIPEHANDLESTATE:
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index c8e35783c0..4807e62436 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -6,17 +6,17 @@
SMB Version handling
Copyright (C) John H Terpstra 1995-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/>.
*/
@@ -876,9 +876,9 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
/* remove any trailing username */
if ((p = strchr_m(QueueName,'%')))
*p = 0;
-
+
DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName));
-
+
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh"))
return False;
@@ -899,11 +899,11 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
SSVAL(*rparam,4,0);
return(True);
}
-
+
snum = find_service(QueueName);
if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
return False;
-
+
if (uLevel==52) {
count = get_printerdrivernumber(snum);
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
@@ -934,7 +934,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
}
*rdata_len = desc.usedlen;
-
+
/*
* We must set the return code to ERRbuftoosmall
* in order to support lanman style printing with Win NT/2k
@@ -942,7 +942,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
*/
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
-
+
*rdata_len = desc.usedlen;
*rparam_len = 6;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
@@ -954,7 +954,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
-
+
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
SAFE_FREE(queue);
@@ -986,7 +986,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
print_status_struct *status = NULL;
int *subcntarr = NULL;
int queuecnt = 0, subcnt = 0, succnt = 0;
-
+
if (!param_format || !output_format1 || !p) {
return False;
}
@@ -994,7 +994,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-
+
if (!prefix_ok(param_format,"WrLeh")) {
return False;
}
@@ -1071,7 +1071,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
}
SAFE_FREE(subcntarr);
-
+
*rdata_len = desc.usedlen;
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
@@ -1082,7 +1082,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
SSVAL(*rparam,6,queuecnt);
-
+
for (i = 0; i < queuecnt; i++) {
if (queue) {
SAFE_FREE(queue[i]);
@@ -1091,7 +1091,7 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
SAFE_FREE(queue);
SAFE_FREE(status);
-
+
return True;
err:
@@ -1248,11 +1248,11 @@ static int get_server_info(uint32 servertype,
DEBUG(4,("s: dom mismatch "));
ok = False;
}
-
+
if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
ok = False;
}
-
+
/* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
@@ -1266,7 +1266,7 @@ static int get_server_info(uint32 servertype,
s->name, s->type, s->comment, s->domain));
}
}
-
+
TALLOC_FREE(lines);
return count;
}
@@ -1284,7 +1284,7 @@ static int fill_srv_info(struct srv_info_struct *service,
char* p2;
int l2;
int len;
-
+
switch (uLevel) {
case 0:
struct_len = 16;
@@ -1295,7 +1295,7 @@ static int fill_srv_info(struct srv_info_struct *service,
default:
return -1;
}
-
+
if (!buf) {
len = 0;
switch (uLevel) {
@@ -1308,7 +1308,7 @@ static int fill_srv_info(struct srv_info_struct *service,
*stringspace = len;
return struct_len + len;
}
-
+
len = struct_len;
p = *buf;
if (*buflen < struct_len) {
@@ -1324,7 +1324,7 @@ static int fill_srv_info(struct srv_info_struct *service,
if (!baseaddr) {
baseaddr = p;
}
-
+
switch (uLevel) {
case 0:
push_ascii(p,service->name, MAX_NETBIOSNAME_LEN, STR_TERMINATE);
@@ -1416,7 +1416,7 @@ static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid,
if (!check_server_info(uLevel,str2)) {
return False;
}
-
+
DEBUG(4, ("server request level: %s %8x ", str2, servertype));
DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
@@ -1454,7 +1454,7 @@ static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid,
data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
s->name, s->type, s->comment, s->domain));
-
+
if (data_len <= buf_len) {
counted++;
fixed_len += f_len;
@@ -1470,7 +1470,7 @@ static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid,
if (!*rdata) {
return False;
}
-
+
p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
p = *rdata;
f_len = fixed_len;
@@ -1493,7 +1493,7 @@ static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid,
count2--;
}
}
-
+
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
@@ -1540,9 +1540,9 @@ static bool api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
if (!prefix_ok(str1,"zWrLeh")) {
return False;
}
-
+
*rdata_len = 0;
-
+
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
@@ -1599,7 +1599,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
char* p2;
int l2;
int len;
-
+
switch( uLevel ) {
case 0:
struct_len = 13;
@@ -1616,8 +1616,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
default:
return -1;
}
-
-
+
if (!buf) {
len = 0;
@@ -1635,7 +1634,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
}
return struct_len + len;
}
-
+
len = struct_len;
p = *buf;
if ((*buflen) < struct_len) {
@@ -1653,9 +1652,9 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
if (!baseaddr) {
baseaddr = p;
}
-
+
push_ascii(p,lp_servicename(snum),13, STR_TERMINATE);
-
+
if (uLevel > 0) {
int type;
@@ -1671,7 +1670,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
}
-
+
if (uLevel > 1) {
SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
SSVALS(p,22,-1); /* max uses */
@@ -1680,7 +1679,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
}
-
+
if (uLevel > 2) {
memset(p+40,0,SHPWLEN+2);
SSVAL(p,50,0);
@@ -1691,7 +1690,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
SSVAL(p,64,0);
SSVAL(p,66,0);
}
-
+
if (stringbuf) {
(*buf) = p + struct_len;
(*buflen) -= struct_len;
@@ -1718,7 +1717,7 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
char *p = skip_string(param,tpscnt,netname);
int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
int snum;
-
+
if (!str1 || !str2 || !netname || !p) {
return False;
}
@@ -1727,7 +1726,7 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
if (snum < 0) {
return False;
}
-
+
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh")) {
return False;
@@ -1735,7 +1734,7 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
if (!check_share_info(uLevel,str2)) {
return False;
}
-
+
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
return False;
@@ -1745,7 +1744,7 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
if (*rdata_len < 0) {
return False;
}
-
+
*rparam_len = 6;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
@@ -1754,7 +1753,7 @@ static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
-
+
return True;
}
@@ -1790,7 +1789,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
int i;
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
-
+
if (!str1 || !str2 || !p) {
return False;
}
@@ -1801,7 +1800,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
if (!check_share_info(uLevel,str2)) {
return False;
}
-
+
/* Ensure all the usershares are loaded. */
become_root();
load_registry_shares();
@@ -1834,7 +1833,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
if (!*rdata) {
return False;
}
-
+
p2 = (*rdata) + fixed_len; /* auxiliary data (strings) will go here */
p = *rdata;
f_len = fixed_len;
@@ -1853,7 +1852,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
}
}
}
-
+
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
@@ -1863,7 +1862,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,counted);
SSVAL(*rparam,6,total);
-
+
DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
counted,total,uLevel,
buf_len,*rdata_len,mdrcnt));
@@ -2004,7 +2003,7 @@ static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
*rdata_len = 0;
-
+
return True;
error_exit:
@@ -2042,7 +2041,7 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
struct samr_displayentry *entries;
int num_entries;
-
+
if (!str1 || !str2 || !p) {
return False;
}
@@ -2282,8 +2281,11 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
int num_users=0;
int errflags=0;
int i, resume_context, cli_buf_size;
- struct pdb_search *search;
- struct samr_displayentry *users;
+ uint32_t resume_handle;
+
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle samr_handle, domain_handle;
+ NTSTATUS status;
char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
char *str2 = skip_string(param,tpscnt,str1);
@@ -2328,40 +2330,88 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
p = *rdata;
endp = *rdata + *rdata_len;
- become_root();
- search = pdb_search_users(ACB_NORMAL);
- unbecome_root();
- if (search == NULL) {
- DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
- return False;
+ status = rpc_pipe_open_internal(
+ talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+ conn->server_info, &samr_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
+ nt_errstr(status)));
+ return false;
}
- become_root();
- num_users = pdb_search_entries(search, resume_context, 0xffffffff,
- &users);
- unbecome_root();
+ status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
+ SAMR_ACCESS_OPEN_DOMAIN, &samr_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
+
+ status = rpccli_samr_OpenDomain(samr_pipe, talloc_tos(), &samr_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+ get_global_sam_sid(), &domain_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
errflags=NERR_Success;
- for (i=0; i<num_users; i++) {
- const char *name = users[i].account_name;
+ resume_handle = 0;
- if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
- strlcpy(p,name,PTR_DIFF(endp,p));
- DEBUG(10,("api_RNetUserEnum:adding entry %d username "
- "%s\n",count_sent,p));
- p += 21;
- count_sent++;
- } else {
- /* set overflow error */
- DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
- "username %s\n",count_sent,name));
- errflags=234;
+ while (true) {
+ struct samr_SamArray *sam_entries;
+ uint32_t num_entries;
+
+ status = rpccli_samr_EnumDomainUsers(samr_pipe, talloc_tos(),
+ &domain_handle,
+ &resume_handle,
+ 0, &sam_entries, 1,
+ &num_entries);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("rpccli_samr_EnumDomainUsers returned "
+ "%s\n", nt_errstr(status)));
+ break;
+ }
+
+ if (num_entries == 0) {
+ DEBUG(10, ("rpccli_samr_EnumDomainUsers returned "
+ "no entries -- done\n"));
+ break;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ const char *name;
+
+ name = sam_entries->entries[i].name.string;
+
+ if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)
+ &&(strlen(name)<=21)) {
+ strlcpy(p,name,PTR_DIFF(endp,p));
+ DEBUG(10,("api_RNetUserEnum:adding entry %d "
+ "username %s\n",count_sent,p));
+ p += 21;
+ count_sent++;
+ } else {
+ /* set overflow error */
+ DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
+ "username %s\n",count_sent,name));
+ errflags=234;
+ break;
+ }
+ }
+
+ if (errflags != NERR_Success) {
break;
}
+
+ TALLOC_FREE(sam_entries);
}
- pdb_search_destroy(search);
+ rpccli_samr_Close(samr_pipe, talloc_tos(), &domain_handle);
+ rpccli_samr_Close(samr_pipe, talloc_tos(), &samr_handle);
*rdata_len = PTR_DIFF(p,*rdata);
@@ -2538,7 +2588,7 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
memset((char *)pass1,'\0',sizeof(fstring));
memset((char *)pass2,'\0',sizeof(fstring));
-
+
return(True);
}
@@ -2677,7 +2727,7 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
}
errcode = NERR_notsupported;
-
+
switch (function) {
case 81: /* delete */
if (print_job_delete(conn->server_info, snum, jobid, &werr))
@@ -2695,7 +2745,7 @@ static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
if (!W_ERROR_IS_OK(werr))
errcode = W_ERROR_V(werr);
-
+
out:
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
@@ -2845,9 +2895,9 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
sharename));
return False;
}
-
+
*rdata_len = 0;
-
+
/* check it's a supported varient */
if ((strcmp(str1,"WWsTP")) ||
(!check_printjob_info(&desc,uLevel,str2)))
@@ -2884,7 +2934,7 @@ static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
out:
SSVALS(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
-
+
return(True);
}
@@ -3638,7 +3688,7 @@ static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
desc.buflen = mdrcnt;
desc.subformat = NULL;
desc.format = str2;
-
+
if (init_package(&desc,1,0)) {
PACKI(&desc,"W",0); /* code */
PACKS(&desc,"B21",name); /* eff. name */
@@ -3870,11 +3920,11 @@ static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
if (strcmp(str1,"zWrLeh") != 0) {
return False;
}
-
+
if (uLevel > 2) {
return False; /* defined only for uLevel 0,1,2 */
}
-
+
if (!check_printjob_info(&desc,uLevel,str2)) {
return False;
}
diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c
index ebd93ff5d0..96fe4d2cab 100644
--- a/source3/smbd/mangle_hash.c
+++ b/source3/smbd/mangle_hash.c
@@ -53,7 +53,7 @@
*
*/
-static const char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
+static const char basechars[43]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index 859e5e7227..3a3939c511 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -85,7 +85,7 @@
#define FLAG_CHECK(c, flag) (char_flags[(unsigned char)(c)] & (flag))
/* these are the characters we use in the 8.3 hash. Must be 36 chars long */
-static const char * const basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static const char basechars[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#define base_forward(v) basechars[v]
/* the list of reserved dos names - all of these are illegal */
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 729d144ea1..57608a9b40 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -212,7 +212,7 @@ static DATA_BLOB negprot_spnego(void)
*/
- if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
+ if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
#if 0
/* Code for PocketPC client */
blob = data_blob(guid, 16);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 1ee3edbdbe..0ad4df6e90 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -621,7 +621,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
+ SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
p += 8;
SOFF_T(p,0,file_len);
p += 8;
@@ -1086,7 +1086,7 @@ static void call_nt_transact_create(connection_struct *conn,
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
+ SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
p += 8;
SOFF_T(p,0,file_len);
p += 8;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 7d23b92359..f7a52d7bd2 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -67,13 +67,15 @@ NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
static NTSTATUS check_open_rights(struct connection_struct *conn,
const char *fname,
- uint32_t access_mask)
+ uint32_t access_mask,
+ uint32_t *access_granted)
{
/* Check if we have rights to open. */
NTSTATUS status;
- uint32_t access_granted = 0;
struct security_descriptor *sd;
+ *access_granted = 0;
+
status = SMB_VFS_GET_NT_ACL(conn, fname,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
@@ -90,9 +92,17 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
status = smb1_file_se_access_check(sd,
conn->server_info->ptok,
access_mask,
- &access_granted);
+ access_granted);
TALLOC_FREE(sd);
+
+ DEBUG(10,("check_open_rights: file %s requesting "
+ "0x%x returning 0x%x (%s)\n",
+ fname,
+ (unsigned int)access_mask,
+ (unsigned int)*access_granted,
+ nt_errstr(status) ));
+
return status;
}
@@ -415,14 +425,49 @@ static NTSTATUS open_file(files_struct *fsp,
} else {
fsp->fh->fd = -1; /* What we used to call a stat open. */
if (file_existed) {
+ uint32_t access_granted = 0;
+
status = check_open_rights(conn,
path,
- access_mask);
+ access_mask,
+ &access_granted);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("open_file: Access denied on "
- "file %s\n",
- path));
- return status;
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ if ((access_mask & DELETE_ACCESS) &&
+ (access_granted == DELETE_ACCESS) &&
+ can_delete_file_in_directory(conn, path)) {
+ /* Were we trying to do a stat open
+ * for delete and didn't get DELETE
+ * access (only) ? Check if the
+ * directory allows DELETE_CHILD.
+ * See here:
+ * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
+ * for details. */
+
+ DEBUG(10,("open_file: overrode ACCESS_DENIED "
+ "on file %s\n",
+ path ));
+ } else {
+ DEBUG(10, ("open_file: Access denied on "
+ "file %s\n",
+ path));
+ return status;
+ }
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
+ fsp->posix_open &&
+ S_ISLNK(psbuf->st_mode)) {
+ /* This is a POSIX stat open for delete
+ * or rename on a symlink that points
+ * nowhere. Allow. */
+ DEBUG(10, ("open_file: allowing POSIX open "
+ "on bad symlink %s\n",
+ path ));
+ } else {
+ DEBUG(10, ("open_file: check_open_rights "
+ "on file %s returned %s\n",
+ path, nt_errstr(status) ));
+ return status;
+ }
}
}
}
@@ -2395,9 +2440,11 @@ static NTSTATUS open_directory(connection_struct *conn,
}
if (info == FILE_WAS_OPENED) {
+ uint32_t access_granted = 0;
status = check_open_rights(conn,
fname,
- access_mask);
+ access_mask,
+ &access_granted);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("open_directory: check_open_rights on "
"file %s failed with %s\n",
@@ -2826,8 +2873,11 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
&& (create_disposition != FILE_CREATE)
&& (share_access & FILE_SHARE_DELETE)
&& (access_mask & DELETE_ACCESS)
- && (!can_delete_file_in_directory(conn, fname))) {
+ && (!(can_delete_file_in_directory(conn, fname) ||
+ can_access_file_acl(conn, fname, DELETE_ACCESS)))) {
status = NT_STATUS_ACCESS_DENIED;
+ DEBUG(10,("create_file_unixpath: open file %s "
+ "for delete ACCESS_DENIED\n", fname ));
goto fail;
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index e4b5016538..788d2f7238 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -32,61 +32,23 @@ int32 get_number_of_exclusive_open_oplocks(void)
return exclusive_oplocks_open;
}
-/****************************************************************************
- Return True if an oplock message is pending.
-****************************************************************************/
-
-bool oplock_message_waiting(void)
-{
- if (koplocks && koplocks->ops->msg_waiting(koplocks)) {
- return True;
- }
-
- return False;
-}
-
-/****************************************************************************
- Find out if there are any kernel oplock messages waiting and process them
- if so. pfds is the fd_set from the main select loop (which contains any
- kernel oplock fd if that's what the system uses (IRIX). If may be NULL if
- we're calling this in a shutting down state.
-****************************************************************************/
-
-void process_kernel_oplocks(struct messaging_context *msg_ctx)
+/*
+ * helper function used by the kernel oplock backends to post the break message
+ */
+void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp)
{
- /*
- * We need to check for kernel oplocks before going into the select
- * here, as the EINTR generated by the linux kernel oplock may have
- * already been eaten. JRA.
- */
-
- if (!koplocks) {
- return;
- }
+ uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE];
- while (koplocks->ops->msg_waiting(koplocks)) {
- files_struct *fsp;
- char msg[MSG_SMB_KERNEL_BREAK_SIZE];
+ /* Put the kernel break info into the message. */
+ push_file_id_16((char *)msg, &fsp->file_id);
+ SIVAL(msg,16,fsp->fh->gen_id);
- fsp = koplocks->ops->receive_message(koplocks);
+ /* Don't need to be root here as we're only ever
+ sending to ourselves. */
- if (fsp == NULL) {
- DEBUG(3, ("Kernel oplock message announced, but none "
- "received\n"));
- return;
- }
-
- /* Put the kernel break info into the message. */
- push_file_id_16(msg, &fsp->file_id);
- SIVAL(msg,16,fsp->fh->gen_id);
-
- /* Don't need to be root here as we're only ever
- sending to ourselves. */
-
- messaging_send_buf(msg_ctx, procid_self(),
- MSG_SMB_KERNEL_BREAK,
- (uint8 *)&msg, MSG_SMB_KERNEL_BREAK_SIZE);
- }
+ messaging_send_buf(msg_ctx, procid_self(),
+ MSG_SMB_KERNEL_BREAK,
+ msg, MSG_SMB_KERNEL_BREAK_SIZE);
}
/****************************************************************************
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index 0cfa960425..d7f45e67de 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -252,13 +252,6 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx,
}
}
-static bool irix_oplock_msg_waiting(struct kernel_oplocks *_ctx)
-{
- struct irix_oplocks_context *ctx = talloc_get_type(_ctx->private_data,
- struct irix_oplocks_context);
- return ctx->pending;
-}
-
static void irix_oplocks_read_fde_handler(struct event_context *ev,
struct fd_event *fde,
uint16_t flags,
@@ -266,10 +259,10 @@ static void irix_oplocks_read_fde_handler(struct event_context *ev,
{
struct irix_oplocks_context *ctx = talloc_get_type(private_data,
struct irix_oplocks_context);
+ files_struct *fsp;
- ctx->pending = true;
- process_kernel_oplocks(smbd_messaging_context());
- ctx->pending = false;
+ fsp = irix_oplock_receive_message(ctx->ctx);
+ break_kernel_oplock(smbd_messaging_context(), fsp);
}
/****************************************************************************
@@ -277,10 +270,8 @@ static void irix_oplocks_read_fde_handler(struct event_context *ev,
****************************************************************************/
static const struct kernel_oplocks_ops irix_koplocks = {
- .receive_message = irix_oplock_receive_message,
.set_oplock = irix_set_kernel_oplock,
.release_oplock = irix_release_kernel_oplock,
- .msg_waiting = irix_oplock_msg_waiting
};
struct kernel_oplocks *irix_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 8087167ff4..51cce0ed48 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -43,19 +43,6 @@
#define F_SETSIG 10
#endif
-/****************************************************************************
- Handle a LEASE signal, incrementing the signals_received and blocking the signal.
-****************************************************************************/
-
-static void signal_handler(int sig, siginfo_t *info, void *unused)
-{
- if (oplock_signals_received < FD_PENDING_SIZE - 1) {
- fd_pending_array[oplock_signals_received] = (SIG_ATOMIC_T)info->si_fd;
- oplock_signals_received++;
- } /* Else signal is lost. */
- sys_select_signal(RT_SIGNAL_LEASE);
-}
-
/*
* public function to get linux lease capability. Needed by some VFS modules (eg. gpfs.c)
*/
@@ -101,24 +88,17 @@ int linux_setlease(int fd, int leasetype)
* oplock break protocol.
****************************************************************************/
-static files_struct *linux_oplock_receive_message(struct kernel_oplocks *ctx)
+static void linux_oplock_signal_handler(struct tevent_context *ev_ctx,
+ struct tevent_signal *se,
+ int signum, int count,
+ void *_info, void *private_data)
{
- int fd;
+ siginfo_t *info = (siginfo_t *)_info;
+ int fd = info->si_fd;
files_struct *fsp;
- BlockSignals(True, RT_SIGNAL_LEASE);
- fd = fd_pending_array[0];
fsp = file_find_fd(fd);
- fd_pending_array[0] = (SIG_ATOMIC_T)-1;
- if (oplock_signals_received > 1)
- memmove(CONST_DISCARD(void *, &fd_pending_array[0]),
- CONST_DISCARD(void *, &fd_pending_array[1]),
- sizeof(SIG_ATOMIC_T)*(oplock_signals_received-1));
- oplock_signals_received--;
- /* now we can receive more signals */
- BlockSignals(False, RT_SIGNAL_LEASE);
-
- return fsp;
+ break_kernel_oplock(smbd_messaging_context(), fsp);
}
/****************************************************************************
@@ -180,15 +160,6 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx,
}
/****************************************************************************
- See if a oplock message is waiting.
-****************************************************************************/
-
-static bool linux_oplock_msg_waiting(struct kernel_oplocks *ctx)
-{
- return oplock_signals_received != 0;
-}
-
-/****************************************************************************
See if the kernel supports oplocks.
****************************************************************************/
@@ -208,16 +179,14 @@ static bool linux_oplocks_available(void)
****************************************************************************/
static const struct kernel_oplocks_ops linux_koplocks = {
- .receive_message = linux_oplock_receive_message,
.set_oplock = linux_set_kernel_oplock,
.release_oplock = linux_release_kernel_oplock,
- .msg_waiting = linux_oplock_msg_waiting
};
struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
{
- struct sigaction act;
struct kernel_oplocks *ctx;
+ struct tevent_signal *se;
if (!linux_oplocks_available()) {
DEBUG(3,("Linux kernel oplocks not available\n"));
@@ -232,19 +201,18 @@ struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
ctx->ops = &linux_koplocks;
- ZERO_STRUCT(act);
-
- act.sa_handler = NULL;
- act.sa_sigaction = signal_handler;
- act.sa_flags = SA_SIGINFO;
- sigemptyset( &act.sa_mask );
- if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
- DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n"));
+ se = tevent_add_signal(smbd_event_context(),
+ ctx,
+ RT_SIGNAL_LEASE, SA_SIGINFO,
+ linux_oplock_signal_handler,
+ ctx);
+ if (!se) {
+ DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler"));
+ TALLOC_FREE(ctx);
return NULL;
}
- /* the signal can start off blocked due to a bug in bash */
- BlockSignals(False, RT_SIGNAL_LEASE);
+ ctx->private_data = se;
DEBUG(3,("Linux kernel oplocks enabled\n"));
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index b148cff045..f287adc92d 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -144,12 +144,18 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
Reply to a write on a pipe.
****************************************************************************/
+struct pipe_write_state {
+ size_t numtowrite;
+};
+
+static void pipe_write_done(struct async_req *subreq);
+
void reply_pipe_write(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
- size_t numtowrite = SVAL(req->vwv+1, 0);
- ssize_t nwritten;
const uint8_t *data;
+ struct pipe_write_state *state;
+ struct async_req *subreq;
if (!fsp_is_np(fsp)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -161,39 +167,59 @@ void reply_pipe_write(struct smb_request *req)
return;
}
+ state = talloc(req, struct pipe_write_state);
+ if (state == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ req->async_priv = state;
+
+ state->numtowrite = SVAL(req->vwv+1, 0);
+
data = req->buf + 3;
- if (numtowrite == 0) {
- nwritten = 0;
- } else {
- NTSTATUS status;
- if (!fsp_is_np(fsp)) {
- reply_nterror(req, NT_STATUS_INVALID_HANDLE);
- return;
- }
- DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n",
- (int)fsp->fnum, fsp->fsp_name, (int)numtowrite));
- status = np_write(fsp->fake_file_handle, data, numtowrite,
- &nwritten);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
+ DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
+ fsp->fsp_name, (int)state->numtowrite));
+
+ subreq = np_write_send(state, smbd_event_context(),
+ fsp->fake_file_handle, data, state->numtowrite);
+ if (subreq == NULL) {
+ TALLOC_FREE(state);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
+ subreq->async.fn = pipe_write_done;
+ subreq->async.priv = talloc_move(req->conn, &req);
+}
+
+static void pipe_write_done(struct async_req *subreq)
+{
+ struct smb_request *req = talloc_get_type_abort(
+ subreq->async.priv, struct smb_request);
+ struct pipe_write_state *state = talloc_get_type_abort(
+ req->async_priv, struct pipe_write_state);
+ NTSTATUS status;
+ ssize_t nwritten = -1;
- if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
+ status = np_write_recv(subreq, &nwritten);
+ TALLOC_FREE(subreq);
+ if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) {
reply_unixerror(req, ERRDOS, ERRnoaccess);
- return;
+ goto send;
}
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", fsp->fnum,
- (int)nwritten));
- return;
+ DEBUG(3,("write-IPC nwritten=%d\n", (int)nwritten));
+
+ send:
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ IS_CONN_ENCRYPTED(req->conn)||req->encrypted)) {
+ exit_server_cleanly("construct_reply: srv_send_smb failed.");
+ }
+ TALLOC_FREE(req);
}
/****************************************************************************
@@ -203,16 +229,20 @@ void reply_pipe_write(struct smb_request *req)
wrinkles to handle pipes.
****************************************************************************/
+struct pipe_write_andx_state {
+ bool pipe_start_message_raw;
+ size_t numtowrite;
+};
+
+static void pipe_write_andx_done(struct async_req *subreq);
+
void reply_pipe_write_and_X(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0));
- size_t numtowrite = SVAL(req->vwv+10, 0);
- ssize_t nwritten;
int smb_doff = SVAL(req->vwv+11, 0);
- bool pipe_start_message_raw =
- ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
- == (PIPE_START_MESSAGE|PIPE_RAW_MODE));
uint8_t *data;
+ struct pipe_write_andx_state *state;
+ struct async_req *subreq;
if (!fsp_is_np(fsp)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -224,55 +254,76 @@ void reply_pipe_write_and_X(struct smb_request *req)
return;
}
+ state = talloc(req, struct pipe_write_andx_state);
+ if (state == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ req->async_priv = state;
+
+ state->numtowrite = SVAL(req->vwv+10, 0);
+ state->pipe_start_message_raw =
+ ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
+ == (PIPE_START_MESSAGE|PIPE_RAW_MODE));
+
DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
- (int)fsp->fnum, fsp->fsp_name, (int)numtowrite));
+ (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite));
data = (uint8_t *)smb_base(req->inbuf) + smb_doff;
- if (numtowrite == 0) {
- nwritten = 0;
- } else {
- NTSTATUS status;
-
- if(pipe_start_message_raw) {
- /*
- * For the start of a message in named pipe byte mode,
- * the first two bytes are a length-of-pdu field. Ignore
- * them (we don't trust the client). JRA.
- */
- if(numtowrite < 2) {
- DEBUG(0,("reply_pipe_write_and_X: start of "
- "message set and not enough data "
- "sent.(%u)\n",
- (unsigned int)numtowrite ));
- reply_unixerror(req, ERRDOS, ERRnoaccess);
- return;
- }
-
- data += 2;
- numtowrite -= 2;
- }
- status = np_write(fsp->fake_file_handle, data, numtowrite,
- &nwritten);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
+ if (state->pipe_start_message_raw) {
+ /*
+ * For the start of a message in named pipe byte mode,
+ * the first two bytes are a length-of-pdu field. Ignore
+ * them (we don't trust the client). JRA.
+ */
+ if (state->numtowrite < 2) {
+ DEBUG(0,("reply_pipe_write_and_X: start of message "
+ "set and not enough data sent.(%u)\n",
+ (unsigned int)state->numtowrite ));
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
return;
}
+
+ data += 2;
+ state->numtowrite -= 2;
}
- if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) {
- reply_unixerror(req, ERRDOS,ERRnoaccess);
+ subreq = np_write_send(state, smbd_event_context(),
+ fsp->fake_file_handle, data, state->numtowrite);
+ if (subreq == NULL) {
+ TALLOC_FREE(state);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
+ subreq->async.fn = pipe_write_andx_done;
+ subreq->async.priv = talloc_move(req->conn, &req);
+}
+
+static void pipe_write_andx_done(struct async_req *subreq)
+{
+ struct smb_request *req = talloc_get_type_abort(
+ subreq->async.priv, struct smb_request);
+ struct pipe_write_andx_state *state = talloc_get_type_abort(
+ req->async_priv, struct pipe_write_andx_state);
+ NTSTATUS status;
+ ssize_t nwritten = -1;
+
+ status = np_write_recv(subreq, &nwritten);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) {
+ reply_unixerror(req, ERRDOS,ERRnoaccess);
+ goto done;
+ }
reply_outbuf(req, 6, 0);
- nwritten = (pipe_start_message_raw ? nwritten + 2 : nwritten);
+ nwritten = (state->pipe_start_message_raw ? nwritten + 2 : nwritten);
SSVAL(req->outbuf,smb_vwv2,nwritten);
-
- DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", fsp->fnum,
- (int)nwritten));
+ DEBUG(3,("writeX-IPC nwritten=%d\n", (int)nwritten));
+
+ done:
chain_reply(req);
}
@@ -282,15 +333,20 @@ void reply_pipe_write_and_X(struct smb_request *req)
wrinkles to handle pipes.
****************************************************************************/
+struct pipe_read_andx_state {
+ uint8_t *outbuf;
+ int smb_mincnt;
+ int smb_maxcnt;
+};
+
+static void pipe_read_andx_done(struct async_req *subreq);
+
void reply_pipe_read_and_X(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
- int smb_maxcnt = SVAL(req->vwv+5, 0);
- int smb_mincnt = SVAL(req->vwv+6, 0);
- ssize_t nread;
uint8_t *data;
- bool unused;
- NTSTATUS status;
+ struct pipe_read_andx_state *state;
+ struct async_req *subreq;
/* we don't use the offset given to use for pipe reads. This
is deliberate, instead we always return the next lump of
@@ -309,18 +365,56 @@ void reply_pipe_read_and_X(struct smb_request *req)
return;
}
- reply_outbuf(req, 12, smb_maxcnt);
+ state = talloc(req, struct pipe_read_andx_state);
+ if (state == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ req->async_priv = state;
+ state->smb_maxcnt = SVAL(req->vwv+5, 0);
+ state->smb_mincnt = SVAL(req->vwv+6, 0);
+
+ reply_outbuf(req, 12, state->smb_maxcnt);
data = (uint8_t *)smb_buf(req->outbuf);
- status = np_read(fsp->fake_file_handle, data, smb_maxcnt, &nread,
- &unused);
+ /*
+ * We have to tell the upper layers that we're async.
+ */
+ state->outbuf = req->outbuf;
+ req->outbuf = NULL;
+
+ subreq = np_read_send(state, smbd_event_context(),
+ fsp->fake_file_handle, data,
+ state->smb_maxcnt);
+ if (subreq == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ subreq->async.fn = pipe_read_andx_done;
+ subreq->async.priv = talloc_move(req->conn, &req);
+}
+static void pipe_read_andx_done(struct async_req *subreq)
+{
+ struct smb_request *req = talloc_get_type_abort(
+ subreq->async.priv, struct smb_request);
+ struct pipe_read_andx_state *state = talloc_get_type_abort(
+ req->async_priv, struct pipe_read_andx_state);
+ NTSTATUS status;
+ ssize_t nread;
+ bool is_data_outstanding;
+
+ status = np_read_recv(subreq, &nread, &is_data_outstanding);
+ TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
+ reply_nterror(req, status);
+ goto done;
}
+ req->outbuf = state->outbuf;
+ state->outbuf = NULL;
+
srv_set_message((char *)req->outbuf, 12, nread, False);
SSVAL(req->outbuf,smb_vwv5,nread);
@@ -329,10 +423,11 @@ void reply_pipe_read_and_X(struct smb_request *req)
+ 1 /* the wct field */
+ 12 * sizeof(uint16_t) /* vwv */
+ 2); /* the buflen field */
- SSVAL(req->outbuf,smb_vwv11,smb_maxcnt);
+ SSVAL(req->outbuf,smb_vwv11,state->smb_maxcnt);
- DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
- fsp->fnum, smb_mincnt, smb_maxcnt, (int)nread));
+ DEBUG(3,("readX-IPC min=%d max=%d nread=%d\n",
+ state->smb_mincnt, state->smb_maxcnt, (int)nread));
+ done:
chain_reply(req);
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 72f5c94bc5..7ea6e39fcb 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
SMB NT Security Descriptor / Unix permission conversion.
- Copyright (C) Jeremy Allison 1994-2000.
+ Copyright (C) Jeremy Allison 1994-2009.
Copyright (C) Andreas Gruenbacher 2002.
This program is free software; you can redistribute it and/or modify
@@ -47,30 +47,65 @@ typedef struct canon_ace {
enum ace_owner owner_type;
enum ace_attribute attr;
posix_id unix_ug;
- bool inherited;
+ uint8_t ace_flags; /* From windows ACE entry. */
} canon_ace;
#define ALL_ACE_PERMS (S_IRUSR|S_IWUSR|S_IXUSR)
/*
* EA format of user.SAMBA_PAI (Samba_Posix_Acl_Interitance)
- * attribute on disk.
+ * attribute on disk - version 1.
+ * All values are little endian.
*
- * | 1 | 1 | 2 | 2 | ....
+ * | 1 | 1 | 2 | 2 | ....
* +------+------+-------------+---------------------+-------------+--------------------+
* | vers | flag | num_entries | num_default_entries | ..entries.. | default_entries... |
* +------+------+-------------+---------------------+-------------+--------------------+
+ *
+ * Entry format is :
+ *
+ * | 1 | 4 |
+ * +------+-------------------+
+ * | value| uid/gid or world |
+ * | type | value |
+ * +------+-------------------+
+ *
+ * Version 2 format. Stores extra Windows metadata about an ACL.
+ *
+ * | 1 | 2 | 2 | 2 | ....
+ * +------+----------+-------------+---------------------+-------------+--------------------+
+ * | vers | ace | num_entries | num_default_entries | ..entries.. | default_entries... |
+ * | 2 | type | | | | |
+ * +------+----------+-------------+---------------------+-------------+--------------------+
+ *
+ * Entry format is :
+ *
+ * | 1 | 1 | 4 |
+ * +------+------+-------------------+
+ * | ace | value| uid/gid or world |
+ * | flag | type | value |
+ * +------+-------------------+------+
+ *
*/
-#define PAI_VERSION_OFFSET 0
-#define PAI_FLAG_OFFSET 1
-#define PAI_NUM_ENTRIES_OFFSET 2
-#define PAI_NUM_DEFAULT_ENTRIES_OFFSET 4
-#define PAI_ENTRIES_BASE 6
+#define PAI_VERSION_OFFSET 0
+
+#define PAI_V1_FLAG_OFFSET 1
+#define PAI_V1_NUM_ENTRIES_OFFSET 2
+#define PAI_V1_NUM_DEFAULT_ENTRIES_OFFSET 4
+#define PAI_V1_ENTRIES_BASE 6
+#define PAI_V1_ACL_FLAG_PROTECTED 0x1
+#define PAI_V1_ENTRY_LENGTH 5
+
+#define PAI_V1_VERSION 1
-#define PAI_VERSION 1
-#define PAI_ACL_FLAG_PROTECTED 0x1
-#define PAI_ENTRY_LENGTH 5
+#define PAI_V2_TYPE_OFFSET 1
+#define PAI_V2_NUM_ENTRIES_OFFSET 3
+#define PAI_V2_NUM_DEFAULT_ENTRIES_OFFSET 5
+#define PAI_V2_ENTRIES_BASE 7
+#define PAI_V2_ENTRY_LENGTH 6
+
+#define PAI_V2_VERSION 2
/*
* In memory format of user.SAMBA_PAI attribute.
@@ -78,12 +113,13 @@ typedef struct canon_ace {
struct pai_entry {
struct pai_entry *next, *prev;
+ uint8_t ace_flags;
enum ace_owner owner_type;
posix_id unix_ug;
};
struct pai_val {
- bool pai_protected;
+ uint16_t sd_type;
unsigned int num_entries;
struct pai_entry *entry_list;
unsigned int num_def_entries;
@@ -94,19 +130,19 @@ struct pai_val {
Return a uint32 of the pai_entry principal.
************************************************************************/
-static uint32 get_pai_entry_val(struct pai_entry *paie)
+static uint32_t get_pai_entry_val(struct pai_entry *paie)
{
switch (paie->owner_type) {
case UID_ACE:
DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- return (uint32)paie->unix_ug.uid;
+ return (uint32_t)paie->unix_ug.uid;
case GID_ACE:
DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- return (uint32)paie->unix_ug.gid;
+ return (uint32_t)paie->unix_ug.gid;
case WORLD_ACE:
default:
DEBUG(10,("get_pai_entry_val: world ace\n"));
- return (uint32)-1;
+ return (uint32_t)-1;
}
}
@@ -114,41 +150,30 @@ static uint32 get_pai_entry_val(struct pai_entry *paie)
Return a uint32 of the entry principal.
************************************************************************/
-static uint32 get_entry_val(canon_ace *ace_entry)
+static uint32_t get_entry_val(canon_ace *ace_entry)
{
switch (ace_entry->owner_type) {
case UID_ACE:
DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid ));
- return (uint32)ace_entry->unix_ug.uid;
+ return (uint32_t)ace_entry->unix_ug.uid;
case GID_ACE:
DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid ));
- return (uint32)ace_entry->unix_ug.gid;
+ return (uint32_t)ace_entry->unix_ug.gid;
case WORLD_ACE:
default:
DEBUG(10,("get_entry_val: world ace\n"));
- return (uint32)-1;
+ return (uint32_t)-1;
}
}
/************************************************************************
- Count the inherited entries.
-************************************************************************/
-
-static unsigned int num_inherited_entries(canon_ace *ace_list)
-{
- unsigned int num_entries = 0;
-
- for (; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_entries++;
- return num_entries;
-}
-
-/************************************************************************
- Create the on-disk format. Caller must free.
+ Create the on-disk format (always v2 now). Caller must free.
************************************************************************/
-static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, bool pai_protected, size_t *store_size)
+static char *create_pai_buf_v2(canon_ace *file_ace_list,
+ canon_ace *dir_ace_list,
+ uint16_t sd_type,
+ size_t *store_size)
{
char *pai_buf = NULL;
canon_ace *ace_list = NULL;
@@ -156,17 +181,18 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, b
unsigned int num_entries = 0;
unsigned int num_def_entries = 0;
- for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_entries++;
+ for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
+ num_entries++;
+ }
- for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next)
- if (ace_list->inherited)
- num_def_entries++;
+ for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
+ num_def_entries++;
+ }
- DEBUG(10,("create_pai_buf: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries ));
+ DEBUG(10,("create_pai_buf_v2: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries ));
- *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
+ *store_size = PAI_V2_ENTRIES_BASE +
+ ((num_entries + num_def_entries)*PAI_V2_ENTRY_LENGTH);
pai_buf = (char *)SMB_MALLOC(*store_size);
if (!pai_buf) {
@@ -174,34 +200,32 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, b
}
/* Set up the header. */
- memset(pai_buf, '\0', PAI_ENTRIES_BASE);
- SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION);
- SCVAL(pai_buf,PAI_FLAG_OFFSET,(pai_protected ? PAI_ACL_FLAG_PROTECTED : 0));
- SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries);
- SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
+ memset(pai_buf, '\0', PAI_V2_ENTRIES_BASE);
+ SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_V2_VERSION);
+ SSVAL(pai_buf,PAI_V2_TYPE_OFFSET, sd_type);
+ SSVAL(pai_buf,PAI_V2_NUM_ENTRIES_OFFSET,num_entries);
+ SSVAL(pai_buf,PAI_V2_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
- entry_offset = pai_buf + PAI_ENTRIES_BASE;
+ entry_offset = pai_buf + PAI_V2_ENTRIES_BASE;
for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
- if (ace_list->inherited) {
- uint8 type_val = (unsigned char)ace_list->owner_type;
- uint32 entry_val = get_entry_val(ace_list);
+ uint8_t type_val = (uint8_t)ace_list->owner_type;
+ uint32_t entry_val = get_entry_val(ace_list);
- SCVAL(entry_offset,0,type_val);
- SIVAL(entry_offset,1,entry_val);
- entry_offset += PAI_ENTRY_LENGTH;
- }
+ SCVAL(entry_offset,0,ace_list->ace_flags);
+ SCVAL(entry_offset,1,type_val);
+ SIVAL(entry_offset,2,entry_val);
+ entry_offset += PAI_V2_ENTRY_LENGTH;
}
for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
- if (ace_list->inherited) {
- uint8 type_val = (unsigned char)ace_list->owner_type;
- uint32 entry_val = get_entry_val(ace_list);
+ uint8_t type_val = (uint8_t)ace_list->owner_type;
+ uint32_t entry_val = get_entry_val(ace_list);
- SCVAL(entry_offset,0,type_val);
- SIVAL(entry_offset,1,entry_val);
- entry_offset += PAI_ENTRY_LENGTH;
- }
+ SCVAL(entry_offset,0,ace_list->ace_flags);
+ SCVAL(entry_offset,1,type_val);
+ SIVAL(entry_offset,2,entry_val);
+ entry_offset += PAI_V2_ENTRY_LENGTH;
}
return pai_buf;
@@ -211,44 +235,39 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, b
Store the user.SAMBA_PAI attribute on disk.
************************************************************************/
-static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list,
- canon_ace *dir_ace_list, bool pai_protected)
+static void store_inheritance_attributes(files_struct *fsp,
+ canon_ace *file_ace_list,
+ canon_ace *dir_ace_list,
+ uint16_t sd_type)
{
int ret;
size_t store_size;
char *pai_buf;
- if (!lp_map_acl_inherit(SNUM(fsp->conn)))
- return;
-
- /*
- * Don't store if this ACL isn't protected and
- * none of the entries in it are marked as inherited.
- */
-
- if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) {
- /* Instead just remove the attribute if it exists. */
- if (fsp->fh->fd != -1)
- SMB_VFS_FREMOVEXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME);
- else
- SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
+ if (!lp_map_acl_inherit(SNUM(fsp->conn))) {
return;
}
- pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size);
+ pai_buf = create_pai_buf_v2(file_ace_list, dir_ace_list,
+ sd_type, &store_size);
- if (fsp->fh->fd != -1)
+ if (fsp->fh->fd != -1) {
ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, store_size, 0);
- else
+ } else {
ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, store_size, 0);
+ }
SAFE_FREE(pai_buf);
- DEBUG(10,("store_inheritance_attribute:%s for file %s\n", pai_protected ? " (protected)" : "", fsp->fsp_name));
- if (ret == -1 && !no_acl_syscall_error(errno))
+ DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n",
+ (unsigned int)sd_type,
+ fsp->fsp_name));
+
+ if (ret == -1 && !no_acl_syscall_error(errno)) {
DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
+ }
}
/************************************************************************
@@ -272,161 +291,290 @@ static void free_inherited_info(struct pai_val *pal)
}
/************************************************************************
- Was this ACL protected ?
-************************************************************************/
-
-static bool get_protected_flag(struct pai_val *pal)
-{
- if (!pal)
- return False;
- return pal->pai_protected;
-}
-
-/************************************************************************
- Was this ACE inherited ?
+ Get any stored ACE flags.
************************************************************************/
-static bool get_inherited_flag(struct pai_val *pal, canon_ace *ace_entry, bool default_ace)
+static uint16_t get_pai_flags(struct pai_val *pal, canon_ace *ace_entry, bool default_ace)
{
struct pai_entry *paie;
- if (!pal)
- return False;
+ if (!pal) {
+ return 0;
+ }
/* If the entry exists it is inherited. */
for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) {
if (ace_entry->owner_type == paie->owner_type &&
get_entry_val(ace_entry) == get_pai_entry_val(paie))
- return True;
+ return paie->ace_flags;
}
- return False;
+ return 0;
}
/************************************************************************
- Ensure an attribute just read is valid.
+ Ensure an attribute just read is valid - v1.
************************************************************************/
-static bool check_pai_ok(char *pai_buf, size_t pai_buf_data_size)
+static bool check_pai_ok_v1(const char *pai_buf, size_t pai_buf_data_size)
{
uint16 num_entries;
uint16 num_def_entries;
- if (pai_buf_data_size < PAI_ENTRIES_BASE) {
+ if (pai_buf_data_size < PAI_V1_ENTRIES_BASE) {
/* Corrupted - too small. */
- return False;
+ return false;
}
- if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION)
- return False;
+ if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_V1_VERSION) {
+ return false;
+ }
- num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET);
- num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+ num_entries = SVAL(pai_buf,PAI_V1_NUM_ENTRIES_OFFSET);
+ num_def_entries = SVAL(pai_buf,PAI_V1_NUM_DEFAULT_ENTRIES_OFFSET);
/* Check the entry lists match. */
/* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */
- if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size)
- return False;
+ if (((num_entries + num_def_entries)*PAI_V1_ENTRY_LENGTH) +
+ PAI_V1_ENTRIES_BASE != pai_buf_data_size) {
+ return false;
+ }
- return True;
+ return true;
+}
+
+/************************************************************************
+ Ensure an attribute just read is valid - v2.
+************************************************************************/
+
+static bool check_pai_ok_v2(const char *pai_buf, size_t pai_buf_data_size)
+{
+ uint16 num_entries;
+ uint16 num_def_entries;
+
+ if (pai_buf_data_size < PAI_V2_ENTRIES_BASE) {
+ /* Corrupted - too small. */
+ return false;
+ }
+
+ if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_V2_VERSION) {
+ return false;
+ }
+
+ num_entries = SVAL(pai_buf,PAI_V2_NUM_ENTRIES_OFFSET);
+ num_def_entries = SVAL(pai_buf,PAI_V2_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ /* Check the entry lists match. */
+ /* Each entry is 6 bytes (flags + type + 4 bytes of uid or gid). */
+
+ if (((num_entries + num_def_entries)*PAI_V2_ENTRY_LENGTH) +
+ PAI_V2_ENTRIES_BASE != pai_buf_data_size) {
+ return false;
+ }
+
+ return true;
}
+/************************************************************************
+ Decode the owner.
+************************************************************************/
+
+static bool get_pai_owner_type(struct pai_entry *paie, const char *entry_offset)
+{
+ paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
+ switch( paie->owner_type) {
+ case UID_ACE:
+ paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
+ DEBUG(10,("get_pai_owner_type: uid = %u\n",
+ (unsigned int)paie->unix_ug.uid ));
+ break;
+ case GID_ACE:
+ paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
+ DEBUG(10,("get_pai_owner_type: gid = %u\n",
+ (unsigned int)paie->unix_ug.gid ));
+ break;
+ case WORLD_ACE:
+ paie->unix_ug.world = -1;
+ DEBUG(10,("get_pai_owner_type: world ace\n"));
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
/************************************************************************
- Convert to in-memory format.
+ Process v2 entries.
************************************************************************/
-static struct pai_val *create_pai_val(char *buf, size_t size)
+static const char *create_pai_v1_entries(struct pai_val *paiv,
+ const char *entry_offset,
+ bool def_entry)
{
- char *entry_offset;
- struct pai_val *paiv = NULL;
int i;
- if (!check_pai_ok(buf, size))
+ for (i = 0; i < paiv->num_entries; i++) {
+ struct pai_entry *paie = SMB_MALLOC_P(struct pai_entry);
+ if (!paie) {
+ return NULL;
+ }
+
+ paie->ace_flags = SEC_ACE_FLAG_INHERITED_ACE;
+ if (!get_pai_owner_type(paie, entry_offset)) {
+ return NULL;
+ }
+
+ if (!def_entry) {
+ DLIST_ADD(paiv->entry_list, paie);
+ } else {
+ DLIST_ADD(paiv->def_entry_list, paie);
+ }
+ entry_offset += PAI_V1_ENTRY_LENGTH;
+ }
+ return entry_offset;
+}
+
+/************************************************************************
+ Convert to in-memory format from version 1.
+************************************************************************/
+
+static struct pai_val *create_pai_val_v1(const char *buf, size_t size)
+{
+ const char *entry_offset;
+ struct pai_val *paiv = NULL;
+
+ if (!check_pai_ok_v1(buf, size)) {
return NULL;
+ }
paiv = SMB_MALLOC_P(struct pai_val);
- if (!paiv)
+ if (!paiv) {
return NULL;
+ }
memset(paiv, '\0', sizeof(struct pai_val));
- paiv->pai_protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED);
+ paiv->sd_type = (CVAL(buf,PAI_V1_FLAG_OFFSET) == PAI_V1_ACL_FLAG_PROTECTED) ?
+ SE_DESC_DACL_PROTECTED : 0;
- paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET);
- paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+ paiv->num_entries = SVAL(buf,PAI_V1_NUM_ENTRIES_OFFSET);
+ paiv->num_def_entries = SVAL(buf,PAI_V1_NUM_DEFAULT_ENTRIES_OFFSET);
- entry_offset = buf + PAI_ENTRIES_BASE;
+ entry_offset = buf + PAI_V1_ENTRIES_BASE;
- DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n",
- paiv->pai_protected ? " (pai_protected)" : "", paiv->num_entries, paiv->num_def_entries ));
+ DEBUG(10,("create_pai_val: num_entries = %u, num_def_entries = %u\n",
+ paiv->num_entries, paiv->num_def_entries ));
- for (i = 0; i < paiv->num_entries; i++) {
- struct pai_entry *paie;
+ entry_offset = create_pai_v1_entries(paiv, entry_offset, false);
+ if (entry_offset == NULL) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset = create_pai_v1_entries(paiv, entry_offset, true);
+ if (entry_offset == NULL) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+
+ return paiv;
+}
+
+/************************************************************************
+ Process v2 entries.
+************************************************************************/
+
+static const char *create_pai_v2_entries(struct pai_val *paiv,
+ const char *entry_offset,
+ bool def_entry)
+{
+ int i;
- paie = SMB_MALLOC_P(struct pai_entry);
+ for (i = 0; i < paiv->num_entries; i++) {
+ struct pai_entry *paie = SMB_MALLOC_P(struct pai_entry);
if (!paie) {
- free_inherited_info(paiv);
return NULL;
}
- paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
- switch( paie->owner_type) {
- case UID_ACE:
- paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- break;
- case GID_ACE:
- paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- break;
- case WORLD_ACE:
- paie->unix_ug.world = -1;
- DEBUG(10,("create_pai_val: world ace\n"));
- break;
- default:
- free_inherited_info(paiv);
- return NULL;
- }
- entry_offset += PAI_ENTRY_LENGTH;
- DLIST_ADD(paiv->entry_list, paie);
- }
+ paie->ace_flags = CVAL(entry_offset,0);
- for (i = 0; i < paiv->num_def_entries; i++) {
- struct pai_entry *paie;
+ entry_offset++;
- paie = SMB_MALLOC_P(struct pai_entry);
- if (!paie) {
- free_inherited_info(paiv);
+ if (!get_pai_owner_type(paie, entry_offset)) {
return NULL;
}
-
- paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
- switch( paie->owner_type) {
- case UID_ACE:
- paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid ));
- break;
- case GID_ACE:
- paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
- DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid ));
- break;
- case WORLD_ACE:
- paie->unix_ug.world = -1;
- DEBUG(10,("create_pai_val: (def) world ace\n"));
- break;
- default:
- free_inherited_info(paiv);
- return NULL;
+ if (!def_entry) {
+ DLIST_ADD(paiv->entry_list, paie);
+ } else {
+ DLIST_ADD(paiv->def_entry_list, paie);
}
- entry_offset += PAI_ENTRY_LENGTH;
- DLIST_ADD(paiv->def_entry_list, paie);
+ entry_offset += PAI_V2_ENTRY_LENGTH;
+ }
+ return entry_offset;
+}
+
+/************************************************************************
+ Convert to in-memory format from version 2.
+************************************************************************/
+
+static struct pai_val *create_pai_val_v2(const char *buf, size_t size)
+{
+ const char *entry_offset;
+ struct pai_val *paiv = NULL;
+
+ if (!check_pai_ok_v2(buf, size)) {
+ return NULL;
+ }
+
+ paiv = SMB_MALLOC_P(struct pai_val);
+ if (!paiv) {
+ return NULL;
+ }
+
+ memset(paiv, '\0', sizeof(struct pai_val));
+
+ paiv->sd_type = SVAL(buf,PAI_V2_TYPE_OFFSET);
+
+ paiv->num_entries = SVAL(buf,PAI_V2_NUM_ENTRIES_OFFSET);
+ paiv->num_def_entries = SVAL(buf,PAI_V2_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ entry_offset = buf + PAI_V2_ENTRIES_BASE;
+
+ DEBUG(10,("create_pai_val_v2: num_entries = %u, num_def_entries = %u\n",
+ paiv->num_entries, paiv->num_def_entries ));
+
+ entry_offset = create_pai_v2_entries(paiv, entry_offset, false);
+ if (entry_offset == NULL) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset = create_pai_v2_entries(paiv, entry_offset, true);
+ if (entry_offset == NULL) {
+ free_inherited_info(paiv);
+ return NULL;
}
return paiv;
}
/************************************************************************
+ Convert to in-memory format - from either version 1 or 2.
+************************************************************************/
+
+static struct pai_val *create_pai_val(const char *buf, size_t size)
+{
+ if (size < 1) {
+ return NULL;
+ }
+ if (CVAL(buf,PAI_VERSION_OFFSET) == PAI_V1_VERSION) {
+ return create_pai_val_v1(buf, size);
+ } else if (CVAL(buf,PAI_VERSION_OFFSET) == PAI_V2_VERSION) {
+ return create_pai_val_v2(buf, size);
+ } else {
+ return NULL;
+ }
+}
+
+/************************************************************************
Load the user.SAMBA_PAI attribute.
************************************************************************/
@@ -437,19 +585,22 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
struct pai_val *paiv = NULL;
ssize_t ret;
- if (!lp_map_acl_inherit(SNUM(fsp->conn)))
+ if (!lp_map_acl_inherit(SNUM(fsp->conn))) {
return NULL;
+ }
- if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL)
+ if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL) {
return NULL;
+ }
do {
- if (fsp->fh->fd != -1)
+ if (fsp->fh->fd != -1) {
ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, pai_buf_size);
- else
+ } else {
ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, pai_buf_size);
+ }
if (ret == -1) {
if (errno != ERANGE) {
@@ -483,8 +634,11 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
paiv = create_pai_val(pai_buf, ret);
- if (paiv && paiv->pai_protected)
- DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name));
+ if (paiv) {
+ DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n",
+ (unsigned int)paiv->sd_type,
+ fsp->fsp_name));
+ }
SAFE_FREE(pai_buf);
return paiv;
@@ -547,8 +701,10 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn,
paiv = create_pai_val(pai_buf, ret);
- if (paiv && paiv->pai_protected) {
- DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fname));
+ if (paiv) {
+ DEBUG(10,("load_inherited_info: ACL type 0x%x for file %s\n",
+ (unsigned int)paiv->sd_type,
+ fname));
}
SAFE_FREE(pai_buf);
@@ -641,8 +797,8 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "MASK " );
break;
}
- if (pace->inherited)
- dbgtext( "(inherited) ");
+
+ dbgtext( "ace_flags = 0x%x ", (unsigned int)pace->ace_flags);
dbgtext( "perms ");
dbgtext( "%c", pace->perms & S_IRUSR ? 'r' : '-');
dbgtext( "%c", pace->perms & S_IWUSR ? 'w' : '-');
@@ -1519,7 +1675,9 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->perms |= map_nt_perms( &psa->access_mask, S_IRUSR);
current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
- current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
+
+ /* Store the ace_flag. */
+ current_ace->ace_flags = psa->flags;
/*
* Now add the created ace to either the file list, the directory
@@ -2160,7 +2318,7 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head)
other_ace = ace;
}
}
-
+
if (!owner_ace || !other_ace) {
DEBUG(0,("arrange_posix_perms: Invalid POSIX permissions for file %s, missing owner or other.\n",
filename ));
@@ -2184,7 +2342,7 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head)
*pp_list_head = list_head;
}
-
+
/****************************************************************************
Create a linked list of canonical ACE entries.
****************************************************************************/
@@ -2297,7 +2455,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
- ace->inherited = get_inherited_flag(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
+ ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
DLIST_ADD(list_head, ace);
}
@@ -2968,8 +3126,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
&ace->trustee,
nt_acl_type,
acc,
- ace->inherited ?
- SEC_ACE_FLAG_INHERITED_ACE : 0);
+ ace->ace_flags);
}
/* The User must have access to a profile share - even
@@ -2990,11 +3147,10 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
&ace->trustee,
nt_acl_type,
acc,
+ ace->ace_flags |
SEC_ACE_FLAG_OBJECT_INHERIT|
SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY|
- (ace->inherited ?
- SEC_ACE_FLAG_INHERITED_ACE : 0));
+ SEC_ACE_FLAG_INHERIT_ONLY);
}
/* The User must have access to a profile share - even
@@ -3045,8 +3201,10 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
* flag doesn't seem to bother Windows NT.
* Always set this if map acl inherit is turned off.
*/
- if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) {
- psd->type |= SE_DESC_DACL_PROTECTED;
+ if (pal == NULL || !lp_map_acl_inherit(SNUM(conn))) {
+ psd->type |= SEC_DESC_DACL_PROTECTED;
+ } else {
+ psd->type |= pal->sd_type;
}
if (psd->dacl) {
@@ -3236,7 +3394,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
int info;
unsigned int i, j;
SEC_DESC *psd = dup_sec_desc(talloc_tos(), pcsd);
- bool is_dacl_protected = (pcsd->type & SE_DESC_DACL_PROTECTED);
+ bool is_dacl_protected = (pcsd->type & SEC_DESC_DACL_PROTECTED);
ZERO_STRUCT(sbuf);
@@ -3617,8 +3775,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (set_acl_as_root) {
become_root();
}
- store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
- (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
+ store_inheritance_attributes(fsp,
+ file_ace_list,
+ dir_ace_list,
+ psd->type);
if (set_acl_as_root) {
unbecome_root();
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index a025bb4197..c9fc1fbb6a 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -692,57 +692,55 @@ struct idle_event *event_add_idle(struct event_context *event_ctx,
return result;
}
-/****************************************************************************
- Do all async processing in here. This includes kernel oplock messages, change
- notify events etc.
-****************************************************************************/
-
-static void async_processing(void)
+static void smbd_sig_term_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
{
- DEBUG(10,("async_processing: Doing async processing.\n"));
-
- process_aio_queue();
-
- process_kernel_oplocks(smbd_messaging_context());
-
- /* Do the aio check again after receive_local_message as it does a
- select and may have eaten our signal. */
- /* Is this till true? -- vl */
- process_aio_queue();
+ exit_server_cleanly("termination signal");
+}
- if (got_sig_term) {
- exit_server_cleanly("termination signal");
- }
+void smbd_setup_sig_term_handler(void)
+{
+ struct tevent_signal *se;
- /* check for sighup processing */
- if (reload_after_sighup) {
- change_to_root_user();
- DEBUG(1,("Reloading services after SIGHUP\n"));
- reload_services(False);
- reload_after_sighup = 0;
+ se = tevent_add_signal(smbd_event_context(),
+ smbd_event_context(),
+ SIGTERM, 0,
+ smbd_sig_term_handler,
+ NULL);
+ if (!se) {
+ exit_server("failed to setup SIGTERM handler");
}
}
-/****************************************************************************
- Do a select on an two fd's - with timeout.
-
- If a local udp message has been pushed onto the
- queue (this can only happen during oplock break
- processing) call async_processing()
-
- If a pending smb message has been pushed onto the
- queue (this can only happen during oplock break
- processing) return this next.
+static void smbd_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ change_to_root_user();
+ DEBUG(1,("Reloading services after SIGHUP\n"));
+ reload_services(False);
+}
- If the first smbfd is ready then read an smb from it.
- if the second (loopback UDP) fd is ready then read a message
- from it and setup the buffer header to identify the length
- and from address.
- Returns False on timeout or error.
- Else returns True.
+void smbd_setup_sig_hup_handler(void)
+{
+ struct tevent_signal *se;
-The timeout is in milliseconds
-****************************************************************************/
+ se = tevent_add_signal(smbd_event_context(),
+ smbd_event_context(),
+ SIGHUP, 0,
+ smbd_sig_hup_handler,
+ NULL);
+ if (!se) {
+ exit_server("failed to setup SIGHUP handler");
+ }
+}
static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
{
@@ -762,26 +760,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
FD_ZERO(&w_fds);
/*
- * Ensure we process oplock break messages by preference.
- * We have to do this before the select, after the select
- * and if the select returns EINTR. This is due to the fact
- * that the selects called from async_processing can eat an EINTR
- * caused by a signal (we can't take the break message there).
- * This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
- */
-
- if (oplock_message_waiting()) {
- DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
- async_processing();
- /*
- * After async processing we must go and do the select again, as
- * the state of the flag in fds for the server file descriptor is
- * indeterminate - we may have done I/O on it in the oplock processing. JRA.
- */
- return NT_STATUS_RETRY;
- }
-
- /*
* Are there any timed events waiting ? If so, ensure we don't
* select for longer than it would take to wait for them.
*/
@@ -814,20 +792,6 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
return NT_STATUS_RETRY;
}
- /* if we get EINTR then maybe we have received an oplock
- signal - treat this as select returning 1. This is ugly, but
- is the best we can do until the oplock code knows more about
- signals */
- if (selrtn == -1 && errno == EINTR) {
- async_processing();
- /*
- * After async processing we must go and do the select again, as
- * the state of the flag in fds for the server file descriptor is
- * indeterminate - we may have done I/O on it in the oplock processing. JRA.
- */
- return NT_STATUS_RETRY;
- }
-
/* Check if error */
if (selrtn == -1) {
/* something is wrong. Maybe the socket is dead? */
@@ -866,31 +830,6 @@ NTSTATUS allow_new_trans(struct trans_state *list, int mid)
return NT_STATUS_OK;
}
-/****************************************************************************
- We're terminating and have closed all our files/connections etc.
- If there are any pending local messages we need to respond to them
- before termination so that other smbds don't think we just died whilst
- holding oplocks.
-****************************************************************************/
-
-void respond_to_all_remaining_local_messages(void)
-{
- /*
- * Assert we have no exclusive open oplocks.
- */
-
- if(get_number_of_exclusive_open_oplocks()) {
- DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
- get_number_of_exclusive_open_oplocks() ));
- return;
- }
-
- process_kernel_oplocks(smbd_messaging_context());
-
- return;
-}
-
-
/*
These flags determine some of the permissions required to do an operation
@@ -1420,8 +1359,6 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
connection_struct *conn;
struct smb_request *req;
- chain_size = 0;
-
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
@@ -1830,9 +1767,8 @@ void check_reload(time_t t)
mypid = getpid();
}
- if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
+ if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
reload_services(True);
- reload_after_sighup = False;
last_smb_conf_reload_time = t;
}
@@ -1903,12 +1839,135 @@ static void smbd_server_connection_handler(struct event_context *ev,
}
}
+
+/****************************************************************************
+received when we should release a specific IP
+****************************************************************************/
+static void release_ip(const char *ip, void *priv)
+{
+ char addr[INET6_ADDRSTRLEN];
+
+ if (strcmp(client_socket_addr(get_client_fd(),addr,sizeof(addr)), ip) == 0) {
+ /* we can't afford to do a clean exit - that involves
+ database writes, which would potentially mean we
+ are still running after the failover has finished -
+ we have to get rid of this process ID straight
+ away */
+ DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
+ ip));
+ /* note we must exit with non-zero status so the unclean handler gets
+ called in the parent, so that the brl database is tickled */
+ _exit(1);
+ }
+}
+
+static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
+ uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
+{
+ release_ip((char *)data->data, NULL);
+}
+
+#ifdef CLUSTER_SUPPORT
+static int client_get_tcp_info(struct sockaddr_storage *server,
+ struct sockaddr_storage *client)
+{
+ socklen_t length;
+ if (server_fd == -1) {
+ return -1;
+ }
+ length = sizeof(*server);
+ if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
+ return -1;
+ }
+ length = sizeof(*client);
+ if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+/*
+ * Send keepalive packets to our client
+ */
+static bool keepalive_fn(const struct timeval *now, void *private_data)
+{
+ if (!send_keepalive(smbd_server_fd())) {
+ DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+ return False;
+ }
+ return True;
+}
+
+/*
+ * Do the recurring check if we're idle
+ */
+static bool deadtime_fn(const struct timeval *now, void *private_data)
+{
+ if ((conn_num_open() == 0)
+ || (conn_idle_all(now->tv_sec))) {
+ DEBUG( 2, ( "Closing idle connection\n" ) );
+ messaging_send(smbd_messaging_context(), procid_self(),
+ MSG_SHUTDOWN, &data_blob_null);
+ return False;
+ }
+
+ return True;
+}
+
+/*
+ * Do the recurring log file and smb.conf reload checks.
+ */
+
+static bool housekeeping_fn(const struct timeval *now, void *private_data)
+{
+ change_to_root_user();
+
+ /* update printer queue caches if necessary */
+ update_monitored_printq_cache();
+
+ /* check if we need to reload services */
+ check_reload(time(NULL));
+
+ /* Change machine password if neccessary. */
+ attempt_machine_password_change();
+
+ /*
+ * Force a log file check.
+ */
+ force_check_log_size();
+ check_log_size();
+ return true;
+}
+
/****************************************************************************
Process commands from the client
****************************************************************************/
void smbd_process(void)
{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char remaddr[INET6_ADDRSTRLEN];
+
+ smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
+ if (!smbd_server_conn) {
+ exit_server("failed to create smbd_server_connection");
+ }
+
+ /* Ensure child is set to blocking mode */
+ set_blocking(smbd_server_fd(),True);
+
+ set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
+ set_socket_options(smbd_server_fd(), lp_socket_options());
+
+ /* this is needed so that we get decent entries
+ in smbstatus for port 445 connects */
+ set_remote_machine_name(get_peer_addr(smbd_server_fd(),
+ remaddr,
+ sizeof(remaddr)),
+ false);
+ reload_services(true);
+
/*
* Before the first packet, check the global hosts allow/ hosts deny
* parameters before doing any parsing of packets passed to us by the
@@ -1931,12 +1990,96 @@ void smbd_process(void)
exit_server_cleanly("connection denied");
}
- max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+ static_init_rpc;
- smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
- if (!smbd_server_conn) {
- exit_server("failed to create smbd_server_connection");
+ init_modules();
+
+ if (!init_account_policy()) {
+ exit_server("Could not open account policy tdb.\n");
+ }
+
+ if (*lp_rootdir()) {
+ if (chroot(lp_rootdir()) != 0) {
+ DEBUG(0,("Failed changed root to %s\n", lp_rootdir()));
+ exit_server("Failed to chroot()");
+ }
+ DEBUG(0,("Changed root to %s\n", lp_rootdir()));
+ }
+
+ /* Setup oplocks */
+ if (!init_oplocks(smbd_messaging_context()))
+ exit_server("Failed to init oplocks");
+
+ /* Setup aio signal handler. */
+ initialize_async_io_handler();
+
+ /* register our message handlers */
+ messaging_register(smbd_messaging_context(), NULL,
+ MSG_SMB_FORCE_TDIS, msg_force_tdis);
+ messaging_register(smbd_messaging_context(), NULL,
+ MSG_SMB_RELEASE_IP, msg_release_ip);
+ messaging_register(smbd_messaging_context(), NULL,
+ MSG_SMB_CLOSE_FILE, msg_close_file);
+
+ if ((lp_keepalive() != 0)
+ && !(event_add_idle(smbd_event_context(), NULL,
+ timeval_set(lp_keepalive(), 0),
+ "keepalive", keepalive_fn,
+ NULL))) {
+ DEBUG(0, ("Could not add keepalive event\n"));
+ exit(1);
+ }
+
+ if (!(event_add_idle(smbd_event_context(), NULL,
+ timeval_set(IDLE_CLOSED_TIMEOUT, 0),
+ "deadtime", deadtime_fn, NULL))) {
+ DEBUG(0, ("Could not add deadtime event\n"));
+ exit(1);
}
+
+ if (!(event_add_idle(smbd_event_context(), NULL,
+ timeval_set(SMBD_SELECT_TIMEOUT, 0),
+ "housekeeping", housekeeping_fn, NULL))) {
+ DEBUG(0, ("Could not add housekeeping event\n"));
+ exit(1);
+ }
+
+#ifdef CLUSTER_SUPPORT
+
+ if (lp_clustering()) {
+ /*
+ * We need to tell ctdb about our client's TCP
+ * connection, so that for failover ctdbd can send
+ * tickle acks, triggering a reconnection by the
+ * client.
+ */
+
+ struct sockaddr_storage srv, clnt;
+
+ if (client_get_tcp_info(&srv, &clnt) == 0) {
+
+ NTSTATUS status;
+
+ status = ctdbd_register_ips(
+ messaging_ctdbd_connection(),
+ &srv, &clnt, release_ip, NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("ctdbd_register_ips failed: %s\n",
+ nt_errstr(status)));
+ }
+ } else
+ {
+ DEBUG(0,("Unable to get tcp info for "
+ "CTDB_CONTROL_TCP_CLIENT: %s\n",
+ strerror(errno)));
+ }
+ }
+
+#endif
+
+ max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+
smbd_server_conn->fde = event_add_fd(smbd_event_context(),
smbd_server_conn,
smbd_server_fd(),
@@ -1947,9 +2090,12 @@ void smbd_process(void)
exit_server("failed to create smbd_server_connection fde");
}
+ TALLOC_FREE(frame);
+
while (True) {
NTSTATUS status;
- TALLOC_CTX *frame = talloc_stackframe_pool(8192);
+
+ frame = talloc_stackframe_pool(8192);
errno = 0;
@@ -1958,9 +2104,35 @@ void smbd_process(void)
!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
" exiting\n", nt_errstr(status)));
- return;
+ break;
}
TALLOC_FREE(frame);
}
+
+ exit_server_cleanly(NULL);
+}
+
+bool req_is_in_chain(struct smb_request *req)
+{
+ if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
+ /*
+ * We're right now handling a subsequent request, so we must
+ * be in a chain
+ */
+ return true;
+ }
+
+ if (!is_andx_req(req->cmd)) {
+ return false;
+ }
+
+ if (req->wct < 2) {
+ /*
+ * Okay, an illegal request, but definitely not chained :-)
+ */
+ return false;
+ }
+
+ return (CVAL(req->vwv+0, 0) != 0xFF);
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 52dab0a013..bb5fadd465 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1816,7 +1816,7 @@ void reply_open_and_X(struct smb_request *req)
END_PROFILE(SMBopenX);
return;
}
- sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
+ sbuf.st_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
}
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
@@ -2728,11 +2728,12 @@ static void reply_readbraw_error(void)
Use sendfile in readbraw.
****************************************************************************/
-void send_file_readbraw(connection_struct *conn,
- files_struct *fsp,
- SMB_OFF_T startpos,
- size_t nread,
- ssize_t mincount)
+static void send_file_readbraw(connection_struct *conn,
+ struct smb_request *req,
+ files_struct *fsp,
+ SMB_OFF_T startpos,
+ size_t nread,
+ ssize_t mincount)
{
char *outbuf = NULL;
ssize_t ret=0;
@@ -2745,7 +2746,7 @@ void send_file_readbraw(connection_struct *conn,
* reply_readbraw has already checked the length.
*/
- if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
+ if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
ssize_t sendfile_read = -1;
char header[4];
@@ -2963,7 +2964,7 @@ void reply_readbraw(struct smb_request *req)
(unsigned long)mincount,
(unsigned long)nread ) );
- send_file_readbraw(conn, fsp, startpos, nread, mincount);
+ send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
DEBUG(5,("reply_readbraw finished\n"));
END_PROFILE(SMBreadbraw);
@@ -3229,7 +3230,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
* on a train in Germany :-). JRA.
*/
- if ((chain_size == 0) && (CVAL(req->vwv+0, 0) == 0xFF) &&
+ if (!req_is_in_chain(req) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
@@ -5615,7 +5616,13 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
return map_nt_error_from_unix(errno);
}
} else {
- if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) {
+ int ret = -1;
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf);
+ } else {
+ ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf);
+ }
+ if (ret == -1) {
return map_nt_error_from_unix(errno);
}
}
@@ -5720,6 +5727,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
const char *dname;
long offset = 0;
int create_options = 0;
+ bool posix_pathnames = lp_posix_pathnames();
ZERO_STRUCT(sbuf1);
ZERO_STRUCT(sbuf2);
@@ -5831,7 +5839,11 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
}
ZERO_STRUCT(sbuf1);
- SMB_VFS_STAT(conn, directory, &sbuf1);
+ if (posix_pathnames) {
+ SMB_VFS_LSTAT(conn, directory, &sbuf1);
+ } else {
+ SMB_VFS_STAT(conn, directory, &sbuf1);
+ }
if (S_ISDIR(sbuf1.st_mode)) {
create_options |= FILE_DIRECTORY_FILE;
@@ -5848,7 +5860,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
FILE_SHARE_WRITE),
FILE_OPEN, /* create_disposition*/
create_options, /* create_options */
- 0, /* file_attributes */
+ posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
0, /* oplock_request */
0, /* allocation_size */
NULL, /* sd */
@@ -5947,7 +5959,11 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
}
ZERO_STRUCT(sbuf1);
- SMB_VFS_STAT(conn, fname, &sbuf1);
+ if (posix_pathnames) {
+ SMB_VFS_LSTAT(conn, fname, &sbuf1);
+ } else {
+ SMB_VFS_STAT(conn, fname, &sbuf1);
+ }
create_options = 0;
@@ -5966,7 +5982,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
FILE_SHARE_WRITE),
FILE_OPEN, /* create_disposition*/
create_options, /* create_options */
- 0, /* file_attributes */
+ posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
0, /* oplock_request */
0, /* allocation_size */
NULL, /* sd */
@@ -7166,7 +7182,14 @@ void reply_setattrE(struct smb_request *req)
return;
}
} else {
- if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
+ int ret = -1;
+
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(conn, fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf);
+ }
+ if (ret == -1) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
END_PROFILE(SMBsetattrE);
@@ -7281,7 +7304,7 @@ void reply_getattrE(struct smb_request *req)
SIVAL(req->outbuf, smb_vwv6, 0);
SIVAL(req->outbuf, smb_vwv8, 0);
} else {
- uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
+ uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &sbuf);
SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
SIVAL(req->outbuf, smb_vwv8, allocation_size);
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 505763014e..5f6783e05c 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -45,26 +45,6 @@ int get_client_fd(void)
return server_fd;
}
-#ifdef CLUSTER_SUPPORT
-static int client_get_tcp_info(struct sockaddr_storage *server,
- struct sockaddr_storage *client)
-{
- socklen_t length;
- if (server_fd == -1) {
- return -1;
- }
- length = sizeof(*server);
- if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
- return -1;
- }
- length = sizeof(*client);
- if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
- return -1;
- }
- return 0;
-}
-#endif
-
struct event_context *smbd_event_context(void)
{
if (!smbd_event_ctx) {
@@ -134,35 +114,6 @@ static void smb_stat_cache_delete(struct messaging_context *msg,
}
/****************************************************************************
- Terminate signal.
-****************************************************************************/
-
-static void sig_term(void)
-{
- got_sig_term = 1;
- sys_select_signal(SIGTERM);
-}
-
-/****************************************************************************
- Catch a sighup.
-****************************************************************************/
-
-static void sig_hup(int sig)
-{
- reload_after_sighup = 1;
- sys_select_signal(SIGHUP);
-}
-
-/****************************************************************************
- Catch a sigcld
-****************************************************************************/
-static void sig_cld(int sig)
-{
- got_sig_cld = 1;
- sys_select_signal(SIGCLD);
-}
-
-/****************************************************************************
Send a SIGTERM to our process group.
*****************************************************************************/
@@ -185,27 +136,6 @@ static void msg_sam_sync(struct messaging_context *msg,
DEBUG(10, ("** sam sync message received, ignoring\n"));
}
-
-/****************************************************************************
- Open the socket communication - inetd.
-****************************************************************************/
-
-static bool open_sockets_inetd(void)
-{
- /* Started from inetd. fd 0 is the socket. */
- /* We will abort gracefully when the client or remote system
- goes away */
- smbd_set_server_fd(dup(0));
-
- /* close our standard file descriptors */
- close_low_fds(False); /* Don't close stderr */
-
- set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), lp_socket_options());
-
- return True;
-}
-
static void msg_exit_server(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -321,46 +251,271 @@ static bool allowable_number_of_smbd_processes(void)
return num_children < max_processes;
}
+static void smbd_sig_chld_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ pid_t pid;
+ int status;
+
+ while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
+ bool unclean_shutdown = False;
+
+ /* If the child terminated normally, assume
+ it was an unclean shutdown unless the
+ status is 0
+ */
+ if (WIFEXITED(status)) {
+ unclean_shutdown = WEXITSTATUS(status);
+ }
+ /* If the child terminated due to a signal
+ we always assume it was unclean.
+ */
+ if (WIFSIGNALED(status)) {
+ unclean_shutdown = True;
+ }
+ remove_child_pid(pid, unclean_shutdown);
+ }
+}
+
+static void smbd_setup_sig_chld_handler(void)
+{
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(smbd_event_context(),
+ smbd_event_context(),
+ SIGCHLD, 0,
+ smbd_sig_chld_handler,
+ NULL);
+ if (!se) {
+ exit_server("failed to setup SIGCHLD handler");
+ }
+}
+
+struct smbd_open_socket;
+
+struct smbd_parent_context {
+ bool interactive;
+
+ /* the list of listening sockets */
+ struct smbd_open_socket *sockets;
+};
+
+struct smbd_open_socket {
+ struct smbd_open_socket *prev, *next;
+ struct smbd_parent_context *parent;
+ int fd;
+ struct tevent_fd *fde;
+};
+
+static void smbd_open_socket_close_fn(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ int fd,
+ void *private_data)
+{
+ /* this might be the socket_wrapper swrap_close() */
+ close(fd);
+}
+
+static void smbd_accept_connection(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ struct smbd_open_socket *s = talloc_get_type_abort(private_data,
+ struct smbd_open_socket);
+ struct sockaddr_storage addr;
+ socklen_t in_addrlen = sizeof(addr);
+ pid_t pid = 0;
+
+ smbd_set_server_fd(accept(s->fd,(struct sockaddr *)&addr,&in_addrlen));
+
+ if (smbd_server_fd() == -1 && errno == EINTR)
+ return;
+
+ if (smbd_server_fd() == -1) {
+ DEBUG(0,("open_sockets_smbd: accept: %s\n",
+ strerror(errno)));
+ return;
+ }
+
+ if (s->parent->interactive) {
+ smbd_process();
+ exit_server_cleanly("end of interactive mode");
+ return;
+ }
+
+ if (!allowable_number_of_smbd_processes()) {
+ close(smbd_server_fd());
+ smbd_set_server_fd(-1);
+ return;
+ }
+
+ pid = sys_fork();
+ if (pid == 0) {
+ /* Child code ... */
+ am_parent = 0;
+
+ /* Stop zombies, the parent explicitly handles
+ * them, counting worker smbds. */
+ CatchChild();
+
+ /* close our standard file
+ descriptors */
+ close_low_fds(False);
+
+ TALLOC_FREE(s->parent);
+ s = NULL;
+
+ if (!reinit_after_fork(
+ smbd_messaging_context(),
+ smbd_event_context(),
+ true)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ smb_panic("reinit_after_fork() failed");
+ }
+
+ smbd_setup_sig_term_handler();
+ smbd_setup_sig_hup_handler();
+
+ smbd_process();
+ exit_server_cleanly("end of child");
+ return;
+ } else if (pid < 0) {
+ DEBUG(0,("smbd_accept_connection: sys_fork() failed: %s\n",
+ strerror(errno)));
+ }
+
+ /* The parent doesn't need this socket */
+ close(smbd_server_fd());
+
+ /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
+ Clear the closed fd info out of server_fd --
+ and more importantly, out of client_fd in
+ util_sock.c, to avoid a possible
+ getpeername failure if we reopen the logs
+ and use %I in the filename.
+ */
+
+ smbd_set_server_fd(-1);
+
+ if (pid != 0) {
+ add_child_pid(pid);
+ }
+
+ /* Force parent to check log size after
+ * spawning child. Fix from
+ * klausr@ITAP.Physik.Uni-Stuttgart.De. The
+ * parent smbd will log to logserver.smb. It
+ * writes only two messages for each child
+ * started/finished. But each child writes,
+ * say, 50 messages also in logserver.smb,
+ * begining with the debug_count of the
+ * parent, before the child opens its own log
+ * file logserver.client. In a worst case
+ * scenario the size of logserver.smb would be
+ * checked after about 50*50=2500 messages
+ * (ca. 100kb).
+ * */
+ force_check_log_size();
+}
+
+static bool smbd_open_one_socket(struct smbd_parent_context *parent,
+ const struct sockaddr_storage *ifss,
+ uint16_t port)
+{
+ struct smbd_open_socket *s;
+
+ s = talloc(parent, struct smbd_open_socket);
+ if (!s) {
+ return false;
+ }
+
+ s->parent = parent;
+ s->fd = open_socket_in(SOCK_STREAM,
+ port,
+ parent->sockets == NULL ? 0 : 2,
+ ifss,
+ true);
+ if (s->fd == -1) {
+ DEBUG(0,("smbd_open_once_socket: open_socket_in: "
+ "%s\n", strerror(errno)));
+ close(s->fd);
+ TALLOC_FREE(s);
+ /*
+ * We ignore an error here, as we've done before
+ */
+ return true;
+ }
+
+ /* ready to listen */
+ set_socket_options(s->fd, "SO_KEEPALIVE");
+ set_socket_options(s->fd, lp_socket_options());
+
+ /* Set server socket to
+ * non-blocking for the accept. */
+ set_blocking(s->fd, False);
+
+ if (listen(s->fd, SMBD_LISTEN_BACKLOG) == -1) {
+ DEBUG(0,("open_sockets_smbd: listen: "
+ "%s\n", strerror(errno)));
+ close(s->fd);
+ TALLOC_FREE(s);
+ return false;
+ }
+
+ s->fde = tevent_add_fd(smbd_event_context(),
+ s,
+ s->fd, TEVENT_FD_READ,
+ smbd_accept_connection,
+ s);
+ if (!s->fde) {
+ DEBUG(0,("open_sockets_smbd: "
+ "tevent_add_fd: %s\n",
+ strerror(errno)));
+ close(s->fd);
+ TALLOC_FREE(s);
+ return false;
+ }
+ tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn);
+
+ DLIST_ADD_END(parent->sockets, s, struct smbd_open_socket *);
+
+ return true;
+}
+
/****************************************************************************
Open the socket communication.
****************************************************************************/
-static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ports)
+static bool open_sockets_smbd(struct smbd_parent_context *parent,
+ const char *smb_ports)
{
int num_interfaces = iface_count();
- int num_sockets = 0;
- int fd_listenset[FD_SETSIZE];
- fd_set listen_set;
- int s;
- int maxfd = 0;
int i;
char *ports;
- struct dns_reg_state * dns_reg = NULL;
unsigned dns_port = 0;
- if (!is_daemon) {
- return open_sockets_inetd();
- }
-
#ifdef HAVE_ATEXIT
atexit(killkids);
#endif
/* Stop zombies */
- CatchSignal(SIGCLD, sig_cld);
-
- FD_ZERO(&listen_set);
+ smbd_setup_sig_chld_handler();
/* use a reasonable default set of ports - listing on 445 and 139 */
if (!smb_ports) {
ports = lp_smb_ports();
if (!ports || !*ports) {
- ports = smb_xstrdup(SMB_PORTS);
+ ports = talloc_strdup(talloc_tos(), SMB_PORTS);
} else {
- ports = smb_xstrdup(ports);
+ ports = talloc_strdup(talloc_tos(), ports);
}
} else {
- ports = smb_xstrdup(smb_ports);
+ ports = talloc_strdup(talloc_tos(), smb_ports);
}
if (lp_interfaces() && lp_bind_interfaces_only()) {
@@ -372,7 +527,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
/* Now open a listen socket for each of the
interfaces. */
for(i = 0; i < num_interfaces; i++) {
- TALLOC_CTX *frame = NULL;
const struct sockaddr_storage *ifss =
iface_n_sockaddr_storage(i);
char *tok;
@@ -385,64 +539,22 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
continue;
}
- frame = talloc_stackframe();
for (ptr=ports;
- next_token_talloc(frame,&ptr, &tok, " \t,");) {
+ next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) {
unsigned port = atoi(tok);
if (port == 0 || port > 0xffff) {
continue;
}
- /* Keep the first port for mDNS service
- * registration.
- */
- if (dns_port == 0) {
- dns_port = port;
- }
-
- s = fd_listenset[num_sockets] =
- open_socket_in(SOCK_STREAM,
- port,
- num_sockets == 0 ? 0 : 2,
- ifss,
- true);
- if(s == -1) {
- continue;
- }
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,lp_socket_options());
-
- /* Set server socket to
- * non-blocking for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("open_sockets_smbd: listen: "
- "%s\n", strerror(errno)));
- close(s);
- TALLOC_FREE(frame);
- return False;
- }
- FD_SET(s,&listen_set);
- maxfd = MAX( maxfd, s);
-
- num_sockets++;
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too "
- "many sockets to bind to\n"));
- TALLOC_FREE(frame);
- return False;
+ if (!smbd_open_one_socket(parent, ifss, port)) {
+ return false;
}
}
- TALLOC_FREE(frame);
}
} else {
/* Just bind to 0.0.0.0 - accept connections
from anywhere. */
- TALLOC_CTX *frame = talloc_stackframe();
char *tok;
const char *ptr;
const char *sock_addr = lp_socket_address();
@@ -459,8 +571,8 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
}
for (sock_ptr=sock_addr;
- next_token_talloc(frame, &sock_ptr, &sock_tok, " \t,"); ) {
- for (ptr=ports; next_token_talloc(frame, &ptr, &tok, " \t,"); ) {
+ next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
+ for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) {
struct sockaddr_storage ss;
unsigned port = atoi(tok);
@@ -481,52 +593,14 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
continue;
}
- s = open_socket_in(SOCK_STREAM,
- port,
- num_sockets == 0 ? 0 : 2,
- &ss,
- true);
- if (s == -1) {
- continue;
- }
-
- /* ready to listen */
- set_socket_options(s,"SO_KEEPALIVE");
- set_socket_options(s,lp_socket_options());
-
- /* Set server socket to non-blocking
- * for the accept. */
- set_blocking(s,False);
-
- if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
- DEBUG(0,("open_sockets_smbd: "
- "listen: %s\n",
- strerror(errno)));
- close(s);
- TALLOC_FREE(frame);
- return False;
- }
-
- fd_listenset[num_sockets] = s;
- FD_SET(s,&listen_set);
- maxfd = MAX( maxfd, s);
-
- num_sockets++;
-
- if (num_sockets >= FD_SETSIZE) {
- DEBUG(0,("open_sockets_smbd: Too "
- "many sockets to bind to\n"));
- TALLOC_FREE(frame);
- return False;
+ if (!smbd_open_one_socket(parent, &ss, port)) {
+ return false;
}
}
}
- TALLOC_FREE(frame);
}
- SAFE_FREE(ports);
-
- if (num_sockets == 0) {
+ if (parent->sockets == NULL) {
DEBUG(0,("open_sockets_smbd: No "
"sockets available to bind to.\n"));
return false;
@@ -565,57 +639,37 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
MSG_SMB_INJECT_FAULT, msg_inject_fault);
#endif
+ if (dns_port != 0) {
+ smbd_setup_mdns_registration(smbd_event_context(),
+ parent, dns_port);
+ }
+
+ return true;
+}
+
+static void smbd_parent_loop(struct smbd_parent_context *parent)
+{
/* now accept incoming connections - forking a new process
for each incoming connection */
DEBUG(2,("waiting for a connection\n"));
while (1) {
struct timeval now, idle_timeout;
fd_set r_fds, w_fds;
+ int maxfd = 0;
int num;
-
- if (got_sig_cld) {
- pid_t pid;
- int status;
-
- got_sig_cld = False;
-
- while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
- bool unclean_shutdown = False;
-
- /* If the child terminated normally, assume
- it was an unclean shutdown unless the
- status is 0
- */
- if (WIFEXITED(status)) {
- unclean_shutdown = WEXITSTATUS(status);
- }
- /* If the child terminated due to a signal
- we always assume it was unclean.
- */
- if (WIFSIGNALED(status)) {
- unclean_shutdown = True;
- }
- remove_child_pid(pid, unclean_shutdown);
- }
- }
+ TALLOC_CTX *frame = talloc_stackframe();
if (run_events(smbd_event_context(), 0, NULL, NULL)) {
+ TALLOC_FREE(frame);
continue;
}
idle_timeout = timeval_zero();
- memcpy((char *)&r_fds, (char *)&listen_set,
- sizeof(listen_set));
FD_ZERO(&w_fds);
+ FD_ZERO(&r_fds);
GetTimeOfDay(&now);
- /* Kick off our mDNS registration. */
- if (dns_port != 0) {
- dns_register_smbd(&dns_reg, dns_port, &maxfd,
- &r_fds, &idle_timeout);
- }
-
event_add_to_select_args(smbd_event_context(), &now,
&r_fds, &w_fds, &idle_timeout,
&maxfd);
@@ -624,26 +678,13 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
timeval_is_zero(&idle_timeout) ?
NULL : &idle_timeout);
- if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
- continue;
- }
-
- if (num == -1 && errno == EINTR) {
- if (got_sig_term) {
- exit_server_cleanly(NULL);
- }
-
- /* check for sighup processing */
- if (reload_after_sighup) {
- change_to_root_user();
- DEBUG(1,("Reloading services after SIGHUP\n"));
- reload_services(False);
- reload_after_sighup = 0;
- }
+ /* check if we need to reload services */
+ check_reload(time(NULL));
+ if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
+ TALLOC_FREE(frame);
continue;
}
-
/* If the idle timeout fired and we don't have any connected
* users, exit gracefully. We should be running under a process
@@ -652,128 +693,7 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
if (num == 0 && count_all_current_connections() == 0) {
exit_server_cleanly("idle timeout");
}
-
- /* process pending nDNS responses */
- if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
- --num;
- }
-
- /* check if we need to reload services */
- check_reload(time(NULL));
-
- /* Find the sockets that are read-ready -
- accept on these. */
- for( ; num > 0; num--) {
- struct sockaddr addr;
- socklen_t in_addrlen = sizeof(addr);
- pid_t child = 0;
-
- s = -1;
- for(i = 0; i < num_sockets; i++) {
- if(FD_ISSET(fd_listenset[i],&r_fds)) {
- s = fd_listenset[i];
- /* Clear this so we don't look
- at it again. */
- FD_CLR(fd_listenset[i],&r_fds);
- break;
- }
- }
-
- smbd_set_server_fd(accept(s,&addr,&in_addrlen));
-
- if (smbd_server_fd() == -1 && errno == EINTR)
- continue;
-
- if (smbd_server_fd() == -1) {
- DEBUG(2,("open_sockets_smbd: accept: %s\n",
- strerror(errno)));
- continue;
- }
-
- /* Ensure child is set to blocking mode */
- set_blocking(smbd_server_fd(),True);
-
- if (smbd_server_fd() != -1 && interactive)
- return True;
-
- if (allowable_number_of_smbd_processes() &&
- smbd_server_fd() != -1 &&
- ((child = sys_fork())==0)) {
- char remaddr[INET6_ADDRSTRLEN];
-
- /* Child code ... */
-
- /* Stop zombies, the parent explicitly handles
- * them, counting worker smbds. */
- CatchChild();
-
- /* close the listening socket(s) */
- for(i = 0; i < num_sockets; i++)
- close(fd_listenset[i]);
-
- /* close our mDNS daemon handle */
- dns_register_close(&dns_reg);
-
- /* close our standard file
- descriptors */
- close_low_fds(False);
- am_parent = 0;
-
- set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(),
- lp_socket_options());
-
- /* this is needed so that we get decent entries
- in smbstatus for port 445 connects */
- set_remote_machine_name(get_peer_addr(smbd_server_fd(),
- remaddr,
- sizeof(remaddr)),
- false);
-
- if (!reinit_after_fork(
- smbd_messaging_context(),
- smbd_event_context(),
- true)) {
- DEBUG(0,("reinit_after_fork() failed\n"));
- smb_panic("reinit_after_fork() failed");
- }
-
- return True;
- }
- /* The parent doesn't need this socket */
- close(smbd_server_fd());
-
- /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
- Clear the closed fd info out of server_fd --
- and more importantly, out of client_fd in
- util_sock.c, to avoid a possible
- getpeername failure if we reopen the logs
- and use %I in the filename.
- */
-
- smbd_set_server_fd(-1);
-
- if (child != 0) {
- add_child_pid(child);
- }
-
- /* Force parent to check log size after
- * spawning child. Fix from
- * klausr@ITAP.Physik.Uni-Stuttgart.De. The
- * parent smbd will log to logserver.smb. It
- * writes only two messages for each child
- * started/finished. But each child writes,
- * say, 50 messages also in logserver.smb,
- * begining with the debug_count of the
- * parent, before the child opens its own log
- * file logserver.client. In a worst case
- * scenario the size of logserver.smb would be
- * checked after about 50*50=2500 messages
- * (ca. 100kb).
- * */
- force_check_log_size();
-
- } /* end for num */
+ TALLOC_FREE(frame);
} /* end while 1 */
/* NOTREACHED return True; */
@@ -897,8 +817,6 @@ static void exit_server_common(enum server_exit_reason how,
/* delete our entry in the connections database. */
yield_connection(NULL,"");
- respond_to_all_remaining_local_messages();
-
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
dfs_unlogin();
@@ -963,34 +881,6 @@ void exit_server_fault(void)
exit_server("critical server fault");
}
-
-/****************************************************************************
-received when we should release a specific IP
-****************************************************************************/
-static void release_ip(const char *ip, void *priv)
-{
- char addr[INET6_ADDRSTRLEN];
-
- if (strcmp(client_socket_addr(get_client_fd(),addr,sizeof(addr)), ip) == 0) {
- /* we can't afford to do a clean exit - that involves
- database writes, which would potentially mean we
- are still running after the failover has finished -
- we have to get rid of this process ID straight
- away */
- DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
- ip));
- /* note we must exit with non-zero status so the unclean handler gets
- called in the parent, so that the brl database is tickled */
- _exit(1);
- }
-}
-
-static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
- uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
-{
- release_ip((char *)data->data, NULL);
-}
-
/****************************************************************************
Initialise connect, service and file structs.
****************************************************************************/
@@ -1017,59 +907,6 @@ static bool init_structs(void )
return True;
}
-/*
- * Send keepalive packets to our client
- */
-static bool keepalive_fn(const struct timeval *now, void *private_data)
-{
- if (!send_keepalive(smbd_server_fd())) {
- DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
- return False;
- }
- return True;
-}
-
-/*
- * Do the recurring check if we're idle
- */
-static bool deadtime_fn(const struct timeval *now, void *private_data)
-{
- if ((conn_num_open() == 0)
- || (conn_idle_all(now->tv_sec))) {
- DEBUG( 2, ( "Closing idle connection\n" ) );
- messaging_send(smbd_messaging_context(), procid_self(),
- MSG_SHUTDOWN, &data_blob_null);
- return False;
- }
-
- return True;
-}
-
-/*
- * Do the recurring log file and smb.conf reload checks.
- */
-
-static bool housekeeping_fn(const struct timeval *now, void *private_data)
-{
- change_to_root_user();
-
- /* update printer queue caches if necessary */
- update_monitored_printq_cache();
-
- /* check if we need to reload services */
- check_reload(time(NULL));
-
- /* Change machine password if neccessary. */
- attempt_machine_password_change();
-
- /*
- * Force a log file check.
- */
- force_check_log_size();
- check_log_size();
- return true;
-}
-
/****************************************************************************
main program.
****************************************************************************/
@@ -1114,6 +951,7 @@ extern void build_options(bool screen);
POPT_COMMON_DYNCONFIG
POPT_TABLEEND
};
+ struct smbd_parent_context *parent = NULL;
TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
smbd_init_globals();
@@ -1199,9 +1037,6 @@ extern void build_options(bool screen);
fault_setup((void (*)(void *))exit_server_fault);
dump_core_setup("smbd");
- CatchSignal(SIGTERM , SIGNAL_CAST sig_term);
- CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
-
/* we are never interested in SIGPIPE */
BlockSignals(True,SIGPIPE);
@@ -1311,6 +1146,9 @@ extern void build_options(bool screen);
exit(1);
}
+ smbd_setup_sig_term_handler();
+ smbd_setup_sig_hup_handler();
+
/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
if (smbd_memcache() == NULL) {
@@ -1372,111 +1210,36 @@ extern void build_options(bool screen);
start_background_queue();
}
- if (!open_sockets_smbd(is_daemon, interactive, ports))
- exit(1);
-
- /*
- * everything after this point is run after the fork()
- */
-
- static_init_rpc;
-
- init_modules();
-
- /* Possibly reload the services file. Only worth doing in
- * daemon mode. In inetd mode, we know we only just loaded this.
- */
- if (is_daemon) {
- reload_services(True);
- }
-
- if (!init_account_policy()) {
- DEBUG(0,("Could not open account policy tdb.\n"));
- exit(1);
- }
+ if (!is_daemon) {
+ /* inetd mode */
+ TALLOC_FREE(frame);
- if (*lp_rootdir()) {
- if (chroot(lp_rootdir()) == 0)
- DEBUG(2,("Changed root to %s\n", lp_rootdir()));
- }
+ /* Started from inetd. fd 0 is the socket. */
+ /* We will abort gracefully when the client or remote system
+ goes away */
+ smbd_set_server_fd(dup(0));
- /* Setup oplocks */
- if (!init_oplocks(smbd_messaging_context()))
- exit(1);
+ /* close our standard file descriptors */
+ close_low_fds(False); /* Don't close stderr */
- /* Setup aio signal handler. */
- initialize_async_io_handler();
+ smbd_process();
- /* register our message handlers */
- messaging_register(smbd_messaging_context(), NULL,
- MSG_SMB_FORCE_TDIS, msg_force_tdis);
- messaging_register(smbd_messaging_context(), NULL,
- MSG_SMB_RELEASE_IP, msg_release_ip);
- messaging_register(smbd_messaging_context(), NULL,
- MSG_SMB_CLOSE_FILE, msg_close_file);
-
- if ((lp_keepalive() != 0)
- && !(event_add_idle(smbd_event_context(), NULL,
- timeval_set(lp_keepalive(), 0),
- "keepalive", keepalive_fn,
- NULL))) {
- DEBUG(0, ("Could not add keepalive event\n"));
- exit(1);
+ exit_server_cleanly(NULL);
+ return(0);
}
- if (!(event_add_idle(smbd_event_context(), NULL,
- timeval_set(IDLE_CLOSED_TIMEOUT, 0),
- "deadtime", deadtime_fn, NULL))) {
- DEBUG(0, ("Could not add deadtime event\n"));
- exit(1);
+ parent = talloc_zero(smbd_event_context(), struct smbd_parent_context);
+ if (!parent) {
+ exit_server("talloc(struct smbd_parent_context) failed");
}
+ parent->interactive = interactive;
- if (!(event_add_idle(smbd_event_context(), NULL,
- timeval_set(SMBD_SELECT_TIMEOUT, 0),
- "housekeeping", housekeeping_fn, NULL))) {
- DEBUG(0, ("Could not add housekeeping event\n"));
- exit(1);
- }
-
-#ifdef CLUSTER_SUPPORT
-
- if (lp_clustering()) {
- /*
- * We need to tell ctdb about our client's TCP
- * connection, so that for failover ctdbd can send
- * tickle acks, triggering a reconnection by the
- * client.
- */
-
- struct sockaddr_storage srv, clnt;
-
- if (client_get_tcp_info(&srv, &clnt) == 0) {
-
- NTSTATUS status;
-
- status = ctdbd_register_ips(
- messaging_ctdbd_connection(),
- &srv, &clnt, release_ip, NULL);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("ctdbd_register_ips failed: %s\n",
- nt_errstr(status)));
- }
- } else
- {
- DEBUG(0,("Unable to get tcp info for "
- "CTDB_CONTROL_TCP_CLIENT: %s\n",
- strerror(errno)));
- }
- }
-
-#endif
+ if (!open_sockets_smbd(parent, ports))
+ exit_server("open_sockets_smbd() failed");
TALLOC_FREE(frame);
- smbd_process();
-
- namecache_shutdown();
+ smbd_parent_loop(parent);
exit_server_cleanly(NULL);
return(0);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index a2ad56bea1..7a03ef7f3c 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -795,7 +795,7 @@ static void reply_spnego_negotiate(struct smb_request *req,
#ifdef HAVE_KRB5
if (kerb_mech && ((lp_security()==SEC_ADS) ||
- lp_use_kerberos_keytab()) ) {
+ USE_KERBEROS_KEYTAB) ) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
@@ -887,7 +887,7 @@ static void reply_spnego_auth(struct smb_request *req,
(unsigned long)secblob.length));
#ifdef HAVE_KRB5
if (kerb_mech && ((lp_security()==SEC_ADS) ||
- lp_use_kerberos_keytab()) ) {
+ USE_KERBEROS_KEYTAB)) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1b161d5338..6c082a8273 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -29,7 +29,6 @@
extern enum protocol_types Protocol;
-#define get_file_size(sbuf) ((sbuf).st_size)
#define DIR_ENTRY_SAFETY_MARGIN 4096
static char *store_file_unix_basic(connection_struct *conn,
@@ -59,31 +58,6 @@ uint64_t smb_roundup(connection_struct *conn, uint64_t val)
return val;
}
-/********************************************************************
- Given a stat buffer return the allocated size on disk, taking into
- account sparse files.
-********************************************************************/
-
-uint64_t get_allocation_size(connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
-{
- uint64_t ret;
-
- if(S_ISDIR(sbuf->st_mode)) {
- return 0;
- }
-
-#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- ret = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
-#else
- ret = (uint64_t)get_file_size(*sbuf);
-#endif
-
- if (fsp && fsp->initial_allocation_size)
- ret = MAX(ret,fsp->initial_allocation_size);
-
- return smb_roundup(conn, ret);
-}
-
/****************************************************************************
Utility functions for dealing with extended attributes.
****************************************************************************/
@@ -1034,7 +1008,7 @@ static void call_trans2open(connection_struct *conn,
return;
}
- size = get_file_size(sbuf);
+ size = get_file_size_stat(&sbuf);
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
@@ -1424,9 +1398,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
if (!(mode & aDIR)) {
- file_size = get_file_size(sbuf);
+ file_size = get_file_size_stat(&sbuf);
}
- allocation_size = get_allocation_size(conn,NULL,&sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
mdate_ts = get_mtimespec(&sbuf);
adate_ts = get_atimespec(&sbuf);
@@ -3523,10 +3497,10 @@ static char *store_file_unix_basic(connection_struct *conn,
DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
- SOFF_T(pdata,0,get_file_size(*psbuf)); /* File size 64 Bit */
+ SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */
pdata += 8;
- SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
+ SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */
@@ -4094,7 +4068,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
fullpathname = fname;
if (!(mode & aDIR))
- file_size = get_file_size(sbuf);
+ file_size = get_file_size_stat(&sbuf);
/* Pull out any data sent here before we realloc. */
switch (info_level) {
@@ -4180,7 +4154,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
mtime_ts = get_mtimespec(&sbuf);
atime_ts = get_atimespec(&sbuf);
- allocation_size = get_allocation_size(conn,fsp,&sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
if (!fsp) {
/* Do we have this path open ? */
@@ -4188,7 +4162,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
fsp1 = file_find_di_first(fileid);
if (fsp1 && fsp1->initial_allocation_size) {
- allocation_size = get_allocation_size(conn, fsp1, &sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
}
}
@@ -5044,7 +5018,7 @@ static NTSTATUS smb_set_file_size(connection_struct *conn,
DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
- if (size == get_file_size(*psbuf)) {
+ if (size == get_file_size_stat(psbuf)) {
return NT_STATUS_OK;
}
@@ -5832,7 +5806,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
if (fsp && fsp->fh->fd != -1) {
/* Open file handle. */
/* Only change if needed. */
- if (allocation_size != get_file_size(*psbuf)) {
+ if (allocation_size != get_file_size_stat(psbuf)) {
if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
return map_nt_error_from_unix(errno);
}
@@ -5874,7 +5848,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
}
/* Only change if needed. */
- if (allocation_size != get_file_size(*psbuf)) {
+ if (allocation_size != get_file_size_stat(psbuf)) {
if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
status = map_nt_error_from_unix(errno);
close_file(req, new_fsp, NORMAL_CLOSE);
@@ -6101,7 +6075,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
/* Ensure we don't try and change anything else. */
raw_unixmode = SMB_MODE_NO_CHANGE;
- size = get_file_size(*psbuf);
+ size = get_file_size_stat(psbuf);
ft.atime = get_atimespec(psbuf);
ft.mtime = get_mtimespec(psbuf);
/*
@@ -6117,7 +6091,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* */
if (!size) {
- size = get_file_size(*psbuf);
+ size = get_file_size_stat(psbuf);
}
#endif
diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c
index 1bff95f4f3..4e8dcdd09a 100644
--- a/source3/torture/locktest.c
+++ b/source3/torture/locktest.c
@@ -257,9 +257,10 @@ static struct cli_state *connect_one(char *share, int snum)
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- password[snum], strlen(password[snum])+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ status = cli_tcon_andx(c, share, "?????", password[snum],
+ strlen(password[snum])+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("tree connect failed: %s\n", nt_errstr(status)));
cli_shutdown(c);
return NULL;
}
diff --git a/source3/torture/masktest.c b/source3/torture/masktest.c
index 2c3bda1d43..fb562c8075 100644
--- a/source3/torture/masktest.c
+++ b/source3/torture/masktest.c
@@ -249,9 +249,10 @@ static struct cli_state *connect_one(char *share)
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ status = cli_tcon_andx(c, share, "?????", password,
+ strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("tree connect failed: %s\n", nt_errstr(status)));
cli_shutdown(c);
return NULL;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 8a1a61e79a..1210a36a39 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -1101,6 +1101,7 @@ static bool run_tcon_test(int dummy)
uint16 vuid1, vuid2;
char buf[4];
bool ret = True;
+ NTSTATUS status;
memset(buf, '\0', sizeof(buf));
@@ -1127,10 +1128,11 @@ static bool run_tcon_test(int dummy)
return False;
}
- if (!cli_send_tconX(cli, share, "?????",
- password, strlen(password)+1)) {
+ status = cli_tcon_andx(cli, share, "?????",
+ password, strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
printf("%s refused 2nd tree connect (%s)\n", host,
- cli_errstr(cli));
+ nt_errstr(status));
cli_shutdown(cli);
return False;
}
@@ -1239,14 +1241,14 @@ static bool tcon_devtest(struct cli_state *cli,
const char *return_devtype,
NTSTATUS expected_error)
{
- bool status;
+ NTSTATUS status;
bool ret;
- status = cli_send_tconX(cli, myshare, devtype,
- password, strlen(password)+1);
+ status = cli_tcon_andx(cli, myshare, devtype,
+ password, strlen(password)+1);
if (NT_STATUS_IS_OK(expected_error)) {
- if (status) {
+ if (NT_STATUS_IS_OK(status)) {
if (strcmp(cli->dev, return_devtype) == 0) {
ret = True;
} else {
@@ -1264,7 +1266,7 @@ static bool tcon_devtest(struct cli_state *cli,
}
cli_tdis(cli);
} else {
- if (status) {
+ if (NT_STATUS_IS_OK(status)) {
printf("tconx to share %s with type %s "
"should have failed but succeeded\n",
myshare, devtype);
@@ -2157,7 +2159,7 @@ static bool run_fdsesstest(int dummy)
return False;
saved_cnum = cli->cnum;
- if (!cli_send_tconX(cli, share, "?????", "", 1))
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
return False;
new_cnum = cli->cnum;
cli->cnum = saved_cnum;
@@ -5831,6 +5833,11 @@ static void usage(void)
load_case_tables();
+ if (is_default_dyn_CONFIGFILE()) {
+ if(getenv("SMB_CONF_PATH")) {
+ set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
+ }
+ }
lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
load_interfaces();
diff --git a/source3/utils/eventlogadm.c b/source3/utils/eventlogadm.c
index 5fed4d1a39..d134ea8fea 100644
--- a/source3/utils/eventlogadm.c
+++ b/source3/utils/eventlogadm.c
@@ -5,6 +5,7 @@
*
*
* Copyright (C) Brian Moran 2005.
+ * Copyright (C) Guenther Deschner 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
@@ -37,6 +38,7 @@ static void usage( char *s )
printf( "\nUsage: %s [OPTION]\n\n", s );
printf( " -o write <Eventlog Name> \t\t\t\t\tWrites records to eventlog from STDIN\n" );
printf( " -o addsource <EventlogName> <sourcename> <msgfileDLLname> \tAdds the specified source & DLL eventlog registry entry\n" );
+ printf( " -o dump <Eventlog Name> <starting_record>\t\t\t\t\tDump stored eventlog entries on STDOUT\n" );
printf( "\nMiscellaneous options:\n" );
printf( " -d\t\t\t\t\t\t\t\tturn debug on\n" );
printf( " -h\t\t\t\t\t\t\t\tdisplay help\n\n" );
@@ -83,12 +85,14 @@ static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename
FILE *f1;
char *argfname;
ELOG_TDB *etdb;
+ NTSTATUS status;
/* fixed constants are bad bad bad */
char linein[1024];
bool is_eor;
- Eventlog_entry ee;
- int rcnum;
+ struct eventlog_Record_tdb ee;
+ uint32_t record_number;
+ TALLOC_CTX *mem_ctx = talloc_tos();
f1 = stdin;
if ( !f1 ) {
@@ -103,7 +107,7 @@ static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename
argfname = argv[0];
- if ( !( etdb = elog_open_tdb( argfname, False ) ) ) {
+ if ( !( etdb = elog_open_tdb( argfname, False, False ) ) ) {
printf( "can't open the eventlog TDB (%s)\n", argfname );
return -1;
}
@@ -122,26 +126,29 @@ static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename
is_eor = False;
- parse_logentry( ( char * ) &linein, &ee, &is_eor );
+ parse_logentry( mem_ctx, ( char * ) &linein, &ee, &is_eor );
/* should we do something with the return code? */
if ( is_eor ) {
- fixup_eventlog_entry( &ee );
+ fixup_eventlog_record_tdb( &ee );
if ( opt_debug )
- printf( "record number [%d], tg [%d] , tw [%d]\n", ee.record.record_number, ee.record.time_generated, ee.record.time_written );
+ printf( "record number [%d], tg [%d] , tw [%d]\n",
+ ee.record_number, (int)ee.time_generated, (int)ee.time_written );
- if ( ee.record.time_generated != 0 ) {
+ if ( ee.time_generated != 0 ) {
/* printf("Writing to the event log\n"); */
- rcnum = write_eventlog_tdb( ELOG_TDB_CTX(etdb), &ee );
- if ( !rcnum ) {
- printf( "Can't write to the event log\n" );
+ status = evlog_push_record_tdb( mem_ctx, ELOG_TDB_CTX(etdb),
+ &ee, &record_number );
+ if ( !NT_STATUS_IS_OK(status) ) {
+ printf( "Can't write to the event log: %s\n",
+ nt_errstr(status) );
} else {
if ( opt_debug )
printf( "Wrote record %d\n",
- rcnum );
+ record_number );
}
} else {
if ( opt_debug )
@@ -156,6 +163,54 @@ static int DoWriteCommand( int argc, char **argv, bool debugflag, char *exename
return 0;
}
+static int DoDumpCommand(int argc, char **argv, bool debugflag, char *exename)
+{
+ ELOG_TDB *etdb;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ const char *tdb_filename;
+ uint32_t count = 1;
+
+ if (argc > 2) {
+ return -1;
+ }
+
+ tdb_filename = argv[0];
+
+ if (argc > 1) {
+ count = atoi(argv[1]);
+ }
+
+ etdb = elog_open_tdb(argv[0], false, true);
+ if (!etdb) {
+ printf("can't open the eventlog TDB (%s)\n", argv[0]);
+ return -1;
+ }
+
+ while (1) {
+
+ struct eventlog_Record_tdb *r;
+ char *s;
+
+ r = evlog_pull_record_tdb(mem_ctx, etdb->tdb, count);
+ if (!r) {
+ break;
+ }
+
+ printf("displaying record: %d\n", count);
+
+ s = NDR_PRINT_STRUCT_STRING(mem_ctx, eventlog_Record_tdb, r);
+ if (s) {
+ printf("%s\n", s);
+ talloc_free(s);
+ }
+ count++;
+ }
+
+ elog_close_tdb(etdb, false);
+
+ return 0;
+}
+
/* would be nice to use the popT stuff here, however doing so forces us to drag in a lot of other infrastructure */
int main( int argc, char *argv[] )
@@ -221,6 +276,10 @@ int main( int argc, char *argv[] )
rc = DoWriteCommand( argc, argv, opt_debug, exename );
break;
}
+ if ( !StrCaseCmp( opname, "dump" ) ) {
+ rc = DoDumpCommand( argc, argv, opt_debug, exename );
+ break;
+ }
printf( "unknown command [%s]\n", opname );
usage( exename );
exit( 1 );
diff --git a/source3/utils/net.c b/source3/utils/net.c
index c9525ab2eb..d483198a9e 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -589,6 +589,14 @@ static struct functable net_func[] = {
" Use 'net help lua' to get more information about 'net "
"lua' commands."
},
+ { "eventlog",
+ net_eventlog,
+ NET_TRANSPORT_LOCAL,
+ "Dump Win32 *.evt eventlog files",
+ " Use 'net help eventlog' to get more information about 'net "
+ "eventlog' commands."
+ },
+
#ifdef WITH_FAKE_KASERVER
{ "afs",
net_afs,
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 766f3216f0..86fb9f6782 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -1920,7 +1920,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
d_printf("Password change for principal %s succeeded.\n", host_principal);
- if (lp_use_kerberos_keytab()) {
+ if (USE_SYSTEM_KEYTAB) {
d_printf("Attempting to update system keytab with new password.\n");
if (ads_keytab_create_default(ads)) {
d_printf("Failed to update system keytab.\n");
@@ -2241,9 +2241,9 @@ int net_ads_keytab(struct net_context *c, int argc, const char **argv)
{NULL, NULL, 0, NULL, NULL}
};
- if (!lp_use_kerberos_keytab()) {
- d_printf("\nWarning: \"use kerberos keytab\" must be set to \"true\" in order to \
-use keytab functions.\n");
+ if (!USE_KERBEROS_KEYTAB) {
+ d_printf("\nWarning: \"kerberos method\" must be set to a "
+ "keytab method to use keytab functions.\n");
}
return net_run_function(c, argc, argv, "net ads keytab", func);
diff --git a/source3/utils/net_eventlog.c b/source3/utils/net_eventlog.c
new file mode 100644
index 0000000000..197a7cd330
--- /dev/null
+++ b/source3/utils/net_eventlog.c
@@ -0,0 +1,313 @@
+/*
+ * Samba Unix/Linux SMB client library
+ * Distributed SMB/CIFS Server Management Utility
+ * Local win32 eventlog interface
+ *
+ * Copyright (C) Guenther Deschner 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 "utils/net.h"
+
+/**
+ * Dump an *evt win32 eventlog file
+ *
+ * @param argc Standard main() style argc.
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped.
+ *
+ * @return A shell status integer (0 for success).
+ **/
+
+static int net_eventlog_dump(struct net_context *c, int argc,
+ const char **argv)
+{
+ int ret = -1;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ struct EVENTLOG_EVT_FILE evt;
+ char *s;
+
+ if (argc < 1 || c->display_usage) {
+ d_fprintf(stderr, "usage: net eventlog dump <file.evt>\n");
+ goto done;
+ }
+
+ blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
+ if (!blob.data) {
+ d_fprintf(stderr, "failed to load evt file: %s\n", argv[0]);
+ goto done;
+ }
+
+ ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt,
+ (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ d_fprintf(stderr, "evt pull failed: %s\n", ndr_errstr(ndr_err));
+ goto done;
+ }
+
+ s = NDR_PRINT_STRUCT_STRING(ctx, EVENTLOG_EVT_FILE, &evt);
+ if (s) {
+ printf("%s\n", s);
+ }
+
+ ret = 0;
+ done:
+ TALLOC_FREE(ctx);
+ return ret;
+}
+
+/**
+ * Import an *evt win32 eventlog file to internal tdb representation
+ *
+ * @param argc Standard main() style argc.
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped.
+ *
+ * @return A shell status integer (0 for success).
+ **/
+
+static int net_eventlog_import(struct net_context *c, int argc,
+ const char **argv)
+{
+ int ret = -1;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ uint32_t num_records = 0;
+ uint32_t i;
+ ELOG_TDB *etdb = NULL;
+
+ struct EVENTLOGHEADER evt_header;
+ struct EVENTLOG_EVT_FILE evt;
+
+ if (argc < 2 || c->display_usage) {
+ d_fprintf(stderr, "usage: net eventlog import <file> <eventlog>\n");
+ goto done;
+ }
+
+ blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
+ if (!blob.data) {
+ d_fprintf(stderr, "failed to load evt file: %s\n", argv[0]);
+ goto done;
+ }
+
+ /* dump_data(0, blob.data, blob.length); */
+ ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt_header,
+ (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGHEADER);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ d_fprintf(stderr, "evt header pull failed: %s\n", ndr_errstr(ndr_err));
+ goto done;
+ }
+
+ if (evt_header.Flags & ELF_LOGFILE_HEADER_WRAP) {
+ d_fprintf(stderr, "input file is wrapped, cannot proceed\n");
+ goto done;
+ }
+
+ ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt,
+ (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ d_fprintf(stderr, "evt pull failed: %s\n", ndr_errstr(ndr_err));
+ goto done;
+ }
+
+ /* NDR_PRINT_DEBUG(EVENTLOG_EVT_FILE, &evt); */
+
+ etdb = elog_open_tdb(argv[1], false, false);
+ if (!etdb) {
+ d_fprintf(stderr, "can't open the eventlog TDB (%s)\n", argv[1]);
+ goto done;
+ }
+
+ num_records = evt.hdr.CurrentRecordNumber - evt.hdr.OldestRecordNumber;
+
+ for (i=0; i<num_records; i++) {
+ uint32_t record_number;
+ struct eventlog_Record_tdb e;
+
+ status = evlog_evt_entry_to_tdb_entry(ctx, &evt.records[i], &e);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = evlog_push_record_tdb(ctx, ELOG_TDB_CTX(etdb),
+ &e, &record_number);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "can't write to the eventlog: %s\n",
+ nt_errstr(status));
+ goto done;
+ }
+ }
+
+ printf("wrote %d entries to tdb\n", i);
+
+ ret = 0;
+ done:
+
+ elog_close_tdb(etdb, false);
+
+ TALLOC_FREE(ctx);
+ return ret;
+}
+
+/**
+ * Export internal eventlog tdb representation to an *evt win32 eventlog file
+ *
+ * @param argc Standard main() style argc.
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped.
+ *
+ * @return A shell status integer (0 for success).
+ **/
+
+static int net_eventlog_export(struct net_context *c, int argc,
+ const char **argv)
+{
+ int ret = -1;
+ NTSTATUS status;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ uint32_t num_records = 0;
+ struct EVENTLOG_EVT_FILE evt;
+ ELOG_TDB *etdb = NULL;
+ uint32_t count = 1;
+ size_t endoffset = 0;
+
+ if (argc < 2 || c->display_usage) {
+ d_fprintf(stderr, "usage: net eventlog export <file> <eventlog>\n");
+ goto done;
+ }
+
+ etdb = elog_open_tdb(argv[1], false, true);
+ if (!etdb) {
+ d_fprintf(stderr, "can't open the eventlog TDB (%s)\n", argv[1]);
+ goto done;
+ }
+
+ ZERO_STRUCT(evt);
+
+ while (1) {
+
+ struct eventlog_Record_tdb *r;
+ struct EVENTLOGRECORD e;
+
+ r = evlog_pull_record_tdb(ctx, etdb->tdb, count);
+ if (!r) {
+ break;
+ }
+
+ status = evlog_tdb_entry_to_evt_entry(ctx, r, &e);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ endoffset += ndr_size_EVENTLOGRECORD(&e, NULL, 0);
+
+ ADD_TO_ARRAY(ctx, struct EVENTLOGRECORD, e, &evt.records, &num_records);
+ count++;
+ }
+
+ evt.hdr.StartOffset = 0x30;
+ evt.hdr.EndOffset = evt.hdr.StartOffset + endoffset;
+ evt.hdr.CurrentRecordNumber = count;
+ evt.hdr.OldestRecordNumber = 1;
+ evt.hdr.MaxSize = tdb_fetch_int32(etdb->tdb, EVT_MAXSIZE);
+ evt.hdr.Flags = 0;
+ evt.hdr.Retention = tdb_fetch_int32(etdb->tdb, EVT_RETENTION);
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(EVENTLOGHEADER, &evt.hdr);
+ }
+
+ evt.eof.BeginRecord = 0x30;
+ evt.eof.EndRecord = evt.hdr.StartOffset + endoffset;
+ evt.eof.CurrentRecordNumber = evt.hdr.CurrentRecordNumber;
+ evt.eof.OldestRecordNumber = evt.hdr.OldestRecordNumber;
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(EVENTLOGEOF, &evt.eof);
+ }
+
+ ndr_err = ndr_push_struct_blob(&blob, ctx, NULL, &evt,
+ (ndr_push_flags_fn_t)ndr_push_EVENTLOG_EVT_FILE);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ d_fprintf(stderr, "evt push failed: %s\n", ndr_errstr(ndr_err));
+ goto done;
+ }
+
+ if (!file_save(argv[0], blob.data, blob.length)) {
+ d_fprintf(stderr, "failed to save evt file: %s\n", argv[0]);
+ goto done;
+ }
+
+ ret = 0;
+ done:
+
+ elog_close_tdb(etdb, false);
+
+ TALLOC_FREE(ctx);
+ return ret;
+}
+
+/**
+ * 'net rpc eventlog' entrypoint.
+ * @param argc Standard main() style argc.
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped.
+ **/
+
+int net_eventlog(struct net_context *c, int argc, const char **argv)
+{
+ int ret = -1;
+
+ struct functable func[] = {
+ {
+ "dump",
+ net_eventlog_dump,
+ NET_TRANSPORT_LOCAL,
+ "Dump eventlog",
+ "net eventlog dump\n"
+ " Dump win32 *.evt eventlog file"
+ },
+ {
+ "import",
+ net_eventlog_import,
+ NET_TRANSPORT_LOCAL,
+ "Import eventlog",
+ "net eventlog import\n"
+ " Import win32 *.evt eventlog file"
+ },
+ {
+ "export",
+ net_eventlog_export,
+ NET_TRANSPORT_LOCAL,
+ "Export eventlog",
+ "net eventlog export\n"
+ " Export win32 *.evt eventlog file"
+ },
+
+
+ { NULL, NULL, 0, NULL, NULL }
+ };
+
+ ret = net_run_function(c, argc, argv, "net eventlog", func);
+
+ return ret;
+}
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index a65fbbb6eb..75ac032db9 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -427,6 +427,9 @@ int net_usershare(struct net_context *c, int argc, const char **argv);
int net_lua(struct net_context *c, int argc, const char **argv);
+/* The following definitions come from utils/net_eventlog.c */
+
+int net_eventlog(struct net_context *c, int argc, const char **argv);
/* The following definitions come from utils/net_util.c */
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 0f59f02746..c54d479413 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -181,8 +181,7 @@ int run_rpc_command(struct net_context *c,
}
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
- cli_get_pipe_name_from_iface(
- debug_ctx(), interface),
+ get_pipe_name_from_iface(interface),
nt_errstr(nt_status) ));
cli_shutdown(cli);
return -1;
@@ -797,7 +796,7 @@ static int rpc_user_info(struct net_context *c, int argc, const char **argv)
status = NetUserGetGroups(c->opt_host,
argv[0],
0,
- (uint8_t **)&u0,
+ (uint8_t **)(void *)&u0,
(uint32_t)-1,
&entries_read,
&total_entries);
@@ -1394,7 +1393,7 @@ static NTSTATUS rpc_group_delete_internals(struct net_context *c,
struct samr_RidTypeArray *rids = NULL;
/* char **names; */
int i;
- /* DOM_GID *user_gids; */
+ /* struct samr_RidWithAttribute *user_gids; */
struct samr_Ids group_rids, name_types;
struct lsa_String lsa_acct_name;
@@ -2997,7 +2996,7 @@ static int rpc_share_list(struct net_context *c, int argc, const char **argv)
status = NetShareEnum(c->opt_host,
level,
- (uint8_t **)&i1,
+ (uint8_t **)(void *)&i1,
(uint32_t)-1,
&entries_read,
&total_entries,
@@ -3022,7 +3021,7 @@ static int rpc_share_list(struct net_context *c, int argc, const char **argv)
static bool check_share_availability(struct cli_state *cli, const char *netname)
{
- if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
d_printf("skipping [%s]: not a file share.\n", netname);
return false;
}
@@ -4281,7 +4280,7 @@ static void show_userlist(struct rpc_pipe_client *pipe_hnd,
cnum = cli->cnum;
- if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
return;
}
@@ -4378,7 +4377,6 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
{
int ret;
bool r;
- ENUM_HND hnd;
uint32 i;
FILE *f;
@@ -4411,8 +4409,6 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
for (i=0; i<num_tokens; i++)
collect_alias_memberships(&tokens[i].token);
- init_enum_hnd(&hnd, 0);
-
share_list.num_shares = 0;
share_list.shares = NULL;
@@ -4776,7 +4772,7 @@ static int rpc_file_user(struct net_context *c, int argc, const char **argv)
NULL,
username,
3,
- (uint8_t **)&i3,
+ (uint8_t **)(void *)&i3,
preferred_len,
&entries_read,
&total_entries,
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 5651676693..0c363d373e 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -243,14 +243,17 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
CHECK_RPC_ERR(rpccli_samr_Connect2(pipe_hnd, mem_ctx,
pipe_hnd->desthost,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
+ SAMR_ACCESS_ENUM_DOMAINS
+ | SAMR_ACCESS_OPEN_DOMAIN,
&sam_pol),
"could not connect to SAM database");
CHECK_RPC_ERR(rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
&sam_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
+ SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
+ | SAMR_DOMAIN_ACCESS_CREATE_USER
+ | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
domain_sid,
&domain_pol),
"could not open domain");
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index f07b5011c8..c12778f8c7 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -76,8 +76,9 @@ static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
char **domains;
char **names;
- if (!cli_send_tconX(cli, "IPC$", "?????", "", 0)) {
- return cli_nt_error(cli);
+ status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
@@ -124,8 +125,9 @@ static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
DOM_SID *sids;
enum lsa_SidType *types;
- if (!cli_send_tconX(cli, "IPC$", "?????", "", 0)) {
- return cli_nt_error(cli);
+ status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index 99821ae501..481ac1b9ad 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -28,6 +28,11 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
+/* idmap version determines auto-conversion - this is the database
+ structure version specifier. */
+
+#define IDMAP_VERSION 2
+
/* High water mark keys */
#define HWM_GROUP "GROUP HWM"
#define HWM_USER "USER HWM"
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index fad27ea224..5720bfc517 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -173,36 +173,161 @@ static void terminate(bool is_parent)
exit(0);
}
-static SIG_ATOMIC_T do_sigterm = 0;
+static void winbindd_sig_term_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ bool *is_parent = talloc_get_type_abort(private_data, bool);
+
+ DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
+ signum, (int)*is_parent));
+ terminate(*is_parent);
+}
-static void termination_handler(int signum)
+bool winbindd_setup_sig_term_handler(bool parent)
{
- do_sigterm = 1;
- sys_select_signal(signum);
+ struct tevent_signal *se;
+ bool *is_parent;
+
+ is_parent = talloc(winbind_event_context(), bool);
+ if (!is_parent) {
+ return false;
+ }
+
+ *is_parent = parent;
+
+ se = tevent_add_signal(winbind_event_context(),
+ is_parent,
+ SIGTERM, 0,
+ winbindd_sig_term_handler,
+ is_parent);
+ if (!se) {
+ DEBUG(0,("failed to setup SIGTERM handler"));
+ talloc_free(is_parent);
+ return false;
+ }
+
+ se = tevent_add_signal(winbind_event_context(),
+ is_parent,
+ SIGINT, 0,
+ winbindd_sig_term_handler,
+ is_parent);
+ if (!se) {
+ DEBUG(0,("failed to setup SIGINT handler"));
+ talloc_free(is_parent);
+ return false;
+ }
+
+ se = tevent_add_signal(winbind_event_context(),
+ is_parent,
+ SIGQUIT, 0,
+ winbindd_sig_term_handler,
+ is_parent);
+ if (!se) {
+ DEBUG(0,("failed to setup SIGINT handler"));
+ talloc_free(is_parent);
+ return false;
+ }
+
+ return true;
}
-static SIG_ATOMIC_T do_sigusr2 = 0;
+static void winbindd_sig_hup_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ const char *file = (const char *)private_data;
+
+ DEBUG(1,("Reloading services after SIGHUP\n"));
+ flush_caches();
+ reload_services_file(file);
+}
-static void sigusr2_handler(int signum)
+bool winbindd_setup_sig_hup_handler(const char *lfile)
{
- do_sigusr2 = 1;
- sys_select_signal(SIGUSR2);
+ struct tevent_signal *se;
+ char *file = NULL;
+
+ if (lfile) {
+ file = talloc_strdup(winbind_event_context(),
+ lfile);
+ if (!file) {
+ return false;
+ }
+ }
+
+ se = tevent_add_signal(winbind_event_context(),
+ winbind_event_context(),
+ SIGHUP, 0,
+ winbindd_sig_hup_handler,
+ file);
+ if (!se) {
+ return false;
+ }
+
+ return true;
}
-static SIG_ATOMIC_T do_sighup = 0;
+static void winbindd_sig_chld_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ pid_t pid;
+
+ while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
+ winbind_child_died(pid);
+ }
+}
-static void sighup_handler(int signum)
+static bool winbindd_setup_sig_chld_handler(void)
{
- do_sighup = 1;
- sys_select_signal(SIGHUP);
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(winbind_event_context(),
+ winbind_event_context(),
+ SIGCHLD, 0,
+ winbindd_sig_chld_handler,
+ NULL);
+ if (!se) {
+ return false;
+ }
+
+ return true;
}
-static SIG_ATOMIC_T do_sigchld = 0;
+static void winbindd_sig_usr2_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum,
+ int count,
+ void *siginfo,
+ void *private_data)
+{
+ print_winbindd_status();
+}
-static void sigchld_handler(int signum)
+static bool winbindd_setup_sig_usr2_handler(void)
{
- do_sigchld = 1;
- sys_select_signal(SIGCHLD);
+ struct tevent_signal *se;
+
+ se = tevent_add_signal(winbind_event_context(),
+ winbind_event_context(),
+ SIGCHLD, 0,
+ winbindd_sig_usr2_handler,
+ NULL);
+ if (!se) {
+ return false;
+ }
+
+ return true;
}
/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
@@ -224,7 +349,9 @@ static void msg_shutdown(struct messaging_context *msg,
struct server_id server_id,
DATA_BLOB *data)
{
- do_sigterm = 1;
+ /* only the parent waits for this message */
+ DEBUG(0,("Got shutdown message\n"));
+ terminate(true);
}
@@ -797,27 +924,6 @@ static bool remove_idle_client(void)
return False;
}
-/* check if HUP has been received and reload files */
-void winbind_check_sighup(const char *lfile)
-{
- if (do_sighup) {
-
- DEBUG(3, ("got SIGHUP\n"));
-
- flush_caches();
- reload_services_file(lfile);
-
- do_sighup = 0;
- }
-}
-
-/* check if TERM has been received */
-void winbind_check_sigterm(bool is_parent)
-{
- if (do_sigterm)
- terminate(is_parent);
-}
-
/* Process incoming clients on listen_sock. We use a tricky non-blocking,
non-forking, non-threaded model which allows us to handle many
simultaneous connections while remaining impervious to many denial of
@@ -979,26 +1085,6 @@ static void process_loop(void)
#if 0
winbindd_check_cache_size(time(NULL));
#endif
-
- /* Check signal handling things */
-
- winbind_check_sigterm(true);
- winbind_check_sighup(NULL);
-
- if (do_sigusr2) {
- print_winbindd_status();
- do_sigusr2 = 0;
- }
-
- if (do_sigchld) {
- pid_t pid;
-
- do_sigchld = 0;
-
- while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
- winbind_child_died(pid);
- }
- }
}
/* Main function */
@@ -1168,18 +1254,6 @@ int main(int argc, char **argv, char **envp)
BlockSignals(False, SIGHUP);
BlockSignals(False, SIGCHLD);
- /* Setup signal handlers */
-
- CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
- CatchSignal(SIGQUIT, termination_handler);
- CatchSignal(SIGTERM, termination_handler);
- CatchSignal(SIGCHLD, sigchld_handler);
-
- CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
-
- CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
- CatchSignal(SIGHUP, sighup_handler);
-
if (!interactive)
become_daemon(Fork, no_process_group);
@@ -1207,6 +1281,19 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
+ /* Setup signal handlers */
+
+ if (!winbindd_setup_sig_term_handler(true))
+ exit(1);
+ if (!winbindd_setup_sig_hup_handler(NULL))
+ exit(1);
+ if (!winbindd_setup_sig_chld_handler())
+ exit(1);
+ if (!winbindd_setup_sig_usr2_handler())
+ exit(1);
+
+ CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
+
/*
* Ensure all cache and idmap caches are consistent
* and initialized before we startup.
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index a0df81eb6e..8326aba40a 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -25,6 +25,7 @@
#include "includes.h"
#include "winbindd.h"
+#include "tdb_validate.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index ab1218c560..35768fe7f2 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -961,15 +961,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
winbindd_set_locator_kdc_envs(domain);
- if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
-
- result = cli_nt_error(*cli);
+ result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
+ if (!NT_STATUS_IS_OK(result)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
-
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
-
goto done;
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index c320e96746..d40bab94ef 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1160,6 +1160,12 @@ bool winbindd_reinit_after_fork(const char *logfilename)
reopen_logs();
}
+ if (!winbindd_setup_sig_term_handler(false))
+ return false;
+ if (!winbindd_setup_sig_hup_handler(override_logfile ? NULL :
+ logfilename))
+ return false;
+
/* Don't handle the same messages as our parent. */
messaging_deregister(winbind_messaging_context(),
MSG_SMB_CONF_UPDATED, NULL);
@@ -1354,7 +1360,7 @@ static bool fork_domain_child(struct winbindd_child *child)
}
if (child->domain && child->domain->primary &&
- !lp_use_kerberos_keytab() &&
+ !USE_KERBEROS_KEYTAB &&
lp_server_role() == ROLE_DOMAIN_MEMBER) {
struct timeval next_change;
@@ -1379,11 +1385,6 @@ static bool fork_domain_child(struct winbindd_child *child)
struct timeval now;
TALLOC_CTX *frame = talloc_stackframe();
- /* check for signals */
- winbind_check_sigterm(false);
- winbind_check_sighup(override_logfile ? NULL :
- child->logfilename);
-
if (run_events(winbind_event_context(), 0, NULL, NULL)) {
TALLOC_FREE(frame);
continue;
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index bc532bbce7..9d9b264124 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -1353,8 +1353,10 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
sid_copy(&group_sid, &domain->sid);
sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(domain->name, &group_sid,
- &group_gid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(domain->have_idmap_config
+ ? domain->name : "",
+ &group_sid, &group_gid)))
+ {
union unid_t id;
enum lsa_SidType type;
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 594f8be942..977ee9c6b1 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -63,8 +63,8 @@ void setup_async_write(struct winbindd_fd_event *event, void *data, size_t lengt
void *private_data);
void request_error(struct winbindd_cli_state *state);
void request_ok(struct winbindd_cli_state *state);
-void winbind_check_sighup(const char *lfile);
-void winbind_check_sigterm(bool in_parent);
+bool winbindd_setup_sig_term_handler(bool parent);
+bool winbindd_setup_sig_hup_handler(const char *lfile);
int main(int argc, char **argv, char **envp);
/* The following definitions come from winbindd/winbindd_reqtrans.c */
@@ -498,7 +498,6 @@ void winbindd_lookupname(struct winbindd_cli_state *state);
void winbindd_lookuprids(struct winbindd_cli_state *state);
void winbindd_sid_to_uid(struct winbindd_cli_state *state);
void winbindd_sid_to_gid(struct winbindd_cli_state *state);
-void winbindd_sids_to_unixids(struct winbindd_cli_state *state);
void winbindd_set_mapping(struct winbindd_cli_state *state);
void winbindd_remove_mapping(struct winbindd_cli_state *state);
void winbindd_set_hwm(struct winbindd_cli_state *state);
diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c
index 5356e16a74..62fd4d7f07 100644
--- a/source3/winbindd/winbindd_user.c
+++ b/source3/winbindd/winbindd_user.c
@@ -80,9 +80,17 @@ static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name
if (!pw || !dom_name || !user_name)
return False;
+ domain = find_domain_from_name_noinit(dom_name);
+ if (domain == NULL) {
+ DEBUG(5,("winbindd_fill_pwent: Failed to find domain for %s. "
+ "Disabling name alias support\n", dom_name));
+ nt_status = NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
/* Resolve the uid number */
- if (!NT_STATUS_IS_OK(idmap_sid_to_uid(dom_name, user_sid,
+ if (!NT_STATUS_IS_OK(idmap_sid_to_uid(domain->have_idmap_config ?
+ dom_name : "", user_sid,
&pw->pw_uid))) {
DEBUG(1, ("error getting user id for sid %s\n",
sid_string_dbg(user_sid)));
@@ -91,26 +99,18 @@ static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name
/* Resolve the gid number */
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(dom_name, group_sid,
+ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(domain->have_idmap_config ?
+ dom_name : "", group_sid,
&pw->pw_gid))) {
DEBUG(1, ("error getting group id for sid %s\n",
sid_string_dbg(group_sid)));
return False;
}
- strlower_m(user_name);
-
/* Username */
- domain = find_domain_from_name_noinit(dom_name);
- if (domain) {
- nt_status = normalize_name_map(ctx, domain, user_name,
- &mapped_name);
- } else {
- DEBUG(5,("winbindd_fill_pwent: Failed to find domain for %s. "
- "Disabling name alias support\n", dom_name));
- nt_status = NT_STATUS_NO_SUCH_DOMAIN;
- }
+ strlower_m(user_name);
+ nt_status = normalize_name_map(ctx, domain, user_name, &mapped_name);
/* Basic removal of whitespace */
if (NT_STATUS_IS_OK(nt_status)) {