summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in57
-rw-r--r--source3/auth/auth.c76
-rw-r--r--source3/auth/auth_compat.c5
-rw-r--r--source3/auth/auth_ntlmssp.c6
-rw-r--r--source3/auth/auth_util.c40
-rw-r--r--source3/auth/auth_wbc.c150
-rw-r--r--source3/client/client.c6
-rw-r--r--source3/client/mount.cifs.c40
-rw-r--r--source3/configure.in88
-rw-r--r--source3/include/auth.h3
-rw-r--r--source3/include/dbwrap.h4
-rw-r--r--source3/include/includes.h10
-rw-r--r--source3/include/libsmbclient.h20
-rw-r--r--source3/include/locking.h1
-rw-r--r--source3/include/nt_printing.h2
-rw-r--r--source3/include/ntlmssp.h3
-rw-r--r--source3/include/proto.h235
-rw-r--r--source3/include/reg_db.h1
-rw-r--r--source3/include/reg_objects.h16
-rw-r--r--source3/include/regfio.h2
-rw-r--r--source3/include/rpc_secdes.h3
-rw-r--r--source3/include/rpc_spoolss.h388
-rw-r--r--source3/include/smb.h56
-rw-r--r--source3/include/smb_ldap.h255
-rw-r--r--source3/include/smb_share_modes.h11
-rw-r--r--source3/include/smbprofile.h28
-rw-r--r--source3/include/vfs.h3
-rw-r--r--source3/include/vfs_macros.h6
-rw-r--r--source3/lib/dbwrap.c26
-rw-r--r--source3/lib/dbwrap_tdb.c12
-rw-r--r--source3/lib/display_sec.c8
-rw-r--r--source3/lib/events.c2
-rw-r--r--source3/lib/fault.c174
-rw-r--r--source3/lib/file_id.c47
-rw-r--r--source3/lib/ldap_debug_handler.c4
-rw-r--r--source3/lib/secdesc.c63
-rw-r--r--source3/lib/smbconf/smbconf_reg.c177
-rw-r--r--source3/lib/smbldap.c2
-rw-r--r--source3/lib/system.c32
-rw-r--r--source3/lib/tdb_validate.c5
-rw-r--r--source3/lib/util.c173
-rw-r--r--source3/lib/util_sock.c104
-rw-r--r--source3/lib/util_str.c112
-rw-r--r--source3/lib/wb_reqtrans.c401
-rw-r--r--source3/lib/wbclient.c62
-rw-r--r--source3/libaddns/dns.h6
-rw-r--r--source3/libads/disp_sec.c8
-rw-r--r--source3/libgpo/gpo_reg.c8
-rw-r--r--source3/libgpo/gpo_sec.c4
-rw-r--r--source3/libnet/libnet_join.c6
-rw-r--r--source3/librpc/gen_ndr/ndr_notify.c8
-rw-r--r--source3/librpc/gen_ndr/notify.h2
-rw-r--r--source3/librpc/idl/notify.idl2
-rw-r--r--source3/librpc/ndr/util.c39
-rw-r--r--source3/libsmb/cliconnect.c25
-rw-r--r--source3/libsmb/libsmb_context.c44
-rw-r--r--source3/libsmb/libsmb_dir.c29
-rw-r--r--source3/libsmb/libsmb_file.c2
-rw-r--r--source3/libsmb/libsmb_path.c21
-rw-r--r--source3/libsmb/libsmb_server.c19
-rw-r--r--source3/libsmb/libsmb_stat.c2
-rw-r--r--source3/libsmb/nmblib.c15
-rw-r--r--source3/libsmb/ntlmssp.c12
-rw-r--r--source3/libsmb/smb_share_modes.c39
-rw-r--r--source3/locking/brlock.c8
-rw-r--r--source3/locking/locking.c6
-rw-r--r--source3/modules/nfs4_acls.c90
-rw-r--r--source3/modules/nfs4_acls.h10
-rw-r--r--source3/modules/onefs.h53
-rw-r--r--source3/modules/onefs_acl.c18
-rw-r--r--source3/modules/onefs_cbrl.c26
-rw-r--r--source3/modules/onefs_notify.c680
-rw-r--r--source3/modules/onefs_shadow_copy.c782
-rw-r--r--source3/modules/onefs_shadow_copy.h32
-rw-r--r--source3/modules/onefs_streams.c18
-rw-r--r--source3/modules/onefs_system.c376
-rw-r--r--source3/modules/vfs_acl_tdb.c95
-rw-r--r--source3/modules/vfs_acl_xattr.c12
-rw-r--r--source3/modules/vfs_default.c15
-rw-r--r--source3/modules/vfs_extd_audit.c8
-rw-r--r--source3/modules/vfs_fileid.c6
-rw-r--r--source3/modules/vfs_full_audit.c6
-rw-r--r--source3/modules/vfs_onefs.c179
-rw-r--r--source3/modules/vfs_onefs_shadow_copy.c717
-rw-r--r--source3/modules/vfs_solarisacl.c9
-rw-r--r--source3/modules/vfs_streams_depot.c17
-rw-r--r--source3/modules/vfs_streams_xattr.c15
-rw-r--r--source3/modules/vfs_xattr_tdb.c23
-rw-r--r--source3/nmbd/nmbd.c14
-rw-r--r--source3/param/loadparm.c48
-rw-r--r--source3/passdb/pdb_interface.c2
-rw-r--r--source3/passdb/pdb_ldap.c16
-rw-r--r--source3/passdb/pdb_wbc_sam.c450
-rw-r--r--source3/printing/notify.c4
-rw-r--r--source3/printing/nt_printing.c98
-rw-r--r--source3/printing/printfsp.c3
-rw-r--r--source3/printing/printing.c6
-rw-r--r--source3/printing/tests/vlp.c2
-rw-r--r--source3/profile/profile.c7
-rw-r--r--source3/registry/reg_api.c183
-rw-r--r--source3/registry/reg_backend_current_version.c2
-rw-r--r--source3/registry/reg_backend_db.c655
-rw-r--r--source3/registry/reg_backend_hkpt_params.c2
-rw-r--r--source3/registry/reg_backend_netlogon_params.c2
-rw-r--r--source3/registry/reg_backend_perflib.c2
-rw-r--r--source3/registry/reg_backend_printing.c20
-rw-r--r--source3/registry/reg_backend_prod_options.c2
-rw-r--r--source3/registry/reg_backend_shares.c4
-rw-r--r--source3/registry/reg_backend_smbconf.c16
-rw-r--r--source3/registry/reg_backend_tcpip_params.c2
-rw-r--r--source3/registry/reg_dispatcher.c47
-rw-r--r--source3/registry/reg_eventlog.c18
-rw-r--r--source3/registry/reg_objects.c175
-rw-r--r--source3/registry/regfio.c2
-rw-r--r--source3/rpc_client/cli_spoolss.c562
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c119
-rw-r--r--source3/rpc_client/rpc_transport_sock.c110
-rw-r--r--source3/rpc_parse/parse_sec.c4
-rw-r--r--source3/rpc_parse/parse_spoolss.c1999
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c2
-rw-r--r--source3/rpc_server/srv_netlog_nt.c4
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c38
-rw-r--r--source3/rpc_server/srv_spoolss.c47
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c1216
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c6
-rw-r--r--source3/rpcclient/cmd_eventlog.c4
-rw-r--r--source3/rpcclient/cmd_netlogon.c44
-rw-r--r--source3/rpcclient/cmd_samr.c32
-rw-r--r--source3/rpcclient/cmd_spoolss.c736
-rw-r--r--source3/services/services_db.c18
-rw-r--r--source3/smbd/close.c22
-rw-r--r--source3/smbd/fileio.c3
-rw-r--r--source3/smbd/files.c43
-rw-r--r--source3/smbd/globals.c3
-rw-r--r--source3/smbd/negprot.c5
-rw-r--r--source3/smbd/notify.c17
-rw-r--r--source3/smbd/nttrans.c2
-rw-r--r--source3/smbd/open.c37
-rw-r--r--source3/smbd/oplock.c28
-rw-r--r--source3/smbd/oplock_irix.c18
-rw-r--r--source3/smbd/oplock_onefs.c5
-rw-r--r--source3/smbd/posix_acls.c52
-rw-r--r--source3/smbd/reply.c36
-rw-r--r--source3/smbd/server.c12
-rw-r--r--source3/smbd/sesssetup.c11
-rw-r--r--source3/smbd/trans2.c14
-rw-r--r--source3/smbd/vfs.c15
-rw-r--r--source3/utils/net_conf.c33
-rw-r--r--source3/utils/net_rpc_printer.c439
-rw-r--r--source3/utils/net_rpc_registry.c11
-rw-r--r--source3/utils/profiles.c38
-rw-r--r--source3/utils/sharesec.c6
-rw-r--r--source3/utils/smbfilter.c11
-rw-r--r--source3/utils/smbget.c9
-rw-r--r--source3/winbindd/idmap_ldap.c8
-rw-r--r--source3/winbindd/winbindd.c2
-rw-r--r--source3/winbindd/winbindd_cache.c18
-rw-r--r--source3/winbindd/winbindd_dual.c2
158 files changed, 7759 insertions, 6275 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 9bac7191fa..d957d70edb 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -197,7 +197,7 @@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ bin/sharesec@EXEEXT@ \
bin/smbcquotas@EXEEXT@ bin/eventlogadm@EXEEXT@
BIN_PROGS4 = bin/ldbedit@EXEEXT@ bin/ldbsearch@EXEEXT@ bin/ldbadd@EXEEXT@ \
- bin/ldbdel@EXEEXT@ bin/ldbmodify@EXEEXT@
+ bin/ldbdel@EXEEXT@ bin/ldbmodify@EXEEXT@ bin/ldbrename@EXEEXT@
TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \
bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \
@@ -338,7 +338,9 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
../lib/util/util_file.o ../lib/util/data_blob.o \
../lib/util/util.o ../lib/util/fsusage.o \
../lib/util/params.o ../lib/util/talloc_stack.o \
- ../lib/util/genrand.o ../lib/util/util_net.o
+ ../lib/util/genrand.o ../lib/util/util_net.o \
+ ../lib/util/become_daemon.o ../lib/util/system.o \
+ ../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o
CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \
../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \
@@ -443,7 +445,10 @@ LIBSMB_OBJ0 = \
LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \
$(LIBSMB_ERR_OBJ)
-CLDAP_OBJ = libads/cldap.o
+LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o
+LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o
+
+CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ)
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \
@@ -464,7 +469,7 @@ RPC_CLIENT_OBJ1 = rpc_client/cli_netlogon.o
LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
$(RPC_CLIENT_OBJ1) rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \
- rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
+ rpc_client/cli_spoolss.o \
rpc_client/init_spoolss.o \
rpc_client/init_samr.o \
librpc/rpc/dcerpc.o \
@@ -621,7 +626,8 @@ PROFILES_OBJ = utils/profiles.o \
$(LIB_OBJ) $(LIB_DUMMY_OBJ) \
$(POPT_LIB_OBJ)
-OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o smbd/oplock_onefs.o
+OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \
+ smbd/oplock_onefs.o
NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
@@ -666,7 +672,8 @@ VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o
VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \
modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.c \
- modules/onefs_cbrl.o
+ modules/onefs_cbrl.o modules/onefs_notify.o
+VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o
PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
@@ -682,6 +689,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o
AUTH_SERVER_OBJ = auth/auth_server.o
AUTH_UNIX_OBJ = auth/auth_unix.o
AUTH_WINBIND_OBJ = auth/auth_winbind.o
+AUTH_WBC_OBJ = auth/auth_wbc.o
AUTH_SCRIPT_OBJ = auth/auth_script.o
AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o
@@ -752,7 +760,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o smbd/connection.o
-NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -931,7 +939,7 @@ NET_OBJ = $(NET_OBJ1) \
$(PRIVILEGES_BASIC_OBJ) @LIBLUA_STATIC@ \
$(LIB_EVENTLOG_OBJ)
-CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
+CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -948,24 +956,24 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
torture/denytest.o torture/mangle_test.o
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
lib/wb_reqtrans.o lib/wbclient.o \
@LIBWBCLIENT_STATIC@ \
$(LIBNDR_GEN_OBJ0)
-MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
-MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
-NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -980,7 +988,7 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ
LOG2PCAP_OBJ = utils/log2pcaphex.o
-LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
+LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -1020,7 +1028,7 @@ REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \
DEBUG2HTML_OBJ = utils/debug2html.o utils/debugparse.o
-SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
+SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -1124,6 +1132,7 @@ LDBSEARCH_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbsearch.o
LDBADD_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbadd.o
LDBDEL_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbdel.o
LDBMODIFY_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbmodify.o
+LDBRENAME_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbrename.o
WINBIND_KRB5_LOCATOR_OBJ1 = ../nsswitch/winbind_krb5_locator.o
WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(LIBREPLACE_OBJ)
@@ -1615,6 +1624,12 @@ bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIB
$(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
$(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(LDBRENAME_OBJ) $(DYNEXP) $(LDFLAGS) \
+ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \
+ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS)
+
#####################################################################
#
@@ -2340,6 +2355,10 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(AUTH_WINBIND_OBJ)
+bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(AUTH_WBC_OBJ)
+
bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(AUTH_UNIX_OBJ)
@@ -2356,6 +2375,10 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o
@echo "Building plugin $@"
@$(SHLD_MODULE) passdb/pdb_tdb.o
+bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) passdb/pdb_wbc_sam.o
+
bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o
@echo "Building plugin $@"
@$(SHLD_MODULE) passdb/pdb_smbpasswd.o
@@ -2559,6 +2582,10 @@ bin/onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ONEFS_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_ONEFS_OBJ) @ONEFS_LIBS@
+bin/onefs_shadow_copy.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ONEFS_SHADOW_COPY_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_ONEFS_SHADOW_COPY_OBJ)
+
bin/pc_onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(PERFCOUNT_ONEFS_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(PERFCOUNT_ONEFS_OBJ)
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 505098c76a..fd4c503752 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -2,17 +2,17 @@
Unix SMB/CIFS implementation.
Password and authentication handling
Copyright (C) Andrew Bartlett 2001-2002
-
+
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/>.
*/
@@ -49,7 +49,7 @@ NTSTATUS smb_register_auth(int version, const char *name, auth_init_function ini
DEBUG(0,("There already is an auth method registered with the name %s!\n", name));
return NT_STATUS_OBJECT_NAME_COLLISION;
}
-
+
entry = SMB_XMALLOC_P(struct auth_init_function_entry);
entry->name = smb_xstrdup(name);
entry->init = init;
@@ -67,7 +67,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
if (strcmp(entry->name, name)==0) return entry;
entry = entry->next;
}
-
+
return NULL;
}
@@ -76,7 +76,8 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
Returns a const char of length 8 bytes.
****************************************************************************/
-static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
+static void get_ntlm_challenge(struct auth_context *auth_context,
+ uint8_t chal[8])
{
DATA_BLOB challenge = data_blob_null;
const char *challenge_set_by = NULL;
@@ -86,7 +87,8 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
if (auth_context->challenge.length) {
DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n",
auth_context->challenge_set_by));
- return auth_context->challenge.data;
+ memcpy(chal, auth_context->challenge.data, 8);
+ return;
}
auth_context->challenge_may_be_modified = False;
@@ -108,7 +110,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
if (!mem_ctx) {
smb_panic("talloc_init() failed!");
}
-
+
challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
if (!challenge.length) {
DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
@@ -121,27 +123,27 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
}
talloc_destroy(mem_ctx);
}
-
+
if (!challenge_set_by) {
- uchar chal[8];
-
- generate_random_buffer(chal, sizeof(chal));
+ uchar tmp[8];
+
+ generate_random_buffer(tmp, sizeof(tmp));
auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
- chal, sizeof(chal));
-
+ tmp, sizeof(tmp));
+
challenge_set_by = "random";
auth_context->challenge_may_be_modified = True;
}
-
+
DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
DEBUG(5, ("challenge is: \n"));
dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
-
+
SMB_ASSERT(auth_context->challenge.length == 8);
auth_context->challenge_set_by=challenge_set_by;
- return auth_context->challenge.data;
+ memcpy(chal, auth_context->challenge.data, 8);
}
@@ -249,7 +251,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
NTSTATUS result;
-
+
mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
user_info->domain, user_info->smb_name);
@@ -281,7 +283,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
}
/* successful authentication */
-
+
if (NT_STATUS_IS_OK(nt_status)) {
unix_username = (*server_info)->unix_name;
if (!(*server_info)->guest) {
@@ -289,7 +291,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
become_root();
nt_status = smb_pam_accountcheck(unix_username);
unbecome_root();
-
+
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n",
unix_username));
@@ -298,7 +300,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
unix_username, nt_errstr(nt_status)));
}
}
-
+
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG((*server_info)->guest ? 5 : 2,
("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
@@ -307,17 +309,17 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
user_info->internal_username,
unix_username));
}
-
+
return nt_status;
}
-
+
/* failed authentication; check for guest lapping */
-
+
DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n",
user_info->smb_name, user_info->internal_username,
nt_errstr(nt_status)));
ZERO_STRUCTP(server_info);
-
+
return nt_status;
}
@@ -349,7 +351,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context)
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_init("authentication context");
-
+
*auth_context = TALLOC_P(mem_ctx, struct auth_context);
if (!*auth_context) {
DEBUG(0,("make_auth_context: talloc failed!\n"));
@@ -362,7 +364,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context)
(*auth_context)->check_ntlm_password = check_ntlm_password;
(*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
(*auth_context)->free = free_auth_context;
-
+
return NT_STATUS_OK;
}
@@ -382,21 +384,21 @@ bool load_auth_module(struct auth_context *auth_context,
static_init_auth;
initialised_static_modules = True;
}
-
+
DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n",
module));
-
+
p = strchr(module_name, ':');
if (p) {
*p = 0;
module_params = p+1;
trim_char(module_params, ' ', ' ');
}
-
+
trim_char(module_name, ' ', ' ');
-
+
entry = auth_find_backend_entry(module_name);
-
+
if (entry == NULL) {
if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) {
entry = auth_find_backend_entry(module_name);
@@ -434,7 +436,7 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
DEBUG(2,("make_auth_context_text_list: No auth method list!?\n"));
return NT_STATUS_UNSUCCESSFUL;
}
-
+
if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
return nt_status;
@@ -443,9 +445,9 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
DLIST_ADD_END(list, t, auth_methods *);
}
}
-
+
(*auth_context)->auth_method_list = list;
-
+
return nt_status;
}
@@ -523,7 +525,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
} else {
DEBUG(5,("Using specified auth order\n"));
}
-
+
nt_status = make_auth_context_text_list(auth_context,
auth_method_list);
@@ -541,7 +543,7 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
return nt_status;
}
-
+
(*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
(*auth_context)->challenge_set_by = "fixed";
return nt_status;
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c
index 00d9dea816..925c0d4f81 100644
--- a/source3/auth/auth_compat.c
+++ b/source3/auth/auth_compat.c
@@ -39,13 +39,14 @@ NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_pass
{
struct auth_context *plaintext_auth_context = NULL;
auth_usersupplied_info *user_info = NULL;
- const uint8 *chal;
+ uint8_t chal[8];
NTSTATUS nt_status;
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
return nt_status;
}
- chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
+ plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context,
+ chal);
if (!make_user_info_for_reply(&user_info,
smb_name, lp_workgroup(), chal,
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index 0d46b14f97..034d354a33 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -27,11 +27,13 @@
* @return an 8 byte random challenge
*/
-static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
+static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
+ uint8_t chal[8])
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
(AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
- return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context);
+ auth_ntlmssp_state->auth_context->get_ntlm_challenge(
+ auth_ntlmssp_state->auth_context, chal);
}
/**
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 0dab05b97c..c39aa8501d 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -710,8 +710,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
NTSTATUS status;
size_t i;
struct dom_sid tmp_sid;
- const char *name_to_use;
- bool force_nss;
/*
* If winbind is not around, we can not make much use of the SIDs the
@@ -719,22 +717,11 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
* mapped to some local unix user.
*/
- DEBUG(10, ("creating token for %s (SAM: %s)\n", server_info->unix_name,
- server_info->sam_account->username));
-
- force_nss = lp_force_username_map() && !server_info->nss_token;
if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
- server_info->nss_token || force_nss) {
- if (force_nss)
- name_to_use =
- pdb_get_username(server_info->sam_account);
- else
- name_to_use = server_info->unix_name;
-
+ (server_info->nss_token)) {
status = create_token_from_username(server_info,
- name_to_use,
+ server_info->unix_name,
server_info->guest,
- force_nss,
&server_info->utok.uid,
&server_info->utok.gid,
&server_info->unix_name,
@@ -819,7 +806,7 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
}
/*
- * Create an artificial NT token given just a username. (Initially indended
+ * Create an artificial NT token given just a username. (Initially intended
* for force user)
*
* We go through lookup_name() to avoid problems we had with 'winbind use
@@ -839,7 +826,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
bool is_guest,
- bool force_nss,
uid_t *uid, gid_t *gid,
char **found_username,
struct nt_user_token **token)
@@ -855,9 +841,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
size_t num_gids;
size_t i;
- DEBUG(10, ("creating token for %s,%s guest,%s forcing NSS lookup\n",
- username, is_guest ? "" : " not", force_nss ? "" : " not"));
-
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
@@ -876,13 +859,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
goto done;
}
- if (!sid_to_uid(&user_sid, uid)) {
- DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
- username, sid_string_dbg(&user_sid)));
- goto done;
- }
-
- if (sid_check_is_in_our_domain(&user_sid) && !force_nss) {
+ if (sid_check_is_in_our_domain(&user_sid)) {
bool ret;
/* This is a passdb user, so ask passdb */
@@ -924,7 +901,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
*found_username = talloc_strdup(mem_ctx,
pdb_get_username(sam_acct));
- } else if (force_nss || sid_check_is_in_unix_users(&user_sid)) {
+ } else if (sid_check_is_in_unix_users(&user_sid)) {
/* This is a unix user not in passdb. We need to ask nss
* directly, without consulting passdb */
@@ -939,6 +916,12 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
unix_user:
+ if (!sid_to_uid(&user_sid, uid)) {
+ DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
+ username, sid_string_dbg(&user_sid)));
+ goto done;
+ }
+
uid_to_unix_users_sid(*uid, &user_sid);
pass = getpwuid_alloc(tmp_ctx, *uid);
@@ -1080,7 +1063,6 @@ bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
}
status = create_token_from_username(mem_ctx, username, False,
- lp_force_username_map(),
&uid, &gid, &found_username,
&token);
diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c
new file mode 100644
index 0000000000..580c8b550d
--- /dev/null
+++ b/source3/auth/auth_wbc.c
@@ -0,0 +1,150 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client authentication mechanism designed to defer all
+ authentication to the winbind daemon.
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Andrew Bartlett 2001 - 2002
+ Copyright (C) Dan Sledz 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/>.
+*/
+
+/* This auth module is very similar to auth_winbind with 3 distinct
+ * differences.
+ *
+ * 1) Does not fallback to another auth module if winbindd is unavailable
+ * 2) Does not validate the domain of the user
+ * 3) Handles unencrypted passwords
+ *
+ * The purpose of this module is to defer all authentication decisions (ie:
+ * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc
+ * compatible daemon. This centeralizes all authentication decisions to a
+ * single provider.
+ *
+ * This auth backend is most useful when used in conjunction with pdb_wbc_sam.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
+/* Authenticate a user with a challenge/response */
+
+static NTSTATUS check_wbc_security(const struct auth_context *auth_context,
+ void *my_private_data,
+ TALLOC_CTX *mem_ctx,
+ const auth_usersupplied_info *user_info,
+ auth_serversupplied_info **server_info)
+{
+ NTSTATUS nt_status;
+ wbcErr wbc_status;
+ struct wbcAuthUserParams params;
+ struct wbcAuthUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *err = NULL;
+
+ if (!user_info || !auth_context || !server_info) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ /* Send off request */
+
+ params.account_name = user_info->smb_name;
+ params.domain_name = user_info->domain;
+ params.workstation_name = user_info->wksta_name;
+
+ params.flags = 0;
+ params.parameter_control= user_info->logon_parameters;
+
+ /* Handle plaintext */
+ if (!user_info->encrypted) {
+ DEBUG(3,("Checking plaintext password for %s.\n",
+ user_info->internal_username));
+ params.level = WBC_AUTH_USER_LEVEL_PLAIN;
+
+ params.password.plaintext = (char *)user_info->plaintext_password.data;
+ } else {
+ DEBUG(3,("Checking encrypted password for %s.\n",
+ user_info->internal_username));
+ params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
+
+ memcpy(params.password.response.challenge,
+ auth_context->challenge.data,
+ sizeof(params.password.response.challenge));
+
+ params.password.response.nt_length = user_info->nt_resp.length;
+ params.password.response.nt_data = user_info->nt_resp.data;
+ params.password.response.lm_length = user_info->lm_resp.length;
+ params.password.response.lm_data = user_info->lm_resp.data;
+
+ }
+
+ /* we are contacting the privileged pipe */
+ become_root();
+ wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
+ unbecome_root();
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n",
+ wbc_status, wbcErrorString(wbc_status)));
+ }
+
+ if (wbc_status == WBC_ERR_NO_MEMORY) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (wbc_status == WBC_ERR_AUTH_ERROR) {
+ nt_status = NT_STATUS(err->nt_status);
+ wbcFreeMemory(err);
+ return nt_status;
+ }
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return NT_STATUS_LOGON_FAILURE;
+ }
+
+ DEBUG(10,("wbcAuthenticateUserEx succeeded\n"));
+
+ nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
+ user_info->smb_name,
+ user_info->domain,
+ info, server_info);
+ wbcFreeMemory(info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ (*server_info)->nss_token |= user_info->was_mapped;
+
+ return nt_status;
+}
+
+/* module initialisation */
+static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_context, auth_method)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ (*auth_method)->name = "wbc";
+ (*auth_method)->auth = check_wbc_security;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS auth_wbc_init(void)
+{
+ return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc);
+}
diff --git a/source3/client/client.c b/source3/client/client.c
index 2f9e3c0d49..aaa9e35d96 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -1784,13 +1784,13 @@ static struct file_list {
Free a file_list structure.
****************************************************************************/
-static void free_file_list (struct file_list *list_head)
+static void free_file_list (struct file_list *l_head)
{
struct file_list *list, *next;
- for (list = list_head; list; list = next) {
+ for (list = l_head; list; list = next) {
next = list->next;
- DLIST_REMOVE(list_head, list);
+ DLIST_REMOVE(l_head, list);
SAFE_FREE(list->file_path);
SAFE_FREE(list);
}
diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c
index a736609580..8623d3c04b 100644
--- a/source3/client/mount.cifs.c
+++ b/source3/client/mount.cifs.c
@@ -179,7 +179,6 @@ static void mount_cifs_usage(void)
printf("\n\t%s -V\n",thisprogram);
SAFE_FREE(mountpassword);
- exit(EX_USAGE);
}
/* caller frees username if necessary */
@@ -650,7 +649,9 @@ static int parse_options(char ** optionsp, int * filesys_flags)
} else if (strncmp(data, "exec", 4) == 0) {
*filesys_flags &= ~MS_NOEXEC;
} else if (strncmp(data, "guest", 5) == 0) {
- got_password=1;
+ user_name = (char *)calloc(1, 1);
+ got_user = 1;
+ got_password = 1;
} else if (strncmp(data, "ro", 2) == 0) {
*filesys_flags |= MS_RDONLY;
} else if (strncmp(data, "rw", 2) == 0) {
@@ -1017,6 +1018,14 @@ uppercase_string(char *string)
return 1;
}
+static void print_cifs_mount_version(void)
+{
+ printf("mount.cifs version: %s.%s%s\n",
+ MOUNT_CIFS_VERSION_MAJOR,
+ MOUNT_CIFS_VERSION_MINOR,
+ MOUNT_CIFS_VENDOR_SUFFIX);
+}
+
int main(int argc, char ** argv)
{
int c;
@@ -1078,6 +1087,24 @@ int main(int argc, char ** argv)
exit(EX_SYSERR);
}
mountpoint = argv[2];
+ } else if (argc == 2) {
+ if ((strcmp(argv[1], "-V") == 0) ||
+ (strcmp(argv[1], "--version") == 0))
+ {
+ print_cifs_mount_version();
+ exit(0);
+ }
+
+ if ((strcmp(argv[1], "-h") == 0) ||
+ (strcmp(argv[1], "-?") == 0) ||
+ (strcmp(argv[1], "--help") == 0))
+ {
+ mount_cifs_usage();
+ exit(0);
+ }
+
+ mount_cifs_usage();
+ exit(EX_USAGE);
} else {
mount_cifs_usage();
exit(EX_USAGE);
@@ -1102,7 +1129,7 @@ int main(int argc, char ** argv)
case '?':
case 'h': /* help */
mount_cifs_usage ();
- exit(EX_USAGE);
+ exit(0);
case 'n':
++nomtab;
break;
@@ -1134,11 +1161,8 @@ int main(int argc, char ** argv)
case 'v':
++verboseflag;
break;
- case 'V':
- printf ("mount.cifs version: %s.%s%s\n",
- MOUNT_CIFS_VERSION_MAJOR,
- MOUNT_CIFS_VERSION_MINOR,
- MOUNT_CIFS_VENDOR_SUFFIX);
+ case 'V':
+ print_cifs_mount_version();
exit (0);
case 'w':
flags &= ~MS_RDONLY;
diff --git a/source3/configure.in b/source3/configure.in
index 57d475fcc5..d67feccb9b 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -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_spoolss2 rpc_eventlog 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 pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc 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"
@@ -1044,6 +1044,9 @@ AC_SEARCH_LIBS(backtrace_symbols, [execinfo])
AC_CHECK_FUNCS(backtrace_symbols)
AC_CHECK_LIB(exc, trace_back_stack)
+# check for sysctlbyname for BSD systems
+AC_CHECK_FUNCS(sysctlbyname)
+
printf "%s" "checking for GPFS GPL libs... "
save_LIBS="$LIBS"
LIBS="$LIBS -lgpfs_gpl"
@@ -1084,7 +1087,8 @@ AC_TRY_LINK([#include <isi_version/isi_version.h>],
echo $samba_cv_HAVE_ONEFS
if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then
AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS])
- default_shared_modules="$default_shared_modules vfs_onefs perfcount_onefs"
+ default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs"
+ default_static_modules="$default_static_modules"
ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util"
# Need to also add general libs for oplocks support
save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat"
@@ -5713,6 +5717,34 @@ AC_MSG_CHECKING(whether to build winbind)
# Initially, the value of $host_os decides whether winbind is supported
HAVE_WINBIND=yes
+HAVE_WBCLIENT=no
+
+# Define external wbclient library to link against. This disables winbind.
+# We define this here so --with-winbind can override it.
+AC_ARG_WITH(wbclient,
+[AS_HELP_STRING([--with-wbclient], [Use external wbclient (optional)])],
+[
+ case "$withval" in
+ no)
+ HAVE_WBCLIENT=no
+ ;;
+ yes)
+ HAVE_WBCLIENT=yes
+ HAVE_WINBIND=no
+ ;;
+ *)
+ HAVE_WBCLIENT=yes
+ HAVE_WINBIND=no
+ WBCLIENT_INCLUDES="-I$withval/include"
+ WBCLIENT_LDFLAGS="-L$withval/lib"
+ ;;
+ esac ],
+)
+
+AC_SUBST(WBCLIENT_INCLUDES)
+AC_SUBST(WBCLIENT_LDFLAGS)
+AC_SUBST(WBCLIENT_LIBS)
+
# Define the winbind shared library name and any specific linker flags
# it needs to be built with.
@@ -5794,6 +5826,7 @@ AC_ARG_WITH(winbind,
case "$withval" in
yes)
HAVE_WINBIND=yes
+ HAVE_WBCLIENT=no
;;
no)
HAVE_WINBIND=no
@@ -5817,27 +5850,35 @@ if test x"$HAVE_WINBIND" = x"no"; then
WINBIND_NSS=""
WINBIND_WINS_NSS=""
fi
-
-if test x"$enable_developer" = x"yes" -a x"$LINK_LIBWBCLIENT" = x"STATIC" ; then
- BUILD_LIBWBCLIENT_SHARED=no
-else
- BUILD_LIBWBCLIENT_SHARED=yes
-fi
-
-LIBWBCLIENT_SHARED_TARGET=bin/libwbclient.$SHLIBEXT
-LIBWBCLIENT_STATIC_TARGET=bin/libwbclient.a
-LIBWBCLIENT_SOVER=0
-if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_SHARED" = x"yes"; then
- NSS_MODULES="${WINBIND_NSS} ${WINBIND_WINS_NSS}"
- ## Only worry about libwbclient if we have shared library support
- ## and winbindd
- LIBWBCLIENT_SHARED=$LIBWBCLIENT_SHARED_TARGET
- LIBWBCLIENT=libwbclient
- INSTALL_LIBWBCLIENT=installlibwbclient
- UNINSTALL_LIBWBCLIENT=uninstalllibwbclient
- WINBIND_LIBS="-lwbclient"
+if test x"$HAVE_WBCLIENT" = x"yes"; then
+ AC_CHECK_LIB(wbclient, wbcInterfaceDetails,
+ [WINBIND_LIBS="-lwbclient"], AC_MSG_ERROR([Could not find wbclient]), [$WBCLIENT_LDFLAGS])
+ WINBIND_LIBS="$WINBIND_LIBS $WBCLIENT_LDFLAGS"
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_WINBIND,1,[Whether to link to wbclient])
+ EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)"
else
- LIBWBCLIENT_STATIC=$LIBWBCLIENT_STATIC_TARGET
+ if test x"$enable_developer" = x"yes" -a x"$LINK_LIBWBCLIENT" = x"STATIC" ; then
+ BUILD_LIBWBCLIENT_SHARED=no
+ else
+ BUILD_LIBWBCLIENT_SHARED=yes
+ fi
+
+ LIBWBCLIENT_SHARED_TARGET=bin/libwbclient.$SHLIBEXT
+ LIBWBCLIENT_STATIC_TARGET=bin/libwbclient.a
+ LIBWBCLIENT_SOVER=0
+ if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_SHARED" = x"yes"; then
+ NSS_MODULES="${WINBIND_NSS} ${WINBIND_WINS_NSS}"
+ ## Only worry about libwbclient if we have shared
+ # library support
+ LIBWBCLIENT_SHARED=$LIBWBCLIENT_SHARED_TARGET
+ LIBWBCLIENT=libwbclient
+ INSTALL_LIBWBCLIENT=installlibwbclient
+ UNINSTALL_LIBWBCLIENT=uninstalllibwbclient
+ WINBIND_LIBS="-lwbclient"
+ else
+ LIBWBCLIENT_STATIC=$LIBWBCLIENT_STATIC_TARGET
+ fi
fi
if test x"$HAVE_WINBIND" = x"yes"; then
@@ -6089,6 +6130,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT"
[ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] )
SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB)
SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
+SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB)
SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o)
@@ -6131,6 +6173,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o)
SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH)
SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH)
SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH)
+SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH)
SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH)
SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH)
SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH)
@@ -6178,6 +6221,7 @@ SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS)
SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS)
SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS)
SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
diff --git a/source3/include/auth.h b/source3/include/auth.h
index 17bccce3d7..7d778b92d0 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -92,7 +92,8 @@ struct auth_context {
struct auth_methods *auth_method_list;
TALLOC_CTX *mem_ctx;
- const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context);
+ void (*get_ntlm_challenge)(struct auth_context *auth_context,
+ uint8_t chal[8]);
NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context,
const struct auth_usersupplied_info *user_info,
struct auth_serversupplied_info **server_info);
diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h
index aad4ccd721..16f10cc125 100644
--- a/source3/include/dbwrap.h
+++ b/source3/include/dbwrap.h
@@ -46,6 +46,10 @@ struct db_context {
int (*transaction_start)(struct db_context *db);
int (*transaction_commit)(struct db_context *db);
int (*transaction_cancel)(struct db_context *db);
+ int (*parse_record)(struct db_context *db, TDB_DATA key,
+ int (*parser)(TDB_DATA key, TDB_DATA data,
+ void *private_data),
+ void *private_data);
void *private_data;
bool persistent;
};
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 1906830d48..523a11e255 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -190,12 +190,12 @@ typedef int ber_int_t;
#undef HAVE_LDAP
#endif
-#if HAVE_GSSAPI_H
-#include <gssapi.h>
-#elif HAVE_GSSAPI_GSSAPI_H
+#if HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#elif HAVE_GSSAPI_GSSAPI_GENERIC_H
#include <gssapi/gssapi_generic.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
#endif
#if HAVE_COM_ERR_H
@@ -577,6 +577,8 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "../talloc/talloc.h"
#include "event.h"
+#include "../lib/util/tevent_unix.h"
+#include "../lib/util/tevent_ntstatus.h"
#include "../lib/util/data_blob.h"
#include "../lib/util/time.h"
@@ -677,8 +679,6 @@ struct printjob;
#include "smbldap.h"
-#include "smb_ldap.h"
-
/*
* Reasons for cache flush.
*/
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index f8a6c8a235..869aeb6a03 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -2677,12 +2677,24 @@ smbc_version(void);
*/
void
-smbc_set_credentials(char *workgroup,
- char *user,
- char *password,
+smbc_set_credentials(const char *workgroup,
+ const char *user,
+ const char *password,
smbc_bool use_kerberos,
- char *signing_state);
+ const char *signing_state);
+/*
+ * Wrapper around smbc_set_credentials.
+ * Used to set correct credentials that will
+ * be used to connect to DFS target share
+ * in libsmbclient
+ */
+
+void
+smbc_set_credentials_with_fallback(SMBCCTX *ctx,
+ const char *workgroup,
+ const char *user,
+ const char *password);
/**
* @ingroup structure
diff --git a/source3/include/locking.h b/source3/include/locking.h
index 3fd5b94de7..1833ba3f80 100644
--- a/source3/include/locking.h
+++ b/source3/include/locking.h
@@ -49,6 +49,7 @@ struct file_id {
other than a dev_t for the device */
uint64_t devid;
uint64_t inode;
+ uint64_t extid; /* Support systems that use an extended id (e.g. snapshots). */
};
struct byte_range_lock {
diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 3bf51f2c9d..43fd363b55 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -439,7 +439,7 @@ typedef struct _Printer{
uint32 options;
fstring localmachine;
uint32 printerlocal;
- SPOOL_NOTIFY_OPTION *option;
+ struct spoolss_NotifyOption *option;
POLICY_HND client_hnd;
bool client_connected;
uint32 change;
diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h
index 55b9249ea7..f3414fe928 100644
--- a/source3/include/ntlmssp.h
+++ b/source3/include/ntlmssp.h
@@ -109,7 +109,8 @@ typedef struct ntlmssp_state
* @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication
*
*/
- const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state);
+ void (*get_challenge)(const struct ntlmssp_state *ntlmssp_state,
+ uint8_t challenge[8]);
/**
* Callback to find if the challenge used by NTLM authentication may be modified
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3806c9657e..5bae973c3d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -110,7 +110,6 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
NTSTATUS create_local_token(auth_serversupplied_info *server_info);
NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
bool is_guest,
- bool force_nss,
uid_t *uid, gid_t *gid,
char **found_username,
struct nt_user_token **token);
@@ -508,12 +507,12 @@ void dump_core_setup(const char *progname);
/* The following definitions come from lib/file_id.c */
-struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode);
struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf);
bool file_id_equal(const struct file_id *id1, const struct file_id *id2);
const char *file_id_string_tos(const struct file_id *id);
void push_file_id_16(char *buf, const struct file_id *id);
-void pull_file_id_16(char *buf, struct file_id *id);
+void push_file_id_24(char *buf, const struct file_id *id);
+void pull_file_id_24(char *buf, struct file_id *id);
/* The following definitions come from lib/gencache.c */
@@ -696,8 +695,13 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src);
NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
struct security_descriptor *secdesc,
uint8 **data, size_t *len);
+NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
+ struct sec_desc_buf *secdesc_buf,
+ uint8_t **data, size_t *len);
NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
struct security_descriptor **psecdesc);
+NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
+ struct sec_desc_buf **psecdesc_buf);
SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
SEC_ACL *dacl, size_t *sd_size);
SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc);
@@ -973,8 +977,6 @@ struct passwd *sys_getpwnam(const char *name);
struct passwd *sys_getpwuid(uid_t uid);
struct group *sys_getgrnam(const char *name);
struct group *sys_getgrgid(gid_t gid);
-pid_t sys_fork(void);
-pid_t sys_getpid(void);
int sys_popen(const char *command);
int sys_pclose(int fd);
ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size);
@@ -1139,11 +1141,9 @@ int set_message_bcc(char *buf,int num_bytes);
ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob);
char *unix_clean_name(TALLOC_CTX *ctx, const char *s);
char *clean_name(TALLOC_CTX *ctx, const char *s);
-void close_low_fds(bool stderr_too);
ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos);
int set_blocking(int fd, bool set);
void smb_msleep(unsigned int t);
-void become_daemon(bool Fork, bool no_process_group);
bool reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived);
@@ -1243,15 +1243,6 @@ bool is_valid_policy_hnd(const POLICY_HND *hnd);
bool policy_hnd_equal(const struct policy_handle *hnd1,
const struct policy_handle *hnd2);
const char *strip_hostname(const char *s);
-struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, size_t initial,
- ssize_t (*more)(uint8_t *buf, size_t buflen,
- void *priv),
- void *priv);
-ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **pbuf, int *perr);
-
/* The following definitions come from lib/util_file.c */
@@ -1432,12 +1423,12 @@ int open_socket_in(int type,
bool rebind);
NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
int timeout, int *pfd);
-struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const struct sockaddr_storage *pss,
- uint16_t port,
- int timeout);
-NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd);
+struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout);
+NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd);
struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct timeval wait_time,
@@ -2283,6 +2274,9 @@ ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads,
enum ndr_err_code ndr_push_server_id(struct ndr_push *ndr, int ndr_flags, const struct server_id *r);
enum ndr_err_code ndr_pull_server_id(struct ndr_pull *ndr, int ndr_flags, struct server_id *r);
void ndr_print_server_id(struct ndr_print *ndr, const char *name, const struct server_id *r);
+enum ndr_err_code ndr_push_file_id(struct ndr_push *ndr, int ndr_flags, const struct file_id *r);
+enum ndr_err_code ndr_pull_file_id(struct ndr_pull *ndr, int ndr_flags, struct file_id *r);
+void ndr_print_file_id(struct ndr_print *ndr, const char *name, const struct file_id *r);
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
_PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name, const struct sockaddr_storage *ss);
const char *ndr_errstr(enum ndr_err_code err);
@@ -3114,7 +3108,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t,
bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name);
int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len);
void sort_query_replies(char *data, int n, struct in_addr ip);
-int name_mangle( char *In, char *Out, char name_type );
+char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type);
int name_extract(char *buf,int ofs, fstring name);
int name_len(char *s1);
@@ -3970,7 +3964,6 @@ const char *lp_afs_username_map(void);
int lp_afs_token_lifetime(void);
char *lp_log_nt_token_command(void);
char *lp_username_map(void);
-bool lp_force_username_map(void);
const char *lp_logon_script(void);
const char *lp_logon_path(void);
const char *lp_logon_drive(void);
@@ -4700,6 +4693,10 @@ NTSTATUS pdb_nds_init(void);
NTSTATUS pdb_smbpasswd_init(void) ;
+/* The following definitions come from passdb/pdb_wbc_sam.c */
+
+NTSTATUS pdb_wbc_sam_init(void);
+
/* The following definitions come from passdb/pdb_tdb.c */
bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen);
@@ -5052,12 +5049,15 @@ WERROR init_registry_data(void);
WERROR regdb_init(void);
WERROR regdb_open( void );
int regdb_close( void );
+WERROR regdb_transaction_start(void);
+WERROR regdb_transaction_commit(void);
+WERROR regdb_transaction_cancel(void);
int regdb_get_seqnum(void);
-bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr);
-int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr);
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr);
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr);
int regdb_fetch_values( const char* key, REGVAL_CTR *values );
bool regdb_store_values( const char *key, REGVAL_CTR *values );
-bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys);
+bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys);
bool regdb_values_need_update(REGVAL_CTR *values);
/* The following definitions come from registry/reg_backend_hkpt_params.c */
@@ -5093,9 +5093,11 @@ void reghook_dump_cache( int debuglevel );
/* The following definitions come from registry/reg_dispatcher.c */
-bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys );
+bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys );
bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val );
-int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr );
+WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey);
+WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey);
+int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr );
int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val );
bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
const struct nt_user_token *token );
@@ -5103,7 +5105,7 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
struct security_descriptor **psecdesc);
WERROR regkey_set_secdesc(REGISTRY_KEY *key,
struct security_descriptor *psecdesc);
-bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys);
+bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys);
bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values);
/* The following definitions come from registry/reg_eventlog.c */
@@ -5129,11 +5131,14 @@ WERROR registry_init_smbconf(const char *keyname);
/* The following definitions come from registry/reg_objects.c */
-WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname );
-int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname );
-bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname );
-int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr );
-char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index );
+WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr);
+WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum);
+int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr);
+WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname );
+WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname );
+bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname );
+int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr );
+char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index );
int regval_ctr_numvals( REGVAL_CTR *ctr );
REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val );
void free_registry_value( REGISTRY_VALUE *val );
@@ -5472,40 +5477,49 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
const char *printername,
uint32_t access_desired,
struct policy_handle *handle);
+WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ const char *architecture,
+ uint32_t level,
+ uint32_t offered,
+ uint32_t client_major_version,
+ uint32_t client_minor_version,
+ union spoolss_DriverInfo *info,
+ uint32_t *server_major_version,
+ uint32_t *server_minor_version);
+WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct spoolss_SetPrinterInfoCtr *info_ctr);
+WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ uint32_t level,
+ uint32_t offered,
+ union spoolss_PrinterInfo *info);
+WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ uint32_t job_id,
+ uint32_t level,
+ uint32_t offered,
+ union spoolss_JobInfo *info);
WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
char *name, uint32 flags, uint32 level,
uint32 *num_printers, PRINTER_INFO_CTR *ctr);
WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr);
-WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- PRINTER_INFO_CTR *ctr);
-WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- PRINTER_INFO_CTR *ctr, uint32 command);
-WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- const char *env, int version, PRINTER_DRIVER_CTR *ctr);
WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 level, const char *env,
uint32 *num_drivers,
PRINTER_DRIVER_CTR *ctr);
-WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx, uint32 level,
- PRINTER_DRIVER_CTR *ctr);
-WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- uint32 level, PRINTER_INFO_CTR*ctr);
WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, int level, uint32 *num_forms,
FORM_1 **forms);
WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 level, uint32 firstjob,
uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr);
-WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 jobid, uint32 level,
- JOB_INFO_CTR *ctr);
WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *valuename,
REGISTRY_VALUE *value);
@@ -5523,17 +5537,6 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me
POLICY_HND *hnd, const char *keyname,
uint16 **keylist, uint32 *len);
-/* The following definitions come from rpc_client/cli_spoolss_notify.c */
-
-WERROR rpccli_spoolss_rrpcn(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 notify_data_len,
- SPOOL_NOTIFY_INFO_DATA *notify_data,
- uint32 change_low, uint32 change_high);
-WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 flags, uint32 options,
- const char *localmachine, uint32 printerlocal,
- SPOOL_NOTIFY_OPTION *option);
-
/* The following definitions come from rpc_client/init_spoolss.c */
bool init_systemtime(struct spoolss_Time *r,
@@ -5818,28 +5821,12 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int
bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime);
bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
-bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
- prs_struct *ps, int depth);
-bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u );
bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode);
-bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u,
- const char *srv_name, const char* clientname, const char* user_name,
- uint32 level, PRINTER_INFO_CTR *ctr);
-bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
- PRINTER_INFO_2 *info);
-bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3,
- PRINTER_INFO_3 *info);
-bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7,
- PRINTER_INFO_7 *info);
bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
const POLICY_HND *handle,
const char *valuename, uint32 size);
bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth);
bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth);
bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
@@ -5887,11 +5874,6 @@ uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
-bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
- const POLICY_HND *hnd,
- const fstring architecture,
- uint32 level, uint32 clientmajor, uint32 clientminor,
- RPC_BUFFER *buffer, uint32 offered);
bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth);
bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth);
bool make_spoolss_q_enumprinters(
@@ -5909,19 +5891,6 @@ bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_
bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth);
bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
-bool make_spoolss_q_getprinter(
- TALLOC_CTX *mem_ctx,
- SPOOL_Q_GETPRINTER *q_u,
- const POLICY_HND *hnd,
- uint32 level,
- RPC_BUFFER *buffer,
- uint32 offered
-);
-bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
- const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
- uint32 command);
-bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
-bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
uint32 firstjob,
@@ -5941,31 +5910,7 @@ bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct
bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
-bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth);
-bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth);
-bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth);
-bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth);
-bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
-bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u,
- prs_struct *ps, int depth);
-bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
- prs_struct *ps, int depth);
-bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u,
- prs_struct *ps, int depth);
-bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
-bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
-bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
- SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name,
- uint32 level, PRINTER_DRIVER_CTR *info);
-bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
- DRIVER_INFO_3 *info3);
bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
-bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
- NT_PRINTER_INFO_LEVEL_2 *d);
bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth);
@@ -5995,11 +5940,6 @@ void free_printer_info_5(PRINTER_INFO_5 *printer);
void free_printer_info_6(PRINTER_INFO_6 *printer);
void free_printer_info_7(PRINTER_INFO_7 *printer);
void free_job_info_2(JOB_INFO_2 *job);
-bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
- uint32 change_low, uint32 change_high,
- SPOOL_NOTIFY_INFO *info);
-bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth);
-bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth);
bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u,
POLICY_HND *hnd, const char *key,
uint32 size);
@@ -6010,12 +5950,6 @@ bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
uint32 level, RPC_BUFFER *buffer,
uint32 offered);
-bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
- uint32 jobid, uint32 level, RPC_BUFFER *buffer,
- uint32 offered);
-bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
- uint32 flags, uint32 options, const char *localmachine,
- uint32 printerlocal, SPOOL_NOTIFY_OPTION *option);
/* The following definitions come from rpc_server/srv_eventlog_lib.c */
@@ -6141,74 +6075,75 @@ bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
uint32 type, uint8 *data, int real_len );
WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u);
-WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u);
void spoolss_notify_server_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_printer_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_share_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_port_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_driver_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_comment(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_location(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_sepfile(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_print_processor(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_parameters(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_datatype(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_attributes(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
void spoolss_notify_cjobs(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx);
-void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id);
-WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u);
+void construct_info_data(struct spoolss_Notify *info_data,
+ enum spoolss_NotifyType type,
+ enum spoolss_Field field,
+ int id);
DEVICEMODE *construct_dev_mode(const char *servicename);
WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
@@ -6263,7 +6198,6 @@ bool init_service_op_table( void );
/* The following definitions come from rpcclient/cmd_spoolss.c */
-void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch);
/* The following definitions come from rpcclient/cmd_srvsvc.c */
@@ -6587,6 +6521,7 @@ files_struct *file_find_fsp(files_struct *orig_fsp);
files_struct *file_find_di_first(struct file_id id);
files_struct *file_find_di_next(files_struct *start_fsp);
files_struct *file_find_print(void);
+bool file_find_subpath(files_struct *dir_fsp);
void file_sync_all(connection_struct *conn);
void file_free(struct smb_request *req, files_struct *fsp);
files_struct *file_fnum(uint16 fnum);
diff --git a/source3/include/reg_db.h b/source3/include/reg_db.h
index 92448ae543..5cafa0a5fb 100644
--- a/source3/include/reg_db.h
+++ b/source3/include/reg_db.h
@@ -26,5 +26,6 @@
#define REG_VALUE_PREFIX "SAMBA_REGVAL"
#define REG_SECDESC_PREFIX "SAMBA_SECDESC"
+#define REG_SORTED_SUBKEYS_PREFIX "SAMBA_SORTED_SUBKEYS"
#endif /* _REG_DB_H */
diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h
index d9159dd464..a03ac1bff4 100644
--- a/source3/include/reg_objects.h
+++ b/source3/include/reg_objects.h
@@ -66,11 +66,7 @@ typedef struct {
/* container for registry subkey names */
-typedef struct {
- uint32 num_subkeys;
- char **subkeys;
- int seqnum;
-} REGSUBKEY_CTR;
+struct regsubkey_ctr;
/*
*
@@ -132,9 +128,11 @@ typedef struct {
typedef struct {
/* functions for enumerating subkeys and values */
- int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys);
+ int (*fetch_subkeys)( const char *key, struct regsubkey_ctr *subkeys);
int (*fetch_values) ( const char *key, REGVAL_CTR *val );
- bool (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys );
+ bool (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys );
+ WERROR (*create_subkey)(const char *key, const char *subkey);
+ WERROR (*delete_subkey)(const char *key, const char *subkey);
bool (*store_values)( const char *key, REGVAL_CTR *val );
bool (*reg_access_check)( const char *keyname, uint32 requested,
uint32 *granted,
@@ -143,7 +141,7 @@ typedef struct {
struct security_descriptor **psecdesc);
WERROR (*set_secdesc)(const char *key,
struct security_descriptor *sec_desc);
- bool (*subkeys_need_update)(REGSUBKEY_CTR *subkeys);
+ bool (*subkeys_need_update)(struct regsubkey_ctr *subkeys);
bool (*values_need_update)(REGVAL_CTR *values);
} REGISTRY_OPS;
@@ -164,7 +162,7 @@ typedef struct _RegistryKey {
struct registry_key {
REGISTRY_KEY *key;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
REGVAL_CTR *values;
struct nt_user_token *token;
};
diff --git a/source3/include/regfio.h b/source3/include/regfio.h
index 63516a358d..0e957d51e5 100644
--- a/source3/include/regfio.h
+++ b/source3/include/regfio.h
@@ -214,7 +214,7 @@ int regfio_close( REGF_FILE *r );
REGF_NK_REC* regfio_rootkey( REGF_FILE *file );
REGF_NK_REC* regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk );
REGF_NK_REC* regfio_write_key ( REGF_FILE *file, const char *name,
- REGVAL_CTR *values, REGSUBKEY_CTR *subkeys,
+ REGVAL_CTR *values, struct regsubkey_ctr *subkeys,
SEC_DESC *sec_desc, REGF_NK_REC *parent );
diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h
index a1cfad9003..4bf0d9cb9d 100644
--- a/source3/include/rpc_secdes.h
+++ b/source3/include/rpc_secdes.h
@@ -39,9 +39,6 @@
#define SEC_RIGHTS_RESET_PASSWD SEC_RIGHTS_EXTENDED
#define SEC_RIGHTS_FULL_CTRL 0xf01ff
-#define SEC_ACE_OBJECT_PRESENT 0x00000001 /* thanks for Jim McDonough <jmcd@us.ibm.com> */
-#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002
-
/*
* New Windows 2000 bits.
*/
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index 99da007d32..798bbf922c 100644
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -123,39 +123,11 @@
#define PRINTER_STATUS_OK 0x00000000
-#define JOB_ACCESS_READ 0x00000020
-
-/* JOB status codes. */
-
-#define JOB_STATUS_QUEUED 0x0000
-#define JOB_STATUS_PAUSED 0x0001
-#define JOB_STATUS_ERROR 0x0002
-#define JOB_STATUS_DELETING 0x0004
-#define JOB_STATUS_SPOOLING 0x0008
-#define JOB_STATUS_PRINTING 0x0010
-#define JOB_STATUS_OFFLINE 0x0020
-#define JOB_STATUS_PAPEROUT 0x0040
-#define JOB_STATUS_PRINTED 0x0080
-#define JOB_STATUS_DELETED 0x0100
-#define JOB_STATUS_BLOCKED 0x0200
-#define JOB_STATUS_USER_INTERVENTION 0x0400
/* Notify field types */
-#define NOTIFY_ONE_VALUE 1 /* Notify data is stored in value1 */
-#define NOTIFY_TWO_VALUE 2 /* Notify data is stored in value2 */
-#define NOTIFY_POINTER 3 /* Data is a pointer to a buffer */
-#define NOTIFY_STRING 4 /* Data is a pointer to a buffer w/length */
-#define NOTIFY_SECDESC 5 /* Data is a security descriptor */
-
#define PRINTER_NOTIFY_TYPE 0x00
#define JOB_NOTIFY_TYPE 0x01
-#define PRINT_TABLE_END 0xFF
-
-#define MAX_PRINTER_NOTIFY 26
-#define MAX_JOB_NOTIFY 24
-
-#define MAX_NOTIFY_TYPE_FOR_NOW 26
#define PRINTER_NOTIFY_SERVER_NAME 0x00
#define PRINTER_NOTIFY_PRINTER_NAME 0x01
@@ -209,8 +181,6 @@
#define JOB_NOTIFY_TOTAL_BYTES 0x16
#define JOB_NOTIFY_BYTES_PRINTED 0x17
-#define PRINTER_NOTIFY_OPTIONS_REFRESH 0x01
-
/*
* Set of macros for flagging what changed in the PRINTER_INFO_2 struct
* when sending messages to other smbd's
@@ -263,25 +233,6 @@ PRINTER_MESSAGE_INFO;
#define DRIVER_MAX_VERSION 4
-/* this struct is undocumented */
-/* thanks to the ddk ... */
-typedef struct {
- uint32 size; /* length of user_name & client_name + 2? */
- UNISTR2 *client_name;
- UNISTR2 *user_name;
- uint32 build;
- uint32 major;
- uint32 minor;
- uint32 processor;
-} SPOOL_USER_1;
-
-typedef struct {
- uint32 level;
- union {
- SPOOL_USER_1 *user1;
- } user;
-} SPOOL_USER_CTR;
-
/*
* Devicemode structure
*/
@@ -345,41 +296,6 @@ PRINTER_DEFAULT;
/********************************************/
-typedef struct spool_notify_option_type
-{
- uint16 type;
- uint16 reserved0;
- uint32 reserved1;
- uint32 reserved2;
- uint32 count;
- uint32 fields_ptr;
- uint32 count2;
- uint16 fields[MAX_NOTIFY_TYPE_FOR_NOW];
-}
-SPOOL_NOTIFY_OPTION_TYPE;
-
-typedef struct spool_notify_option_type_ctr
-{
- uint32 count;
- SPOOL_NOTIFY_OPTION_TYPE *type;
-}
-SPOOL_NOTIFY_OPTION_TYPE_CTR;
-
-
-
-typedef struct s_header_type
-{
- uint32 type;
- union
- {
- uint32 value;
- UNISTR string;
- }
- data;
-}
-HEADER_TYPE;
-
-
typedef struct spool_q_getprinterdata
{
POLICY_HND handle;
@@ -398,86 +314,6 @@ typedef struct spool_r_getprinterdata
}
SPOOL_R_GETPRINTERDATA;
-typedef struct spool_notify_option
-{
- uint32 version;
- uint32 flags;
- uint32 count;
- uint32 option_type_ptr;
- SPOOL_NOTIFY_OPTION_TYPE_CTR ctr;
-}
-SPOOL_NOTIFY_OPTION;
-
-typedef struct spool_notify_info_data
-{
- uint16 type;
- uint16 field;
- uint32 reserved;
- uint32 id;
- union {
- uint32 value[2];
- struct {
- uint32 length;
- uint16 *string;
- } data;
- struct {
- uint32 size;
- SEC_DESC *desc;
- } sd;
- }
- notify_data;
- uint32 size;
- uint32 enc_type;
-} SPOOL_NOTIFY_INFO_DATA;
-
-typedef struct spool_notify_info
-{
- uint32 version;
- uint32 flags;
- uint32 count;
- SPOOL_NOTIFY_INFO_DATA *data;
-}
-SPOOL_NOTIFY_INFO;
-
-/* If the struct name looks obscure, yes it is ! */
-/* RemoteFindFirstPrinterChangeNotificationEx query struct */
-typedef struct spoolss_q_rffpcnex
-{
- POLICY_HND handle;
- uint32 flags;
- uint32 options;
- uint32 localmachine_ptr;
- UNISTR2 localmachine;
- uint32 printerlocal;
- uint32 option_ptr;
- SPOOL_NOTIFY_OPTION *option;
-}
-SPOOL_Q_RFFPCNEX;
-
-typedef struct spool_r_rffpcnex
-{
- WERROR status;
-}
-SPOOL_R_RFFPCNEX;
-
-/* Remote Find Next Printer Change Notify Ex */
-typedef struct spool_q_rfnpcnex
-{
- POLICY_HND handle;
- uint32 change;
- uint32 option_ptr;
- SPOOL_NOTIFY_OPTION *option;
-}
-SPOOL_Q_RFNPCNEX;
-
-typedef struct spool_r_rfnpcnex
-{
- uint32 info_ptr;
- SPOOL_NOTIFY_INFO info;
- WERROR status;
-}
-SPOOL_R_RFNPCNEX;
-
typedef struct printer_info_0
{
UNISTR printername;
@@ -592,11 +428,6 @@ typedef struct printer_info_6
}
PRINTER_INFO_6;
-#define SPOOL_DS_PUBLISH 1
-#define SPOOL_DS_UPDATE 2
-#define SPOOL_DS_UNPUBLISH 4
-#define SPOOL_DS_PENDING 0x80000000
-
typedef struct printer_info_7
{
UNISTR guid; /* text form of printer guid */
@@ -976,208 +807,8 @@ typedef struct spool_r_enumforms
}
SPOOL_R_ENUMFORMS;
-typedef struct spool_printer_info_level_1
-{
- uint32 flags;
- uint32 description_ptr;
- uint32 name_ptr;
- uint32 comment_ptr;
- UNISTR2 description;
- UNISTR2 name;
- UNISTR2 comment;
-} SPOOL_PRINTER_INFO_LEVEL_1;
-
-typedef struct spool_printer_info_level_2
-{
- uint32 servername_ptr;
- uint32 printername_ptr;
- uint32 sharename_ptr;
- uint32 portname_ptr;
- uint32 drivername_ptr;
- uint32 comment_ptr;
- uint32 location_ptr;
- uint32 devmode_ptr;
- uint32 sepfile_ptr;
- uint32 printprocessor_ptr;
- uint32 datatype_ptr;
- uint32 parameters_ptr;
- uint32 secdesc_ptr;
- uint32 attributes;
- uint32 priority;
- uint32 default_priority;
- uint32 starttime;
- uint32 untiltime;
- uint32 status;
- uint32 cjobs;
- uint32 averageppm;
- UNISTR2 servername;
- UNISTR2 printername;
- UNISTR2 sharename;
- UNISTR2 portname;
- UNISTR2 drivername;
- UNISTR2 comment;
- UNISTR2 location;
- UNISTR2 sepfile;
- UNISTR2 printprocessor;
- UNISTR2 datatype;
- UNISTR2 parameters;
-}
-SPOOL_PRINTER_INFO_LEVEL_2;
-
-typedef struct spool_printer_info_level_3
-{
- uint32 secdesc_ptr;
-}
-SPOOL_PRINTER_INFO_LEVEL_3;
-
-typedef struct spool_printer_info_level_7
-{
- uint32 guid_ptr;
- uint32 action;
- UNISTR2 guid;
-}
-SPOOL_PRINTER_INFO_LEVEL_7;
-
-typedef struct spool_printer_info_level
-{
- uint32 level;
- uint32 info_ptr;
- SPOOL_PRINTER_INFO_LEVEL_1 *info_1;
- SPOOL_PRINTER_INFO_LEVEL_2 *info_2;
- SPOOL_PRINTER_INFO_LEVEL_3 *info_3;
- SPOOL_PRINTER_INFO_LEVEL_7 *info_7;
-}
-SPOOL_PRINTER_INFO_LEVEL;
-
-typedef struct spool_printer_driver_info_level_3
-{
- uint32 cversion;
- uint32 name_ptr;
- uint32 environment_ptr;
- uint32 driverpath_ptr;
- uint32 datafile_ptr;
- uint32 configfile_ptr;
- uint32 helpfile_ptr;
- uint32 monitorname_ptr;
- uint32 defaultdatatype_ptr;
- uint32 dependentfilessize;
- uint32 dependentfiles_ptr;
-
- UNISTR2 name;
- UNISTR2 environment;
- UNISTR2 driverpath;
- UNISTR2 datafile;
- UNISTR2 configfile;
- UNISTR2 helpfile;
- UNISTR2 monitorname;
- UNISTR2 defaultdatatype;
- BUFFER5 dependentfiles;
-
-}
-SPOOL_PRINTER_DRIVER_INFO_LEVEL_3;
-
-/* SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure */
-typedef struct {
- uint32 version;
- uint32 name_ptr;
- uint32 environment_ptr;
- uint32 driverpath_ptr;
- uint32 datafile_ptr;
- uint32 configfile_ptr;
- uint32 helpfile_ptr;
- uint32 monitorname_ptr;
- uint32 defaultdatatype_ptr;
- uint32 dependentfiles_len;
- uint32 dependentfiles_ptr;
- uint32 previousnames_len;
- uint32 previousnames_ptr;
- NTTIME driverdate;
- uint64 driverversion;
- uint32 dummy4;
- uint32 mfgname_ptr;
- uint32 oemurl_ptr;
- uint32 hardwareid_ptr;
- uint32 provider_ptr;
- UNISTR2 name;
- UNISTR2 environment;
- UNISTR2 driverpath;
- UNISTR2 datafile;
- UNISTR2 configfile;
- UNISTR2 helpfile;
- UNISTR2 monitorname;
- UNISTR2 defaultdatatype;
- BUFFER5 dependentfiles;
- BUFFER5 previousnames;
- UNISTR2 mfgname;
- UNISTR2 oemurl;
- UNISTR2 hardwareid;
- UNISTR2 provider;
-} SPOOL_PRINTER_DRIVER_INFO_LEVEL_6;
-
-
-typedef struct spool_printer_driver_info_level
-{
- uint32 level;
- uint32 ptr;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
-}
-SPOOL_PRINTER_DRIVER_INFO_LEVEL;
-
-
-typedef struct spool_q_setprinter
-{
- POLICY_HND handle;
- uint32 level;
- SPOOL_PRINTER_INFO_LEVEL info;
- SEC_DESC_BUF *secdesc_ctr;
- DEVMODE_CTR devmode_ctr;
-
- uint32 command;
-
-}
-SPOOL_Q_SETPRINTER;
-
-typedef struct spool_r_setprinter
-{
- WERROR status;
-}
-SPOOL_R_SETPRINTER;
-
-/********************************************/
-
-typedef struct {
- UNISTR2 *server_name;
- uint32 level;
- SPOOL_PRINTER_INFO_LEVEL info;
- DEVMODE_CTR devmode_ctr;
- SEC_DESC_BUF *secdesc_ctr;
- uint32 user_switch;
- SPOOL_USER_CTR user_ctr;
-} SPOOL_Q_ADDPRINTEREX;
-
-typedef struct {
- POLICY_HND handle;
- WERROR status;
-} SPOOL_R_ADDPRINTEREX;
-
/********************************************/
-typedef struct spool_q_addprinterdriver
-{
- uint32 server_name_ptr;
- UNISTR2 server_name;
- uint32 level;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL info;
-}
-SPOOL_Q_ADDPRINTERDRIVER;
-
-typedef struct spool_r_addprinterdriver
-{
- WERROR status;
-}
-SPOOL_R_ADDPRINTERDRIVER;
-
typedef struct spool_q_enumprintprocessors
{
uint32 name_ptr;
@@ -1351,25 +982,6 @@ typedef struct spool_r_getjob
}
SPOOL_R_GETJOB;
-typedef struct spool_q_rrpcn
-{
- POLICY_HND handle;
- uint32 change_low;
- uint32 change_high;
- uint32 unknown0;
- uint32 unknown1;
- uint32 info_ptr;
- SPOOL_NOTIFY_INFO info;
-}
-SPOOL_Q_REPLY_RRPCN;
-
-typedef struct spool_r_rrpcn
-{
- uint32 unknown0;
- WERROR status;
-}
-SPOOL_R_REPLY_RRPCN;
-
typedef struct spool_q_enumprinterkey
{
POLICY_HND handle;
diff --git a/source3/include/smb.h b/source3/include/smb.h
index bef0fd177b..f02088731d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -758,18 +758,19 @@ Offset Data length.
16 uint32 private_options 4
20 uint32 time sec 4
24 uint32 time usec 4
-28 SMB_DEV_T dev 8 bytes.
-36 SMB_INO_T inode 8 bytes
-44 unsigned long file_id 4 bytes
-48 uint32 uid 4 bytes
-52 uint16 flags 2 bytes
-54
+28 uint64 dev 8 bytes
+36 uint64 inode 8 bytes
+44 uint64 extid 8 bytes
+52 unsigned long file_id 4 bytes
+56 uint32 uid 4 bytes
+60 uint16 flags 2 bytes
+62
*/
#ifdef CLUSTER_SUPPORT
-#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 58
+#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 66
#else
-#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 54
+#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 62
#endif
struct share_mode_lock {
@@ -1620,48 +1621,43 @@ enum acl_compatibility {ACL_COMPAT_AUTO, ACL_COMPAT_WINNT, ACL_COMPAT_WIN2K};
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)LEVEL_II_OPLOCK|(unsigned int)FAKE_LEVEL_II_OPLOCK))
-struct inform_level2_message {
- SMB_DEV_T dev;
- SMB_INO_T inode;
- uint16 mid;
- unsigned long target_file_id;
- unsigned long source_file_id;
-};
-
/* kernel_oplock_message definition.
struct kernel_oplock_message {
- SMB_DEV_T dev;
- SMB_INO_T inode;
+ uint64_t dev;
+ uint64_t inode;
+ unit64_t extid;
unsigned long file_id;
};
Offset Data length.
-0 SMB_DEV_T dev 8 bytes.
-8 SMB_INO_T inode 8 bytes
-16 unsigned long file_id 4 bytes
-20
+0 uint64_t dev 8 bytes
+8 uint64_t inode 8 bytes
+16 uint64_t extid 8 bytes
+24 unsigned long file_id 4 bytes
+28
*/
-#define MSG_SMB_KERNEL_BREAK_SIZE 20
+#define MSG_SMB_KERNEL_BREAK_SIZE 28
/* file_renamed_message definition.
struct file_renamed_message {
- SMB_DEV_T dev;
- SMB_INO_T inode;
+ uint64_t dev;
+ uint64_t inode;
char names[1]; A variable area containing sharepath and filename.
};
Offset Data length.
-0 SMB_DEV_T dev 8 bytes.
-8 SMB_INO_T inode 8 bytes
-16 char [] name zero terminated namelen bytes
-minimum length == 18.
+0 uint64_t dev 8 bytes
+8 uint64_t inode 8 bytes
+16 unit64_t extid 8 bytes
+24 char [] name zero terminated namelen bytes
+minimum length == 24.
*/
-#define MSG_FILE_RENAMED_MIN_SIZE 16
+#define MSG_FILE_RENAMED_MIN_SIZE 24
/*
* On the wire return values for oplock types.
diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h
deleted file mode 100644
index a3c270d95c..0000000000
--- a/source3/include/smb_ldap.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- Unix SMB/CIFS Implementation.
- LDAP protocol helper functions for SAMBA
- Copyright (C) Volker Lendecke 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef _SMB_LDAP_H
-#define _SMB_LDAP_H
-
-enum ldap_request_tag {
- LDAP_TAG_BindRequest = 0,
- LDAP_TAG_BindResponse = 1,
- LDAP_TAG_UnbindRequest = 2,
- LDAP_TAG_SearchRequest = 3,
- LDAP_TAG_SearchResultEntry = 4,
- LDAP_TAG_SearchResultDone = 5,
- LDAP_TAG_ModifyRequest = 6,
- LDAP_TAG_ModifyResponse = 7,
- LDAP_TAG_AddRequest = 8,
- LDAP_TAG_AddResponse = 9,
- LDAP_TAG_DelRequest = 10,
- LDAP_TAG_DelResponse = 11,
- LDAP_TAG_ModifyDNRequest = 12,
- LDAP_TAG_ModifyDNResponse = 13,
- LDAP_TAG_CompareRequest = 14,
- LDAP_TAG_CompareResponse = 15,
- LDAP_TAG_AbandonRequest = 16,
- LDAP_TAG_SearchResultReference = 19,
- LDAP_TAG_ExtendedRequest = 23,
- LDAP_TAG_ExtendedResponse = 24
-};
-
-enum ldap_auth_mechanism {
- LDAP_AUTH_MECH_SIMPLE = 0,
- LDAP_AUTH_MECH_SASL = 3
-};
-
-#ifndef LDAP_SUCCESS
-enum ldap_result_code {
- LDAP_SUCCESS = 0,
- LDAP_SASL_BIND_IN_PROGRESS = 0x0e,
- LDAP_INVALID_CREDENTIALS = 0x31,
- LDAP_OTHER = 0x50
-};
-#endif /* LDAP_SUCCESS */
-
-struct ldap_Result {
- int resultcode;
- const char *dn;
- const char *errormessage;
- const char *referral;
-};
-
-struct ldap_attribute {
- const char *name;
- int num_values;
- DATA_BLOB *values;
-};
-
-struct ldap_BindRequest {
- int version;
- const char *dn;
- enum ldap_auth_mechanism mechanism;
- union {
- const char *password;
- struct {
- const char *mechanism;
- DATA_BLOB secblob;
- } SASL;
- } creds;
-};
-
-struct ldap_BindResponse {
- struct ldap_Result response;
- union {
- DATA_BLOB secblob;
- } SASL;
-};
-
-struct ldap_UnbindRequest {
- uint8 __dummy;
-};
-
-enum ldap_scope {
- LDAP_SEARCH_SCOPE_BASE = 0,
- LDAP_SEARCH_SCOPE_SINGLE = 1,
- LDAP_SEARCH_SCOPE_SUB = 2
-};
-
-enum ldap_deref {
- LDAP_DEREFERENCE_NEVER = 0,
- LDAP_DEREFERENCE_IN_SEARCHING = 1,
- LDAP_DEREFERENCE_FINDING_BASE = 2,
- LDAP_DEREFERENCE_ALWAYS
-};
-
-struct ldap_SearchRequest {
- const char *basedn;
- enum ldap_scope scope;
- enum ldap_deref deref;
- uint32 timelimit;
- uint32 sizelimit;
- bool attributesonly;
- char *filter;
- int num_attributes;
- const char **attributes;
-};
-
-struct ldap_SearchResEntry {
- const char *dn;
- int num_attributes;
- struct ldap_attribute *attributes;
-};
-
-struct ldap_SearchResRef {
- int num_referrals;
- const char **referrals;
-};
-
-enum ldap_modify_type {
- LDAP_MODIFY_NONE = -1,
- LDAP_MODIFY_ADD = 0,
- LDAP_MODIFY_DELETE = 1,
- LDAP_MODIFY_REPLACE = 2
-};
-
-struct ldap_mod {
- enum ldap_modify_type type;
- struct ldap_attribute attrib;
-};
-
-struct ldap_ModifyRequest {
- const char *dn;
- int num_mods;
- struct ldap_mod *mods;
-};
-
-struct ldap_AddRequest {
- const char *dn;
- int num_attributes;
- struct ldap_attribute *attributes;
-};
-
-struct ldap_DelRequest {
- const char *dn;
-};
-
-struct ldap_ModifyDNRequest {
- const char *dn;
- const char *newrdn;
- bool deleteolddn;
- const char *newsuperior;
-};
-
-struct ldap_CompareRequest {
- const char *dn;
- const char *attribute;
- const char *value;
-};
-
-struct ldap_AbandonRequest {
- uint32 messageid;
-};
-
-struct ldap_ExtendedRequest {
- const char *oid;
- DATA_BLOB value;
-};
-
-struct ldap_ExtendedResponse {
- struct ldap_Result response;
- const char *name;
- DATA_BLOB value;
-};
-
-union ldap_Request {
- struct ldap_BindRequest BindRequest;
- struct ldap_BindResponse BindResponse;
- struct ldap_UnbindRequest UnbindRequest;
- struct ldap_SearchRequest SearchRequest;
- struct ldap_SearchResEntry SearchResultEntry;
- struct ldap_Result SearchResultDone;
- struct ldap_SearchResRef SearchResultReference;
- struct ldap_ModifyRequest ModifyRequest;
- struct ldap_Result ModifyResponse;
- struct ldap_AddRequest AddRequest;
- struct ldap_Result AddResponse;
- struct ldap_DelRequest DelRequest;
- struct ldap_Result DelResponse;
- struct ldap_ModifyDNRequest ModifyDNRequest;
- struct ldap_Result ModifyDNResponse;
- struct ldap_CompareRequest CompareRequest;
- struct ldap_Result CompareResponse;
- struct ldap_AbandonRequest AbandonRequest;
- struct ldap_ExtendedRequest ExtendedRequest;
- struct ldap_ExtendedResponse ExtendedResponse;
-};
-
-struct ldap_Control {
- const char *oid;
- bool critical;
- DATA_BLOB value;
-};
-
-struct ldap_message {
- TALLOC_CTX *mem_ctx;
- uint32 messageid;
- uint8 type;
- union ldap_Request r;
- int num_controls;
- struct ldap_Control *controls;
-};
-
-struct ldap_queue_entry {
- struct ldap_queue_entry *next, *prev;
- int msgid;
- struct ldap_message *msg;
-};
-
-struct ldap_connection {
- TALLOC_CTX *mem_ctx;
- int sock;
- int next_msgid;
- char *host;
- uint16 port;
- bool ldaps;
-
- const char *auth_dn;
- const char *simple_pw;
-
- /* Current outstanding search entry */
- int searchid;
-
- /* List for incoming search entries */
- struct ldap_queue_entry *search_entries;
-
- /* Outstanding LDAP requests that have not yet been replied to */
- struct ldap_queue_entry *outstanding;
-};
-
-#endif
diff --git a/source3/include/smb_share_modes.h b/source3/include/smb_share_modes.h
index 101bec8245..4a2d832cc2 100644
--- a/source3/include/smb_share_modes.h
+++ b/source3/include/smb_share_modes.h
@@ -46,6 +46,7 @@ struct smbdb_ctx;
struct smb_share_mode_entry {
uint64_t dev;
uint64_t ino;
+ uint64_t extid;
uint32_t share_access;
uint32_t access_mask;
struct timeval open_time;
@@ -66,11 +67,13 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx);
int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino);
+ uint64_t ino,
+ uint64_t extid);
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino);
+ uint64_t ino,
+ uint64_t extid);
/*
* Share mode database accessor functions.
@@ -79,23 +82,27 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close);
int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const char *path);
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *set_entry);
int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const struct smb_share_mode_entry *new_entry);
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index 131416b685..f9a0436546 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -75,6 +75,10 @@ enum profile_stats_values
#define syscall_open_count __profile_stats_value(PR_VALUE_SYSCALL_OPEN, count)
#define syscall_open_time __profile_stats_value(PR_VALUE_SYSCALL_OPEN, time)
+ PR_VALUE_SYSCALL_CREATEFILE,
+#define syscall_createfile_count __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, count)
+#define syscall_createfile_time __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, time)
+
PR_VALUE_SYSCALL_CLOSE,
#define syscall_close_count __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, count)
#define syscall_close_time __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, time)
@@ -111,6 +115,10 @@ enum profile_stats_values
#define syscall_rename_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME, count)
#define syscall_rename_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME, time)
+ PR_VALUE_SYSCALL_RENAME_AT,
+#define syscall_rename_at_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, count)
+#define syscall_rename_at_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, time)
+
PR_VALUE_SYSCALL_FSYNC,
#define syscall_fsync_count __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, count)
#define syscall_fsync_time __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, time)
@@ -215,6 +223,26 @@ enum profile_stats_values
#define syscall_set_quota_count __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, count)
#define syscall_set_quota_time __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, time)
+ PR_VALUE_SYSCALL_GET_SD,
+#define syscall_get_sd_count __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, count)
+#define syscall_get_sd_time __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, time)
+
+ PR_VALUE_SYSCALL_SET_SD,
+#define syscall_set_sd_count __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, count)
+#define syscall_set_sd_time __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, time)
+
+ PR_VALUE_SYSCALL_BRL_LOCK,
+#define syscall_brl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, count)
+#define syscall_brl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, time)
+
+ PR_VALUE_SYSCALL_BRL_UNLOCK,
+#define syscall_brl_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, count)
+#define syscall_brl_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, time)
+
+ PR_VALUE_SYSCALL_BRL_CANCEL,
+#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count)
+#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time)
+
/* counters for individual SMB types */
PR_VALUE_SMBMKDIR,
#define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index ffa1a95ed0..0ee7f236b0 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -383,7 +383,8 @@ struct vfs_ops {
struct notify_event *ev),
void *private_data, void *handle_p);
int (*chflags)(struct vfs_handle_struct *handle, const char *path, unsigned int flags);
- struct file_id (*file_id_create)(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode);
+ struct file_id (*file_id_create)(struct vfs_handle_struct *handle,
+ const SMB_STRUCT_STAT *sbuf);
NTSTATUS (*streaminfo)(struct vfs_handle_struct *handle,
struct files_struct *fsp,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 3af612375b..7dacd2319a 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -85,7 +85,7 @@
#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (path), (resolved_path)))
#define SMB_VFS_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs.ops.notify_watch((conn)->vfs.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p)))
#define SMB_VFS_CHFLAGS(conn, path, flags) ((conn)->vfs.ops.chflags((conn)->vfs.handles.chflags, (path), (flags)))
-#define SMB_VFS_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (dev), (inode)))
+#define SMB_VFS_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops.file_id_create((conn)->vfs.handles.file_id_create, (sbuf)))
#define SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs.ops.streaminfo((conn)->vfs.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
#define SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs.ops.get_real_filename((conn)->vfs.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
#define SMB_VFS_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs.ops.brl_lock_windows((conn)->vfs.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
@@ -217,7 +217,7 @@
#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (path), (resolved_path)))
#define SMB_VFS_OPAQUE_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_opaque.ops.notify_watch((conn)->vfs_opaque.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p)))
#define SMB_VFS_OPAQUE_CHFLAGS(conn, path, flags) ((conn)->vfs_opaque.ops.chflags((conn)->vfs_opaque.handles.chflags, (path), (flags)))
-#define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, dev, inode) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (dev), (inode)))
+#define SMB_VFS_OPAQUE_FILE_ID_CREATE(conn, sbuf) ((conn)->vfs.ops_opaque.file_id_create((conn)->vfs_opaque.handles.file_id_create, (sbuf)))
#define SMB_VFS_OPAQUE_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams) ((conn)->vfs_opaque.ops.streaminfo((conn)->vfs_opaque.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
#define SMB_VFS_OPAQUE_GET_REAL_FILENAME(conn, path, name, mem_ctx, found_name) ((conn)->vfs_opaque.ops.get_real_filename((conn)->vfs_opaque.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
#define SMB_VFS_OPAQUE_BRL_LOCK_WINDOWS(conn, br_lck, plock, blocking_lock, blr) ((conn)->vfs_opaque.ops.brl_lock_windows((conn)->vfs_opaque.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
@@ -350,7 +350,7 @@
#define SMB_VFS_NEXT_REALPATH(handle, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (path), (resolved_path)))
#define SMB_VFS_NEXT_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) ((conn)->vfs_next.ops.notify_watch((conn)->vfs_next.handles.notify_watch, (ctx), (e), (callback), (private_data), (handle_p)))
#define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) ((handle)->vfs_next.ops.chflags((handle)->vfs_next.handles.chflags, (path), (flags)))
-#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (dev), (inode)))
+#define SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf) ((handle)->vfs_next.ops.file_id_create((handle)->vfs_next.handles.file_id_create, (sbuf)))
#define SMB_VFS_NEXT_STREAMINFO(handle, fsp, fname, mem_ctx, num_streams, streams) ((handle)->vfs_next.ops.streaminfo((handle)->vfs_next.handles.streaminfo, (fsp), (fname), (mem_ctx), (num_streams), (streams)))
#define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) ((handle)->vfs_next.ops.get_real_filename((handle)->vfs_next.handles.get_real_filename, (path), (name), (mem_ctx), (found_name)))
#define SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock, blocking_lock, blr) ((handle)->vfs_next.ops.brl_lock_windows((handle)->vfs_next.handles.brl_lock_windows, (br_lck), (plock), (blocking_lock), (blr)))
diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c
index a57b7c97a5..5e7ce6099f 100644
--- a/source3/lib/dbwrap.c
+++ b/source3/lib/dbwrap.c
@@ -42,6 +42,29 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
return 0;
}
+/*
+ * Fall back using fetch if no genuine parse operation is provided
+ */
+
+static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key,
+ int (*parser)(TDB_DATA key,
+ TDB_DATA data,
+ void *private_data),
+ void *private_data)
+{
+ TDB_DATA data;
+ int res;
+
+ res = db->fetch(db, talloc_tos(), key, &data);
+ if (res != 0) {
+ return res;
+ }
+
+ res = parser(key, data, private_data);
+ TALLOC_FREE(data.dptr);
+ return res;
+}
+
/**
* open a database
*/
@@ -101,6 +124,9 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
if ((result != NULL) && (result->fetch == NULL)) {
result->fetch = dbwrap_fallback_fetch;
}
+ if ((result != NULL) && (result->parse_record == NULL)) {
+ result->parse_record = dbwrap_fallback_parse_record;
+ }
return result;
}
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index b5eb1881d4..c71e073b41 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -176,6 +176,17 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
return 0;
}
+static int db_tdb_parse(struct db_context *db, TDB_DATA key,
+ int (*parser)(TDB_DATA key, TDB_DATA data,
+ void *private_data),
+ void *private_data)
+{
+ struct db_tdb_ctx *ctx = talloc_get_type_abort(
+ db->private_data, struct db_tdb_ctx);
+
+ return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data);
+}
+
static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
@@ -351,6 +362,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
result->fetch = db_tdb_fetch;
result->traverse = db_tdb_traverse;
result->traverse_read = db_tdb_traverse_read;
+ result->parse_record = db_tdb_parse;
result->get_seqnum = db_tdb_get_seqnum;
result->get_flags = db_tdb_get_flags;
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c
index 636639c11d..fe1ae77edd 100644
--- a/source3/lib/display_sec.c
+++ b/source3/lib/display_sec.c
@@ -155,13 +155,13 @@ void display_sec_ace_flags(uint8_t flags)
****************************************************************************/
static void disp_sec_ace_object(struct security_ace_object *object)
{
- if (object->flags & SEC_ACE_OBJECT_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_PRESENT\n");
+ if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s\n", GUID_string(talloc_tos(),
&object->type.type));
}
- if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n");
+ if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s\n", GUID_string(talloc_tos(),
&object->inherited_type.inherited_type));
}
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 44b4562757..9e81a47796 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -282,7 +282,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level,
samba_level = 2;
break;
case TEVENT_DEBUG_TRACE:
- samba_level = 5;
+ samba_level = 10;
break;
};
diff --git a/source3/lib/fault.c b/source3/lib/fault.c
index a1530987f3..efd1dddfd4 100644
--- a/source3/lib/fault.c
+++ b/source3/lib/fault.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Critical Fault handling
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Tim Prouty 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
@@ -87,6 +88,128 @@ void fault_setup(void (*fn)(void *))
#endif
}
+/**
+ * Build up the default corepath as "<logbase>/cores/<progname>"
+ */
+static char *get_default_corepath(const char *logbase, const char *progname)
+{
+ char *tmp_corepath;
+
+ /* Setup core dir in logbase. */
+ tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase);
+ if (!tmp_corepath)
+ return NULL;
+
+ if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST)
+ goto err_out;
+
+ if (chmod(tmp_corepath, 0700) == -1)
+ goto err_out;
+
+ talloc_free(tmp_corepath);
+
+ /* Setup progname-specific core subdir */
+ tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname);
+ if (!tmp_corepath)
+ return NULL;
+
+ if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST)
+ goto err_out;
+
+ if (chown(tmp_corepath, getuid(), getgid()) == -1)
+ goto err_out;
+
+ if (chmod(tmp_corepath, 0700) == -1)
+ goto err_out;
+
+ return tmp_corepath;
+
+ err_out:
+ talloc_free(tmp_corepath);
+ return NULL;
+}
+
+/**
+ * Get the FreeBSD corepath.
+ *
+ * On FreeBSD the current working directory is ignored when creating a core
+ * file. Instead the core directory is controlled via sysctl. This consults
+ * the value of "kern.corefile" so the correct corepath can be printed out
+ * before dump_core() calls abort.
+ */
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+static char *get_freebsd_corepath(void)
+{
+ char *tmp_corepath = NULL;
+ char *end = NULL;
+ size_t len = 128;
+ int ret;
+
+ /* Loop with increasing sizes so we don't allocate too much. */
+ do {
+ if (len > 1024) {
+ goto err_out;
+ }
+
+ tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath,
+ char, len);
+ if (!tmp_corepath) {
+ return NULL;
+ }
+
+ ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL,
+ 0);
+ if (ret == -1) {
+ if (errno != ENOMEM) {
+ DEBUG(0, ("sysctlbyname failed getting "
+ "kern.corefile %s\n",
+ strerror(errno)));
+ goto err_out;
+ }
+
+ /* Not a large enough array, try a bigger one. */
+ len = len << 1;
+ }
+ } while (ret == -1);
+
+ /* Strip off the common filename expansion */
+ if ((end = strrchr_m(tmp_corepath, '/'))) {
+ *end = '\0';
+ }
+
+ return tmp_corepath;
+
+ err_out:
+ if (tmp_corepath) {
+ talloc_free(tmp_corepath);
+ }
+ return NULL;
+}
+#endif
+
+/**
+ * Try getting system-specific corepath if one exists.
+ *
+ * If the system doesn't define a corepath, then the default is used.
+ */
+static char *get_corepath(const char *logbase, const char *progname)
+{
+ char *tmp_corepath = NULL;
+
+ /* @todo: Add support for the linux corepath. */
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+ tmp_corepath = get_freebsd_corepath();
+#endif
+
+ /* If this has been set correctly, we're done. */
+ if (tmp_corepath) {
+ return tmp_corepath;
+ }
+
+ /* Fall back to the default. */
+ return get_default_corepath(logbase, progname);
+}
+
/*******************************************************************
make all the preparations to safely dump a core file
********************************************************************/
@@ -104,7 +227,7 @@ void dump_core_setup(const char *progname)
*end = '\0';
}
} else {
- /* We will end up here is the log file is given on the command
+ /* We will end up here if the log file is given on the command
* line by the -l option but the "log file" option is not set
* in smb.conf.
*/
@@ -115,50 +238,13 @@ void dump_core_setup(const char *progname)
SMB_ASSERT(progname != NULL);
- if (asprintf(&corepath, "%s/cores", logbase) < 0) {
- SAFE_FREE(logbase);
- return;
- }
- if (mkdir(corepath,0700) == -1) {
- if (errno != EEXIST) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- }
- if (chmod(corepath,0700) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
-
- SAFE_FREE(corepath);
- if (asprintf(&corepath, "%s/cores/%s",
- logbase, progname) < 0) {
- SAFE_FREE(logbase);
- return;
- }
- if (mkdir(corepath,0700) == -1) {
- if (errno != EEXIST) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- }
-
- if (chown(corepath,getuid(),getgid()) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- if (chmod(corepath,0700) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
+ corepath = get_corepath(logbase, progname);
+ if (!corepath) {
+ DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname,
+ strerror(errno)));
+ goto out;
}
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
#ifdef HAVE_GETRLIMIT
#ifdef RLIMIT_CORE
@@ -185,6 +271,8 @@ void dump_core_setup(const char *progname)
/* FIXME: if we have a core-plus-pid facility, configurably set
* this up here.
*/
+ out:
+ SAFE_FREE(logbase);
}
void dump_core(void)
diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c
index 0633d4b88d..0902e3d224 100644
--- a/source3/lib/file_id.c
+++ b/source3/lib/file_id.c
@@ -22,26 +22,11 @@
#include "includes.h"
/*
- return a file_id which gives a unique ID for a file given the device and
- inode numbers
- */
-struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode)
-{
- struct file_id key;
- /* the ZERO_STRUCT ensures padding doesn't break using the key as a
- * blob */
- ZERO_STRUCT(key);
- key.devid = dev;
- key.inode = inode;
- return key;
-}
-
-/*
generate a file_id from a stat structure
*/
struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
{
- return SMB_VFS_FILE_ID_CREATE(conn, sbuf->st_dev, sbuf->st_ino);
+ return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
}
/*
@@ -49,7 +34,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
*/
bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
{
- return id1->inode == id2->inode && id1->devid == id2->devid;
+ return id1->inode == id2->inode && id1->devid == id2->devid &&
+ id1->extid == id2->extid;
}
/*
@@ -57,15 +43,17 @@ bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
*/
const char *file_id_string_tos(const struct file_id *id)
{
- char *result = talloc_asprintf(talloc_tos(), "%llx:%llx",
+ char *result = talloc_asprintf(talloc_tos(), "%llx:%llx:%llx",
(unsigned long long)id->devid,
- (unsigned long long)id->inode);
+ (unsigned long long)id->inode,
+ (unsigned long long)id->extid);
SMB_ASSERT(result != NULL);
return result;
}
/*
- push a 16 byte version of a file id into a buffer
+ push a 16 byte version of a file id into a buffer. This ignores the extid
+ and is needed when dev/inodes are stored in persistent storage (tdbs).
*/
void push_file_id_16(char *buf, const struct file_id *id)
{
@@ -76,13 +64,28 @@ void push_file_id_16(char *buf, const struct file_id *id)
}
/*
- pul a 16 byte version of a file id from a buffer
+ push a 24 byte version of a file id into a buffer
+ */
+void push_file_id_24(char *buf, const struct file_id *id)
+{
+ SIVAL(buf, 0, id->devid&0xFFFFFFFF);
+ SIVAL(buf, 4, id->devid>>32);
+ SIVAL(buf, 8, id->inode&0xFFFFFFFF);
+ SIVAL(buf, 12, id->inode>>32);
+ SIVAL(buf, 16, id->extid&0xFFFFFFFF);
+ SIVAL(buf, 20, id->extid>>32);
+}
+
+/*
+ pull a 24 byte version of a file id from a buffer
*/
-void pull_file_id_16(char *buf, struct file_id *id)
+void pull_file_id_24(char *buf, struct file_id *id)
{
ZERO_STRUCTP(id);
id->devid = IVAL(buf, 0);
id->devid |= ((uint64_t)IVAL(buf,4))<<32;
id->inode = IVAL(buf, 8);
id->inode |= ((uint64_t)IVAL(buf,12))<<32;
+ id->extid = IVAL(buf, 16);
+ id->extid |= ((uint64_t)IVAL(buf,20))<<32;
}
diff --git a/source3/lib/ldap_debug_handler.c b/source3/lib/ldap_debug_handler.c
index 2181ff014d..98623d1985 100644
--- a/source3/lib/ldap_debug_handler.c
+++ b/source3/lib/ldap_debug_handler.c
@@ -19,13 +19,11 @@
#include "includes.h"
-#if HAVE_LDAP
-
+#if defined(HAVE_LDAP) && defined(HAVE_LBER_LOG_PRINT_FN)
static void samba_ldap_log_print_fn(LDAP_CONST char *data)
{
DEBUG(lp_ldap_debug_threshold(), ("[LDAP] %s", data));
}
-
#endif
void init_ldap_debugging(void)
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index 232bbca43c..a81c4ae82a 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -291,6 +291,32 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
}
/*******************************************************************
+ Convert a secdesc_buf into a byte stream
+********************************************************************/
+
+NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
+ struct sec_desc_buf *secdesc_buf,
+ uint8_t **data, size_t *len)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(
+ &blob, mem_ctx, NULL, secdesc_buf,
+ (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
+ ndr_errstr(ndr_err)));
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *data = blob.data;
+ *len = blob.length;
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
Parse a byte stream into a secdesc
********************************************************************/
NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
@@ -327,6 +353,43 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
}
/*******************************************************************
+ Parse a byte stream into a sec_desc_buf
+********************************************************************/
+
+NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
+ struct sec_desc_buf **psecdesc_buf)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct sec_desc_buf *result;
+
+ if ((data == NULL) || (len == 0)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf);
+ if (result == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ blob = data_blob_const(data, len);
+
+ ndr_err = ndr_pull_struct_blob(
+ &blob, result, NULL, result,
+ (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(result);
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *psecdesc_buf = result;
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
Creates a SEC_DESC structure with typical defaults.
********************************************************************/
diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c
index e36fa8a2a1..5a5c0ead65 100644
--- a/source3/lib/smbconf/smbconf_reg.c
+++ b/source3/lib/smbconf/smbconf_reg.c
@@ -23,7 +23,7 @@
#define INCLUDES_VALNAME "includes"
struct reg_private_data {
- NT_USER_TOKEN *token;
+ struct registry_key *base_key;
bool open; /* did _we_ open the registry? */
};
@@ -72,54 +72,6 @@ static bool smbconf_reg_valname_valid(const char *valname)
}
/**
- * Open a registry key specified by "path"
- */
-static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx,
- struct smbconf_ctx *ctx,
- const char *path,
- uint32 desired_access,
- struct registry_key **key)
-{
- WERROR werr = WERR_OK;
-
- if (ctx == NULL) {
- DEBUG(1, ("Error: configuration is not open!\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- if (rpd(ctx)->token == NULL) {
- DEBUG(1, ("Error: token missing from smbconf_ctx. "
- "was smbconf_init() called?\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- werr = ctx->ops->open_conf(ctx);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(1, ("Error opening the registry.\n"));
- goto done;
- }
-
- if (path == NULL) {
- DEBUG(1, ("Error: NULL path string given\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token,
- key);
-
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(5, ("Error opening registry path '%s': %s\n",
- path, win_errstr(werr)));
- }
-
-done:
- return werr;
-}
-
-/**
* Open a subkey of the base key (i.e a service)
*/
static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
@@ -128,37 +80,12 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
uint32 desired_access,
struct registry_key **key)
{
- WERROR werr = WERR_OK;
- char *path = NULL;
-
if (servicename == NULL) {
- path = talloc_strdup(mem_ctx, ctx->path);
- } else {
- path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path,
- servicename);
- }
- if (path == NULL) {
- werr = WERR_NOMEM;
- goto done;
+ *key = rpd(ctx)->base_key;
+ return WERR_OK;
}
-
- werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key);
-
-done:
- talloc_free(path);
- return werr;
-}
-
-/**
- * open the base key
- */
-static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx,
- struct smbconf_ctx *ctx,
- uint32 desired_access,
- struct registry_key **key)
-{
- return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access,
- key);
+ return reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
+ desired_access, key);
}
/**
@@ -189,7 +116,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
struct registry_key **newkey)
{
WERROR werr = WERR_OK;
- struct registry_key *create_parent = NULL;
TALLOC_CTX *create_ctx;
enum winreg_CreateAction action = REG_ACTION_NONE;
@@ -198,13 +124,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
* and will be destroyed when leaving this function... */
create_ctx = talloc_stackframe();
- werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE,
- &create_parent);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
-
- werr = reg_createkey(mem_ctx, create_parent, subkeyname,
+ werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname,
REG_KEY_WRITE, newkey, &action);
if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
@@ -215,7 +135,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
subkeyname, win_errstr(werr)));
}
-done:
talloc_free(create_ctx);
return werr;
}
@@ -608,6 +527,7 @@ done:
static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
{
WERROR werr = WERR_OK;
+ struct nt_user_token *token;
if (path == NULL) {
path = KEY_SMBCONF;
@@ -620,8 +540,7 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data);
- werr = ntstatus_to_werror(registry_create_admin_token(ctx,
- &(rpd(ctx)->token)));
+ werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error creating admin token\n"));
goto done;
@@ -633,6 +552,19 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
goto done;
}
+ werr = ctx->ops->open_conf(ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Error opening the registry.\n"));
+ goto done;
+ }
+
+ werr = reg_open_path(ctx, ctx->path,
+ SEC_RIGHTS_ENUM_SUBKEYS | REG_KEY_WRITE,
+ token, &rpd(ctx)->base_key);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
done:
return werr;
}
@@ -723,6 +655,13 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
struct registry_key *new_key = NULL;
TALLOC_CTX* mem_ctx = talloc_stackframe();
enum winreg_CreateAction action;
+ struct nt_user_token *token;
+
+ werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Error creating admin token\n"));
+ goto done;
+ }
path = talloc_strdup(mem_ctx, ctx->path);
if (path == NULL) {
@@ -731,8 +670,8 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
}
p = strrchr(path, '\\');
*p = '\0';
- werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE,
- &parent_key);
+ werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
+ &parent_key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
@@ -765,7 +704,6 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
uint32_t added_count = 0;
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
- struct registry_key *key = NULL;
char *subkey_name = NULL;
char **tmp_share_names = NULL;
@@ -777,13 +715,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
tmp_ctx = talloc_stackframe();
/* if there are values in the base key, return NULL as share name */
- werr = smbconf_reg_open_base_key(tmp_ctx, ctx,
- SEC_RIGHTS_ENUM_SUBKEYS, &key);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
- if (smbconf_reg_key_has_values(key)) {
+ if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) {
werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
0, NULL);
if (!W_ERROR_IS_OK(werr)) {
@@ -803,7 +736,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
}
for (count = 0;
- werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL),
+ werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
+ &subkey_name, NULL),
W_ERROR_IS_OK(werr);
count++)
{
@@ -865,18 +799,16 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx,
const char *servicename)
{
WERROR werr;
- TALLOC_CTX *mem_ctx = talloc_stackframe();
struct registry_key *key = NULL;
if (servicename == NULL) {
- werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE,
- &key);
- } else {
- werr = smbconf_reg_create_service_key(mem_ctx, ctx,
- servicename, &key);
+ return WERR_OK;
}
- talloc_free(mem_ctx);
+ werr = smbconf_reg_create_service_key(talloc_tos(), ctx,
+ servicename, &key);
+
+ talloc_free(key);
return werr;
}
@@ -896,6 +828,9 @@ static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
REG_KEY_READ, &key);
if (!W_ERROR_IS_OK(werr)) {
+ if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
+ werr = WERR_NO_SUCH_SERVICE;
+ }
goto done;
}
@@ -934,21 +869,15 @@ static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx,
const char *servicename)
{
WERROR werr = WERR_OK;
- struct registry_key *key = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
-
if (servicename != NULL) {
- werr = reg_deletekey_recursive(key, key, servicename);
+ werr = reg_deletekey_recursive(mem_ctx, rpd(ctx)->base_key,
+ servicename);
} else {
- werr = smbconf_reg_delete_values(key);
+ werr = smbconf_reg_delete_values(rpd(ctx)->base_key);
}
-done:
talloc_free(mem_ctx);
return werr;
}
@@ -1137,6 +1066,21 @@ done:
return werr;
}
+static WERROR smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_start();
+}
+
+static WERROR smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_commit();
+}
+
+static WERROR smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_cancel();
+}
+
struct smbconf_ops smbconf_ops_reg = {
.init = smbconf_reg_init,
.shutdown = smbconf_reg_shutdown,
@@ -1157,6 +1101,9 @@ struct smbconf_ops smbconf_ops_reg = {
.get_includes = smbconf_reg_get_includes,
.set_includes = smbconf_reg_set_includes,
.delete_includes = smbconf_reg_delete_includes,
+ .transaction_start = smbconf_reg_transaction_start,
+ .transaction_commit = smbconf_reg_transaction_commit,
+ .transaction_cancel = smbconf_reg_transaction_cancel,
};
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index f0561a5081..e24d35818c 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -581,7 +581,9 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
int smb_ldap_start_tls(LDAP *ldap_struct, int version)
{
+#ifdef LDAP_OPT_X_TLS
int rc;
+#endif
if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
return LDAP_SUCCESS;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index ed66666ddb..10b55f662d 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -1043,35 +1043,6 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command)
}
/**************************************************************************
- Wrapper for fork. Ensures that mypid is reset. Used so we can write
- a sys_getpid() that only does a system call *once*.
-****************************************************************************/
-
-static pid_t mypid = (pid_t)-1;
-
-pid_t sys_fork(void)
-{
- pid_t forkret = fork();
-
- if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
- mypid = (pid_t) -1;
-
- return forkret;
-}
-
-/**************************************************************************
- Wrapper for getpid. Ensures we only do a system call *once*.
-****************************************************************************/
-
-pid_t sys_getpid(void)
-{
- if (mypid == (pid_t)-1)
- mypid = getpid();
-
- return mypid;
-}
-
-/**************************************************************************
Wrapper for popen. Safer as it doesn't search a path.
Modified from the glibc sources.
modified by tridge to return a file descriptor. We must kick our FILE* habit
@@ -2008,7 +1979,6 @@ static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
{
ssize_t len = 0;
- int stop = 0;
DIR *dirp;
struct dirent *de;
int newfd = dup(attrdirfd);
@@ -2080,7 +2050,7 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
{
int filedes = openat(fildes, path, oflag, mode);
if (filedes == -1) {
- DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)));
+ DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes,path,strerror(errno)));
if (errno == EINVAL) {
errno = ENOTSUP;
} else {
diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c
index 1f5dfe4d25..092546e3eb 100644
--- a/source3/lib/tdb_validate.c
+++ b/source3/lib/tdb_validate.c
@@ -118,7 +118,8 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
/* parent */
- DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid));
+ DEBUG(10, ("tdb_validate: fork succeeded, child PID = %u\n",
+ (unsigned int)child_pid));
DEBUG(10, ("tdb_validate: waiting for child to finish...\n"));
while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
@@ -134,7 +135,7 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
}
if (wait_pid != child_pid) {
DEBUG(1, ("tdb_validate: waitpid returned pid %d, "
- "but %d was expected\n", wait_pid, child_pid));
+ "but %u was expected\n", wait_pid, (unsigned int)child_pid));
goto done;
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 6079e71063..89f7be8e6c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -798,43 +798,6 @@ char *clean_name(TALLOC_CTX *ctx, const char *s)
}
/*******************************************************************
- Close the low 3 fd's and open dev/null in their place.
-********************************************************************/
-
-void close_low_fds(bool stderr_too)
-{
-#ifndef VALGRIND
- int fd;
- int i;
-
- close(0);
- close(1);
-
- if (stderr_too)
- close(2);
-
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- if (i == 2 && !stderr_too)
- continue;
-
- fd = sys_open("/dev/null",O_RDWR,0);
- if (fd < 0)
- fd = sys_open("/dev/null",O_WRONLY,0);
- if (fd < 0) {
- DEBUG(0,("Can't open /dev/null\n"));
- return;
- }
- if (fd != i) {
- DEBUG(0,("Didn't get file descriptor %d\n",i));
- return;
- }
- }
-#endif
-}
-
-/*******************************************************************
Write data into an fd at a given offset. Ignore seek errors.
********************************************************************/
@@ -924,36 +887,6 @@ void smb_msleep(unsigned int t)
#endif
}
-/****************************************************************************
- Become a daemon, discarding the controlling terminal.
-****************************************************************************/
-
-void become_daemon(bool Fork, bool no_process_group)
-{
- if (Fork) {
- if (sys_fork()) {
- _exit(0);
- }
- }
-
- /* detach from the terminal */
-#ifdef HAVE_SETSID
- if (!no_process_group) setsid();
-#elif defined(TIOCNOTTY)
- if (!no_process_group) {
- int i = sys_open("/dev/tty", O_RDWR, 0);
- if (i != -1) {
- ioctl(i, (int) TIOCNOTTY, (char *)0);
- close(i);
- }
- }
-#endif /* HAVE_SETSID */
-
- /* Close fd's 0,1,2. Needed if started by rsh */
- close_low_fds(False); /* Don't close stderr, let the debug system
- attach it to the logfile */
-}
-
bool reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived)
@@ -966,6 +899,13 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
* numbers as each other */
set_need_random_reseed();
+#ifdef WITH_MADVISE_PROTECTED
+ /* Protect parent process from being killed by kernel when system
+ * memory is low. Child processes can still be killed */
+ if(!parent_longlived)
+ madvise(NULL,0,MADV_PROTECT);
+#endif
+
/* tdb needs special fork handling */
if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
@@ -3205,102 +3145,3 @@ const char *strip_hostname(const char *s)
return s;
}
-
-struct read_pkt_state {
- struct event_context *ev;
- int fd;
- uint8_t *buf;
- ssize_t (*more)(uint8_t *buf, size_t buflen, void *priv);
- void *priv;
-};
-
-static void read_pkt_done(struct async_req *subreq);
-
-struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, size_t initial,
- ssize_t (*more)(uint8_t *buf, size_t buflen,
- void *priv),
- void *priv)
-{
- struct async_req *result, *subreq;
- struct read_pkt_state *state;
-
- if (!async_req_setup(mem_ctx, &result, &state,
- struct read_pkt_state)) {
- return NULL;
- }
- state->ev = ev;
- state->fd = fd;
- state->more = more;
-
- state->buf = talloc_array(state, uint8_t, initial);
- if (state->buf == NULL) {
- goto fail;
- }
- subreq = recvall_send(state, ev, fd, state->buf, initial, 0);
- if (subreq == NULL) {
- goto fail;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = result;
- return result;
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void read_pkt_done(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
- size_t current_size;
- ssize_t received;
- ssize_t more;
- int err;
-
- received = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (received == -1) {
- async_req_error(req, err);
- return;
- }
- current_size = talloc_get_size(state->buf);
-
- more = state->more(state->buf, current_size, state->priv);
- if (more < 0) {
- async_req_error(req, EIO);
- return;
- }
- if (more == 0) {
- async_req_done(req);
- return;
- }
- state->buf = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t,
- current_size + more);
- if (async_req_nomem(state->buf, req)) {
- return;
- }
- subreq = recvall_send(state, state->ev, state->fd,
- state->buf + current_size, more, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = req;
-}
-
-ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **pbuf, int *perr)
-{
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
-
- if (async_req_is_errno(req, perr)) {
- return -1;
- }
- *pbuf = talloc_move(mem_ctx, &state->buf);
- return talloc_get_size(*pbuf);
-}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c46aa2ac49..6e75a67a85 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -953,7 +953,7 @@ struct open_socket_out_state {
int wait_nsec;
};
-static void open_socket_out_connected(struct async_req *subreq);
+static void open_socket_out_connected(struct tevent_req *subreq);
static int open_socket_out_state_destructor(struct open_socket_out_state *s)
{
@@ -967,19 +967,20 @@ static int open_socket_out_state_destructor(struct open_socket_out_state *s)
Create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
-struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const struct sockaddr_storage *pss,
- uint16_t port,
- int timeout)
+struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout)
{
char addr[INET6_ADDRSTRLEN];
- struct async_req *result, *subreq;
+ struct tevent_req *result, *subreq;
struct open_socket_out_state *state;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct open_socket_out_state)) {
+ result = tevent_req_create(mem_ctx, &state,
+ struct open_socket_out_state);
+ if (result == NULL) {
return NULL;
}
state->ev = ev;
@@ -995,7 +996,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
}
talloc_set_destructor(state, open_socket_out_state_destructor);
- if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) {
+ if (!tevent_req_set_endtime(
+ result, ev, timeval_current_ofs(0, timeout*1000))) {
goto fail;
}
@@ -1026,38 +1028,36 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
(struct sockaddr *)&state->ss,
state->salen);
if ((subreq == NULL)
- || !async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ || !tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
+ goto fail;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = result;
+ subreq->async.private_data = result;
return result;
post_status:
- if (!async_post_ntstatus(result, ev, status)) {
- goto fail;
- }
- return result;
+ tevent_req_nterror(result, status);
+ return tevent_req_post(result, ev);
fail:
TALLOC_FREE(result);
return NULL;
}
-static void open_socket_out_connected(struct async_req *subreq)
+static void open_socket_out_connected(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ struct tevent_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct tevent_req);
struct open_socket_out_state *state = talloc_get_type_abort(
- req->private_data, struct open_socket_out_state);
- int err;
+ req->private_state, struct open_socket_out_state);
+ int ret;
int sys_errno;
- err = async_connect_recv(subreq, &sys_errno);
+ ret = async_connect_recv(subreq, &sys_errno);
TALLOC_FREE(subreq);
- if (err == 0) {
- async_req_done(req);
+ if (ret == 0) {
+ tevent_req_done(req);
return;
}
@@ -1080,38 +1080,39 @@ static void open_socket_out_connected(struct async_req *subreq)
subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss,
state->salen);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- if (!async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
- async_req_error(req, ENOMEM);
+ if (!tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
return;
}
#ifdef EISCONN
if (sys_errno == EISCONN) {
- async_req_done(req);
+ tevent_req_done(req);
return;
}
#endif
/* real error */
- async_req_error(req, sys_errno);
+ tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
}
-NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
+NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
{
struct open_socket_out_state *state = talloc_get_type_abort(
- req->private_data, struct open_socket_out_state);
- int err;
+ req->private_state, struct open_socket_out_state);
+ NTSTATUS status;
- if (async_req_is_errno(req, &err)) {
- return map_nt_error_from_unix(err);
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
}
*pfd = state->fd;
state->fd = -1;
@@ -1123,7 +1124,7 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
+ struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
ev = event_context_init(frame);
@@ -1135,10 +1136,10 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
if (req == NULL) {
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
+ if (!tevent_req_poll(req, ev)) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto fail;
}
-
status = open_socket_out_recv(req, pfd);
fail:
TALLOC_FREE(frame);
@@ -1154,7 +1155,7 @@ struct open_socket_out_defer_state {
};
static void open_socket_out_defer_waited(struct async_req *subreq);
-static void open_socket_out_defer_connected(struct async_req *subreq);
+static void open_socket_out_defer_connected(struct tevent_req *subreq);
struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
@@ -1201,6 +1202,7 @@ 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);
+ struct tevent_req *subreq2;
bool ret;
ret = async_wait_recv(subreq);
@@ -1210,19 +1212,19 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
return;
}
- subreq = open_socket_out_send(state, state->ev, &state->ss,
- state->port, state->timeout);
- if (async_req_nomem(subreq, req)) {
+ subreq2 = open_socket_out_send(state, state->ev, &state->ss,
+ state->port, state->timeout);
+ if (async_req_nomem(subreq2, req)) {
return;
}
- subreq->async.fn = open_socket_out_defer_connected;
- subreq->async.priv = req;
+ subreq2->async.fn = open_socket_out_defer_connected;
+ subreq2->async.private_data = req;
}
-static void open_socket_out_defer_connected(struct async_req *subreq)
+static void open_socket_out_defer_connected(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, 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;
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 9358061797..b9ccb83e55 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -36,118 +36,6 @@ const char toupper_ascii_fast_table[128] = {
};
/**
- * @file
- * @brief String utilities.
- **/
-
-static bool next_token_internal_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep,
- bool ltrim)
-{
- char *s;
- char *saved_s;
- char *pbuf;
- bool quoted;
- size_t len=1;
-
- *pp_buff = NULL;
- if (!ptr) {
- return(false);
- }
-
- s = (char *)*ptr;
-
- /* default to simple separators */
- if (!sep) {
- sep = " \t\n\r";
- }
-
- /* find the first non sep char, if left-trimming is requested */
- if (ltrim) {
- while (*s && strchr_m(sep,*s)) {
- s++;
- }
- }
-
- /* nothing left? */
- if (!*s) {
- return false;
- }
-
- /* When restarting we need to go from here. */
- saved_s = s;
-
- /* Work out the length needed. */
- for (quoted = false; *s &&
- (quoted || !strchr_m(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- }
- }
-
- /* We started with len = 1 so we have space for the nul. */
- *pp_buff = TALLOC_ARRAY(ctx, char, len);
- if (!*pp_buff) {
- return false;
- }
-
- /* copy over the token */
- pbuf = *pp_buff;
- s = saved_s;
- for (quoted = false; *s &&
- (quoted || !strchr_m(sep,*s)); s++) {
- if ( *s == '\"' ) {
- quoted = !quoted;
- } else {
- *pbuf++ = *s;
- }
- }
-
- *ptr = (*s) ? s+1 : s;
- *pbuf = 0;
-
- return true;
-}
-
-#if 0
-/*
- * Get the next token from a string, return false if none found. Handles
- * double-quotes. This version trims leading separator characters before
- * looking for a token.
- */
-bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
-{
- return next_token_internal(ptr, buff, sep, bufsize, true);
-}
-#endif
-
-bool next_token_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep)
-{
- return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
-}
-
-/*
- * Get the next token from a string, return false if none found. Handles
- * double-quotes. This version does not trim leading separator characters
- * before looking for a token.
- */
-
-bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep)
-{
- return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
-}
-
-/**
* Case insensitive string compararison.
*
* iconv does not directly give us a way to compare strings in
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index 9bf6f29105..65906dcb91 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -27,9 +27,7 @@
struct req_read_state {
struct winbindd_request *wb_req;
- struct tevent_context *ev;
size_t max_extra_data;
- int fd;
};
bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
@@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
return WBC_ERR_SUCCESS;
}
-static void wb_req_read_len(struct async_req *subreq);
-static void wb_req_read_main(struct async_req *subreq);
-static void wb_req_read_extra(struct async_req *subreq);
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_req_read_done(struct tevent_req *subreq);
struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int fd, size_t max_extra_data)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
state->max_extra_data = max_extra_data;
- state->wb_req = talloc(state, struct winbindd_request);
- if (state->wb_req == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length),
- sizeof(state->wb_req->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state);
if (subreq == NULL) {
goto nomem;
}
- subreq->async.fn = wb_req_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_req_read_done;
+ subreq->async.private_data = result;
return result;
-
nomem:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_read_len(struct async_req *subreq)
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
- req->private_data, struct req_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
+ private_data, struct req_read_state);
+ struct winbindd_request *req = (struct winbindd_request *)buf;
- if (state->wb_req->length != sizeof(struct winbindd_request)) {
- 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, WBC_ERR_INVALID_RESPONSE);
- return;
+ if (buflen == 4) {
+ if (req->length != sizeof(struct winbindd_request)) {
+ DEBUG(0, ("wb_req_read_len: Invalid request size "
+ "received: %d (expected %d)\n",
+ (int)req->length,
+ (int)sizeof(struct winbindd_request)));
+ return -1;
+ }
+ return sizeof(struct winbindd_request) - 4;
}
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
- sizeof(struct winbindd_request) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
+ if ((state->max_extra_data != 0)
+ && (req->extra_len > state->max_extra_data)) {
+ DEBUG(3, ("Got request with %d bytes extra data on "
+ "unprivileged socket\n", (int)req->extra_len));
+ return -1;
}
- subreq->async.fn = wb_req_read_main;
- subreq->async.priv = req;
+ return req->extra_len;
}
-static void wb_req_read_main(struct async_req *subreq)
+static void wb_req_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
req->private_data, struct req_read_state);
int err;
ssize_t ret;
+ uint8_t *buf;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- if ((state->max_extra_data != 0)
- && (state->wb_req->extra_len > state->max_extra_data)) {
- DEBUG(3, ("Got request with %d bytes extra data on "
- "unprivileged socket\n",
- (int)state->wb_req->extra_len));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_req->extra_data.data = TALLOC_ARRAY(
- state->wb_req, char, state->wb_req->extra_len + 1);
- if (async_req_nomem(state->wb_req->extra_data.data, req)) {
- return;
- }
-
- state->wb_req->extra_data.data[state->wb_req->extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_req = (struct winbindd_request *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_req->extra_len != 0) {
+ state->wb_req->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_request);
+ } else {
+ state->wb_req->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_request **preq)
{
@@ -237,90 +181,60 @@ wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct req_write_state {
- struct winbindd_request *wb_req;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_req_write_main(struct async_req *subreq);
-static void wb_req_write_extra(struct async_req *subreq);
+static void wb_req_write_done(struct tevent_req *subreq);
struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_request *wb_req)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_req = wb_req;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_req,
- sizeof(struct winbindd_request), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_req;
+ state->iov[0].iov_len = sizeof(struct winbindd_request);
+
+ if (wb_req->extra_len != 0) {
+ state->iov[1].iov_base = wb_req->extra_data.data;
+ state->iov[1].iov_len = wb_req->extra_len;
+ count = 2;
}
- subreq->async.fn = wb_req_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_req_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_write_main(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct req_write_state *state = talloc_get_type_abort(
- req->private_data, struct req_write_state);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(state, state->ev, state->fd,
- state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_write_extra(struct async_req *subreq)
+static void wb_req_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
async_req_done(req);
}
@@ -331,40 +245,29 @@ wbcErr wb_req_write_recv(struct async_req *req)
struct resp_read_state {
struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- size_t max_extra_data;
- int fd;
};
-static void wb_resp_read_len(struct async_req *subreq);
-static void wb_resp_read_main(struct async_req *subreq);
-static void wb_resp_read_extra(struct async_req *subreq);
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_resp_read_done(struct tevent_req *subreq);
struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = talloc(state, struct winbindd_response);
- if (state->wb_resp == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_resp->length),
- sizeof(state->wb_resp->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state);
if (subreq == NULL) {
goto nomem;
}
-
- subreq->async.fn = wb_resp_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_resp_read_done;
+ subreq->async.private_data = result;
return result;
nomem:
@@ -372,100 +275,50 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
return NULL;
}
-static void wb_resp_read_len(struct async_req *subreq)
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_read_state *state = talloc_get_type_abort(
- req->private_data, struct resp_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_resp->length < sizeof(struct winbindd_response)) {
- DEBUG(0, ("wb_resp_read_len: Invalid response size received: "
- "%d (expected at least%d)\n",
- (int)state->wb_resp->length,
- (int)sizeof(struct winbindd_response)));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1,
- sizeof(struct winbindd_response) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_main;
- subreq->async.priv = req;
+ struct winbindd_response *resp = (struct winbindd_response *)buf;
+
+ if (buflen == 4) {
+ if (resp->length < sizeof(struct winbindd_response)) {
+ DEBUG(0, ("wb_resp_read_len: Invalid response size "
+ "received: %d (expected at least%d)\n",
+ (int)resp->length,
+ (int)sizeof(struct winbindd_response)));
+ return -1;
+ }
+ }
+ return resp->length - buflen;
}
-static void wb_resp_read_main(struct async_req *subreq)
+static void wb_resp_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct resp_read_state *state = talloc_get_type_abort(
req->private_data, struct resp_read_state);
+ uint8_t *buf;
int err;
ssize_t ret;
- size_t extra_len;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- extra_len = state->wb_resp->length - sizeof(struct winbindd_response);
- if (extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_resp->extra_data.data = TALLOC_ARRAY(
- state->wb_resp, char, extra_len+1);
- if (async_req_nomem(state->wb_resp->extra_data.data, req)) {
- return;
- }
- ((char *)state->wb_resp->extra_data.data)[extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_resp->extra_data.data,
- extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_resp = (struct winbindd_response *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_resp->length > sizeof(struct winbindd_response)) {
+ state->wb_resp->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_response);
+ } else {
+ state->wb_resp->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presp)
{
@@ -481,91 +334,61 @@ wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct resp_write_state {
- struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_resp_write_main(struct async_req *subreq);
-static void wb_resp_write_extra(struct async_req *subreq);
+static void wb_resp_write_done(struct tevent_req *subreq);
struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_response *wb_resp)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = wb_resp;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_resp,
- sizeof(struct winbindd_response), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_resp;
+ state->iov[0].iov_len = sizeof(struct winbindd_response);
+
+ if (wb_resp->length > sizeof(struct winbindd_response)) {
+ state->iov[1].iov_base = wb_resp->extra_data.data;
+ state->iov[1].iov_len =
+ wb_resp->length - sizeof(struct winbindd_response);
+ count = 2;
}
- subreq->async.fn = wb_resp_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_resp_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_resp_write_main(struct async_req *subreq)
+static void wb_resp_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_write_state *state = talloc_get_type_abort(
- req->private_data, struct resp_write_state);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
- if (state->wb_resp->length == sizeof(struct winbindd_response)) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(
- state, state->ev, state->fd,
- state->wb_resp->extra_data.data,
- state->wb_resp->length - sizeof(struct winbindd_response), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_write_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (err < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
async_req_done(req);
}
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 4d3a609530..b8d55a944a 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -147,17 +147,30 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
return result;
}
+struct wb_connect_state {
+ int dummy;
+};
+
+static void wbc_connect_connected(struct tevent_req *subreq);
+
static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- const char *dir)
+ struct tevent_context *ev,
+ struct wb_context *wb_ctx,
+ const char *dir)
{
- struct async_req *req;
+ struct async_req *result;
+ struct tevent_req *subreq;
+ struct wb_connect_state *state;
struct sockaddr_un sunaddr;
struct stat st;
char *path = NULL;
wbcErr wbc_err;
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct wb_connect_state)) {
+ return NULL;
+ }
+
if (wb_ctx->fd != -1) {
close(wb_ctx->fd);
wb_ctx->fd = -1;
@@ -205,33 +218,46 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
goto post_status;
}
- req = async_connect_send(mem_ctx, ev, wb_ctx->fd,
- (struct sockaddr *)&sunaddr,
- sizeof(sunaddr));
- if (req == NULL) {
+ subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
+ (struct sockaddr *)&sunaddr,
+ sizeof(sunaddr));
+ if (subreq == NULL) {
goto nomem;
}
- if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) {
- TALLOC_FREE(req);
+ subreq->async.fn = wbc_connect_connected;
+ subreq->async.private_data = result;
+
+ if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
goto nomem;
}
- return req;
+ return result;
nomem:
wbc_err = WBC_ERR_NO_MEMORY;
post_status:
- req = async_req_new(mem_ctx);
- if (req == NULL) {
- return NULL;
- }
- if (async_post_error(req, ev, wbc_err)) {
- return req;
+ if (async_post_error(result, ev, wbc_err)) {
+ return result;
}
- TALLOC_FREE(req);
+ TALLOC_FREE(result);
return NULL;
}
+static void wbc_connect_connected(struct tevent_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct async_req);
+ int res, err;
+
+ res = async_connect_recv(subreq, &err);
+ TALLOC_FREE(subreq);
+ if (res == -1) {
+ async_req_error(req, map_wbc_err_from_errno(err));
+ return;
+ }
+ async_req_done(req);
+}
+
static wbcErr wb_connect_recv(struct async_req *req)
{
return async_req_simple_recv_wbcerr(req);
diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h
index 42662a224b..57a9b6a002 100644
--- a/source3/libaddns/dns.h
+++ b/source3/libaddns/dns.h
@@ -81,12 +81,12 @@
#include <krb5.h>
#endif
-#if HAVE_GSSAPI_H
-#include <gssapi.h>
-#elif HAVE_GSSAPI_GSSAPI_H
+#if HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#elif HAVE_GSSAPI_GSSAPI_GENERIC_H
#include <gssapi/gssapi_generic.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
#endif
#if defined(HAVE_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_GENERIC_H)
diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c
index a5e04a4a6c..3bf0b6f7a7 100644
--- a/source3/libads/disp_sec.c
+++ b/source3/libads/disp_sec.c
@@ -112,15 +112,15 @@ static void ads_disp_sec_ace_object(ADS_STRUCT *ads,
TALLOC_CTX *mem_ctx,
struct security_ace_object *object)
{
- if (object->flags & SEC_ACE_OBJECT_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_PRESENT\n");
+ if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx,
&object->type.type),
ads_interprete_guid_from_object(ads, mem_ctx,
&object->type.type));
}
- if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n");
+ if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx,
&object->inherited_type.inherited_type),
ads_interprete_guid_from_object(ads, mem_ctx,
diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c
index 3d385dec14..9367bcae9c 100644
--- a/source3/libgpo/gpo_reg.c
+++ b/source3/libgpo/gpo_reg.c
@@ -691,7 +691,7 @@ static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
SEC_ACE ace[6];
uint32_t mask;
- SEC_ACL *acl = NULL;
+ SEC_ACL *theacl = NULL;
uint8_t inherit_flags;
@@ -735,15 +735,15 @@ static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
SEC_ACE_TYPE_ACCESS_ALLOWED,
mask, inherit_flags);
- acl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
- W_ERROR_HAVE_NO_MEMORY(acl);
+ theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
+ W_ERROR_HAVE_NO_MEMORY(theacl);
*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
SEC_DESC_SELF_RELATIVE |
SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
NULL, NULL, NULL,
- acl, sd_size);
+ theacl, sd_size);
W_ERROR_HAVE_NO_MEMORY(*sd);
return WERR_OK;
diff --git a/source3/libgpo/gpo_sec.c b/source3/libgpo/gpo_sec.c
index 42ab72a99b..c72bb26732 100644
--- a/source3/libgpo/gpo_sec.c
+++ b/source3/libgpo/gpo_sec.c
@@ -38,12 +38,12 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec
}
switch (object->flags) {
- case SEC_ACE_OBJECT_PRESENT:
+ case SEC_ACE_OBJECT_TYPE_PRESENT:
if (GUID_equal(&object->type.type,
&ext_right_apg_guid)) {
return True;
}
- case SEC_ACE_OBJECT_INHERITED_PRESENT:
+ case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT:
if (GUID_equal(&object->inherited_type.inherited_type,
&ext_right_apg_guid)) {
return True;
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 20f7b97745..117178f376 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -50,12 +50,6 @@
#define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \
LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT)
-#define W_ERROR_NOT_OK_GOTO_DONE(x) do { \
- if (!W_ERROR_IS_OK(x)) {\
- goto done;\
- }\
-} while (0)
-
/****************************************************************
****************************************************************/
diff --git a/source3/librpc/gen_ndr/ndr_notify.c b/source3/librpc/gen_ndr/ndr_notify.c
index 00ba8bc293..d4ac42e961 100644
--- a/source3/librpc/gen_ndr/ndr_notify.c
+++ b/source3/librpc/gen_ndr/ndr_notify.c
@@ -10,6 +10,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f
NDR_CHECK(ndr_push_server_id(ndr, NDR_SCALARS, &r->server));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->filter));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->subdir_filter));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->dir_fd));
+ NDR_CHECK(ndr_push_file_id(ndr, NDR_SCALARS, &r->dir_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
@@ -21,6 +23,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_push_server_id(ndr, NDR_BUFFERS, &r->server));
+ NDR_CHECK(ndr_push_file_id(ndr, NDR_BUFFERS, &r->dir_id));
}
return NDR_ERR_SUCCESS;
}
@@ -32,6 +35,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f
NDR_CHECK(ndr_pull_server_id(ndr, NDR_SCALARS, &r->server));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->filter));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->subdir_filter));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->dir_fd));
+ NDR_CHECK(ndr_pull_file_id(ndr, NDR_SCALARS, &r->dir_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
@@ -43,6 +48,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_server_id(ndr, NDR_BUFFERS, &r->server));
+ NDR_CHECK(ndr_pull_file_id(ndr, NDR_BUFFERS, &r->dir_id));
}
return NDR_ERR_SUCCESS;
}
@@ -54,6 +60,8 @@ _PUBLIC_ void ndr_print_notify_entry(struct ndr_print *ndr, const char *name, co
ndr_print_server_id(ndr, "server", &r->server);
ndr_print_uint32(ndr, "filter", r->filter);
ndr_print_uint32(ndr, "subdir_filter", r->subdir_filter);
+ ndr_print_uint32(ndr, "dir_fd", r->dir_fd);
+ ndr_print_file_id(ndr, "dir_id", &r->dir_id);
ndr_print_string(ndr, "path", r->path);
ndr_print_uint32(ndr, "path_len", r->path_len);
ndr_print_pointer(ndr, "private_data", r->private_data);
diff --git a/source3/librpc/gen_ndr/notify.h b/source3/librpc/gen_ndr/notify.h
index c809702e5d..a5ec4a46e6 100644
--- a/source3/librpc/gen_ndr/notify.h
+++ b/source3/librpc/gen_ndr/notify.h
@@ -9,6 +9,8 @@ struct notify_entry {
struct server_id server;
uint32_t filter;
uint32_t subdir_filter;
+ uint32_t dir_fd;
+ struct file_id dir_id;
const char * path;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */
uint32_t path_len;
void* private_data;
diff --git a/source3/librpc/idl/notify.idl b/source3/librpc/idl/notify.idl
index c4e633c254..550783b5cd 100644
--- a/source3/librpc/idl/notify.idl
+++ b/source3/librpc/idl/notify.idl
@@ -18,6 +18,8 @@ interface notify
server_id server;
uint32 filter; /* filter to apply in this directory */
uint32 subdir_filter; /* filter to apply in child directories */
+ uint32 dir_fd; /* fd of open directory */
+ file_id dir_id; /* file_id of open directory */
utf8string path;
uint32 path_len; /* saves some computation on search */
pointer private_data;
diff --git a/source3/librpc/ndr/util.c b/source3/librpc/ndr/util.c
index 5afc4f4f5a..8fac5eadd4 100644
--- a/source3/librpc/ndr/util.c
+++ b/source3/librpc/ndr/util.c
@@ -155,6 +155,45 @@ void ndr_print_server_id(struct ndr_print *ndr, const char *name, const struct s
ndr->depth--;
}
+enum ndr_err_code ndr_push_file_id(struct ndr_push *ndr, int ndr_flags, const struct file_id *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS,
+ (uint64_t)r->devid));
+ NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS,
+ (uint64_t)r->inode));
+ NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS,
+ (uint64_t)r->extid));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_file_id(struct ndr_pull *ndr, int ndr_flags, struct file_id *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->devid));
+ NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->inode));
+ NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->extid));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+void ndr_print_file_id(struct ndr_print *ndr, const char *name, const struct file_id *r)
+{
+ ndr_print_struct(ndr, name, "file_id");
+ ndr->depth++;
+ ndr_print_udlong(ndr, "devid", (uint64_t)r->devid);
+ ndr_print_udlong(ndr, "inode", (uint64_t)r->inode);
+ ndr_print_udlong(ndr, "extid", (uint64_t)r->extid);
+ ndr->depth--;
+}
+
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b)
{
ndr->print(ndr, "%-25s: %s", name, b?"true":"false");
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index dabfc398ce..ad11ee0ed4 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1642,6 +1642,7 @@ bool cli_session_request(struct cli_state *cli,
{
char *p;
int len = 4;
+ char *tmp;
/* 445 doesn't have session request */
if (cli->port == 445)
@@ -1651,14 +1652,30 @@ bool cli_session_request(struct cli_state *cli,
memcpy(&(cli->called ), called , sizeof(*called ));
/* put in the destination name */
+
+ tmp = name_mangle(talloc_tos(), cli->called.name,
+ cli->called.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->called .name, p, cli->called .name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* and my name */
+
+ tmp = name_mangle(talloc_tos(), cli->calling.name,
+ cli->calling.name_type);
+ if (tmp == NULL) {
+ return false;
+ }
+
p = cli->outbuf+len;
- name_mangle(cli->calling.name, p, cli->calling.name_type);
- len += name_len(p);
+ memcpy(p, tmp, name_len(tmp));
+ len += name_len(tmp);
+ TALLOC_FREE(tmp);
/* send a session request (RFC 1002) */
/* setup the packet length
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index c1af48507c..4c12d18ab7 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -630,11 +630,11 @@ smbc_version(void)
* Set the credentials so DFS will work when following referrals.
*/
void
-smbc_set_credentials(char *workgroup,
- char *user,
- char *password,
+smbc_set_credentials(const char *workgroup,
+ const char *user,
+ const char *password,
smbc_bool use_kerberos,
- char *signing_state)
+ const char *signing_state)
{
struct user_auth_info *auth_info;
@@ -652,3 +652,39 @@ smbc_set_credentials(char *workgroup,
cli_cm_set_credentials(auth_info);
TALLOC_FREE(auth_info);
}
+
+void smbc_set_credentials_with_fallback(SMBCCTX *context,
+ const char *workgroup,
+ const char *user,
+ const char *password)
+{
+ smbc_bool use_kerberos = false;
+ const char *signing_state = "off";
+
+ if (! context ||
+ ! workgroup || ! *workgroup ||
+ ! user || ! *user ||
+ ! password || ! *password) {
+
+ return;
+ }
+
+ if (smbc_getOptionUseKerberos(context)) {
+ use_kerberos = True;
+ }
+
+ if (lp_client_signing()) {
+ signing_state = "on";
+ }
+
+ if (lp_client_signing() == Required) {
+ signing_state = "force";
+ }
+
+ smbc_set_credentials(workgroup, user, password,
+ use_kerberos, signing_state);
+
+ if (smbc_getOptionFallbackAfterKerberos(context)) {
+ cli_cm_set_fallback_after_kerberos();
+ }
+}
diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index e9b7b4f95a..56661af70b 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -1500,6 +1500,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
char *user = NULL;
char *password = NULL;
char *workgroup = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
char *path = NULL;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
@@ -1517,7 +1519,7 @@ SMBC_chmod_ctx(SMBCCTX *context,
return -1;
}
- DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
+ DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, (unsigned int)newmode));
if (SMBC_parse_path(frame,
context,
@@ -1550,6 +1552,14 @@ SMBC_chmod_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1; /* errno set by SMBC_server */
}
+
+ /*d_printf(">>>unlink: resolving %s\n", path);*/
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
+ d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
+ return -1;
+ }
mode = 0;
@@ -1558,8 +1568,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
- if (!cli_setatr(srv->cli, path, mode, 0)) {
- errno = SMBC_errno(context, srv->cli);
+ if (!cli_setatr(targetcli, targetpath, mode, 0)) {
+ errno = SMBC_errno(context, targetcli);
TALLOC_FREE(frame);
return -1;
}
@@ -1900,6 +1910,12 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
}
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ocontext,
+ workgroup,
+ user1,
+ password1);
+
/*d_printf(">>>rename: resolving %s\n", path1);*/
if (!cli_resolve_path(frame, "", srv->cli, path1,
&targetcli1, &targetpath1)) {
@@ -1907,6 +1923,13 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
TALLOC_FREE(frame);
return -1;
}
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ncontext,
+ workgroup,
+ user2,
+ password2);
+
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
if (!cli_resolve_path(frame, "", srv->cli, path2,
diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c
index ece056db87..28256bb241 100644
--- a/source3/libsmb/libsmb_file.c
+++ b/source3/libsmb/libsmb_file.c
@@ -382,7 +382,7 @@ SMBC_write_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>write: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", file->srv->cli, path,
&targetcli, &targetpath)) {
diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c
index 6d69924231..6a59a12ed0 100644
--- a/source3/libsmb/libsmb_path.c
+++ b/source3/libsmb/libsmb_path.c
@@ -216,7 +216,7 @@ smbc_urlencode(char *dest,
* are supported.
*/
-static const char *smbc_prefix = "smb:";
+#define SMBC_PREFIX "smb:"
int
SMBC_parse_path(TALLOC_CTX *ctx,
@@ -233,6 +233,7 @@ SMBC_parse_path(TALLOC_CTX *ctx,
char *s;
const char *p;
char *q, *r;
+ char *workgroup = NULL;
int len;
/* Ensure these returns are at least valid pointers. */
@@ -262,8 +263,8 @@ SMBC_parse_path(TALLOC_CTX *ctx,
s = talloc_strdup(ctx, fname);
/* see if it has the right prefix */
- len = strlen(smbc_prefix);
- if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) {
+ len = strlen(SMBC_PREFIX);
+ if (strncmp(s,SMBC_PREFIX,len) || (s[len] != '/' && s[len] != 0)) {
return -1; /* What about no smb: ? */
}
@@ -332,7 +333,6 @@ SMBC_parse_path(TALLOC_CTX *ctx,
u = userinfo;
if (strchr_m(u, ';')) {
- char *workgroup;
next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
if (!workgroup) {
return -1;
@@ -394,6 +394,19 @@ decoding:
(void) urldecode_talloc(ctx, pp_share, *pp_share);
(void) urldecode_talloc(ctx, pp_user, *pp_user);
(void) urldecode_talloc(ctx, pp_password, *pp_password);
+
+ if (!workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ }
+ if (!workgroup) {
+ return -1;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_user,
+ *pp_password);
return 0;
}
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 6d7a86241a..eda37f2187 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -238,6 +238,7 @@ SMBC_server(TALLOC_CTX *ctx,
char **pp_password)
{
SMBCSRV *srv=NULL;
+ char *workgroup = NULL;
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
@@ -359,7 +360,7 @@ SMBC_server(TALLOC_CTX *ctx,
if (srv) {
/* ... then we're done here. Give 'em what they came for. */
- return srv;
+ goto done;
}
/* If we're not asked to connect when a connection doesn't exist... */
@@ -601,6 +602,22 @@ again:
server, share, srv));
DLIST_ADD(context->internal->servers, srv);
+done:
+ if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ } else {
+ workgroup = *pp_workgroup;
+ }
+ if(!workgroup) {
+ return NULL;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_username,
+ *pp_password);
+
return srv;
failed:
diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c
index 1ffe141796..f8571ff110 100644
--- a/source3/libsmb/libsmb_stat.c
+++ b/source3/libsmb/libsmb_stat.c
@@ -155,7 +155,7 @@ SMBC_stat_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
if (!user || user[0] == (char)0) {
user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 02b13ae63e..5f3eda44fe 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -1279,12 +1279,19 @@ static int name_interpret(char *in, fstring name)
Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
****************************************************************************/
-int name_mangle( char *In, char *Out, char name_type )
+char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type)
{
int i;
int len;
nstring buf;
- char *p = Out;
+ char *result;
+ char *p;
+
+ result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
+ if (result == NULL) {
+ return NULL;
+ }
+ p = result;
/* Safely copy the input string, In, into buf[]. */
if (strcmp(In,"*") == 0)
@@ -1321,7 +1328,7 @@ int name_mangle( char *In, char *Out, char name_type )
p[0] = len;
if( len > 0 )
p[len+1] = 0;
- return( name_len(Out) );
+ return result;
case '.':
p[0] = len;
p += (len + 1);
@@ -1333,7 +1340,7 @@ int name_mangle( char *In, char *Out, char name_type )
}
}
- return( name_len(Out) );
+ return result;
}
/****************************************************************************
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index cc13476935..0764f97d85 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -110,12 +110,10 @@ void debug_ntlmssp_flags(uint32 neg_flags)
*
*/
-static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
+static void get_challenge(const struct ntlmssp_state *ntlmssp_state,
+ uint8_t chal[8])
{
- static uchar chal[8];
- generate_random_buffer(chal, sizeof(chal));
-
- return chal;
+ generate_random_buffer(chal, 8);
}
/**
@@ -517,7 +515,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
char *dnsdomname = NULL;
uint32 neg_flags = 0;
uint32 ntlmssp_command, chal_flags;
- const uint8 *cryptkey;
+ uint8_t cryptkey[8];
const char *target_name;
/* parse the NTLMSSP packet */
@@ -541,7 +539,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
/* Ask our caller what challenge they would like in the packet */
- cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
+ ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);
/* Check if we may set the challenge */
if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index af3f7b0dd5..177e0114b3 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -38,7 +38,8 @@ struct smbdb_ctx {
#endif
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev,
- uint64_t ino, const struct smb_share_mode_entry *new_entry,
+ uint64_t ino, uint64_t extid,
+ const struct smb_share_mode_entry *new_entry,
const char *sharepath, const char *filename);
static bool sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2)
@@ -83,6 +84,7 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
struct locking_key {
SMB_DEV_T dev;
SMB_INO_T inode;
+ uint64_t extid;
};
int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
@@ -93,13 +95,14 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
}
static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
- uint64_t ino)
+ uint64_t ino, uint64_t extid)
{
TDB_DATA ld;
memset(lk, '\0', sizeof(*lk));
lk->dev = (SMB_DEV_T)dev;
lk->inode = (SMB_INO_T)ino;
+ lk->extid = extid;
ld.dptr = (uint8 *)lk;
ld.dsize = sizeof(*lk);
return ld;
@@ -111,19 +114,22 @@ static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino)
+ uint64_t ino,
+ uint64_t extid)
{
struct locking_key lk;
- return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
+ return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
+ extid));
}
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
- uint64_t ino)
+ uint64_t ino,
+ uint64_t extid)
{
struct locking_key lk;
return tdb_chainunlock(db_ctx->smb_tdb,
- get_locking_key(&lk, dev, ino));
+ get_locking_key(&lk, dev, ino, extid));
}
/*
@@ -140,7 +146,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry,
e_entry->share_access == (uint32_t)entry->share_access &&
e_entry->access_mask == (uint32_t)entry->access_mask &&
e_entry->dev == entry->id.devid &&
- e_entry->ino == entry->id.inode);
+ e_entry->ino == entry->id.inode &&
+ e_entry->extid == entry->id.extid);
}
/*
@@ -160,6 +167,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
out->access_mask = in->access_mask;
out->id.devid = in->dev;
out->id.inode = in->ino;
+ out->id.extid = in->extid;
out->uid = (uint32)geteuid();
out->flags = 0;
}
@@ -172,6 +180,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close)
{
@@ -187,7 +196,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
*pp_list = NULL;
*p_delete_on_close = 0;
- db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
+ db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
+ extid));
if (!db_data.dptr) {
return 0;
}
@@ -229,6 +239,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
/* Copy into the external list. */
sme->dev = share->id.devid;
sme->ino = share->id.inode;
+ sme->extid = share->id.extid;
sme->share_access = (uint32_t)share->share_access;
sme->access_mask = (uint32_t)share->access_mask;
sme->open_time.tv_sec = share->time.tv_sec;
@@ -257,13 +268,14 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *sharepath, /* Must be absolute utf8 path. */
const char *filename) /* Must be relative utf8 path. */
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -360,24 +372,26 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *filename) /* Must be absolute utf8 path. */
{
if (*filename != '/') {
abort();
}
- return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry,
+ return smb_create_share_mode_entry_ex(db_ctx, dev, ino, extid, new_entry,
"/", &filename[1]);
}
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *del_entry)
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@@ -475,12 +489,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
+ uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const struct smb_share_mode_entry *new_entry)
{
TDB_DATA db_data;
struct locking_key lk;
- TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
+ TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index d12c4affc3..aa522ac780 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -74,6 +74,7 @@ bool brl_same_context(const struct lock_context *ctx1,
static bool brl_overlap(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
+ /* XXX Remove for Win7 compatibility. */
/* this extra check is not redundent - it copes with locks
that go beyond the end of 64 bit file space */
if (lck1->size != 0 &&
@@ -105,8 +106,11 @@ static bool brl_conflict(const struct lock_struct *lck1,
return False;
}
- if (brl_same_context(&lck1->context, &lck2->context) &&
- lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) {
+ /* A READ lock can stack on top of a WRITE lock if they have the same
+ * context & fnum. */
+ if (lck1->lock_type == WRITE_LOCK && lck2->lock_type == READ_LOCK &&
+ brl_same_context(&lck1->context, &lck2->context) &&
+ lck1->fnum == lck2->fnum) {
return False;
}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index cc0295e749..1737eab1c6 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -923,12 +923,12 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
return False;
}
- push_file_id_16(frm, &lck->id);
+ push_file_id_24(frm, &lck->id);
DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
- safe_strcpy(&frm[16], lck->servicepath, sp_len);
- safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
+ safe_strcpy(&frm[24], lck->servicepath, sp_len);
+ safe_strcpy(&frm[24 + sp_len + 1], lck->filename, fn_len);
/* Send the messages. */
for (i=0; i<lck->num_share_modes; i++) {
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 556dad6b5e..7756f8f3ab 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -44,10 +44,10 @@ typedef struct _SMB_ACL4_INT_T
SMB_ACE4_INT_T *last;
} SMB_ACL4_INT_T;
-static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl)
+static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *theacl)
{
- SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
- if (acl==NULL)
+ SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl;
+ if (theacl==NULL)
{
DEBUG(2, ("acl is NULL\n"));
errno = EINVAL;
@@ -83,21 +83,21 @@ static SMB_ACE4_INT_T *get_validated_aceint(SMB4ACE_T *ace)
SMB4ACL_T *smb_create_smb4acl(void)
{
TALLOC_CTX *mem_ctx = talloc_tos();
- SMB_ACL4_INT_T *acl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T));
- if (acl==NULL)
+ SMB_ACL4_INT_T *theacl = (SMB_ACL4_INT_T *)TALLOC_ZERO_SIZE(mem_ctx, sizeof(SMB_ACL4_INT_T));
+ if (theacl==NULL)
{
DEBUG(0, ("TALLOC_SIZE failed\n"));
errno = ENOMEM;
return NULL;
}
- acl->magic = SMB_ACL4_INT_MAGIC;
- /* acl->first, last = NULL not needed */
- return (SMB4ACL_T *)acl;
+ theacl->magic = SMB_ACL4_INT_MAGIC;
+ /* theacl->first, last = NULL not needed */
+ return (SMB4ACL_T *)theacl;
}
-SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop)
+SMB4ACE_T *smb_add_ace4(SMB4ACL_T *theacl, SMB_ACE4PROP_T *prop)
{
- SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+ SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
TALLOC_CTX *mem_ctx = talloc_tos();
SMB_ACE4_INT_T *ace;
@@ -143,18 +143,18 @@ SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace)
return (SMB4ACE_T *)aceint->next;
}
-SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl)
+SMB4ACE_T *smb_first_ace4(SMB4ACL_T *theacl)
{
- SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+ SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
if (aclint==NULL)
return NULL;
return (SMB4ACE_T *)aclint->first;
}
-uint32 smb_get_naces(SMB4ACL_T *acl)
+uint32 smb_get_naces(SMB4ACL_T *theacl)
{
- SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+ SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
if (aclint==NULL)
return 0;
@@ -195,22 +195,23 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
return 0;
}
-static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
+static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *theacl, /* in */
DOM_SID *psid_owner, /* in */
DOM_SID *psid_group, /* in */
+ bool is_directory, /* in */
SEC_ACE **ppnt_ace_list, /* out */
int *pgood_aces /* out */
)
{
- SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)acl;
+ SMB_ACL4_INT_T *aclint = (SMB_ACL4_INT_T *)theacl;
SMB_ACE4_INT_T *aceint;
SEC_ACE *nt_ace_list = NULL;
int good_aces = 0;
DEBUG(10, ("smbacl_nfs42win entered"));
- aclint = get_validated_aclint(acl);
- /* We do not check for naces being 0 or acl being NULL here because it is done upstream */
+ aclint = get_validated_aclint(theacl);
+ /* We do not check for naces being 0 or theacl being NULL here because it is done upstream */
/* in smb_get_nt_acl_nfs4(). */
nt_ace_list = (SEC_ACE *)TALLOC_ZERO_SIZE(mem_ctx, aclint->naces * sizeof(SEC_ACE));
if (nt_ace_list==NULL)
@@ -256,6 +257,10 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
DEBUG(10, ("mapped %d to %s\n", ace->who.id,
sid_string_dbg(&sid)));
+ if (is_directory && (ace->aceMask & SMB_ACE4_ADD_FILE)) {
+ ace->aceMask |= SMB_ACE4_DELETE_CHILD;
+ }
+
mask = ace->aceMask;
init_sec_ace(&nt_ace_list[good_aces++], &sid,
ace->aceType, mask,
@@ -270,7 +275,7 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *acl, /* in */
static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
uint32 security_info,
- SEC_DESC **ppdesc, SMB4ACL_T *acl)
+ SEC_DESC **ppdesc, SMB4ACL_T *theacl)
{
int good_aces = 0;
DOM_SID sid_owner, sid_group;
@@ -279,7 +284,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
SEC_ACL *psa = NULL;
TALLOC_CTX *mem_ctx = talloc_tos();
- if (acl==NULL || smb_get_naces(acl)==0)
+ if (theacl==NULL || smb_get_naces(theacl)==0)
return NT_STATUS_ACCESS_DENIED; /* special because we
* shouldn't alloc 0 for
* win */
@@ -287,7 +292,8 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
uid_to_sid(&sid_owner, sbuf->st_uid);
gid_to_sid(&sid_group, sbuf->st_gid);
- if (smbacl4_nfs42win(mem_ctx, acl, &sid_owner, &sid_group, &nt_ace_list, &good_aces)==False) {
+ if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode),
+ &nt_ace_list, &good_aces)==False) {
DEBUG(8,("smbacl4_nfs42win failed\n"));
return map_nt_error_from_unix(errno);
}
@@ -316,7 +322,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
uint32 security_info,
- SEC_DESC **ppdesc, SMB4ACL_T *acl)
+ SEC_DESC **ppdesc, SMB4ACL_T *theacl)
{
SMB_STRUCT_STAT sbuf;
@@ -326,13 +332,13 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
return map_nt_error_from_unix(errno);
}
- return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl);
+ return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl);
}
NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn,
const char *name,
uint32 security_info,
- SEC_DESC **ppdesc, SMB4ACL_T *acl)
+ SEC_DESC **ppdesc, SMB4ACL_T *theacl)
{
SMB_STRUCT_STAT sbuf;
@@ -342,7 +348,7 @@ NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn,
return map_nt_error_from_unix(errno);
}
- return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, acl);
+ return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, theacl);
}
enum smbacl4_mode_enum {e_simple=0, e_special=1};
@@ -393,9 +399,9 @@ static int smbacl4_get_vfs_params(
return 0;
}
-static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl)
+static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *theacl)
{
- SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+ SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
SMB_ACE4_INT_T *aceint;
DEBUG(level, ("NFS4ACL: size=%d\n", aclint->naces));
@@ -417,10 +423,10 @@ static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *acl)
* return ace if found matching; otherwise NULL
*/
static SMB_ACE4PROP_T *smbacl4_find_equal_special(
- SMB4ACL_T *acl,
+ SMB4ACL_T *theacl,
SMB_ACE4PROP_T *aceNew)
{
- SMB_ACL4_INT_T *aclint = get_validated_aclint(acl);
+ SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl);
SMB_ACE4_INT_T *aceint;
for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) {
@@ -612,14 +618,14 @@ static bool smbacl4_fill_ace4(
static int smbacl4_MergeIgnoreReject(
enum smbacl4_acedup_enum acedup,
- SMB4ACL_T *acl, /* may modify it */
+ SMB4ACL_T *theacl, /* may modify it */
SMB_ACE4PROP_T *ace, /* the "new" ACE */
bool *paddNewACE,
int i
)
{
int result = 0;
- SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(acl, ace);
+ SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace);
if (ace4found)
{
switch(acedup)
@@ -652,14 +658,14 @@ static SMB4ACL_T *smbacl4_win2nfs4(
gid_t ownerGID
)
{
- SMB4ACL_T *acl;
+ SMB4ACL_T *theacl;
uint32 i;
TALLOC_CTX *mem_ctx = talloc_tos();
DEBUG(10, ("smbacl4_win2nfs4 invoked\n"));
- acl = smb_create_smb4acl();
- if (acl==NULL)
+ theacl = smb_create_smb4acl();
+ if (theacl==NULL)
return NULL;
for(i=0; i<dacl->num_aces; i++) {
@@ -676,16 +682,16 @@ static SMB4ACL_T *smbacl4_win2nfs4(
}
if (pparams->acedup!=e_dontcare) {
- if (smbacl4_MergeIgnoreReject(pparams->acedup, acl,
+ if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl,
&ace_v4, &addNewACE, i))
return NULL;
}
if (addNewACE)
- smb_add_ace4(acl, &ace_v4);
+ smb_add_ace4(theacl, &ace_v4);
}
- return acl;
+ return theacl;
}
NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
@@ -694,7 +700,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
set_nfs4acl_native_fn_t set_nfs4_native)
{
smbacl4_vfs_params params;
- SMB4ACL_T *acl = NULL;
+ SMB4ACL_T *theacl = NULL;
bool result;
SMB_STRUCT_STAT sbuf;
@@ -753,16 +759,16 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
return NT_STATUS_OK;
}
- acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
- if (!acl)
+ theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
+ if (!theacl)
return map_nt_error_from_unix(errno);
- smbacl4_dump_nfs4acl(10, acl);
+ smbacl4_dump_nfs4acl(10, theacl);
if (set_acl_as_root) {
become_root();
}
- result = set_nfs4_native(fsp, acl);
+ result = set_nfs4_native(fsp, theacl);
saved_errno = errno;
if (set_acl_as_root) {
unbecome_root();
diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h
index a227c6e0fc..b2d1196b26 100644
--- a/source3/modules/nfs4_acls.h
+++ b/source3/modules/nfs4_acls.h
@@ -117,26 +117,26 @@ SMB4ACL_T *smb_create_smb4acl(void);
/* prop's contents are copied */
/* it doesn't change the order, appends */
-SMB4ACE_T *smb_add_ace4(SMB4ACL_T *acl, SMB_ACE4PROP_T *prop);
+SMB4ACE_T *smb_add_ace4(SMB4ACL_T *theacl, SMB_ACE4PROP_T *prop);
SMB_ACE4PROP_T *smb_get_ace4(SMB4ACE_T *ace);
/* Returns NULL if none - or error */
-SMB4ACE_T *smb_first_ace4(SMB4ACL_T *acl);
+SMB4ACE_T *smb_first_ace4(SMB4ACL_T *theacl);
/* Returns NULL in the end - or error */
SMB4ACE_T *smb_next_ace4(SMB4ACE_T *ace);
-uint32 smb_get_naces(SMB4ACL_T *acl);
+uint32 smb_get_naces(SMB4ACL_T *theacl);
NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
uint32 security_info,
- SEC_DESC **ppdesc, SMB4ACL_T *acl);
+ SEC_DESC **ppdesc, SMB4ACL_T *theacl);
NTSTATUS smb_get_nt_acl_nfs4(connection_struct *conn,
const char *name,
uint32 security_info,
- SEC_DESC **ppdesc, SMB4ACL_T *acl);
+ SEC_DESC **ppdesc, SMB4ACL_T *theacl);
/* Callback function needed to set the native acl
* when applicable */
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index c002739f1f..a0f4fe37de 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -41,18 +41,32 @@ enum onefs_acl_wire_format
#define PARM_ONEFS_TYPE "onefs"
#define PARM_ACL_WIRE_FORMAT "acl wire format"
#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD
+#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always"
+#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false
#define PARM_ATIME_NOW "atime now files"
#define PARM_ATIME_NOW_DEFAULT NULL
#define PARM_ATIME_STATIC "atime static files"
#define PARM_ATIME_STATIC_DEFAULT NULL
#define PARM_ATIME_SLOP "atime now slop"
#define PARM_ATIME_SLOP_DEFAULT 0
+#define PARM_ATOMIC_SENDFILE "atomic sendfile"
+#define PARM_ATOMIC_SENDFILE_DEFAULT true
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control"
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true
#define PARM_CTIME_NOW "ctime now files"
#define PARM_CTIME_NOW_DEFAULT NULL
#define PARM_CTIME_SLOP "ctime now slop"
#define PARM_CTIME_SLOP_DEFAULT 0
+#define PARM_DOT_SNAP_CHILD_ACCESSIBLE "dot snap child accessible"
+#define PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT true
+#define PARM_DOT_SNAP_CHILD_VISIBLE "dot snap child visible"
+#define PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT false
+#define PARM_DOT_SNAP_ROOT_ACCESSIBLE "dot snap root accessible"
+#define PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT true
+#define PARM_DOT_SNAP_ROOT_VISIBLE "dot snap root visible"
+#define PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT true
+#define PARM_DOT_SNAP_TILDE "dot snap tilde"
+#define PARM_DOT_SNAP_TILDE_DEFAULT true
#define PARM_IGNORE_SACLS "ignore sacls"
#define PARM_IGNORE_SACLS_DEFAULT false
#define PARM_MTIME_NOW "mtime now files"
@@ -63,6 +77,10 @@ enum onefs_acl_wire_format
#define PARM_MTIME_SLOP_DEFAULT 0
#define PARM_USE_READDIRPLUS "use readdirplus"
#define PARM_USE_READDIRPLUS_DEFAULT true
+#define PARM_SENDFILE_LARGE_READS "sendfile large reads"
+#define PARM_SENDFILE_LARGE_READS_DEFAULT false
+#define PARM_SENDFILE_SAFE "sendfile safe"
+#define PARM_SENDFILE_SAFE_DEFAULT true
#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode"
#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false
#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone"
@@ -91,9 +109,9 @@ enum onefs_acl_wire_format
#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001
-struct onefs_vfs_config
+struct onefs_vfs_share_config
{
- int32 init_flags;
+ uint32_t init_flags;
/* data for fake timestamps */
int atime_slop;
@@ -119,6 +137,18 @@ struct onefs_vfs_config
name_compare_entry *atime_static_list;
};
+struct onefs_vfs_global_config
+{
+ uint32_t init_flags;
+
+ /* Snapshot options */
+ bool dot_snap_child_accessible;
+ bool dot_snap_child_visible;
+ bool dot_snap_root_accessible;
+ bool dot_snap_root_visible;
+ bool dot_snap_tilde;
+};
+
/*
* vfs interface handlers
*/
@@ -204,6 +234,15 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
struct lock_struct *plock,
struct blocking_lock_record *blr);
+NTSTATUS onefs_notify_watch(vfs_handle_struct *vfs_handle,
+ struct sys_notify_context *ctx,
+ struct notify_entry *e,
+ void (*callback)(struct sys_notify_context *ctx,
+ void *private_data,
+ struct notify_event *ev),
+ void *private_data,
+ void *handle_p);
+
NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, SEC_DESC **ppdesc);
@@ -223,7 +262,7 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
char **pbase, char **pstream);
bool onefs_get_config(int snum, int config_type,
- struct onefs_vfs_config *cfg);
+ struct onefs_vfs_share_config *cfg);
int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp);
@@ -245,7 +284,15 @@ int onefs_sys_create_file(connection_struct *conn,
uint32_t ntfs_flags,
int *granted_oplock);
+ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
+ const DATA_BLOB *header, SMB_OFF_T offset,
+ size_t count);
+
ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
size_t count);
+void onefs_sys_config_enc(void);
+void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config);
+void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config);
+
#endif /* _ONEFS_H */
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 7bc4a1728f..a1bfa6e121 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -273,9 +273,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl,
if (aclu_initialize_acl(acl, aces, num_aces))
goto err_free;
- if (aclu_initialize_acl(acl, aces, num_aces))
- goto err_free;
-
/* Currently aclu_initialize_acl should copy the aces over, allowing
* us to immediately free */
free(aces);
@@ -614,6 +611,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
bool fopened = false;
NTSTATUS status = NT_STATUS_OK;
+ START_PROFILE(syscall_get_sd);
+
*ppdesc = NULL;
DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
@@ -753,6 +752,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(5, ("Finished retrieving/canonicalizing SD!\n"));
/* FALLTHROUGH */
out:
+
+ END_PROFILE(syscall_get_sd);
+
if (alloced && sd) {
if (new_aces_alloced && sd->dacl->aces)
SAFE_FREE(sd->dacl->aces);
@@ -888,18 +890,20 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info_sent, SEC_DESC *psd)
{
struct ifs_security_descriptor sd = {};
- int fd;
+ int fd = -1;
bool fopened = false;
NTSTATUS status;
+ START_PROFILE(syscall_set_sd);
+
DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd,
SNUM(handle->conn));
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("SD initialization failure: %s", nt_errstr(status)));
- return status;
+ DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status)));
+ goto out;
}
fd = fsp->fh->fd;
@@ -938,6 +942,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
/* FALLTHROUGH */
out:
+ END_PROFILE(syscall_set_sd);
+
if (fopened)
close(fd);
diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c
index a860023764..2c5e39c359 100644
--- a/source3/modules/onefs_cbrl.c
+++ b/source3/modules/onefs_cbrl.c
@@ -255,6 +255,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
struct onefs_cbrl_blr_state *bs;
NTSTATUS status;
+ START_PROFILE(syscall_brl_lock);
+
SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
SMB_ASSERT(plock->lock_type != UNLOCK_LOCK);
@@ -301,10 +303,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
/* ASYNC still in progress: The process_* calls will keep
* calling even if we haven't gotten the lock. Keep erroring
* without calling ifs_cbrl, or getting/setting an id. */
- if (bs->state == ONEFS_CBRL_ASYNC)
+ if (bs->state == ONEFS_CBRL_ASYNC) {
goto failure;
- else if (bs->state == ONEFS_CBRL_ERROR)
+ }
+ else if (bs->state == ONEFS_CBRL_ERROR) {
+ END_PROFILE(syscall_brl_lock);
return NT_STATUS_NO_MEMORY;
+ }
SMB_ASSERT(bs->state == ONEFS_CBRL_NONE);
async = true;
@@ -343,6 +348,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle,
}
failure:
+
+ END_PROFILE(syscall_brl_lock);
+
/* Failure - error or async. */
plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID;
@@ -355,6 +363,9 @@ failure:
return status;
success:
+
+ END_PROFILE(syscall_brl_lock);
+
/* Success. */
onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows");
DEBUG(10, ("returning NT_STATUS_OK.\n"));
@@ -371,6 +382,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
int error;
int fd = br_lck->fsp->fh->fd;
+ START_PROFILE(syscall_brl_unlock);
+
SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
SMB_ASSERT(plock->lock_type == UNLOCK_LOCK);
@@ -378,6 +391,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle,
error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE,
plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid,
plock->context.tid, plock->fnum);
+
+ END_PROFILE(syscall_brl_unlock);
+
if (error) {
DEBUG(10, ("returning false.\n"));
return false;
@@ -404,6 +420,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
int fd = br_lck->fsp->fh->fd;
struct onefs_cbrl_blr_state *bs;
+ START_PROFILE(syscall_brl_cancel);
+
SMB_ASSERT(plock);
SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
SMB_ASSERT(blr);
@@ -416,6 +434,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
if (bs->state == ONEFS_CBRL_DONE) {
/* No-op. */
DEBUG(10, ("State=DONE, returning true\n"));
+ END_PROFILE(syscall_brl_cancel);
return true;
}
@@ -427,6 +446,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle,
error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start,
plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid,
plock->context.tid, plock->fnum);
+
+ END_PROFILE(syscall_brl_cancel);
+
if (error) {
DEBUG(10, ("returning false\n"));
bs->state = ONEFS_CBRL_ERROR;
diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c
new file mode 100644
index 0000000000..40f690876d
--- /dev/null
+++ b/source3/modules/onefs_notify.c
@@ -0,0 +1,680 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Support for change notify using OneFS's file event notification system
+ *
+ * Copyright (C) Andrew Tridgell, 2006
+ * Copyright (C) Steven Danneman, 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/>.
+ */
+
+/* Implement handling of change notify requests on files and directories using
+ * Isilon OneFS's "ifs event" file notification system.
+ *
+ * The structure of this file is based off the implementation of change notify
+ * using the inotify system calls in smbd/notify_inotify.c */
+
+/* TODO: We could reduce the number of file descriptors used by merging
+ * multiple watch requests on the same directory into the same
+ * onefs_notify_watch_context. To do this we'd need mux/demux routines that
+ * when receiving an event on that watch context would check it against the
+ * CompletionFilter and WatchTree of open SMB requests, and return notify
+ * events back to the proper SMB requests */
+
+#include "onefs.h"
+
+#include <ifs/ifs_types.h>
+#include <ifs/ifs_syscalls.h>
+#include <isi_util/syscalls.h>
+
+#include <sys/event.h>
+
+#define ONEFS_IFS_EVENT_MAX_NUM 8
+#define ONEFS_IFS_EVENT_MAX_BYTES (ONEFS_IFS_EVENT_MAX_NUM * \
+ sizeof(struct ifs_event))
+
+struct onefs_notify_watch_context {
+ struct sys_notify_context *ctx;
+ int watch_fd;
+ ino_t watch_lin;
+ const char *path;
+ int ifs_event_fd;
+ uint32_t ifs_filter; /* the ifs event mask */
+ uint32_t smb_filter; /* the windows completion filter */
+ void (*callback)(struct sys_notify_context *ctx,
+ void *private_data,
+ struct notify_event *ev);
+ void *private_data;
+};
+
+/**
+ * Conversion map from a SMB completion filter to an IFS event mask.
+ */
+static const struct {
+ uint32_t smb_filter;
+ uint32_t ifs_filter;
+} onefs_notify_conv[] = {
+ {FILE_NOTIFY_CHANGE_FILE_NAME,
+ NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO},
+ {FILE_NOTIFY_CHANGE_DIR_NAME,
+ NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO},
+ {FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ NOTE_CREATE | NOTE_DELETE | NOTE_RENAME_FROM | NOTE_RENAME_TO |
+ NOTE_ATTRIB},
+ {FILE_NOTIFY_CHANGE_SIZE,
+ NOTE_SIZE | NOTE_EXTEND},
+ {FILE_NOTIFY_CHANGE_LAST_WRITE,
+ NOTE_WRITE | NOTE_ATTRIB},
+ /* OneFS doesn't set atime by default, but we can somewhat fake it by
+ * notifying for other events that imply ACCESS */
+ {FILE_NOTIFY_CHANGE_LAST_ACCESS,
+ NOTE_WRITE | NOTE_ATTRIB},
+ /* We don't have an ifs_event for the setting of create time, but we
+ * can fake by notifying when a "new" file is created via rename */
+ {FILE_NOTIFY_CHANGE_CREATION,
+ NOTE_RENAME_TO},
+ {FILE_NOTIFY_CHANGE_SECURITY,
+ NOTE_SECURITY},
+ /* Unsupported bits
+ FILE_NOTIFY_CHANGE_EA (no EAs in OneFS)
+ FILE_NOTIFY_CHANGE_STREAM_NAME (no ifs_event equivalent)
+ FILE_NOTIFY_CHANGE_STREAM_SIZE (no ifs_event equivalent)
+ FILE_NOTIFY_CHANGE_STREAM_WRITE (no ifs_event equivalent) */
+};
+
+#define ONEFS_NOTIFY_UNSUPPORTED (FILE_NOTIFY_CHANGE_LAST_ACCESS | \
+ FILE_NOTIFY_CHANGE_CREATION | \
+ FILE_NOTIFY_CHANGE_EA | \
+ FILE_NOTIFY_CHANGE_STREAM_NAME | \
+ FILE_NOTIFY_CHANGE_STREAM_SIZE | \
+ FILE_NOTIFY_CHANGE_STREAM_WRITE)
+
+/**
+ * Convert Windows/SMB filter/flags to IFS event filter.
+ *
+ * @param[in] smb_filter Windows Completion Filter sent in the SMB
+ *
+ * @return ifs event filter mask
+ */
+static uint32_t
+onefs_notify_smb_filter_to_ifs_filter(uint32_t smb_filter)
+{
+ int i;
+ uint32_t ifs_filter = 0x0;
+
+ for (i=0;i<ARRAY_SIZE(onefs_notify_conv);i++) {
+ if (onefs_notify_conv[i].smb_filter & smb_filter) {
+ ifs_filter |= onefs_notify_conv[i].ifs_filter;
+ }
+ }
+
+ return ifs_filter;
+}
+
+/**
+ * Convert IFS filter/flags to a Windows notify action.
+ *
+ * Returns Win notification actions, types (1-5).
+ *
+ * @param[in] smb_filter Windows Completion Filter sent in the SMB
+ * @param[in] ifs_filter Returned from the kernel in the ifs_event
+ *
+ * @return 0 if there are no more relevant flags.
+ */
+static int
+onefs_notify_ifs_filter_to_smb_action(uint32_t smb_filter, uint32_t ifs_filter)
+{
+ /* Handle Windows special cases, before modifying events bitmask */
+
+ /* Special case 1: win32api->MoveFile needs to send a modified
+ * notification on the new file, if smb_filter == ATTRIBUTES.
+ * Here we handle the case where two separate ATTR & NAME notifications
+ * have been registered. We handle the case where both bits are set in
+ * the same registration in onefs_notify_dispatch() */
+ if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) &&
+ !(smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (ifs_filter & NOTE_FILE) && (ifs_filter & NOTE_RENAME_TO))
+ {
+ return NOTIFY_ACTION_MODIFIED;
+ }
+
+ /* Special case 2: Writes need to send a modified
+ * notification on the file, if smb_filter = ATTRIBUTES. */
+ if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) &&
+ (ifs_filter & NOTE_FILE) && (ifs_filter & NOTE_WRITE))
+ {
+ return NOTIFY_ACTION_MODIFIED;
+ }
+
+ /* Loop because some events may be filtered out. Eventually all
+ * relevant events will be taken care of and returned. */
+ while (1) {
+ if (ifs_filter & NOTE_CREATE) {
+ ifs_filter &= ~NOTE_CREATE;
+ if ((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (ifs_filter & NOTE_FILE))
+ return NOTIFY_ACTION_ADDED;
+ if ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) &&
+ (ifs_filter & NOTE_DIRECTORY))
+ return NOTIFY_ACTION_ADDED;
+ }
+ else if (ifs_filter & NOTE_DELETE) {
+ ifs_filter &= ~NOTE_DELETE;
+ if ((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (ifs_filter & NOTE_FILE))
+ return NOTIFY_ACTION_REMOVED;
+ if ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) &&
+ (ifs_filter & NOTE_DIRECTORY))
+ return NOTIFY_ACTION_REMOVED;
+ }
+ else if (ifs_filter & NOTE_WRITE) {
+ ifs_filter &= ~NOTE_WRITE;
+ if ((smb_filter & FILE_NOTIFY_CHANGE_LAST_WRITE) ||
+ (smb_filter & FILE_NOTIFY_CHANGE_LAST_ACCESS))
+ return NOTIFY_ACTION_MODIFIED;
+ }
+ else if ((ifs_filter & NOTE_SIZE) || (ifs_filter & NOTE_EXTEND)) {
+ ifs_filter &= ~NOTE_SIZE;
+ ifs_filter &= ~NOTE_EXTEND;
+
+ /* TODO: Do something on NOTE_DIR? */
+ if ((smb_filter & FILE_NOTIFY_CHANGE_SIZE) &&
+ (ifs_filter & NOTE_FILE))
+ return NOTIFY_ACTION_MODIFIED;
+ }
+ else if (ifs_filter & NOTE_ATTRIB) {
+ ifs_filter &= ~NOTE_ATTRIB;
+ /* NOTE_ATTRIB needs to be converted to a
+ * LAST_WRITE as well, because we need to send
+ * LAST_WRITE when the mtime changes. Looking into
+ * better alternatives as this causes extra LAST_WRITE
+ * notifications. We also return LAST_ACCESS as a
+ * modification to attribs implies this. */
+ if ((smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) ||
+ (smb_filter & FILE_NOTIFY_CHANGE_LAST_WRITE) ||
+ (smb_filter & FILE_NOTIFY_CHANGE_LAST_ACCESS))
+ return NOTIFY_ACTION_MODIFIED;
+ }
+ else if (ifs_filter & NOTE_LINK) {
+ ifs_filter &= ~NOTE_LINK;
+ /* NOTE_LINK will send out NO notifications */
+ }
+ else if (ifs_filter & NOTE_REVOKE) {
+ ifs_filter &= ~NOTE_REVOKE;
+ /* NOTE_REVOKE will send out NO notifications */
+ }
+ else if (ifs_filter & NOTE_RENAME_FROM) {
+ ifs_filter &= ~NOTE_RENAME_FROM;
+
+ if (((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (ifs_filter & NOTE_FILE)) ||
+ ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) &&
+ (ifs_filter & NOTE_DIRECTORY))) {
+ /* Check if this is a RENAME, not a MOVE */
+ if (ifs_filter & NOTE_RENAME_SAMEDIR) {
+ /* Remove the NOTE_RENAME_SAMEDIR, IFF
+ * RENAME_TO is not in this event */
+ if (!(ifs_filter & NOTE_RENAME_TO))
+ ifs_filter &=
+ ~NOTE_RENAME_SAMEDIR;
+ return NOTIFY_ACTION_OLD_NAME;
+ }
+ return NOTIFY_ACTION_REMOVED;
+ }
+ }
+ else if (ifs_filter & NOTE_RENAME_TO) {
+ ifs_filter &= ~NOTE_RENAME_TO;
+
+ if (((smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (ifs_filter & NOTE_FILE)) ||
+ ((smb_filter & FILE_NOTIFY_CHANGE_DIR_NAME) &&
+ (ifs_filter & NOTE_DIRECTORY))) {
+ /* Check if this is a RENAME, not a MOVE */
+ if (ifs_filter & NOTE_RENAME_SAMEDIR) {
+ /* Remove the NOTE_RENAME_SAMEDIR, IFF
+ * RENAME_FROM is not in this event */
+ if (!(ifs_filter & NOTE_RENAME_FROM))
+ ifs_filter &=
+ ~NOTE_RENAME_SAMEDIR;
+ return NOTIFY_ACTION_NEW_NAME;
+ }
+ return NOTIFY_ACTION_ADDED;
+ }
+ /* RAW-NOTIFY shows us that a rename triggers a
+ * creation time change */
+ if ((smb_filter & FILE_NOTIFY_CHANGE_CREATION) &&
+ (ifs_filter & NOTE_FILE))
+ return NOTIFY_ACTION_MODIFIED;
+ }
+ else if (ifs_filter & NOTE_SECURITY) {
+ ifs_filter &= ~NOTE_SECURITY;
+
+ if (smb_filter & FILE_NOTIFY_CHANGE_SECURITY)
+ return NOTIFY_ACTION_MODIFIED;
+ } else {
+ /* No relevant flags found */
+ return 0;
+ }
+ }
+}
+
+/**
+ * Retrieve a directory path of a changed file, relative to the watched dir
+ *
+ * @param[in] wc watch context for the returned event
+ * @param[in] e ifs_event notification returned from the kernel
+ * @param[out] path name relative to the watched dir. This is talloced
+ * off of wc and needs to be freed by the caller.
+ *
+ * @return true on success
+ *
+ * TODO: This function currently doesn't handle path names with multiple
+ * encodings. enc_get_lin_path() should be used in the future to convert
+ * each path segment's encoding to UTF-8
+ */
+static bool
+get_ifs_event_path(struct onefs_notify_watch_context *wc, struct ifs_event *e,
+ char **path)
+{
+ char *path_buf = NULL;
+ size_t pathlen = 0;
+ int error = 0;
+
+ SMB_ASSERT(path);
+
+ /* Lookup the path from watch_dir through our parent dir */
+ if (e->namelen > 0) {
+ error = lin_get_path(wc->watch_lin,
+ e->parent_lin,
+ HEAD_SNAPID,
+ e->parent_parent_lin,
+ e->parent_name_hash,
+ &pathlen, &path_buf);
+ if (!error) {
+ /* Only add slash if a path exists in path_buf from
+ * lin_get_path call. Windows does not expect a
+ * leading '/' */
+ if (pathlen > 0)
+ *path = talloc_asprintf(wc, "%s/%s",
+ path_buf, e->name);
+ else
+ *path = talloc_asprintf(wc, "%s", e->name);
+ SAFE_FREE(path_buf);
+ }
+ }
+
+ /* If ifs_event didn't return a name, or we errored out of our intial
+ * path lookup, try again using the lin of the changed file */
+ if (!(*path)) {
+ error = lin_get_path(wc->watch_lin,
+ e->lin,
+ HEAD_SNAPID,
+ e->parent_lin,
+ e->name_hash,
+ &pathlen, &path_buf);
+ if (error) {
+ /* It's possible that both the lin and the parent lin
+ * are invalid (or not given) -- we will skip these
+ * events. */
+ DEBUG(3,("Path lookup failed. LINS are invalid: "
+ "e->lin: 0x%llu, e->parent_lin: 0x%llu, "
+ "e->parent_parent_lin: 0x%llu\n",
+ e->lin, e->parent_lin, e->parent_parent_lin));
+ SAFE_FREE(path_buf);
+ return false;
+ } else {
+ *path = talloc_asprintf(wc, "%s", path_buf);
+ DEBUG(5, ("Using path from event LIN = %s\n",
+ path_buf));
+ SAFE_FREE(path_buf);
+ }
+ }
+
+ /* Replacement of UNIX slashes with WIN slashes is handled at a
+ * higher layer. */
+
+ return true;
+}
+
+/**
+ * Dispatch one OneFS notify event to the general Samba code
+ *
+ * @param[in] wc watch context for the returned event
+ * @param[in] e event returned from the kernel
+ *
+ * @return nothing
+ */
+static void
+onefs_notify_dispatch(struct onefs_notify_watch_context *wc,
+ struct ifs_event *e)
+{
+ char *path = NULL;
+ struct notify_event ne;
+
+ DEBUG(5, ("Retrieved ifs event from kernel: lin=%#llx, ifs_events=%#x, "
+ "parent_lin=%#llx, namelen=%d, name=\"%s\"\n",
+ e->lin, e->events, e->parent_lin, e->namelen, e->name));
+
+ /* Check validity of event returned from kernel */
+ if (e->lin == 0) {
+ /* The lin == 0 specifies 1 of 2 cases:
+ * 1) We are out of events. The kernel has a limited
+ * amount (somewhere near 90000)
+ * 2) Split nodes have merged back and had data written
+ * to them -- thus we've missed some of those events. */
+ DEBUG(3, ("We've missed some kernel ifs events!\n"));
+
+ /* Alert higher level to the problem so it returns catch-all
+ * response to the client */
+ ne.path = NULL;
+ ne.action = 0;
+ wc->callback(wc->ctx, wc->private_data, &ne);
+ }
+
+ if (e->lin == wc->watch_lin) {
+ /* Windows doesn't report notifications on root
+ * watched directory */
+ /* TODO: This should be abstracted out to the general layer
+ * instead of being handled in every notify provider */
+ DEBUG(5, ("Skipping notification on root of the watched "
+ "path.\n"));
+ return;
+ }
+
+ /* Retrieve the full path for the ifs event name */
+ if(!get_ifs_event_path(wc, e, &path)) {
+ DEBUG(3, ("Failed to convert the ifs_event lins to a path. "
+ "Skipping this event\n"));
+ return;
+ }
+
+ if (!strncmp(path, ".ifsvar", 7)) {
+ /* Skip notifications on file if its in ifs configuration
+ * directory */
+ goto clean;
+ }
+
+ ne.path = path;
+
+ /* Convert ifs event mask to an smb action mask */
+ ne.action = onefs_notify_ifs_filter_to_smb_action(wc->smb_filter,
+ e->events);
+
+ DEBUG(5, ("Converted smb_filter=%#x, ifs_events=%#x, to "
+ "ne.action = %d, for ne.path = %s\n",
+ wc->smb_filter, e->events, ne.action, ne.path));
+
+ if (!ne.action)
+ goto clean;
+
+ /* Return notify_event to higher level */
+ wc->callback(wc->ctx, wc->private_data, &ne);
+
+ /* SMB expects a file rename/move to generate three actions, a
+ * rename_from/delete on the from file, a rename_to/create on the to
+ * file, and a modify for the rename_to file. If we have two separate
+ * notifications registered for ATTRIBUTES and FILENAME, this case will
+ * be handled by separate ifs_events in
+ * onefs_notify_ifs_filter_to_smb_action(). If both bits are registered
+ * in the same notification, we must send an extra MODIFIED action
+ * here. */
+ if ((wc->smb_filter & FILE_NOTIFY_CHANGE_ATTRIBUTES) &&
+ (wc->smb_filter & FILE_NOTIFY_CHANGE_FILE_NAME) &&
+ (e->events & NOTE_FILE) && (e->events & NOTE_RENAME_TO))
+ {
+ ne.action = NOTIFY_ACTION_MODIFIED;
+ wc->callback(wc->ctx, wc->private_data, &ne);
+ }
+
+ /* FALLTHROUGH */
+clean:
+ talloc_free(path);
+ return;
+}
+
+/**
+ * Callback when the kernel has some events for us
+ *
+ * Read events off ifs event fd and pass them to our dispatch function
+ *
+ * @param ev context of all tevents registered in the smbd
+ * @param fde tevent struct specific to one ifs event channel
+ * @param flags tevent flags passed when we added our ifs event channel fd to
+ * the main loop
+ * @param private_data onefs_notify_watch_context specific to this ifs event
+ * channel
+ *
+ * @return nothing
+ */
+static void
+onefs_notify_handler(struct event_context *ev,
+ struct fd_event *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ struct onefs_notify_watch_context *wc = NULL;
+ struct ifs_event ifs_events[ONEFS_IFS_EVENT_MAX_NUM];
+ ssize_t nread = 0;
+ int count = 0;
+ int i = 0;
+
+ wc = talloc_get_type(private_data, struct onefs_notify_watch_context);
+
+ /* Read as many ifs events from the notify channel as we can */
+ nread = sys_read(wc->ifs_event_fd, &ifs_events,
+ ONEFS_IFS_EVENT_MAX_BYTES);
+ if (nread == 0) {
+ DEBUG(0,("No data found while reading ifs event fd?!\n"));
+ return;
+ }
+ if (nread < 0) {
+ DEBUG(0,("Failed to read ifs event data: %s\n",
+ strerror(errno)));
+ return;
+ }
+
+ count = nread / sizeof(struct ifs_event);
+
+ DEBUG(5, ("Got %d notification events in %d bytes.\n", count, nread));
+
+ /* Dispatch ifs_events one-at-a-time to higher level */
+ for (i=0; i < count; i++) {
+ onefs_notify_dispatch(wc, &ifs_events[i]);
+ }
+}
+
+/**
+ * Destroy the ifs event channel
+ *
+ * This is called from talloc_free() when the generic Samba notify layer frees
+ * the onefs_notify_watch_context.
+ *
+ * @param[in] wc pointer to watch context which is being destroyed
+ *
+ * return 0 on success
+*/
+static int
+onefs_watch_destructor(struct onefs_notify_watch_context *wc)
+{
+ /* The ifs_event_fd will re de-registered from the event loop by
+ * another destructor triggered from the freeing of this wc */
+ close(wc->ifs_event_fd);
+ return 0;
+}
+
+/**
+ * Register a single change notify watch request.
+ *
+ * Open an event listener on a directory to watch for modifications. This
+ * channel is closed by a destructor when the caller calls talloc_free()
+ * on *handle.
+ *
+ * @param[in] vfs_handle handle given to most VFS operations
+ * @param[in] ctx context (conn and tevent) for this connection
+ * @param[in] e filter and path of client's notify request
+ * @param[in] callback function to call when file notification event is received
+ * from the kernel, passing that event up to Samba's
+ * generalized change notify layer
+ * @param[in] private_data opaque data given to us by the general change notify
+ * layer which must be returned in the callback function
+ * @param[out] handle_p handle returned to generalized change notify layer used
+ * to close the event channel when notification is
+ * cancelled
+ *
+ * @return NT_STATUS_OK unless error
+ */
+NTSTATUS
+onefs_notify_watch(vfs_handle_struct *vfs_handle,
+ struct sys_notify_context *ctx,
+ struct notify_entry *e,
+ void (*callback)(struct sys_notify_context *ctx,
+ void *private_data,
+ struct notify_event *ev),
+ void *private_data,
+ void *handle_p)
+{
+ int ifs_event_fd = -1;
+ uint32_t ifs_filter = 0;
+ uint32_t smb_filter = e->filter;
+ bool watch_tree = !!e->subdir_filter;
+ struct onefs_notify_watch_context *wc = NULL;
+ void **handle = (void **)handle_p;
+ SMB_STRUCT_STAT sbuf;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ /* Fallback to default Samba implementation if kernel CN is disabled */
+ if (!lp_kernel_change_notify(vfs_handle->conn->params)) {
+ (*handle) = NULL;
+ return NT_STATUS_OK;
+ }
+
+ /* The OneFS open path should always give us a valid fd on a directory*/
+ SMB_ASSERT(e->dir_fd >= 0);
+
+ /* Always set e->filter to 0 so we don't fallback on the default change
+ * notify backend. It's not cluster coherent or cross-protocol so we
+ * can't guarantee correctness using it. */
+ e->filter = 0;
+ e->subdir_filter = 0;
+
+ /* Snapshots do not currently allow event listeners. See Isilon
+ * bug 33476 for an example of .snapshot debug spew that can occur. */
+ if (e->dir_id.extid != HEAD_SNAPID)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ /* Convert Completion Filter mask to IFS Event mask */
+ ifs_filter = onefs_notify_smb_filter_to_ifs_filter(smb_filter);
+
+ if (smb_filter & ONEFS_NOTIFY_UNSUPPORTED) {
+ /* One or more of the filter bits could not be fully handled by
+ * the ifs_event system. To be correct, if we cannot service a
+ * bit in the completion filter we should return
+ * NT_STATUS_NOT_IMPLEMENTED to let the client know that they
+ * won't be receiving all the notify events that they asked for.
+ * Unfortunately, WinXP clients cache this error message, stop
+ * trying to send any notify requests at all, and instead return
+ * NOT_IMPLEMENTED to all requesting apps without ever sending a
+ * message to us. Thus we lie, and say we can service all bits,
+ * but simply don't return actions for the filter bits we can't
+ * detect or fully implement. */
+ DEBUG(3,("One or more of the Windows completion filter bits "
+ "for \"%s\" could not be fully handled by the "
+ "ifs_event system. The failed bits are "
+ "smb_filter=%#x\n",
+ e->path, smb_filter & ONEFS_NOTIFY_UNSUPPORTED));
+ }
+
+ if (ifs_filter == 0) {
+ /* None of the filter bits given are supported by the ifs_event
+ * system. Don't create a kernel notify channel, but mock
+ * up a fake handle for the caller. */
+ DEBUG(3,("No bits in the Windows completion filter could be "
+ "translated to ifs_event mask for \"%s\", "
+ "smb_filter=%#x\n", e->path, smb_filter));
+ (*handle) = NULL;
+ return NT_STATUS_OK;
+ }
+
+ /* Register an ifs event channel for this watch request */
+ ifs_event_fd = ifs_create_listener(watch_tree ?
+ EVENT_RECURSIVE :
+ EVENT_CHILDREN,
+ ifs_filter,
+ e->dir_fd);
+ if (ifs_event_fd < 0) {
+ DEBUG(0,("Failed to create listener for %s with \"%s\". "
+ "smb_filter=0x%x, ifs_filter=0x%x, watch_tree=%u\n",
+ strerror(errno), e->path, smb_filter, ifs_filter,
+ watch_tree));
+ return map_nt_error_from_unix(errno);
+ }
+
+ /* Create a watch context to track this change notify request */
+ wc = talloc(ctx, struct onefs_notify_watch_context);
+ if (wc == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
+ }
+
+ /* Get LIN for directory */
+ if (sys_fstat(e->dir_fd, &sbuf)) {
+ DEBUG(0, ("stat on directory fd failed: %s\n",
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ goto err;
+ }
+
+ if (sbuf.st_ino == 0) {
+ DEBUG(0, ("0 LIN found!\n"));
+ goto err;
+ }
+
+ wc->ctx = ctx;
+ wc->watch_fd = e->dir_fd;
+ wc->watch_lin = sbuf.st_ino;
+ wc->ifs_event_fd = ifs_event_fd;
+ wc->ifs_filter = ifs_filter;
+ wc->smb_filter = smb_filter;
+ wc->callback = callback;
+ wc->private_data = private_data;
+ wc->path = talloc_strdup(wc, e->path);
+ if (wc->path == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
+ }
+
+ (*handle) = wc;
+
+ /* The caller frees the handle to stop watching */
+ talloc_set_destructor(wc, onefs_watch_destructor);
+
+ /* Add a tevent waiting for the ifs event fd to be readable */
+ event_add_fd(ctx->ev, wc, wc->ifs_event_fd, EVENT_FD_READ,
+ onefs_notify_handler, wc);
+
+ DEBUG(10, ("Watching for changes on \"%s\" smb_filter=0x%x, "
+ "ifs_filter=0x%x, watch_tree=%d, ifs_event_fd=%d, "
+ "dir_fd=%d, dir_lin=0x%llx\n",
+ e->path, smb_filter, ifs_filter, watch_tree,
+ ifs_event_fd, e->dir_fd, sbuf.st_ino));
+
+ return NT_STATUS_OK;
+
+err:
+ talloc_free(wc);
+ SMB_ASSERT(ifs_event_fd >= 0);
+ close(ifs_event_fd);
+ return status;
+}
diff --git a/source3/modules/onefs_shadow_copy.c b/source3/modules/onefs_shadow_copy.c
new file mode 100644
index 0000000000..5b02534715
--- /dev/null
+++ b/source3/modules/onefs_shadow_copy.c
@@ -0,0 +1,782 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * OneFS shadow copy implementation that utilizes the file system's native
+ * snapshot support. This file does all of the heavy lifting.
+ *
+ * Copyright (C) Dave Richards, 2007
+ * Copyright (C) Tim Prouty, 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 <ifs/ifs_syscalls.h>
+#include <sys/types.h>
+#include <sys/isi_enc.h>
+#include <sys/module.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <search.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "onefs_shadow_copy.h"
+
+/* Copied from ../include/proto.h */
+void become_root(void);
+void unbecome_root(void);
+
+#define SNAPSHOT_DIRECTORY ".snapshot"
+
+#define MAX_VERSIONS 64
+
+/**
+ * A snapshot object.
+ *
+ * During snapshot enumeration, snapshots are represented by snapshot objects
+ * and are stored in a snapshot set. The snapshot object represents one
+ * snapshot within the set. An important thing to note about the set is that
+ * the key of the snapshot object is the tv_sec component of the is_time
+ * member. What this means is that we only store one snapshot for each
+ * second. If multiple snapshots were created within the same second, we'll
+ * keep the earliest one and ignore the rest. Thus, not all snapshots are
+ * necessarily retained.
+ */
+struct osc_snapshot {
+ char * is_name;
+ struct timespec is_time;
+ struct osc_snapshot * is_next;
+};
+
+/**
+ * A snapshot context object.
+ *
+ * Snapshot contexts are used to pass information throughout the snapshot
+ * enumeration routines. As a result, snapshot contexts are stored on the
+ * stack and are both created and destroyed within a single API function.
+ */
+struct osc_snapshot_ctx {
+ void * osc_set;
+ struct timespec osc_mtime;
+};
+
+/**
+ * A directory context.
+ *
+ * Directory contexts are the underlying data structured used to enumerate
+ * snapshot versions. An opendir()-, readdir()- and closedir()-like interface
+ * is provided that utilizes directory contexts. At the API level, directory
+ * contexts are passed around as void pointers. Directory contexts are
+ * allocated on the heap and their lifetime is dictated by the calling
+ * routine.
+ */
+struct osc_directory_ctx {
+ size_t idc_pos;
+ size_t idc_len;
+ size_t idc_size;
+ char ** idc_version;
+};
+
+/**
+ * Return a file descriptor to the STF names directory.
+ *
+ * Opens the STF names directory and returns a file descriptor to it.
+ * Subsequent calls return the same value (avoiding the need to re-open the
+ * directory repeatedly). Caveat caller: don't close the file descriptor or
+ * you will be shot!
+ */
+static int
+osc_get_names_directory_fd(void)
+{
+ static int fd = -1;
+
+ if (fd == -1) {
+ become_root();
+ fd = pctl2_lin_open(STF_NAMES_LIN, HEAD_SNAPID, O_RDONLY);
+ unbecome_root();
+ }
+
+ return fd;
+}
+
+/**
+ * Compare two time values.
+ *
+ * Accepts two struct timespecs and compares the tv_sec components of these
+ * values. It returns -1 if the first value preceeds the second, 0 if they
+ * are equal and +1 if the first values succeeds the second.
+ */
+static int
+osc_time_compare(const struct timespec *tsp1, const struct timespec *tsp2)
+{
+ return (tsp1->tv_sec < tsp2->tv_sec) ? -1 :
+ (tsp1->tv_sec > tsp2->tv_sec) ? +1 : 0;
+}
+
+/**
+ * Compare two timespec values.
+ *
+ * Compares two timespec values. It returns -1 if the first value preceeds
+ * the second, 0 if they are equal and +1 if the first values succeeds the
+ * second.
+ */
+static int
+osc_timespec_compare(const struct timespec *tsp1, const struct timespec *tsp2)
+{
+ return (tsp1->tv_sec < tsp2->tv_sec) ? -1 :
+ (tsp1->tv_sec > tsp2->tv_sec) ? +1 :
+ (tsp1->tv_nsec < tsp2->tv_nsec) ? -1 :
+ (tsp1->tv_nsec > tsp2->tv_nsec) ? +1 : 0;
+}
+
+/**
+ * Determine whether a timespec value is zero.
+ *
+ * Return 1 if the struct timespec provided is zero and 0 otherwise.
+ */
+static int
+osc_timespec_is_zero(const struct timespec *tsp)
+{
+ return (tsp->tv_sec == 0) &&
+ (tsp->tv_nsec == 0);
+}
+
+/**
+ * Create a snapshot object.
+ *
+ * Allocates and initializes a new snapshot object. In addition to allocating
+ * space for the snapshot object itself, space is allocated for the snapshot
+ * name. Both the name and time are then copied to the new object.
+ */
+static struct osc_snapshot *
+osc_snapshot_create(const char *name, const struct timespec *tsp)
+{
+ struct osc_snapshot *isp;
+
+ isp = malloc(sizeof *isp);
+ if (isp == NULL)
+ goto out;
+
+ isp->is_name = malloc(strlen(name) + 1);
+ if (isp->is_name == NULL) {
+ free(isp);
+ isp = NULL;
+ goto out;
+ }
+
+ strcpy(isp->is_name, name);
+ isp->is_time = *tsp;
+ isp->is_next = NULL;
+
+ out:
+ return isp;
+}
+
+/**
+ * Destroy a snapshot object.
+ *
+ * Frees both the name and the snapshot object itself. Appropriate NULL
+ * checking is performed because counting on free to do so is immoral.
+ */
+static void
+osc_snapshot_destroy(struct osc_snapshot *isp)
+{
+ if (isp != NULL) {
+ if (isp->is_name != NULL)
+ free(isp->is_name);
+ free(isp);
+ }
+}
+
+/**
+ * Destroy all snapshots in the snapshot list.
+ *
+ * Calls osc_snapshot_destroy() on each snapshot in the list.
+ */
+static void
+osc_snapshot_destroy_list(struct osc_snapshot *isp)
+{
+ struct osc_snapshot *tmp;
+
+ while (isp != NULL) {
+ tmp = isp;
+ isp = isp->is_next;
+ osc_snapshot_destroy(tmp);
+ }
+}
+
+/**
+ * Compare two snapshot objects.
+ *
+ * Compare two snapshot objects. It is really just a wrapper for
+ * osc_time_compare(), which compare the time value of the two snapshots.
+ * N.B. time value in this context refers only to the tv_sec component.
+ */
+static int
+osc_snapshot_compare(const void *vp1, const void *vp2)
+{
+ const struct osc_snapshot *isp1 = vp1;
+ const struct osc_snapshot *isp2 = vp2;
+
+ return -osc_time_compare(&isp1->is_time, &isp2->is_time);
+}
+
+/**
+ * Insert a snapshot into the snapshot set.
+ *
+ * Inserts a new snapshot into the snapshot set. The key for snapshots is
+ * their creation time (it's actually the seconds portion of the creation
+ * time). If a duplicate snapshot is found in the set, the new snapshot is
+ * added to a linked list of snapshots for that second.
+ */
+static void
+osc_snapshot_insert(struct osc_snapshot_ctx *oscp, const char *name,
+ const struct timespec *tsp, int *errorp)
+{
+ struct osc_snapshot *isp1;
+ struct osc_snapshot **ispp;
+
+ isp1 = osc_snapshot_create(name, tsp);
+ if (isp1 == NULL) {
+ *errorp = 1;
+ return;
+ }
+
+ ispp = tsearch(isp1, &oscp->osc_set, osc_snapshot_compare);
+ if (ispp != NULL) {
+ struct osc_snapshot *isp2 = *ispp;
+
+ /* If this is the only snapshot for this second, we're done. */
+ if (isp2 == isp1)
+ return;
+
+ /* Collision: add the new snapshot to the list. */
+ isp1->is_next = isp2->is_next;
+ isp2->is_next = isp1;
+
+ } else
+ *errorp = 1;
+
+}
+
+/**
+ * Process the next snapshot.
+ *
+ * Called for (almost) every entry in a .snapshot directory, ("." and ".." are
+ * ignored in osc_process_snapshot_directory()). All other entries are passed
+ * to osc_process_snapshot(), however. These entries can fall into one of two
+ * categories: snapshot names and snapshot aliases. We only care about
+ * snapshot names (as aliases are just redundant entries). Once it verifies
+ * that name represents a valid snapshot name, it calls fstat() to get the
+ * creation time of the snapshot and then calls osc_snapshot_insert() to add
+ * this entry to the snapshot set.
+ */
+static void
+osc_process_snapshot(struct osc_snapshot_ctx *oscp, const char *name,
+ int *errorp)
+{
+ int fd;
+ struct stf_stat stf_stat;
+ struct stat stbuf;
+
+ fd = osc_get_names_directory_fd();
+ if (fd == -1)
+ goto out;
+
+ fd = enc_openat(fd, name, ENC_DEFAULT, O_RDONLY);
+ if (fd == -1)
+ goto out;
+
+ memset(&stf_stat, 0, sizeof stf_stat);
+ if (ifs_snap_stat(fd, &stf_stat) == -1)
+ goto out;
+
+ if (stf_stat.sf_type != SF_STF)
+ goto out;
+
+ if (fstat(fd, &stbuf) == -1)
+ goto out;
+
+ osc_snapshot_insert(oscp, name, &stbuf.st_birthtimespec, errorp);
+
+ out:
+ if (fd != -1)
+ close(fd);
+}
+
+/**
+ * Process a snapshot directory.
+ *
+ * Opens the snapshot directory and calls osc_process_snapshot() for each
+ * entry. (Well ok, "." and ".." are ignored.) The goal here is to add all
+ * snapshots in the directory to the snapshot set.
+ */
+static void
+osc_process_snapshot_directory(struct osc_snapshot_ctx *oscp, int *errorp)
+{
+ int fd;
+ struct stat stbuf;
+ DIR *dirp;
+ struct dirent *dp;
+
+ fd = osc_get_names_directory_fd();
+ if (fd == -1)
+ goto out;
+
+ if (fstat(fd, &stbuf) == -1)
+ goto out;
+
+ dirp = opendir(SNAPSHOT_DIRECTORY);
+ if (dirp == NULL)
+ goto out;
+
+ for (;;) {
+ dp = readdir(dirp);
+ if (dp == NULL)
+ break;
+
+ if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+ continue;
+
+ osc_process_snapshot(oscp, dp->d_name, errorp);
+ if (*errorp)
+ break;
+ }
+
+ closedir(dirp);
+
+ if (!*errorp)
+ oscp->osc_mtime = stbuf.st_mtimespec;
+
+ out:
+ return;
+}
+
+/**
+ * Initialize a snapshot context object.
+ *
+ * Clears all members of the context object.
+ */
+static void
+osc_snapshot_ctx_init(struct osc_snapshot_ctx *oscp)
+{
+ memset(oscp, 0, sizeof *oscp);
+}
+
+/**
+ * Desoy a snapshot context object.
+ *
+ * Frees all snapshots associated with the snapshot context and then calls
+ * osc_snapshot_ctx_init() to re-initialize the context object.
+ */
+static void
+osc_snapshot_ctx_clean(struct osc_snapshot_ctx *oscp)
+{
+ struct osc_snapshot *tmp;
+
+ while (oscp->osc_set != NULL) {
+ tmp = *(void **)oscp->osc_set;
+ tdelete(tmp, &oscp->osc_set, osc_snapshot_compare);
+ osc_snapshot_destroy_list(tmp);
+ }
+
+ osc_snapshot_ctx_init(oscp);
+}
+
+/**
+ * Return the "global" snapshot context.
+ *
+ * We maintain a single open snapshot context. Return a pointer to it.
+ */
+static struct osc_snapshot_ctx *
+osc_get_snapshot_ctx(void)
+{
+ static struct osc_snapshot_ctx osc = { 0, { 0, 0 } };
+
+ return &osc;
+}
+
+/**
+ * Determine whether a snapshot context is still valid.
+ *
+ * "Valid" in this context means "reusable". We can re-use a previous
+ * snapshot context iff we successfully built a previous snapshot context
+ * and no snapshots have been created or deleted since we did so.
+ * A "names" directory exists within our snapshot
+ * implementation in which all snapshot names are entered. Each time a
+ * snapshot is created or deleted, an entry must be added or removed.
+ * When this happens the modification time on the "names" directory
+ * changes. Therefore, a snapshot context is valid iff the context
+ * pointer is non-NULL, the cached modification time is non-zero
+ * (zero means uninitialized), and the modification time of the "names"
+ * directory matches the cached value.
+ */
+static int
+osc_snapshot_ctx_is_valid(struct osc_snapshot_ctx *oscp)
+{
+ int fd;
+ struct stat stbuf;
+
+ if (oscp == NULL)
+ return 0;
+
+ if (osc_timespec_is_zero(&oscp->osc_mtime))
+ return 0;
+
+ fd = osc_get_names_directory_fd();
+ if (fd == -1)
+ return 0;
+
+ if (fstat(fd, &stbuf) == -1)
+ return 0;
+
+ if (osc_timespec_compare(&oscp->osc_mtime, &stbuf.st_mtimespec) != 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * Create and initialize a directory context.
+ *
+ * Allocates a directory context from the heap and initializes it.
+ */
+static struct osc_directory_ctx *
+osc_directory_ctx_create(void)
+{
+ struct osc_directory_ctx *idcp;
+
+ idcp = malloc(sizeof *idcp);
+ if (idcp != NULL)
+ memset(idcp, 0, sizeof *idcp);
+
+ return idcp;
+}
+
+/**
+ * Destroy a directory context.
+ *
+ * Frees any versions associated with the directory context and then frees the
+ * context itself.
+ */
+static void
+osc_directory_ctx_destroy(struct osc_directory_ctx *idcp)
+{
+ int i;
+
+ if (idcp == NULL)
+ return;
+
+ for (i = 0; i < idcp->idc_len; i++)
+ free(idcp->idc_version[i]);
+
+ free(idcp);
+}
+
+/**
+ * Expand the size of a directory context's version list.
+ *
+ * If osc_directory_ctx_append_version() detects that the version list is too
+ * small to accomodate a new version string, it called
+ * osc_directory_ctx_expand_version_list() to expand the version list.
+ */
+static void
+osc_directory_ctx_expand_version_list(struct osc_snapshot_ctx *oscp,
+ struct osc_directory_ctx *idcp, int *errorp)
+{
+ size_t size;
+ char **cpp;
+
+ size = idcp->idc_size * 2 ?: 1;
+
+ cpp = realloc(idcp->idc_version, size * sizeof (char *));
+ if (cpp == NULL) {
+ *errorp = 1;
+ return;
+ }
+
+ idcp->idc_size = size;
+ idcp->idc_version = cpp;
+}
+
+/**
+ * Append a new version to a directory context.
+ *
+ * Appends a snapshot version to the
+ * directory context's version list.
+ */
+static void
+osc_directory_ctx_append_version(struct osc_snapshot_ctx *oscp,
+ struct osc_directory_ctx *idcp, const struct timespec *tsp, int *errorp)
+{
+ char *cp;
+ struct tm *tmp;
+ char text[64];
+
+ if (idcp->idc_len >= MAX_VERSIONS)
+ return;
+
+ if (idcp->idc_len >= idcp->idc_size) {
+ osc_directory_ctx_expand_version_list(oscp, idcp, errorp);
+ if (*errorp)
+ return;
+ }
+
+ tmp = gmtime(&tsp->tv_sec);
+ if (tmp == NULL) {
+ *errorp = 1;
+ return;
+ }
+
+ snprintf(text, sizeof text,
+ "@GMT-%04u.%02u.%02u-%02u.%02u.%02u",
+ tmp->tm_year + 1900,
+ tmp->tm_mon + 1,
+ tmp->tm_mday,
+ tmp->tm_hour,
+ tmp->tm_min,
+ tmp->tm_sec);
+
+ cp = malloc(strlen(text) + 1);
+ if (cp == NULL) {
+ *errorp = 1;
+ return;
+ }
+
+ strcpy(cp, text);
+
+ idcp->idc_version[idcp->idc_len++] = cp;
+}
+
+/**
+ * Make a directory context from a snapshot context.
+ *
+ * Once a snapshot context has been completely filled-in,
+ * osc_make_directory_ctx() is used to build a directory context from it. The
+ * idea here is to create version for each snapshot in the snapshot set.
+ */
+static void
+osc_make_directory_ctx(struct osc_snapshot_ctx *oscp,
+ struct osc_directory_ctx *idcp, int *errorp)
+{
+ static void
+ walk(const void *vp, VISIT v, int level)
+ {
+ const struct osc_snapshot *isp;
+
+ if ((v != postorder && v != leaf) || *errorp)
+ return;
+
+ isp = *(const struct osc_snapshot **)(u_long)vp;
+
+ osc_directory_ctx_append_version(oscp, idcp, &isp->is_time,
+ errorp);
+ }
+
+ twalk(oscp->osc_set, walk);
+}
+
+/**
+ * Open a version directory.
+ *
+ * Opens a version directory. What this really means is that
+ * osc_version_opendir() returns a handle to a directory context, which can be
+ * used to retrieve version strings.
+ */
+void *
+osc_version_opendir(void)
+{
+ int error = 0;
+ struct osc_directory_ctx *idcp;
+ struct osc_snapshot_ctx *oscp;
+
+ idcp = osc_directory_ctx_create();
+ if (idcp == NULL)
+ goto error_out;
+
+ oscp = osc_get_snapshot_ctx();
+
+ if (!osc_snapshot_ctx_is_valid(oscp)) {
+ osc_snapshot_ctx_clean(oscp);
+ osc_process_snapshot_directory(oscp, &error);
+ if (error)
+ goto error_out;
+ }
+
+ osc_make_directory_ctx(oscp, idcp, &error);
+ if (error)
+ goto error_out;
+
+ goto out;
+
+ error_out:
+ if (idcp != NULL) {
+ osc_directory_ctx_destroy(idcp);
+ idcp = NULL;
+ }
+
+ out:
+ return (void *)idcp;
+}
+
+/**
+ * Read the next version directory entry.
+ *
+ * Returns the name of the next version in the version directory, or NULL if
+ * we're at the end of the directory. What this really does is return the
+ * next version from the version list stored in the directory context.
+ */
+char *
+osc_version_readdir(void *vp)
+{
+ struct osc_directory_ctx *idcp = vp;
+
+ if (idcp == NULL)
+ return NULL;
+
+ if (idcp->idc_pos >= idcp->idc_len)
+ return NULL;
+
+ return idcp->idc_version[idcp->idc_pos++];
+}
+
+/**
+ * Close the version directory.
+ *
+ * Destroys the underlying directory context.
+ */
+void
+osc_version_closedir(void *vp)
+{
+ struct osc_directory_ctx *idcp = vp;
+
+ if (idcp != NULL)
+ osc_directory_ctx_destroy(idcp);
+}
+
+/**
+ * Canonicalize a path.
+ *
+ * Converts paths of the form @GMT-.. to paths of the form ../.snapshot/..
+ * It's not the prettiest routine I've ever written, but what the heck?
+ */
+char *
+osc_canonicalize_path(const char *path, char *snap_component)
+{
+ int error = 0;
+ struct osc_snapshot_ctx *oscp;
+ struct tm tm;
+ int n;
+ struct osc_snapshot is;
+ struct osc_snapshot **ispp;
+ struct osc_snapshot *isp;
+ char *cpath = NULL;
+ char *cpath2 = NULL;
+ const char *snap_component_orig = snap_component;
+ struct stat sb;
+
+ oscp = osc_get_snapshot_ctx();
+
+ if (!osc_snapshot_ctx_is_valid(oscp)) {
+ osc_snapshot_ctx_clean(oscp);
+ osc_process_snapshot_directory(oscp, &error);
+ if (error)
+ goto out;
+ }
+
+ memset(&tm, 0, sizeof tm);
+ n = sscanf(snap_component,
+ "@GMT-%4u.%2u.%2u-%2u.%2u.%2u",
+ &tm.tm_year,
+ &tm.tm_mon,
+ &tm.tm_mday,
+ &tm.tm_hour,
+ &tm.tm_min,
+ &tm.tm_sec);
+ if (n != 6)
+ goto out;
+
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+
+ is.is_name = NULL;
+ is.is_time.tv_sec = timegm(&tm);
+ is.is_time.tv_nsec = 0;
+
+ ispp = tfind(&is, &oscp->osc_set, osc_snapshot_compare);
+ if (ispp == NULL)
+ goto out;
+ isp = *ispp;
+
+ /* Determine the path after "@GMT-..." */
+ while (*snap_component != '/' && *snap_component != '\0')
+ snap_component++;
+
+ while (*snap_component == '/')
+ snap_component++;
+
+ cpath = malloc(strlen(SNAPSHOT_DIRECTORY) + strlen(isp->is_name) +
+ strlen(path) + 3);
+
+ if (cpath == NULL)
+ goto out;
+
+ /*
+ * Use the first snapshot that has a successful stat for the requested
+ * path.
+ */
+ while (true) {
+
+ sprintf(cpath, "%s/%s", SNAPSHOT_DIRECTORY, isp->is_name);
+
+ /* Append path before "@GMT-..." */
+ if (snap_component_orig != path) {
+ strcat(cpath, "/");
+ strncat(cpath, path, snap_component_orig - path);
+ }
+
+ /* Append path after "@GMT-..." */
+ if (*snap_component != '\0') {
+ strcat(cpath, "/");
+ strcat(cpath, snap_component);
+ }
+
+ /* If there is a valid snapshot for this file, we're done. */
+ if (stat(cpath, &sb) == 0)
+ break;
+
+ /* Try the next snapshot. If this was the last one, give up. */
+ isp = isp->is_next;
+ if (isp == NULL)
+ break;
+
+ /* If the realloc fails, give up. */
+ cpath2 = realloc(cpath, strlen(SNAPSHOT_DIRECTORY) +
+ strlen(isp->is_name) + strlen(path) + 3);
+ if (cpath2 == NULL)
+ break;
+ cpath = cpath2;
+ }
+
+ out:
+ return cpath;
+}
diff --git a/source3/modules/onefs_shadow_copy.h b/source3/modules/onefs_shadow_copy.h
new file mode 100644
index 0000000000..6415a4be1a
--- /dev/null
+++ b/source3/modules/onefs_shadow_copy.h
@@ -0,0 +1,32 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * OneFS shadow copy implementation that utilizes the file system's native
+ * snapshot support.
+ *
+ * Copyright (C) Dave Richards, 2007
+ * Copyright (C) Tim Prouty, 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ONEFS_SHADOW_COPY_H
+#define ONEFS_SHADOW_COPY_H
+
+void *osc_version_opendir(void);
+char *osc_version_readdir(void *vp);
+void osc_version_closedir(void *vp);
+char *osc_canonicalize_path(const char *path, char *snap_component);
+
+#endif /* ONEFS_SHADOW_COPY_H */
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 9616ca48d5..6e2794399d 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -160,18 +160,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname,
char *nbase = NULL;
char *nsname = NULL;
+ START_PROFILE(syscall_rename_at);
+
frame = talloc_stackframe();
ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream);
- if (ret)
+ if (ret) {
+ END_PROFILE(syscall_rename_at);
return ret;
+ }
ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream);
- if (ret)
+ if (ret) {
+ END_PROFILE(syscall_rename_at);
return ret;
+ }
if (!old_is_stream && !new_is_stream) {
- return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
+ ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
+ END_PROFILE(syscall_rename_at);
+ return ret;
}
dir_fd = get_stream_dir_fd(handle->conn, obase, NULL);
@@ -192,6 +200,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname,
}
done:
+ END_PROFILE(syscall_rename_at);
+
saved_errno = errno;
if (dir_fd >= 0) {
close(dir_fd);
@@ -220,7 +230,7 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf,
static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname,
SMB_STRUCT_STAT *sbuf)
{
- struct onefs_vfs_config cfg;
+ struct onefs_vfs_share_config cfg;
struct timeval tv_now = {0, 0};
bool static_mtime = False;
bool static_atime = False;
diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c
index 6f93d9ff97..43ebed8d44 100644
--- a/source3/modules/onefs_system.c
+++ b/source3/modules/onefs_system.c
@@ -95,6 +95,8 @@ int onefs_sys_create_file(connection_struct *conn,
uint32_t onefs_dos_attributes;
struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE;
+ START_PROFILE(syscall_createfile);
+
/* Setup security descriptor and get secinfo. */
if (sd != NULL) {
NTSTATUS status;
@@ -123,17 +125,53 @@ int onefs_sys_create_file(connection_struct *conn,
/* Convert samba dos flags to UF_DOS_* attributes. */
onefs_dos_attributes = dos_attributes_to_stat_dos_flags(dos_flags);
+ /**
+ * Deal with kernel creating Default ACLs. (Isilon bug 47447.)
+ *
+ * 1) "nt acl support = no", default_acl = no
+ * 2) "inherit permissions = yes", default_acl = no
+ */
+ if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn)))
+ cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL);
+
+ /*
+ * Some customer workflows require the execute bit to be ignored.
+ */
+ if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_ALLOW_EXECUTE_ALWAYS,
+ PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT) &&
+ (open_access_mask & FILE_EXECUTE)) {
+
+ DEBUG(3, ("Stripping execute bit from %s: (0x%x)\n", path,
+ open_access_mask));
+
+ /* Strip execute. */
+ open_access_mask &= ~FILE_EXECUTE;
+
+ /*
+ * Add READ_DATA, so we're not left with desired_access=0. An
+ * execute call should imply the client will read the data.
+ */
+ open_access_mask |= FILE_READ_DATA;
+
+ DEBUGADD(3, ("New stripped access mask: 0x%x\n",
+ open_access_mask));
+ }
+
DEBUG(10,("onefs_sys_create_file: base_fd = %d, "
- "open_access_mask = 0x%x, flags = 0x%x, mode = 0x%x, "
+ "open_access_mask = 0x%x, flags = 0x%x, mode = 0%o, "
"desired_oplock = %s, id = 0x%x, secinfo = 0x%x, sd = %p, "
- "dos_attributes = 0x%x, path = %s\n", base_fd,
+ "dos_attributes = 0x%x, path = %s, "
+ "default_acl=%s\n", base_fd,
(unsigned int)open_access_mask,
(unsigned int)flags,
(unsigned int)mode,
onefs_oplock_str(onefs_oplock),
(unsigned int)id,
(unsigned int)secinfo, sd,
- (unsigned int)onefs_dos_attributes, path));
+ (unsigned int)onefs_dos_attributes, path,
+ cf_flags_and_bool(cf_flags, CF_FLAGS_DEFAULT_ACL) ?
+ "true" : "false"));
/* Initialize smlock struct for files/dirs but not internal opens */
if (!(oplock_request & INTERNAL_OPEN_ONLY)) {
@@ -144,15 +182,6 @@ int onefs_sys_create_file(connection_struct *conn,
smlock_dump(10, psml);
- /**
- * Deal with kernel creating Default ACLs. (Isilon bug 47447.)
- *
- * 1) "nt acl support = no", default_acl = no
- * 2) "inherit permissions = yes", default_acl = no
- */
- if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn)))
- cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL);
-
ret_fd = ifs_createfile(base_fd, path,
(enum ifs_ace_rights)open_access_mask, flags & ~O_ACCMODE, mode,
onefs_oplock, id, psml, secinfo, pifs_sd, onefs_dos_attributes,
@@ -169,12 +198,279 @@ int onefs_sys_create_file(connection_struct *conn,
}
out:
+ END_PROFILE(syscall_createfile);
aclu_free_sd(pifs_sd, false);
return ret_fd;
}
/**
+ * FreeBSD based sendfile implementation that allows for atomic semantics.
+ */
+static ssize_t onefs_sys_do_sendfile(int tofd, int fromfd,
+ const DATA_BLOB *header, SMB_OFF_T offset, size_t count, bool atomic)
+{
+ size_t total=0;
+ struct sf_hdtr hdr;
+ struct iovec hdtrl;
+ size_t hdr_len = 0;
+ int flags = 0;
+
+ if (atomic) {
+ flags = SF_ATOMIC;
+ }
+
+ hdr.headers = &hdtrl;
+ hdr.hdr_cnt = 1;
+ hdr.trailers = NULL;
+ hdr.trl_cnt = 0;
+
+ /* Set up the header iovec. */
+ if (header) {
+ hdtrl.iov_base = header->data;
+ hdtrl.iov_len = hdr_len = header->length;
+ } else {
+ hdtrl.iov_base = NULL;
+ hdtrl.iov_len = 0;
+ }
+
+ total = count;
+ while (total + hdtrl.iov_len) {
+ SMB_OFF_T nwritten;
+ int ret;
+
+ /*
+ * FreeBSD sendfile returns 0 on success, -1 on error.
+ * Remember, the tofd and fromfd are reversed..... :-).
+ * nwritten includes the header data sent.
+ */
+
+ do {
+ ret = sendfile(fromfd, tofd, offset, total, &hdr,
+ &nwritten, flags);
+ } while (ret == -1 && errno == EINTR);
+
+ /* On error we're done. */
+ if (ret == -1) {
+ return -1;
+ }
+
+ /*
+ * If this was an ATOMIC sendfile, nwritten doesn't
+ * necessarily indicate an error. It could mean count > than
+ * what sendfile can handle atomically (usually 64K) or that
+ * there was a short read due to the file being truncated.
+ */
+ if (nwritten == 0) {
+ return atomic ? 0 : -1;
+ }
+
+ /*
+ * An atomic sendfile should never send partial data!
+ */
+ if (atomic && nwritten != total + hdtrl.iov_len) {
+ DEBUG(0,("Atomic sendfile() sent partial data: "
+ "%llu of %d\n", nwritten,
+ total + hdtrl.iov_len));
+ return -1;
+ }
+
+ /*
+ * If this was a short (signal interrupted) write we may need
+ * to subtract it from the header data, or null out the header
+ * data altogether if we wrote more than hdtrl.iov_len bytes.
+ * We change nwritten to be the number of file bytes written.
+ */
+
+ if (hdtrl.iov_base && hdtrl.iov_len) {
+ if (nwritten >= hdtrl.iov_len) {
+ nwritten -= hdtrl.iov_len;
+ hdtrl.iov_base = NULL;
+ hdtrl.iov_len = 0;
+ } else {
+ hdtrl.iov_base =
+ (caddr_t)hdtrl.iov_base + nwritten;
+ hdtrl.iov_len -= nwritten;
+ nwritten = 0;
+ }
+ }
+ total -= nwritten;
+ offset += nwritten;
+ }
+ return count + hdr_len;
+}
+
+/**
+ * Handles the subtleties of using sendfile with CIFS.
+ */
+ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
+ const DATA_BLOB *header, SMB_OFF_T offset,
+ size_t count)
+{
+ bool atomic = false;
+ ssize_t ret = 0;
+
+ START_PROFILE_BYTES(syscall_sendfile, count);
+
+ if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_ATOMIC_SENDFILE,
+ PARM_ATOMIC_SENDFILE_DEFAULT)) {
+ atomic = true;
+ }
+
+ /* Try the sendfile */
+ ret = onefs_sys_do_sendfile(tofd, fromfd, header, offset, count,
+ atomic);
+
+ /* If the sendfile wasn't atomic, we're done. */
+ if (!atomic) {
+ DEBUG(10, ("non-atomic sendfile read %ul bytes", ret));
+ END_PROFILE(syscall_sendfile);
+ return ret;
+ }
+
+ /*
+ * Atomic sendfile takes care to not write anything to the socket
+ * until all of the requested bytes have been read from the file.
+ * There are two atomic cases that need to be handled.
+ *
+ * 1. The file was truncated causing less data to be read than was
+ * requested. In this case, we return back to the caller to
+ * indicate 0 bytes were written to the socket. This should
+ * prompt the caller to fallback to the standard read path: read
+ * the data, create a header that indicates how many bytes were
+ * actually read, and send the header/data back to the client.
+ *
+ * This saves us from standard sendfile behavior of sending a
+ * header promising more data then will actually be sent. The
+ * only two options are to close the socket and kill the client
+ * connection, or write a bunch of 0s. Closing the client
+ * connection is bad because there could actually be multiple
+ * sessions multiplexed from the same client that are all dropped
+ * because of a truncate. Writing the remaining data as 0s also
+ * isn't good, because the client will have an incorrect version
+ * of the file. If the file is written back to the server, the 0s
+ * will be written back. Fortunately, atomic sendfile allows us
+ * to avoid making this choice in most cases.
+ *
+ * 2. One downside of atomic sendfile, is that there is a limit on
+ * the number of bytes that can be sent atomically. The kernel
+ * has a limited amount of mbuf space that it can read file data
+ * into without exhausting the system's mbufs, so a buffer of
+ * length xfsize is used. The xfsize at the time of writing this
+ * is 64K. xfsize bytes are read from the file, and subsequently
+ * written to the socket. This makes it impossible to do the
+ * sendfile atomically for a byte count > xfsize.
+ *
+ * To cope with large requests, atomic sendfile returns -1 with
+ * errno set to E2BIG. Since windows maxes out at 64K writes,
+ * this is currently only a concern with non-windows clients.
+ * Posix extensions allow the full 24bit bytecount field to be
+ * used in ReadAndX, and clients such as smbclient and the linux
+ * cifs client can request up to 16MB reads! There are a few
+ * options for handling large sendfile requests.
+ *
+ * a. Fall back to the standard read path. This is unacceptable
+ * because it would require prohibitively large mallocs.
+ *
+ * b. Fall back to using samba's fake_send_file which emulates
+ * the kernel sendfile in userspace. This still has the same
+ * problem of sending the header before all of the data has
+ * been read, so it doesn't buy us anything, and has worse
+ * performance than the kernel's zero-copy sendfile.
+ *
+ * c. Use non-atomic sendfile syscall to attempt a zero copy
+ * read, and hope that there isn't a short read due to
+ * truncation. In the case of a short read, there are two
+ * options:
+ *
+ * 1. Kill the client connection
+ *
+ * 2. Write zeros to the socket for the remaining bytes
+ * promised in the header.
+ *
+ * It is safer from a data corruption perspective to kill the
+ * client connection, so this is our default behavior, but if
+ * this causes problems this can be configured to write zeros
+ * via smb.conf.
+ */
+
+ /* Handle case 1: short read -> truncated file. */
+ if (ret == 0) {
+ END_PROFILE(syscall_sendfile);
+ return ret;
+ }
+
+ /* Handle case 2: large read. */
+ if (ret == -1 && errno == E2BIG) {
+
+ if (!lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_SENDFILE_LARGE_READS,
+ PARM_SENDFILE_LARGE_READS_DEFAULT)) {
+ DEBUG(3, ("Not attempting non-atomic large sendfile: "
+ "%lu bytes\n", count));
+ END_PROFILE(syscall_sendfile);
+ return 0;
+ }
+
+ if (count < 0x10000) {
+ DEBUG(0, ("Count < 2^16 and E2BIG was returned! %lu",
+ count));
+ }
+
+ DEBUG(10, ("attempting non-atomic large sendfile: %lu bytes\n",
+ count));
+
+ /* Try a non-atomic sendfile. */
+ ret = onefs_sys_do_sendfile(tofd, fromfd, header, offset,
+ count, false);
+ /* Real error: kill the client connection. */
+ if (ret == -1) {
+ DEBUG(1, ("error on non-atomic large sendfile "
+ "(%lu bytes): %s\n", count,
+ strerror(errno)));
+ END_PROFILE(syscall_sendfile);
+ return ret;
+ }
+
+ /* Short read: kill the client connection. */
+ if (ret != count + header->length) {
+ DEBUG(1, ("short read on non-atomic large sendfile "
+ "(%lu of %lu bytes): %s\n", ret, count,
+ strerror(errno)));
+
+ /*
+ * Returning ret here would cause us to drop into the
+ * codepath that calls sendfile_short_send, which
+ * sends the client a bunch of zeros instead.
+ * Returning -1 kills the connection.
+ */
+ if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_SENDFILE_SAFE,
+ PARM_SENDFILE_SAFE_DEFAULT)) {
+ END_PROFILE(syscall_sendfile);
+ return -1;
+ }
+
+ END_PROFILE(syscall_sendfile);
+ return ret;
+ }
+
+ DEBUG(10, ("non-atomic large sendfile successful\n"));
+ }
+
+ /* There was error in the atomic sendfile. */
+ if (ret == -1) {
+ DEBUG(1, ("error on %s sendfile (%lu bytes): %s\n",
+ atomic ? "atomic" : "non-atomic",
+ count, strerror(errno)));
+ }
+
+ END_PROFILE(syscall_sendfile);
+ return ret;
+}
+
+/**
* Only talloc the spill buffer once (reallocing when necessary).
*/
static char *get_spill_buffer(size_t new_count)
@@ -225,10 +521,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
off_t rbytes;
off_t wbytes;
+ START_PROFILE_BYTES(syscall_recvfile, count);
+
DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = "
"%lu\n", fromfd, tofd, offset, count));
if (count == 0) {
+ END_PROFILE(syscall_recvfile);
return 0;
}
@@ -340,6 +639,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
ret = total_wbytes;
out:
+
+ END_PROFILE(syscall_recvfile);
+
/* Make sure we always try to drain the socket. */
if (!socket_drained && count - total_rbytes) {
int saved_errno = errno;
@@ -354,3 +656,53 @@ out:
return ret;
}
+
+/**
+ * Set the per-process encoding, ignoring errors.
+ */
+void onefs_sys_config_enc(void)
+{
+ int ret;
+
+ ret = enc_set_proc(ENC_UTF8);
+ if (ret) {
+ DEBUG(0, ("Setting process encoding failed: %s",
+ strerror(errno)));
+ }
+}
+
+/**
+ * Set the per-process .snpashot directory options, ignoring errors.
+ */
+void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config)
+{
+ struct ifs_dotsnap_options dso;
+ int ret;
+
+ dso.per_proc = 1;
+ dso.sub_accessible = global_config->dot_snap_child_accessible;
+ dso.sub_visible = global_config->dot_snap_child_visible;
+ dso.root_accessible = global_config->dot_snap_root_accessible;
+ dso.root_visible = global_config->dot_snap_root_visible;
+
+ ret = ifs_set_dotsnap_options(&dso);
+ if (ret) {
+ DEBUG(0, ("Setting snapshot visibility/accessibility "
+ "failed: %s", strerror(errno)));
+ }
+}
+
+/**
+ * Set the per-process flag saying whether or not to accept ~snapshot
+ * as an alternative name for .snapshot directories.
+ */
+void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config)
+{
+ int ret;
+
+ ret = ifs_tilde_snapshot(global_config->dot_snap_tilde);
+ if (ret) {
+ DEBUG(0, ("Setting snapshot tilde failed: %s",
+ strerror(errno)));
+ }
+}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 57fe73c814..73dbca4809 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -94,6 +94,8 @@ static struct db_record *acl_tdb_lock(TALLOC_CTX *mem_ctx,
const struct file_id *id)
{
uint8 id_buf[16];
+
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
return db->fetch_locked(db,
mem_ctx,
@@ -184,22 +186,29 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
TDB_DATA data;
struct file_id id;
struct db_context *db;
+ int ret = -1;
SMB_STRUCT_STAT sbuf;
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
return NT_STATUS_INTERNAL_DB_CORRUPTION);
if (fsp && fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, name, &sbuf);
}
}
+
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
if (db->fetch(db,
@@ -267,6 +276,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
TDB_DATA data;
struct db_context *db;
struct db_record *rec;
+ int ret = -1;
DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
(unsigned int)pblob->length, fsp->fsp_name));
@@ -275,16 +285,22 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
return NT_STATUS_INTERNAL_DB_CORRUPTION);
if (fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf);
}
}
+
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
rec = db->fetch_locked(db, talloc_tos(),
make_tdb_data(id_buf,
@@ -312,6 +328,7 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
SMB_STRUCT_STAT sbuf;
struct db_context *db;
struct db_record *rec;
+ int ret = -1;
DEBUG(10,("store_acl_blob_pathname: storing blob "
"length %u on file %s\n",
@@ -320,11 +337,19 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
return NT_STATUS_INTERNAL_DB_CORRUPTION);
- if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+ }
+
+ if (ret == -1) {
return map_nt_error_from_unix(errno);
}
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
rec = db->fetch_locked(db, talloc_tos(),
@@ -488,7 +513,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
+ }
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
@@ -577,11 +606,17 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path)
{
SMB_STRUCT_STAT sbuf;
struct db_context *db;
- int ret;
+ int ret = -1;
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, path, &sbuf);
+ }
+
+ if (ret == -1) {
return -1;
}
@@ -620,11 +655,17 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path)
SMB_STRUCT_STAT sbuf;
struct db_context *db;
- int ret;
+ int ret = -1;
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, path, &sbuf);
+ }
+
+ if (ret == -1) {
return -1;
}
@@ -722,7 +763,11 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
return NT_STATUS_OK;
}
if (fsp->is_directory || fsp->fh->fd == -1) {
- ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ }
} else {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
}
@@ -807,11 +852,17 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
{
SMB_STRUCT_STAT sbuf;
struct db_context *db;
- int ret;
+ int ret = -1;
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, path, &sbuf);
+ }
+
+ if (ret == -1) {
return -1;
}
@@ -842,7 +893,11 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
if (fsp->is_directory || fsp->fh->fd == -1) {
- ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ }
} else {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
}
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 7c78b506f0..039e469426 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -381,7 +381,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
+ }
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
@@ -559,7 +563,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
return NT_STATUS_OK;
}
if (fsp->is_directory || fsp->fh->fd == -1) {
- ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ }
} else {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index f52ca09c08..7384268dae 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1042,9 +1042,20 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag
#endif
}
-static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode)
+static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
+ SMB_STRUCT_STAT *sbuf)
{
- return file_id_create_dev(dev, inode);
+ struct file_id key;
+
+ /* the ZERO_STRUCT ensures padding doesn't break using the key as a
+ * blob */
+ ZERO_STRUCT(key);
+
+ key.devid = sbuf->st_dev;
+ key.inode = sbuf->st_ino;
+ /* key.extid is unused by default. */
+
+ return key;
}
static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c
index d7c9d39c5e..b59a780f52 100644
--- a/source3/modules/vfs_extd_audit.c
+++ b/source3/modules/vfs_extd_audit.c
@@ -310,7 +310,7 @@ static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n",
- path, mode,
+ path, (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
@@ -330,7 +330,7 @@ static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t m
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n",
- path, mode,
+ path, (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
@@ -350,7 +350,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
+ fsp->fsp_name, (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
@@ -370,7 +370,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
- fsp->fsp_name, mode,
+ fsp->fsp_name, (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
diff --git a/source3/modules/vfs_fileid.c b/source3/modules/vfs_fileid.c
index 787a49f36b..8152c5477e 100644
--- a/source3/modules/vfs_fileid.c
+++ b/source3/modules/vfs_fileid.c
@@ -226,7 +226,7 @@ static void fileid_disconnect(struct vfs_handle_struct *handle)
}
static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle,
- SMB_DEV_T dev, SMB_INO_T inode)
+ const SMB_STRUCT_STAT *sbuf)
{
struct fileid_handle_data *data;
struct file_id id;
@@ -237,8 +237,8 @@ static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle,
struct fileid_handle_data,
return id);
- id.devid = data->device_mapping_fn(data, dev);
- id.inode = inode;
+ id.devid = data->device_mapping_fn(data, sbuf->st_dev);
+ id.inode = sbuf->st_ino;
return id;
}
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 15eafc1b56..3c159f10eb 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -209,7 +209,7 @@ static NTSTATUS smb_full_audit_notify_watch(struct vfs_handle_struct *handle,
static int smb_full_audit_chflags(vfs_handle_struct *handle,
const char *path, unsigned int flags);
static struct file_id smb_full_audit_file_id_create(struct vfs_handle_struct *handle,
- SMB_DEV_T dev, SMB_INO_T inode);
+ const SMB_STRUCT_STAT *sbuf);
static NTSTATUS smb_full_audit_streaminfo(vfs_handle_struct *handle,
struct files_struct *fsp,
const char *fname,
@@ -1664,14 +1664,14 @@ static int smb_full_audit_chflags(vfs_handle_struct *handle,
}
static struct file_id smb_full_audit_file_id_create(struct vfs_handle_struct *handle,
- SMB_DEV_T dev, SMB_INO_T inode)
+ const SMB_STRUCT_STAT *sbuf)
{
struct file_id id_zero;
struct file_id result;
ZERO_STRUCT(id_zero);
- result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, dev, inode);
+ result = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf);
do_log(SMB_VFS_OP_FILE_ID_CREATE,
!file_id_equal(&id_zero, &result),
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 9667d86dba..f81134909f 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -26,14 +26,14 @@
#define ONEFS_DATA_FASTBUF 10
-struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF];
-struct onefs_vfs_config *pshare_config;
+struct onefs_vfs_share_config vfs_share_config[ONEFS_DATA_FASTBUF];
+struct onefs_vfs_share_config *pvfs_share_config;
-static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle,
- struct onefs_vfs_config *cfg)
+static void onefs_load_faketimestamp_config(struct connection_struct *conn,
+ struct onefs_vfs_share_config *cfg)
{
const char **parm;
- int snum = SNUM(handle->conn);
+ int snum = SNUM(conn);
parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
PARM_ATIME_NOW_DEFAULT);
@@ -83,46 +83,141 @@ static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle,
PARM_MTIME_SLOP_DEFAULT);
}
+/**
+ * Set onefs-specific vfs global config parameters.
+ *
+ * Since changes in these parameters require calling syscalls, we only want to
+ * call them when the configuration actually changes.
+ */
+static void onefs_load_global_config(connection_struct *conn)
+{
+ static struct onefs_vfs_global_config global_config;
+ bool dot_snap_child_accessible;
+ bool dot_snap_child_visible;
+ bool dot_snap_root_accessible;
+ bool dot_snap_root_visible;
+ bool dot_snap_tilde;
+ bool reconfig_dso = false;
+ bool reconfig_tilde = false;
+
+ /* Check if this is the first time setting the config options. */
+ if (!(global_config.init_flags & ONEFS_VFS_CONFIG_INITIALIZED)) {
+ global_config.init_flags |= ONEFS_VFS_CONFIG_INITIALIZED;
+
+ /* Set process encoding */
+ onefs_sys_config_enc();
+
+ reconfig_dso = true;
+ reconfig_tilde = true;
+ }
+
+ /* Get the dot snap options from the conf. */
+ dot_snap_child_accessible =
+ lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_DOT_SNAP_CHILD_ACCESSIBLE,
+ PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT);
+ dot_snap_child_visible =
+ lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_DOT_SNAP_CHILD_VISIBLE,
+ PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT);
+ dot_snap_root_accessible =
+ lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_DOT_SNAP_ROOT_ACCESSIBLE,
+ PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT);
+ dot_snap_root_visible =
+ lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_DOT_SNAP_ROOT_VISIBLE,
+ PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT);
+ dot_snap_tilde =
+ lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_DOT_SNAP_TILDE,
+ PARM_DOT_SNAP_TILDE_DEFAULT);
+
+ /* Check if any of the dot snap options need updating. */
+ if (dot_snap_child_accessible !=
+ global_config.dot_snap_child_accessible) {
+ global_config.dot_snap_child_accessible =
+ dot_snap_child_accessible;
+ reconfig_dso = true;
+ }
+ if (dot_snap_child_visible !=
+ global_config.dot_snap_child_visible) {
+ global_config.dot_snap_child_visible =
+ dot_snap_child_visible;
+ reconfig_dso = true;
+ }
+ if (dot_snap_root_accessible !=
+ global_config.dot_snap_root_accessible) {
+ global_config.dot_snap_root_accessible =
+ dot_snap_root_accessible;
+ reconfig_dso = true;
+ }
+ if (dot_snap_root_visible !=
+ global_config.dot_snap_root_visible) {
+ global_config.dot_snap_root_visible =
+ dot_snap_root_visible;
+ reconfig_dso = true;
+ }
+ if (dot_snap_tilde != global_config.dot_snap_tilde) {
+ global_config.dot_snap_tilde = dot_snap_tilde;
+ reconfig_tilde = true;
+ }
+
+ /* If a dot snap option has changed update the process. */
+ if (reconfig_dso) {
+ onefs_sys_config_snap_opt(&global_config);
+ }
-static int onefs_load_config(struct vfs_handle_struct *handle)
+ /* If the dot snap tilde option has changed update the process. */
+ if (reconfig_tilde) {
+ onefs_sys_config_tilde(&global_config);
+ }
+}
+
+static int onefs_load_config(connection_struct *conn)
{
- int snum = SNUM(handle->conn);
+ int snum = SNUM(conn);
int share_count = lp_numservices();
- if (!pshare_config) {
+ /* Share config */
+ if (!pvfs_share_config) {
if (share_count <= ONEFS_DATA_FASTBUF)
- pshare_config = share_config;
+ pvfs_share_config = vfs_share_config;
else {
- pshare_config =
- SMB_MALLOC_ARRAY(struct onefs_vfs_config,
+ pvfs_share_config =
+ SMB_MALLOC_ARRAY(struct onefs_vfs_share_config,
share_count);
- if (!pshare_config) {
+ if (!pvfs_share_config) {
errno = ENOMEM;
return -1;
}
- memset(pshare_config, 0,
- (sizeof(struct onefs_vfs_config) * share_count));
+ memset(pvfs_share_config, 0,
+ (sizeof(struct onefs_vfs_share_config) *
+ share_count));
}
}
- if ((pshare_config[snum].init_flags &
+ if ((pvfs_share_config[snum].init_flags &
ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
- pshare_config[snum].init_flags =
+ pvfs_share_config[snum].init_flags =
ONEFS_VFS_CONFIG_INITIALIZED;
- onefs_load_faketimestamp_config(handle,
- &pshare_config[snum]);
+ onefs_load_faketimestamp_config(conn,
+ &pvfs_share_config[snum]);
}
+ /* Global config */
+ onefs_load_global_config(conn);
+
return 0;
}
bool onefs_get_config(int snum, int config_type,
- struct onefs_vfs_config *cfg)
+ struct onefs_vfs_share_config *cfg)
{
- if (share_config[snum].init_flags & config_type)
- *cfg = share_config[snum];
+ if (vfs_share_config[snum].init_flags & config_type)
+ *cfg = vfs_share_config[snum];
else
return false;
@@ -132,10 +227,13 @@ bool onefs_get_config(int snum, int config_type,
static int onefs_connect(struct vfs_handle_struct *handle, const char *service,
const char *user)
{
- int ret = onefs_load_config(handle);
+ int ret;
- if (ret)
+ ret = onefs_load_config(handle->conn);
+ if (ret) {
+ DEBUG(3, ("Load config failed: %s\n", strerror(errno)));
return ret;
+ }
return SMB_VFS_NEXT_CONNECT(handle, service, user);
}
@@ -156,6 +254,19 @@ static int onefs_open(vfs_handle_struct *handle, const char *fname,
return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
}
+static ssize_t onefs_sendfile(vfs_handle_struct *handle, int tofd,
+ files_struct *fromfsp, const DATA_BLOB *header,
+ SMB_OFF_T offset, size_t count)
+{
+ ssize_t result;
+
+ START_PROFILE_BYTES(syscall_sendfile, count);
+ result = onefs_sys_sendfile(handle->conn, tofd, fromfsp->fh->fd,
+ header, offset, count);
+ END_PROFILE(syscall_sendfile);
+ return result;
+}
+
static ssize_t onefs_recvfile(vfs_handle_struct *handle, int fromfd,
files_struct *tofsp, SMB_OFF_T offset,
size_t count)
@@ -194,6 +305,22 @@ static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle,
return result;
}
+static struct file_id onefs_file_id_create(struct vfs_handle_struct *handle,
+ SMB_STRUCT_STAT *sbuf)
+{
+ struct file_id key;
+
+ /* the ZERO_STRUCT ensures padding doesn't break using the key as a
+ * blob */
+ ZERO_STRUCT(key);
+
+ key.devid = sbuf->st_dev;
+ key.inode = sbuf->st_ino;
+ key.extid = sbuf->st_snapid;
+
+ return key;
+}
+
static int onefs_statvfs(vfs_handle_struct *handle, const char *path,
vfs_statvfs_struct *statbuf)
{
@@ -324,6 +451,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_close), SMB_VFS_OP_CLOSE,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_sendfile), SMB_VFS_OP_SENDFILE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_recvfile), SMB_VFS_OP_RECVFILE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_rename), SMB_VFS_OP_RENAME,
@@ -342,6 +471,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_chflags), SMB_VFS_OP_CHFLAGS,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_file_id_create), SMB_VFS_OP_FILE_ID_CREATE,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_brl_lock_windows), SMB_VFS_OP_BRL_LOCK_WINDOWS,
@@ -350,6 +481,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_brl_cancel_windows), SMB_VFS_OP_BRL_CANCEL_WINDOWS,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(onefs_notify_watch), SMB_VFS_OP_NOTIFY_WATCH,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c
new file mode 100644
index 0000000000..28bc0c5081
--- /dev/null
+++ b/source3/modules/vfs_onefs_shadow_copy.c
@@ -0,0 +1,717 @@
+/*
+ * OneFS shadow copy implementation that utilizes the file system's native
+ * snapshot support. This is based on the original shadow copy module from
+ * 2004.
+ *
+ * Copyright (C) Stefan Metzmacher 2003-2004
+ * Copyright (C) Tim Prouty 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "onefs_shadow_copy.h"
+
+static int vfs_onefs_shadow_copy_debug_level = DBGC_VFS;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS vfs_onefs_shadow_copy_debug_level
+
+#define SHADOW_COPY_PREFIX "@GMT-"
+#define SHADOW_COPY_SAMPLE "@GMT-2004.02.18-15.44.00"
+
+bool
+shadow_copy_match_name(const char *name, char **snap_component)
+{
+ uint32 i = 0;
+ char delim[] = SHADOW_COPY_PREFIX;
+ char* start;
+
+ start = strstr( name, delim );
+
+ /*
+ * The name could have SHADOW_COPY_PREFIX in it so we need to keep
+ * trying until we get something that is the full length of the
+ * SHADOW_COPY_SAMPLE.
+ */
+ while (start != NULL) {
+
+ DEBUG(10,("Processing %s\n", name));
+
+ /* size / correctness check */
+ *snap_component = start;
+ for ( i = sizeof(SHADOW_COPY_PREFIX);
+ i < sizeof(SHADOW_COPY_SAMPLE); i++) {
+ if (start[i] == '/') {
+ if (i == sizeof(SHADOW_COPY_SAMPLE) - 1)
+ return true;
+ else
+ break;
+ } else if (start[i] == '\0')
+ return (i == sizeof(SHADOW_COPY_SAMPLE) - 1);
+ }
+
+ start = strstr( start, delim );
+ }
+
+ return false;
+}
+
+static int
+onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SHADOW_COPY_DATA *shadow_copy_data,
+ bool labels)
+{
+ void *p = osc_version_opendir();
+ char *snap_component = NULL;
+ shadow_copy_data->num_volumes = 0;
+ shadow_copy_data->labels = NULL;
+
+ if (!p) {
+ DEBUG(0, ("shadow_copy_get_shadow_copy_data: osc_opendir() "
+ "failed for [%s]\n",fsp->conn->connectpath));
+ return -1;
+ }
+
+ while (true) {
+ SHADOW_COPY_LABEL *tlabels;
+ char *d;
+
+ d = osc_version_readdir(p);
+ if (d == NULL)
+ break;
+
+ if (!shadow_copy_match_name(d, &snap_component)) {
+ DEBUG(10,("shadow_copy_get_shadow_copy_data: ignore "
+ "[%s]\n",d));
+ continue;
+ }
+
+ DEBUG(7,("shadow_copy_get_shadow_copy_data: not ignore "
+ "[%s]\n",d));
+
+ if (!labels) {
+ shadow_copy_data->num_volumes++;
+ continue;
+ }
+
+ tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(
+ shadow_copy_data->mem_ctx,
+ shadow_copy_data->labels,
+ (shadow_copy_data->num_volumes+1) *
+ sizeof(SHADOW_COPY_LABEL));
+
+ if (tlabels == NULL) {
+ DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of "
+ "memory\n"));
+ osc_version_closedir(p);
+ return -1;
+ }
+
+ snprintf(tlabels[shadow_copy_data->num_volumes++],
+ sizeof(*tlabels), "%s",d);
+
+ shadow_copy_data->labels = tlabels;
+ }
+
+ osc_version_closedir(p);
+
+ return 0;
+}
+
+#define SHADOW_NEXT(op, args, rtype) do { \
+ char *cpath = NULL; \
+ char *snap_component = NULL; \
+ rtype ret; \
+ if (shadow_copy_match_name(path, &snap_component)) \
+ cpath = osc_canonicalize_path(path, snap_component); \
+ ret = SMB_VFS_NEXT_ ## op args; \
+ SAFE_FREE(cpath); \
+ return ret; \
+ } while (0) \
+
+
+
+static uint64_t
+onefs_shadow_copy_disk_free(vfs_handle_struct *handle, const char *path,
+ bool small_query, uint64_t *bsize, uint64_t *dfree,
+ uint64_t *dsize)
+{
+
+ SHADOW_NEXT(DISK_FREE,
+ (handle, cpath ?: path, small_query, bsize, dfree, dsize),
+ uint64_t);
+
+}
+
+static int
+onefs_shadow_copy_statvfs(struct vfs_handle_struct *handle, const char *path,
+ struct vfs_statvfs_struct *statbuf)
+{
+ SHADOW_NEXT(STATVFS,
+ (handle, cpath ?: path, statbuf),
+ int);
+}
+
+static SMB_STRUCT_DIR *
+onefs_shadow_copy_opendir(vfs_handle_struct *handle, const char *path,
+ const char *mask, uint32_t attr)
+{
+ SHADOW_NEXT(OPENDIR,
+ (handle, cpath ?: path, mask, attr),
+ SMB_STRUCT_DIR *);
+}
+
+static int
+onefs_shadow_copy_mkdir(vfs_handle_struct *handle, const char *path,
+ mode_t mode)
+{
+ SHADOW_NEXT(MKDIR,
+ (handle, cpath ?: path, mode),
+ int);
+}
+
+static int
+onefs_shadow_copy_rmdir(vfs_handle_struct *handle, const char *path)
+{
+ SHADOW_NEXT(RMDIR,
+ (handle, cpath ?: path),
+ int);
+}
+
+static int
+onefs_shadow_copy_open(vfs_handle_struct *handle, const char *path,
+ files_struct *fsp, int flags, mode_t mode)
+{
+ SHADOW_NEXT(OPEN,
+ (handle, cpath ?: path, fsp, flags, mode),
+ int);
+}
+
+static NTSTATUS
+onefs_shadow_copy_create_file(vfs_handle_struct *handle,
+ struct smb_request *req,
+ uint16_t root_dir_fid,
+ const char *path,
+ uint32_t create_file_flags,
+ uint32_t access_mask,
+ uint32_t share_access,
+ uint32_t create_disposition,
+ uint32_t create_options,
+ uint32_t file_attributes,
+ uint32_t oplock_request,
+ uint64_t allocation_size,
+ struct security_descriptor *sd,
+ struct ea_list *ea_list,
+ files_struct **result,
+ int *pinfo,
+ SMB_STRUCT_STAT *psbuf)
+{
+ SHADOW_NEXT(CREATE_FILE,
+ (handle, req, root_dir_fid, cpath ?: path,
+ create_file_flags, access_mask, share_access,
+ create_disposition, create_options, file_attributes,
+ oplock_request, allocation_size, sd, ea_list, result,
+ pinfo, psbuf),
+ NTSTATUS);
+}
+
+/**
+ * XXX: macro-ize
+ */
+static int
+onefs_shadow_copy_rename(vfs_handle_struct *handle, const char *old_name,
+ const char *new_name)
+{
+ char *old_cpath = NULL;
+ char *old_snap_component = NULL;
+ char *new_cpath = NULL;
+ char *new_snap_component = NULL;
+ int ret;
+
+ if (shadow_copy_match_name(old_name, &old_snap_component))
+ old_cpath = osc_canonicalize_path(old_name, old_snap_component);
+
+ if (shadow_copy_match_name(new_name, &new_snap_component))
+ new_cpath = osc_canonicalize_path(new_name, new_snap_component);
+
+ ret = SMB_VFS_NEXT_RENAME(handle, old_cpath ?: old_name,
+ new_cpath ?: new_name);
+
+ SAFE_FREE(old_cpath);
+ SAFE_FREE(new_cpath);
+
+ return ret;
+}
+
+static int
+onefs_shadow_copy_stat(vfs_handle_struct *handle, const char *path,
+ SMB_STRUCT_STAT *sbuf)
+{
+ SHADOW_NEXT(STAT,
+ (handle, cpath ?: path, sbuf),
+ int);
+}
+
+static int
+onefs_shadow_copy_lstat(vfs_handle_struct *handle, const char *path,
+ SMB_STRUCT_STAT *sbuf)
+{
+ SHADOW_NEXT(LSTAT,
+ (handle, cpath ?: path, sbuf),
+ int);
+}
+
+static int
+onefs_shadow_copy_unlink(vfs_handle_struct *handle, const char *path)
+{
+ SHADOW_NEXT(UNLINK,
+ (handle, cpath ?: path),
+ int);
+}
+
+static int
+onefs_shadow_copy_chmod(vfs_handle_struct *handle, const char *path,
+ mode_t mode)
+{
+ SHADOW_NEXT(CHMOD,
+ (handle, cpath ?: path, mode),
+ int);
+}
+
+static int
+onefs_shadow_copy_chown(vfs_handle_struct *handle, const char *path,
+ uid_t uid, gid_t gid)
+{
+ SHADOW_NEXT(CHOWN,
+ (handle, cpath ?: path, uid, gid),
+ int);
+}
+
+static int
+onefs_shadow_copy_lchown(vfs_handle_struct *handle, const char *path,
+ uid_t uid, gid_t gid)
+{
+ SHADOW_NEXT(LCHOWN,
+ (handle, cpath ?: path, uid, gid),
+ int);
+}
+
+static int
+onefs_shadow_copy_chdir(vfs_handle_struct *handle, const char *path)
+{
+ SHADOW_NEXT(CHDIR,
+ (handle, cpath ?: path),
+ int);
+}
+
+static int
+onefs_shadow_copy_ntimes(vfs_handle_struct *handle, const char *path,
+ struct smb_file_time *ft)
+{
+ SHADOW_NEXT(NTIMES,
+ (handle, cpath ?: path, ft),
+ int);
+
+}
+
+/**
+ * XXX: macro-ize
+ */
+static bool
+onefs_shadow_copy_symlink(vfs_handle_struct *handle,
+ const char *oldpath, const char *newpath)
+{
+ char *old_cpath = NULL;
+ char *old_snap_component = NULL;
+ char *new_cpath = NULL;
+ char *new_snap_component = NULL;
+ bool ret;
+
+ if (shadow_copy_match_name(oldpath, &old_snap_component))
+ old_cpath = osc_canonicalize_path(oldpath, old_snap_component);
+
+ if (shadow_copy_match_name(newpath, &new_snap_component))
+ new_cpath = osc_canonicalize_path(newpath, new_snap_component);
+
+ ret = SMB_VFS_NEXT_SYMLINK(handle, old_cpath ?: oldpath,
+ new_cpath ?: newpath);
+
+ SAFE_FREE(old_cpath);
+ SAFE_FREE(new_cpath);
+
+ return ret;
+}
+
+static bool
+onefs_shadow_copy_readlink(vfs_handle_struct *handle, const char *path,
+ char *buf, size_t bufsiz)
+{
+ SHADOW_NEXT(READLINK,
+ (handle, cpath ?: path, buf, bufsiz),
+ bool);
+}
+
+/**
+ * XXX: macro-ize
+ */
+static int
+onefs_shadow_copy_link(vfs_handle_struct *handle, const char *oldpath,
+ const char *newpath)
+{
+ char *old_cpath = NULL;
+ char *old_snap_component = NULL;
+ char *new_cpath = NULL;
+ char *new_snap_component = NULL;
+ int ret;
+
+ if (shadow_copy_match_name(oldpath, &old_snap_component))
+ old_cpath = osc_canonicalize_path(oldpath, old_snap_component);
+
+ if (shadow_copy_match_name(newpath, &new_snap_component))
+ new_cpath = osc_canonicalize_path(newpath, new_snap_component);
+
+ ret = SMB_VFS_NEXT_LINK(handle, old_cpath ?: oldpath,
+ new_cpath ?: newpath);
+
+ SAFE_FREE(old_cpath);
+ SAFE_FREE(new_cpath);
+
+ return ret;
+}
+
+static int
+onefs_shadow_copy_mknod(vfs_handle_struct *handle, const char *path,
+ mode_t mode, SMB_DEV_T dev)
+{
+ SHADOW_NEXT(MKNOD,
+ (handle, cpath ?: path, mode, dev),
+ int);
+}
+
+static char *
+onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path,
+ char *resolved_path)
+{
+ SHADOW_NEXT(REALPATH,
+ (handle, cpath ?: path, resolved_path),
+ char *);
+}
+
+static int onefs_shadow_copy_chflags(struct vfs_handle_struct *handle,
+ const char *path, unsigned int flags)
+{
+ SHADOW_NEXT(CHFLAGS,
+ (handle, cpath ?: path, flags),
+ int);
+}
+
+static NTSTATUS
+onefs_shadow_copy_streaminfo(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *path,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *num_streams,
+ struct stream_struct **streams)
+{
+ SHADOW_NEXT(STREAMINFO,
+ (handle, fsp, cpath ?: path, mem_ctx, num_streams,
+ streams),
+ NTSTATUS);
+}
+
+static int
+onefs_shadow_copy_get_real_filename(struct vfs_handle_struct *handle,
+ const char *full_path,
+ const char *path,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ SHADOW_NEXT(GET_REAL_FILENAME,
+ (handle, full_path, cpath ?: path, mem_ctx, found_name),
+ int);
+}
+
+static NTSTATUS
+onefs_shadow_copy_get_nt_acl(struct vfs_handle_struct *handle,
+ const char *path, uint32 security_info,
+ struct security_descriptor **ppdesc)
+{
+ SHADOW_NEXT(GET_NT_ACL,
+ (handle, cpath ?: path, security_info, ppdesc),
+ NTSTATUS);
+}
+
+static int
+onefs_shadow_copy_chmod_acl(vfs_handle_struct *handle, const char *path,
+ mode_t mode)
+{
+ SHADOW_NEXT(CHMOD_ACL,
+ (handle, cpath ?: path, mode),
+ int);
+}
+
+static SMB_ACL_T
+onefs_shadow_copy_sys_acl_get_file(vfs_handle_struct *handle,
+ const char *path, SMB_ACL_TYPE_T type)
+{
+ SHADOW_NEXT(SYS_ACL_GET_FILE,
+ (handle, cpath ?: path, type),
+ SMB_ACL_T);
+}
+
+static int
+onefs_shadow_copy_sys_acl_set_file(vfs_handle_struct *handle, const char *path,
+ SMB_ACL_TYPE_T type, SMB_ACL_T theacl)
+{
+ SHADOW_NEXT(SYS_ACL_SET_FILE,
+ (handle, cpath ?: path, type, theacl),
+ int);
+}
+
+static int
+onefs_shadow_copy_sys_acl_delete_def_file(vfs_handle_struct *handle,
+ const char *path)
+{
+ SHADOW_NEXT(SYS_ACL_DELETE_DEF_FILE,
+ (handle, cpath ?: path),
+ int);
+}
+
+static ssize_t
+onefs_shadow_copy_getxattr(vfs_handle_struct *handle, const char *path,
+ const char *name, void *value, size_t size)
+{
+ SHADOW_NEXT(GETXATTR,
+ (handle, cpath ?: path, name, value, size),
+ ssize_t);
+}
+
+static ssize_t
+onefs_shadow_copy_lgetxattr(vfs_handle_struct *handle, const char *path,
+ const char *name, void *value, size_t size)
+{
+ SHADOW_NEXT(LGETXATTR,
+ (handle, cpath ?: path, name, value, size),
+ ssize_t);
+}
+
+static ssize_t
+onefs_shadow_copy_listxattr(vfs_handle_struct *handle, const char *path,
+ char *list, size_t size)
+{
+ SHADOW_NEXT(LISTXATTR,
+ (handle, cpath ?: path, list, size),
+ ssize_t);
+}
+
+static ssize_t
+onefs_shadow_copy_llistxattr(vfs_handle_struct *handle, const char *path,
+ char *list, size_t size)
+{
+ SHADOW_NEXT(LLISTXATTR,
+ (handle, cpath ?: path, list, size),
+ ssize_t);
+}
+
+static int
+onefs_shadow_copy_removexattr(vfs_handle_struct *handle, const char *path,
+ const char *name)
+{
+ SHADOW_NEXT(REMOVEXATTR,
+ (handle, cpath ?: path, name),
+ int);
+}
+
+static int
+onefs_shadow_copy_lremovexattr(vfs_handle_struct *handle, const char *path,
+ const char *name)
+{
+ SHADOW_NEXT(LREMOVEXATTR,
+ (handle, cpath ?: path, name),
+ int);
+}
+
+static int
+onefs_shadow_copy_setxattr(vfs_handle_struct *handle, const char *path,
+ const char *name, const void *value, size_t size,
+ int flags)
+{
+ SHADOW_NEXT(SETXATTR,
+ (handle, cpath ?: path, name, value, size, flags),
+ int);
+}
+
+static int
+onefs_shadow_copy_lsetxattr(vfs_handle_struct *handle, const char *path,
+ const char *name, const void *value, size_t size,
+ int flags)
+{
+ SHADOW_NEXT(LSETXATTR,
+ (handle, cpath ?: path, name, value, size, flags),
+ int);
+}
+
+static bool
+onefs_shadow_copy_is_offline(struct vfs_handle_struct *handle,
+ const char *path, SMB_STRUCT_STAT *sbuf)
+{
+ SHADOW_NEXT(IS_OFFLINE,
+ (handle, cpath ?: path, sbuf),
+ bool);
+}
+
+static int
+onefs_shadow_copy_set_offline(struct vfs_handle_struct *handle,
+ const char *path)
+{
+ SHADOW_NEXT(SET_OFFLINE,
+ (handle, cpath ?: path),
+ int);
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple onefs_shadow_copy_ops[] = {
+
+ /* Disk operations */
+
+ {SMB_VFS_OP(onefs_shadow_copy_disk_free), SMB_VFS_OP_DISK_FREE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_get_shadow_copy_data),
+ SMB_VFS_OP_GET_SHADOW_COPY_DATA, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(onefs_shadow_copy_statvfs), SMB_VFS_OP_STATVFS,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ /* Directory operations */
+
+ {SMB_VFS_OP(onefs_shadow_copy_opendir), SMB_VFS_OP_OPENDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_mkdir), SMB_VFS_OP_MKDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_rmdir), SMB_VFS_OP_RMDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ /* File operations */
+
+ {SMB_VFS_OP(onefs_shadow_copy_open), SMB_VFS_OP_OPEN,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_create_file), SMB_VFS_OP_CREATE_FILE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_stat), SMB_VFS_OP_STAT,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_lstat), SMB_VFS_OP_LSTAT,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_unlink), SMB_VFS_OP_UNLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_chmod), SMB_VFS_OP_CHMOD,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_chown), SMB_VFS_OP_CHOWN,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_lchown), SMB_VFS_OP_LCHOWN,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_chdir), SMB_VFS_OP_CHDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_ntimes), SMB_VFS_OP_NTIMES,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_symlink), SMB_VFS_OP_SYMLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_readlink), SMB_VFS_OP_READLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_link), SMB_VFS_OP_LINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_mknod), SMB_VFS_OP_MKNOD,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_realpath), SMB_VFS_OP_REALPATH,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_chflags), SMB_VFS_OP_CHFLAGS,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_streaminfo), SMB_VFS_OP_STREAMINFO,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_get_real_filename),
+ SMB_VFS_OP_GET_REAL_FILENAME, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* NT File ACL operations */
+
+ {SMB_VFS_OP(onefs_shadow_copy_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ /* POSIX ACL operations */
+
+ {SMB_VFS_OP(onefs_shadow_copy_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_sys_acl_get_file),
+ SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_sys_acl_set_file),
+ SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_sys_acl_delete_def_file),
+ SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* EA operations. */
+
+ {SMB_VFS_OP(onefs_shadow_copy_getxattr), SMB_VFS_OP_GETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_lgetxattr), SMB_VFS_OP_LGETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_listxattr), SMB_VFS_OP_LISTXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_llistxattr), SMB_VFS_OP_LLISTXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_removexattr), SMB_VFS_OP_REMOVEXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_lremovexattr), SMB_VFS_OP_LREMOVEXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_setxattr), SMB_VFS_OP_SETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_lsetxattr), SMB_VFS_OP_LSETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ /* offline operations */
+ {SMB_VFS_OP(onefs_shadow_copy_is_offline), SMB_VFS_OP_IS_OFFLINE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_shadow_copy_set_offline), SMB_VFS_OP_SET_OFFLINE,
+ SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_shadow_copy_init(void)
+{
+ NTSTATUS ret;
+
+ ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+ "onefs_shadow_copy",
+ onefs_shadow_copy_ops);
+
+ if (!NT_STATUS_IS_OK(ret))
+ return ret;
+
+ vfs_onefs_shadow_copy_debug_level = debug_add_class("onefs_shadow_copy");
+
+ if (vfs_onefs_shadow_copy_debug_level == -1) {
+ vfs_onefs_shadow_copy_debug_level = DBGC_VFS;
+ DEBUG(0, ("Couldn't register custom debugging class!\n"));
+ } else {
+ DEBUG(10, ("Debug class number of 'onefs_shadow_copy': %d\n",
+ vfs_onefs_shadow_copy_debug_level));
+ }
+
+ return ret;
+}
diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c
index 7bdfe8465b..cafb077555 100644
--- a/source3/modules/vfs_solarisacl.c
+++ b/source3/modules/vfs_solarisacl.c
@@ -51,11 +51,12 @@ static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count,
static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solarisacl,
int *count);
static bool solaris_acl_get_fd(int fd, SOLARIS_ACL_T *solarisacl, int *count);
-static bool solaris_acl_sort(SOLARIS_ACL_T acl, int count);
+static bool solaris_acl_sort(SOLARIS_ACL_T theacl, int count);
static SMB_ACL_PERM_T solaris_perm_to_smb_perm(const SOLARIS_PERM_T perm);
static SOLARIS_PERM_T smb_perm_to_solaris_perm(const SMB_ACL_PERM_T perm);
+#if 0
static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count);
-
+#endif
/* public functions - the api */
@@ -347,7 +348,6 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl,
{
bool ret = False;
int i;
- int check_which, check_rc;
DEBUG(10, ("entering smb_acl_to_solaris_acl\n"));
@@ -717,6 +717,7 @@ static bool solaris_acl_sort(SOLARIS_ACL_T solaris_acl, int count)
return True;
}
+#if 0
/*
* acl check function:
* unused at the moment but could be used to get more
@@ -746,7 +747,7 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count)
}
return True;
}
-
+#endif
/* VFS operations structure */
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 1c2c0e5f77..023d2b9ec0 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -153,8 +153,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
base_sbuf = &sbuf;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, base_sbuf->st_dev,
- base_sbuf->st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, base_sbuf);
push_file_id_16((char *)id_buf, &id);
@@ -495,7 +494,13 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname)
* We potentially need to delete the per-inode streams directory
*/
- if (SMB_VFS_NEXT_STAT(handle, fname, &sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf);
+ } else {
+ ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf);
+ }
+
+ if (ret == -1) {
return -1;
}
@@ -679,7 +684,11 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
if (is_ntfs_stream_name(fname)) {
return NT_STATUS_INVALID_PARAMETER;
}
- ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf);
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf);
+ } else {
+ ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf);
+ }
}
if (ret == -1) {
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 77ffff5fb5..3d5478d7a2 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -135,6 +135,7 @@ static bool streams_xattr_recheck(struct stream_io *sio)
static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
{
+ int ret = -1;
struct stream_io *io = (struct stream_io *)
VFS_FETCH_FSP_EXTENSION(handle, fsp);
@@ -148,7 +149,13 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
return -1;
}
- if (SMB_VFS_STAT(handle->conn, io->base, sbuf) == -1) {
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, io->base, sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, io->base, sbuf);
+ }
+
+ if (ret == -1) {
return -1;
}
@@ -719,7 +726,11 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
if (is_ntfs_stream_name(fname)) {
return NT_STATUS_INVALID_PARAMETER;
}
- ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+ }
}
if (ret == -1) {
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 44bfffb94e..4e37ed6477 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -100,6 +100,7 @@ static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx,
NTSTATUS status;
TDB_DATA data;
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
if (db_ctx->fetch(db_ctx, mem_ctx,
@@ -122,6 +123,8 @@ static struct db_record *xattr_tdb_lock_attrs(TALLOC_CTX *mem_ctx,
const struct file_id *id)
{
uint8 id_buf[16];
+
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
return db_ctx->fetch_locked(db_ctx, mem_ctx,
make_tdb_data(id_buf, sizeof(id_buf)));
@@ -216,7 +219,7 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_getattr(db, &id, name, value, size);
}
@@ -235,7 +238,7 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_getattr(db, &id, name, value, size);
}
@@ -338,7 +341,7 @@ static int xattr_tdb_setxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_setattr(db, &id, name, value, size, flags);
}
@@ -358,7 +361,7 @@ static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_setattr(db, &id, name, value, size, flags);
}
@@ -443,7 +446,7 @@ static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_listattr(db, &id, list, size);
}
@@ -462,7 +465,7 @@ static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_listattr(db, &id, list, size);
}
@@ -543,7 +546,7 @@ static int xattr_tdb_removexattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_removeattr(db, &id, name);
}
@@ -561,7 +564,7 @@ static int xattr_tdb_fremovexattr(struct vfs_handle_struct *handle,
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_removeattr(db, &id, name);
}
@@ -628,7 +631,7 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path)
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
@@ -667,7 +670,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path)
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index adefb7d94f..3279466602 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -412,18 +412,18 @@ static void msg_nmbd_send_packet(struct messaging_context *msg,
const struct sockaddr_storage *pss;
const struct in_addr *local_ip;
- DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
+ DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
if (data->length != sizeof(struct packet_struct)) {
- DEBUG(2, ("Discarding invalid packet length from %d\n",
- procid_to_pid(&src)));
+ DEBUG(2, ("Discarding invalid packet length from %u\n",
+ (unsigned int)procid_to_pid(&src)));
return;
}
if ((p->packet_type != NMB_PACKET) &&
(p->packet_type != DGRAM_PACKET)) {
- DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
- procid_to_pid(&src), p->packet_type));
+ DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
+ (unsigned int)procid_to_pid(&src), p->packet_type));
return;
}
@@ -431,8 +431,8 @@ static void msg_nmbd_send_packet(struct messaging_context *msg,
pss = iface_ip((struct sockaddr *)&ss);
if (pss == NULL) {
- DEBUG(2, ("Could not find ip for packet from %d\n",
- procid_to_pid(&src)));
+ DEBUG(2, ("Could not find ip for packet from %u\n",
+ (unsigned int)procid_to_pid(&src)));
return;
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 37af7038c1..89c706d874 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -144,7 +144,6 @@ struct global {
int iAfsTokenLifetime;
char *szLogNtTokenCommand;
char *szUsernameMap;
- bool bForceUsernameMap;
char *szLogonScript;
char *szLogonPath;
char *szLogonDrive;
@@ -1283,15 +1282,6 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
- .label = "force username map",
- .type = P_BOOL,
- .p_class = P_GLOBAL,
- .ptr = &Globals.bForceUsernameMap,
- .special = NULL,
- .enum_list = NULL,
- .flags = FLAG_ADVANCED,
- },
- {
.label = "password level",
.type = P_INTEGER,
.p_class = P_GLOBAL,
@@ -4657,6 +4647,41 @@ static void init_printer_values(struct service *pService)
}
}
+/**
+ * Function to return the default value for the maximum number of open
+ * file descriptors permitted. This function tries to consult the
+ * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
+ * the smaller of those.
+ */
+static int max_open_files(void)
+{
+ int sysctl_max = MAX_OPEN_FILES;
+ int rlimit_max = MAX_OPEN_FILES;
+
+#ifdef HAVE_SYSCTLBYNAME
+ {
+ size_t size = sizeof(sysctl_max);
+ sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
+ 0);
+ }
+#endif
+
+#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
+ {
+ struct rlimit rl = {};
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
+ rlimit_max = rl.rlim_cur;
+
+#if defined(RLIM_INFINITY)
+ if(rl.rlim_cur == RLIM_INFINITY)
+ rlimit_max = MAX_OPEN_FILES;
+ }
+#endif
+#endif
+
+ return MIN(sysctl_max, rlimit_max);
+}
/**
* Common part of freeing allocated data for one parameter.
@@ -4880,7 +4905,7 @@ static void init_globals(bool first_time_only)
Globals.getwd_cache = true;
Globals.bLargeReadwrite = True;
Globals.max_log_size = 5000;
- Globals.max_open_files = MAX_OPEN_FILES;
+ Globals.max_open_files = max_open_files();
Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
Globals.maxprotocol = PROTOCOL_NT1;
Globals.minprotocol = PROTOCOL_CORE;
@@ -5210,7 +5235,6 @@ FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
-FN_GLOBAL_BOOL(lp_force_username_map, &Globals.bForceUsernameMap)
FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 486b5b1b80..e618b425e0 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -1947,7 +1947,7 @@ void pdb_search_destroy(struct pdb_search *search)
}
/*******************************************************************
- trustodm methods
+ trustdom methods
*******************************************************************/
bool pdb_get_trusteddom_pw(const char *domain, char** pwd, DOM_SID *sid,
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 043b620756..70a1c62bef 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -1249,7 +1249,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
pdb_get_profile_path(sampass));
- if (asprintf(&temp, "%li", pdb_get_logon_time(sampass)) < 0) {
+ if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) {
return false;
}
if (need_update(sampass, PDB_LOGONTIME))
@@ -1257,7 +1257,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
SAFE_FREE(temp);
- if (asprintf(&temp, "%li", pdb_get_logoff_time(sampass)) < 0) {
+ if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) {
return false;
}
if (need_update(sampass, PDB_LOGOFFTIME))
@@ -1265,7 +1265,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
SAFE_FREE(temp);
- if (asprintf(&temp, "%li", pdb_get_kickoff_time(sampass)) < 0) {
+ if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) {
return false;
}
if (need_update(sampass, PDB_KICKOFFTIME))
@@ -1273,7 +1273,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
SAFE_FREE(temp);
- if (asprintf(&temp, "%li", pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
+ if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
return false;
}
if (need_update(sampass, PDB_CANCHANGETIME))
@@ -1281,7 +1281,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
SAFE_FREE(temp);
- if (asprintf(&temp, "%li", pdb_get_pass_must_change_time(sampass)) < 0) {
+ if (asprintf(&temp, "%li", (long int)pdb_get_pass_must_change_time(sampass)) < 0) {
return false;
}
if (need_update(sampass, PDB_MUSTCHANGETIME))
@@ -1361,7 +1361,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if (need_update(sampass, PDB_PASSLASTSET)) {
if (asprintf(&temp, "%li",
- pdb_get_pass_last_set_time(sampass)) < 0) {
+ (long int)pdb_get_pass_last_set_time(sampass)) < 0) {
return false;
}
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
@@ -1423,7 +1423,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
temp);
SAFE_FREE(temp);
- if (asprintf(&temp, "%li", badtime) < 0) {
+ if (asprintf(&temp, "%li", (long int)badtime) < 0) {
return false;
}
smbldap_make_mod(
@@ -5941,7 +5941,7 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
sid_string_tos(sid));
smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
- talloc_asprintf(talloc_tos(), "%li", time(NULL)));
+ talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
"sambaClearTextPassword", pwd);
diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c
new file mode 100644
index 0000000000..d2c7fda293
--- /dev/null
+++ b/source3/passdb/pdb_wbc_sam.c
@@ -0,0 +1,450 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Password and authentication handling by wbclient
+
+ Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Jelmer Vernooij 2002
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Volker Lendecke 2006
+ Copyright (C) Dan Sledz 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/>.
+*/
+
+/* This passdb module retrieves full passdb information for local users and
+ * groups from a wbclient compatible daemon.
+ *
+ * The purpose of this module is to defer all SAM authorization information
+ * storage and retrieval to a wbc compatible daemon.
+ *
+ * This passdb backend is most useful when used in conjunction with auth_wbc.
+ *
+ * A few current limitations of this module are:
+ * - read only interface
+ * - no privileges
+ */
+
+#include "includes.h"
+
+/***************************************************************************
+ Default implementations of some functions.
+ ****************************************************************************/
+static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods,
+ struct samu *user,
+ const struct passwd *pwd)
+{
+ NTSTATUS result = NT_STATUS_OK;
+
+ if (pwd == NULL)
+ return NT_STATUS_NO_SUCH_USER;
+
+ memset(user, 0, sizeof(user));
+
+ /* Can we really get away with this little of information */
+ user->methods = methods;
+ result = samu_set_unix(user, pwd);
+
+ return result;
+}
+
+static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname)
+{
+ return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname));
+}
+
+static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid)
+{
+ return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid));
+}
+
+static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
+ DOM_SID *sid)
+{
+ return winbind_uid_to_sid(sid, uid);
+}
+
+static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
+ DOM_SID *sid)
+{
+ return winbind_gid_to_sid(sid, gid);
+}
+
+static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ union unid_t *id, enum lsa_SidType *type)
+{
+ if (winbind_sid_to_uid(&id->uid, sid)) {
+ *type = SID_NAME_USER;
+ } else if (winbind_sid_to_gid(&id->gid, sid)) {
+ /* We assume all gids are groups, not aliases */
+ *type = SID_NAME_DOM_GRP;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *group,
+ uint32 **pp_member_rids,
+ size_t *p_num_members)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ struct samu *user,
+ DOM_SID **pp_sids,
+ gid_t **pp_gids,
+ size_t *p_num_groups)
+{
+ size_t i;
+ const char *username = pdb_get_username(user);
+ uint32_t num_groups;
+
+ if (!winbind_get_groups(mem_ctx, username, &num_groups, pp_gids)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ *p_num_groups = num_groups;
+
+ if (*p_num_groups == 0) {
+ smb_panic("primary group missing");
+ }
+
+ *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
+
+ if (*pp_sids == NULL) {
+ TALLOC_FREE(*pp_gids);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i < *p_num_groups; i++) {
+ gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char **names,
+ enum lsa_SidType *attrs)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ char *domain = NULL;
+ char **account_names = NULL;
+ char name[256];
+ enum lsa_SidType *attr_list = NULL;
+ int i;
+
+ if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids,
+ (const char **)&domain,
+ (const char ***)&account_names, &attr_list))
+ {
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType));
+
+ for (i=0; i<num_rids; i++) {
+ if (attrs[i] == SID_NAME_UNKNOWN) {
+ names[i] = NULL;
+ } else {
+ snprintf(name, sizeof(name), "%s%c%s", domain,
+ *lp_winbind_separator(), account_names[i]);
+ names[i] = talloc_strdup(names, name);
+ }
+ }
+
+done:
+ TALLOC_FREE(account_names);
+ TALLOC_FREE(domain);
+ TALLOC_FREE(attrs);
+ return result;
+}
+
+static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+{
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+{
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+static bool pdb_wbc_sam_search_groups(struct pdb_methods *methods,
+ struct pdb_search *search)
+{
+ return false;
+}
+
+static bool pdb_wbc_sam_search_aliases(struct pdb_methods *methods,
+ struct pdb_search *search,
+ const DOM_SID *sid)
+{
+
+ return false;
+}
+
+static bool pdb_wbc_sam_get_trusteddom_pw(struct pdb_methods *methods,
+ const char *domain,
+ char **pwd,
+ DOM_SID *sid,
+ time_t *pass_last_set_time)
+{
+ return false;
+
+}
+
+static bool pdb_wbc_sam_set_trusteddom_pw(struct pdb_methods *methods,
+ const char *domain,
+ const char *pwd,
+ const DOM_SID *sid)
+{
+ return false;
+}
+
+static bool pdb_wbc_sam_del_trusteddom_pw(struct pdb_methods *methods,
+ const char *domain)
+{
+ return false;
+}
+
+static NTSTATUS pdb_wbc_sam_enum_trusteddoms(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ uint32 *num_domains,
+ struct trustdom_info ***domains)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static bool _make_group_map(struct pdb_methods *methods, const char *domain, const char *name, enum lsa_SidType name_type, gid_t gid, DOM_SID *sid, GROUP_MAP *map)
+{
+ snprintf(map->nt_name, sizeof(map->nt_name), "%s%c%s",
+ domain, *lp_winbind_separator(), name);
+ map->sid_name_use = name_type;
+ map->sid = *sid;
+ map->gid = gid;
+ return true;
+}
+
+static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
+ DOM_SID sid)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ char *name = NULL;
+ char *domain = NULL;
+ enum lsa_SidType name_type;
+ gid_t gid;
+
+ if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain,
+ (const char **) &name, &name_type)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if ((name_type != SID_NAME_DOM_GRP) &&
+ (name_type != SID_NAME_DOMAIN) &&
+ (name_type != SID_NAME_ALIAS) &&
+ (name_type != SID_NAME_WKN_GRP)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!winbind_sid_to_gid(&gid, &sid)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+done:
+ TALLOC_FREE(name);
+ TALLOC_FREE(domain);
+ return result;
+}
+
+static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
+ gid_t gid)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ char *name = NULL;
+ char *domain = NULL;
+ DOM_SID sid;
+ enum lsa_SidType name_type;
+
+ if (!winbind_gid_to_sid(&sid, gid)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain,
+ (const char **)&name, &name_type)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if ((name_type != SID_NAME_DOM_GRP) &&
+ (name_type != SID_NAME_DOMAIN) &&
+ (name_type != SID_NAME_ALIAS) &&
+ (name_type != SID_NAME_WKN_GRP)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+done:
+ TALLOC_FREE(name);
+ TALLOC_FREE(domain);
+
+ return result;
+}
+
+static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
+ const char *name)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ char *user_name = NULL;
+ char *domain = NULL;
+ DOM_SID sid;
+ gid_t gid;
+ enum lsa_SidType name_type;
+
+ if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if ((name_type != SID_NAME_DOM_GRP) &&
+ (name_type != SID_NAME_DOMAIN) &&
+ (name_type != SID_NAME_ALIAS) &&
+ (name_type != SID_NAME_WKN_GRP)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!winbind_sid_to_gid(&gid, &sid)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+ if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
+
+done:
+
+ return result;
+}
+
+static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods,
+ const DOM_SID *sid, enum lsa_SidType sid_name_use,
+ GROUP_MAP **pp_rmap, size_t *p_num_entries,
+ bool unix_only)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ struct acct_info *info)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods,
+ const DOM_SID *alias, DOM_SID **pp_members,
+ size_t *p_num_members)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ const DOM_SID *members,
+ size_t num_members,
+ uint32 **pp_alias_rids,
+ size_t *p_num_alias_rids)
+{
+ if (!winbind_get_sid_aliases(mem_ctx, domain_sid,
+ members, num_members, pp_alias_rids, p_num_alias_rids))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location)
+{
+ NTSTATUS result;
+
+ if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) {
+ return result;
+ }
+
+ (*pdb_method)->name = "wbc_sam";
+
+ (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam;
+ (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid;
+
+ (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid;
+ (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid;
+ (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam;
+ (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping;
+ (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members;
+ (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships;
+ (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo;
+ (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem;
+ (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships;
+ (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids;
+ (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy;
+ (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy;
+ (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid;
+ (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid;
+ (*pdb_method)->sid_to_id = pdb_wbc_sam_sid_to_id;
+
+ (*pdb_method)->search_groups = pdb_wbc_sam_search_groups;
+ (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases;
+
+ (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw;
+ (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw;
+ (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw;
+ (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms;
+
+ (*pdb_method)->private_data = NULL;
+ (*pdb_method)->free_private_data = NULL;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_wbc_sam_init(void)
+{
+ return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam);
+}
diff --git a/source3/printing/notify.c b/source3/printing/notify.c
index d478b86f91..e19212eea8 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -397,8 +397,10 @@ void notify_printer_status_byname(const char *sharename, uint32 status)
{
/* Printer status stored in value1 */
+ int snum = print_queue_snum(sharename);
+
send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE,
- PRINTER_NOTIFY_STATUS, 0,
+ PRINTER_NOTIFY_STATUS, snum,
status, 0, 0);
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index ad3a95826a..d8658e9280 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1381,7 +1381,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
goto error_exit;
}
old_create_time = st.st_mtime;
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
+ DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
+ (long)old_create_time));
}
}
close_file(NULL, fsp, NORMAL_CLOSE);
@@ -1432,7 +1433,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
goto error_exit;
}
new_create_time = st.st_mtime;
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
+ DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
+ (long)new_create_time));
}
}
close_file(NULL, fsp, NORMAL_CLOSE);
@@ -3423,8 +3425,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
goto done;
switch (action) {
- case SPOOL_DS_PUBLISH:
- case SPOOL_DS_UPDATE:
+ case DSPRINT_PUBLISH:
+ case DSPRINT_UPDATE:
/* set the DsSpooler info and attributes */
if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
win_rc = WERR_NOMEM;
@@ -3433,7 +3435,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
break;
- case SPOOL_DS_UNPUBLISH:
+ case DSPRINT_UNPUBLISH:
printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
break;
default:
@@ -3467,11 +3469,11 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
}
switch (action) {
- case SPOOL_DS_PUBLISH:
- case SPOOL_DS_UPDATE:
+ case DSPRINT_PUBLISH:
+ case DSPRINT_UPDATE:
win_rc = nt_printer_publish_ads(ads, printer);
break;
- case SPOOL_DS_UNPUBLISH:
+ case DSPRINT_UNPUBLISH:
win_rc = nt_printer_unpublish_ads(ads, printer);
break;
}
@@ -5408,11 +5410,12 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL;
SEC_DESC_BUF *old_secdesc_ctr = NULL;
- prs_struct ps;
- bool prs_init_done = false;
TALLOC_CTX *mem_ctx = NULL;
TDB_DATA kbuf;
+ TDB_DATA dbuf;
+ DATA_BLOB blob;
WERROR status;
+ NTSTATUS nt_status;
mem_ctx = talloc_init("nt_printing_setsec");
if (mem_ctx == NULL)
@@ -5474,26 +5477,19 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
/* Store the security descriptor in a tdb */
- if (!prs_init(&ps,
- (uint32_t)ndr_size_security_descriptor(new_secdesc_ctr->sd,
- NULL, 0)
- + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) {
- status = WERR_NOMEM;
- goto out;
- }
-
-
- prs_init_done = true;
-
- if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
- &ps, 1)) {
- status = WERR_BADFUNC;
+ nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
+ &blob.data, &blob.length);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ status = ntstatus_to_werror(nt_status);
goto out;
}
kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
- if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) {
+ dbuf.dptr = (unsigned char *)blob.data;
+ dbuf.dsize = blob.length;
+
+ if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
status = WERR_OK;
} else {
DEBUG(1,("Failed to store secdesc for %s\n", sharename));
@@ -5501,12 +5497,10 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
}
/* Free malloc'ed memory */
+ talloc_free(blob.data);
out:
- if (prs_init_done) {
- prs_mem_free(&ps);
- }
if (mem_ctx)
talloc_destroy(mem_ctx);
return status;
@@ -5602,47 +5596,45 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
{
- prs_struct ps;
TDB_DATA kbuf;
+ TDB_DATA dbuf;
+ DATA_BLOB blob;
char *temp;
+ NTSTATUS status;
if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
sharename = temp + 1;
}
- ZERO_STRUCT(ps);
-
/* Fetch security descriptor from tdb */
- kbuf = make_printers_secdesc_tdbkey(ctx, sharename );
-
- if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 ||
- !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
-
- prs_mem_free(&ps);
-
- DEBUG(4,("using default secdesc for %s\n", sharename));
+ kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
- if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
- return False;
- }
-
- /* Save default security descriptor for later */
+ dbuf = tdb_fetch(tdb_printers, kbuf);
+ if (dbuf.dptr) {
- if (!prs_init(&ps, (uint32_t)ndr_size_security_descriptor((*secdesc_ctr)->sd, NULL, 0) +
- sizeof(SEC_DESC_BUF), ctx, MARSHALL))
- return False;
+ status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
+ secdesc_ctr);
+ SAFE_FREE(dbuf.dptr);
- if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
- tdb_prs_store(tdb_printers, kbuf, &ps);
+ if (NT_STATUS_IS_OK(status)) {
+ return true;
}
+ }
- prs_mem_free(&ps);
-
- return True;
+ *secdesc_ctr = construct_default_printer_sdb(ctx);
+ if (!*secdesc_ctr) {
+ return false;
}
- prs_mem_free(&ps);
+ status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
+ &blob.data, &blob.length);
+ if (NT_STATUS_IS_OK(status)) {
+ dbuf.dptr = (unsigned char *)blob.data;
+ dbuf.dsize = blob.length;
+ tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
+ talloc_free(blob.data);
+ }
/* If security descriptor is owned by S-1-1-0 and winbindd is up,
this security descriptor has been created when winbindd was
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index b485711f91..243b8ea03b 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -88,7 +88,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
{
uint32 jobid;
- fstring sharename;
if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) {
/*
@@ -102,7 +101,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
string_free(&fsp->fsp_name);
}
- if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
+ if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
(unsigned int)fsp->rap_print_jobid ));
return;
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 7179184b73..fc3667ea3a 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -117,7 +117,9 @@ bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
{
struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
- fstrcpy( sharename, jinfo->sharename );
+ if (sharename != NULL) {
+ fstrcpy( sharename, jinfo->sharename );
+ }
*pjobid = jinfo->jobid;
DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
(unsigned int)*pjobid, (unsigned int)rap_jobid));
@@ -447,7 +449,7 @@ static const struct {
{ LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
{ LPQ_PRINTED, JOB_STATUS_PRINTED },
{ LPQ_DELETED, JOB_STATUS_DELETED },
- { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
+ { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
{ LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
{ -1, 0 }
};
diff --git a/source3/printing/tests/vlp.c b/source3/printing/tests/vlp.c
index 15459889e9..286e4a4b39 100644
--- a/source3/printing/tests/vlp.c
+++ b/source3/printing/tests/vlp.c
@@ -168,7 +168,7 @@ static int lpq_command(int argc, char **argv)
job_list[i].size,
(i == 0 && job_list[i].status == LPQ_QUEUED) ?
LPQ_SPOOLING : job_list[i].status,
- job_list[i].submit_time, job_list[i].owner,
+ (long int)job_list[i].submit_time, job_list[i].owner,
job_list[i].jobname);
job_count++;
}
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index bdbd805718..6d2d5ae06d 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -290,6 +290,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
"syscall_rmdir", /* PR_VALUE_SYSCALL_RMDIR */
"syscall_closedir", /* PR_VALUE_SYSCALL_CLOSEDIR */
"syscall_open", /* PR_VALUE_SYSCALL_OPEN */
+ "syscall_createfile", /* PR_VALUE_SYSCALL_CREATEFILE */
"syscall_close", /* PR_VALUE_SYSCALL_CLOSE */
"syscall_read", /* PR_VALUE_SYSCALL_READ */
"syscall_pread", /* PR_VALUE_SYSCALL_PREAD */
@@ -299,6 +300,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
"syscall_sendfile", /* PR_VALUE_SYSCALL_SENDFILE */
"syscall_recvfile", /* PR_VALUE_SYSCALL_RECVFILE */
"syscall_rename", /* PR_VALUE_SYSCALL_RENAME */
+ "syscall_rename_at", /* PR_VALUE_SYSCALL_RENAME_AT */
"syscall_fsync", /* PR_VALUE_SYSCALL_FSYNC */
"syscall_stat", /* PR_VALUE_SYSCALL_STAT */
"syscall_fstat", /* PR_VALUE_SYSCALL_FSTAT */
@@ -323,6 +325,11 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
"syscall_realpath", /* PR_VALUE_SYSCALL_REALPATH */
"syscall_get_quota", /* PR_VALUE_SYSCALL_GET_QUOTA */
"syscall_set_quota", /* PR_VALUE_SYSCALL_SET_QUOTA */
+ "syscall_get_sd", /* PR_VALUE_SYSCALL_GET_SD */
+ "syscall_set_sd", /* PR_VALUE_SYSCALL_SET_SD */
+ "syscall_brl_lock", /* PR_VALUE_SYSCALL_BRL_LOCK */
+ "syscall_brl_unlock", /* PR_VALUE_SYSCALL_BRL_UNLOCK */
+ "syscall_brl_cancel", /* PR_VALUE_SYSCALL_BRL_CANCEL */
"SMBmkdir", /* PR_VALUE_SMBMKDIR */
"SMBrmdir", /* PR_VALUE_SMBRMDIR */
"SMBopen", /* PR_VALUE_SMBOPEN */
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index a5f3935821..67767a2e56 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -94,15 +94,16 @@ static WERROR fill_value_cache(struct registry_key *key)
static WERROR fill_subkey_cache(struct registry_key *key)
{
+ WERROR werr;
+
if (key->subkeys != NULL) {
if (!reg_subkeys_need_update(key->key, key->subkeys)) {
return WERR_OK;
}
}
- if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) {
- return WERR_NOMEM;
- }
+ werr = regsubkey_ctr_init(key, &(key->subkeys));
+ W_ERROR_NOT_OK_RETURN(werr);
if (fetch_reg_keys(key->key, key->subkeys) == -1) {
TALLOC_FREE(key->subkeys);
@@ -127,7 +128,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
WERROR result = WERR_OK;
struct registry_key *regkey;
REGISTRY_KEY *key;
- REGSUBKEY_CTR *subkeys = NULL;
+ struct regsubkey_ctr *subkeys = NULL;
DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
@@ -193,8 +194,8 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
- if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
- result = WERR_NOMEM;
+ result = regsubkey_ctr_init(key, &subkeys);
+ if (!W_ERROR_IS_OK(result)) {
goto done;
}
@@ -308,11 +309,13 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key,
return err;
}
- if (idx >= key->subkeys->num_subkeys) {
+ if (idx >= regsubkey_ctr_numkeys(key->subkeys)) {
return WERR_NO_MORE_ITEMS;
}
- if (!(*name = talloc_strdup(mem_ctx, key->subkeys->subkeys[idx]))) {
+ if (!(*name = talloc_strdup(mem_ctx,
+ regsubkey_ctr_specific_key(key->subkeys, idx))))
+ {
return WERR_NOMEM;
}
@@ -406,11 +409,12 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
}
max_len = 0;
- for (i=0; i<key->subkeys->num_subkeys; i++) {
- max_len = MAX(max_len, strlen(key->subkeys->subkeys[i]));
+ for (i=0; i< regsubkey_ctr_numkeys(key->subkeys); i++) {
+ max_len = MAX(max_len,
+ strlen(regsubkey_ctr_specific_key(key->subkeys, i)));
}
- *num_subkeys = key->subkeys->num_subkeys;
+ *num_subkeys = regsubkey_ctr_numkeys(key->subkeys);
*max_subkeylen = max_len;
*max_subkeysize = 0; /* Class length? */
@@ -520,14 +524,8 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
err = fill_subkey_cache(create_parent);
if (!W_ERROR_IS_OK(err)) goto done;
- err = regsubkey_ctr_addkey(create_parent->subkeys, path);
- if (!W_ERROR_IS_OK(err)) goto done;
-
- if (!store_reg_keys(create_parent->key, create_parent->subkeys)) {
- TALLOC_FREE(create_parent->subkeys);
- err = WERR_REG_IO_FAILURE;
- goto done;
- }
+ err = create_reg_subkey(key->key, path);
+ W_ERROR_NOT_OK_GOTO_DONE(err);
/*
* Now open the newly created key
@@ -546,40 +544,36 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
WERROR reg_deletekey(struct registry_key *parent, const char *path)
{
WERROR err;
- TALLOC_CTX *mem_ctx;
char *name, *end;
- int num_subkeys;
struct registry_key *tmp_key, *key;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM;
-
- if (!(name = talloc_strdup(mem_ctx, path))) {
+ name = talloc_strdup(mem_ctx, path);
+ if (name == NULL) {
err = WERR_NOMEM;
- goto error;
+ goto done;
}
/* check if the key has subkeys */
err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key);
- if (!W_ERROR_IS_OK(err)) {
- goto error;
- }
- if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) {
- goto error;
- }
- if (key->subkeys->num_subkeys > 0) {
+ W_ERROR_NOT_OK_GOTO_DONE(err);
+
+ err = fill_subkey_cache(key);
+ W_ERROR_NOT_OK_GOTO_DONE(err);
+
+ if (regsubkey_ctr_numkeys(key->subkeys) > 0) {
err = WERR_ACCESS_DENIED;
- goto error;
+ goto done;
}
/* no subkeys - proceed with delete */
- if ((end = strrchr(name, '\\')) != NULL) {
+ end = strrchr(name, '\\');
+ if (end != NULL) {
*end = '\0';
err = reg_openkey(mem_ctx, parent, name,
SEC_RIGHTS_CREATE_SUBKEY, &tmp_key);
- if (!W_ERROR_IS_OK(err)) {
- goto error;
- }
+ W_ERROR_NOT_OK_GOTO_DONE(err);
parent = tmp_key;
name = end+1;
@@ -587,31 +581,12 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path)
if (name[0] == '\0') {
err = WERR_INVALID_PARAM;
- goto error;
- }
-
- if (!W_ERROR_IS_OK(err = fill_subkey_cache(parent))) {
- goto error;
- }
-
- num_subkeys = parent->subkeys->num_subkeys;
-
- if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) {
- err = WERR_BADFILE;
- goto error;
- }
-
- if (!store_reg_keys(parent->key, parent->subkeys)) {
- TALLOC_FREE(parent->subkeys);
- err = WERR_REG_IO_FAILURE;
- goto error;
+ goto done;
}
- regkey_set_secdesc(key->key, NULL);
-
- err = WERR_OK;
+ err = delete_reg_subkey(parent->key, name);
- error:
+done:
TALLOC_FREE(mem_ctx);
return err;
}
@@ -726,7 +701,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
REGF_NK_REC *subkey;
REGISTRY_KEY registry_key;
REGVAL_CTR *values;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
int i;
char *path = NULL;
WERROR result = WERR_OK;
@@ -748,10 +723,8 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
/* now start parsing the values and subkeys */
- subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR);
- if (subkeys == NULL) {
- return WERR_NOMEM;
- }
+ result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_RETURN(result);
values = TALLOC_ZERO_P(subkeys, REGVAL_CTR);
if (values == NULL) {
@@ -767,7 +740,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
(key->values[i].data_size & ~VK_DATA_IN_OFFSET));
}
- /* copy subkeys into the REGSUBKEY_CTR */
+ /* copy subkeys into the struct regsubkey_ctr */
key->subkey_index = 0;
while ((subkey = regfio_fetch_subkey( regfile, key ))) {
@@ -861,7 +834,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
{
REGF_NK_REC *key;
REGVAL_CTR *values;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
int i, num_subkeys;
char *key_tmp = NULL;
char *keyname, *parentpath;
@@ -909,10 +882,8 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
/* lookup the values and subkeys */
- subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR);
- if (subkeys == NULL) {
- return WERR_NOMEM;
- }
+ result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_RETURN(result);
values = TALLOC_ZERO_P(subkeys, REGVAL_CTR);
if (values == NULL) {
@@ -1091,6 +1062,7 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
WERROR werr = WERR_OK;
struct registry_key *key;
char *subkey_name = NULL;
+ uint32 i;
mem_ctx = talloc_new(ctx);
if (mem_ctx == NULL) {
@@ -1104,25 +1076,21 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
goto done;
}
- while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0,
- &subkey_name, NULL)))
- {
+ werr = fill_subkey_cache(key);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ /*
+ * loop from top to bottom for perfomance:
+ * this way, we need to rehash the regsubkey containers less
+ */
+ for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) {
+ subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1);
werr = reg_deletekey_recursive_internal(mem_ctx, key,
- subkey_name,
- true);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
- }
- if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
- DEBUG(1, ("reg_deletekey_recursive_internal: "
- "Error enumerating subkeys: %s\n",
- win_errstr(werr)));
- goto done;
+ subkey_name,
+ true);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
}
- werr = WERR_OK;
-
if (del_key) {
/* now delete the actual key */
werr = reg_deletekey(parent, path);
@@ -1133,18 +1101,57 @@ done:
return werr;
}
+static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx,
+ struct registry_key *parent,
+ const char *path,
+ bool del_key)
+{
+ WERROR werr;
+
+ werr = regdb_transaction_start();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("reg_deletekey_recursive_trans: "
+ "error starting transaction: %s\n",
+ win_errstr(werr)));
+ return werr;
+ }
+
+ werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key);
+
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, (__location__ " failed to delete key '%s' from key "
+ "'%s': %s\n", path, parent->key->name,
+ win_errstr(werr)));
+ werr = regdb_transaction_cancel();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("reg_deletekey_recursive_trans: "
+ "error cancelling transaction: %s\n",
+ win_errstr(werr)));
+ }
+ } else {
+ werr = regdb_transaction_commit();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("reg_deletekey_recursive_trans: "
+ "error committing transaction: %s\n",
+ win_errstr(werr)));
+ }
+ }
+
+ return werr;
+}
+
WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, true);
+ return reg_deletekey_recursive_trans(ctx, parent, path, true);
}
WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, false);
+ return reg_deletekey_recursive_trans(ctx, parent, path, false);
}
#if 0
diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c
index 04cc0ebfa7..f76840ee22 100644
--- a/source3/registry/reg_backend_current_version.c
+++ b/source3/registry/reg_backend_current_version.c
@@ -70,7 +70,7 @@ static int current_version_fetch_values(const char *key, REGVAL_CTR *values)
}
static int current_version_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index fe5f192713..30f1db9c53 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -103,7 +103,7 @@ static WERROR init_registry_key_internal(const char *add_path)
char *remaining = NULL;
char *keyname;
char *subkeyname;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
const char *p, *p2;
DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path));
@@ -167,9 +167,9 @@ static WERROR init_registry_key_internal(const char *add_path)
* since we are about to update the record.
* We just want any subkeys already present */
- if (!(subkeys = TALLOC_ZERO_P(frame, REGSUBKEY_CTR))) {
+ werr = regsubkey_ctr_init(frame, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("talloc() failure!\n"));
- werr = WERR_NOMEM;
goto fail;
}
@@ -482,6 +482,24 @@ int regdb_close( void )
return 0;
}
+WERROR regdb_transaction_start(void)
+{
+ return (regdb->transaction_start(regdb) == 0) ?
+ WERR_OK : WERR_REG_IO_FAILURE;
+}
+
+WERROR regdb_transaction_commit(void)
+{
+ return (regdb->transaction_commit(regdb) == 0) ?
+ WERR_OK : WERR_REG_IO_FAILURE;
+}
+
+WERROR regdb_transaction_cancel(void)
+{
+ return (regdb->transaction_cancel(regdb) == 0) ?
+ WERR_OK : WERR_REG_IO_FAILURE;
+}
+
/***********************************************************************
return the tdb sequence number of the registry tdb.
this is an indicator for the content of the registry
@@ -492,13 +510,97 @@ int regdb_get_seqnum(void)
return regdb->get_seqnum(regdb);
}
+
+static WERROR regdb_delete_key_with_prefix(const char *keyname,
+ const char *prefix)
+{
+ char *path;
+ WERROR werr = WERR_NOMEM;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ if (keyname == NULL) {
+ werr = WERR_INVALID_PARAM;
+ goto done;
+ }
+
+ if (prefix == NULL) {
+ path = discard_const_p(char, keyname);
+ } else {
+ path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname);
+ if (path == NULL) {
+ goto done;
+ }
+ }
+
+ path = normalize_reg_path(mem_ctx, path);
+ if (path == NULL) {
+ goto done;
+ }
+
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path));
+
+ /* treat "not" found" as ok */
+ if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
+ werr = WERR_OK;
+ }
+
+done:
+ talloc_free(mem_ctx);
+ return werr;
+}
+
+
+static WERROR regdb_delete_values(const char *keyname)
+{
+ return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX);
+}
+
+static WERROR regdb_delete_secdesc(const char *keyname)
+{
+ return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX);
+}
+
+static WERROR regdb_delete_subkeylist(const char *keyname)
+{
+ return regdb_delete_key_with_prefix(keyname, NULL);
+}
+
+static WERROR regdb_delete_key_lists(const char *keyname)
+{
+ WERROR werr;
+
+ werr = regdb_delete_values(keyname);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
+ REG_VALUE_PREFIX, keyname, win_errstr(werr)));
+ goto done;
+ }
+
+ werr = regdb_delete_secdesc(keyname);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
+ REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
+ goto done;
+ }
+
+ werr = regdb_delete_subkeylist(keyname);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, (__location__ " Deleting %s failed: %s\n",
+ keyname, win_errstr(werr)));
+ goto done;
+ }
+
+done:
+ return werr;
+}
+
/***********************************************************************
Add subkey strings to the registry tdb under a defined key
fmt is the same format as tdb_pack except this function only supports
fstrings
***********************************************************************/
-static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
+static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
{
TDB_DATA dbuf;
uint8 *buffer = NULL;
@@ -550,8 +652,8 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
(len+thistime)*2);
if(buffer == NULL) {
DEBUG(0, ("regdb_store_keys: Failed to realloc "
- "memory of size [%d]\n",
- (len+thistime)*2));
+ "memory of size [%u]\n",
+ (unsigned int)(len+thistime)*2));
ret = false;
goto done;
}
@@ -578,6 +680,16 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
goto done;
}
+ /*
+ * Delete a sorted subkey cache for regdb_key_exists, will be
+ * recreated automatically
+ */
+ keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
+ keyname);
+ if (keyname != NULL) {
+ dbwrap_delete_bystring(regdb, keyname);
+ }
+
done:
TALLOC_FREE(ctx);
SAFE_FREE(buffer);
@@ -589,14 +701,14 @@ done:
do not currently exist
***********************************************************************/
-bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
{
- int num_subkeys, i;
+ int num_subkeys, old_num_subkeys, i;
char *path = NULL;
- REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL;
+ struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
char *oldkeyname = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
- NTSTATUS status;
+ WERROR werr;
if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
goto fail;
@@ -607,23 +719,28 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
* changed
*/
- if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) {
+ werr = regsubkey_ctr_init(ctx, &old_subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
return false;
}
regdb_fetch_keys(key, old_subkeys);
- if ((ctr->num_subkeys && old_subkeys->num_subkeys) &&
- (ctr->num_subkeys == old_subkeys->num_subkeys)) {
-
- for (i = 0; i<ctr->num_subkeys; i++) {
- if (strcmp(ctr->subkeys[i],
- old_subkeys->subkeys[i]) != 0) {
+ num_subkeys = regsubkey_ctr_numkeys(ctr);
+ old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
+ if ((num_subkeys && old_num_subkeys) &&
+ (num_subkeys == old_num_subkeys)) {
+
+ for (i = 0; i < num_subkeys; i++) {
+ if (strcmp(regsubkey_ctr_specific_key(ctr, i),
+ regsubkey_ctr_specific_key(old_subkeys, i))
+ != 0)
+ {
break;
}
}
- if (i == ctr->num_subkeys) {
+ if (i == num_subkeys) {
/*
* Nothing changed, no point to even start a tdb
* transaction
@@ -644,7 +761,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
* Re-fetch the old keys inside the transaction
*/
- if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) {
+ werr = regsubkey_ctr_init(ctx, &old_subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
goto cancel;
}
@@ -686,66 +804,14 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
continue;
}
- /* (a) Delete the value list for this key */
-
- path = talloc_asprintf(ctx, "%s/%s/%s",
- REG_VALUE_PREFIX,
- key,
- oldkeyname );
- if (!path) {
- goto cancel;
- }
- path = normalize_reg_path(ctx, path);
- if (!path) {
- goto cancel;
- }
- /* Ignore errors here, we might have no values around */
- dbwrap_delete_bystring(regdb, path);
- TALLOC_FREE(path);
-
- /* (b) Delete the secdesc for this key */
-
- path = talloc_asprintf(ctx, "%s/%s/%s",
- REG_SECDESC_PREFIX,
- key,
- oldkeyname );
- if (!path) {
- goto cancel;
- }
- path = normalize_reg_path(ctx, path);
+ path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
if (!path) {
goto cancel;
}
- status = dbwrap_delete_bystring(regdb, path);
- /* Don't fail if there are no values around. */
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
- {
- DEBUG(1, ("Deleting %s failed: %s\n", path,
- nt_errstr(status)));
- goto cancel;
- }
- TALLOC_FREE(path);
- /* (c) Delete the list of subkeys of this key */
+ werr = regdb_delete_key_lists(path);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
- path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
- if (!path) {
- goto cancel;
- }
- path = normalize_reg_path(ctx, path);
- if (!path) {
- goto cancel;
- }
- status = dbwrap_delete_bystring(regdb, path);
- /* Don't fail if the subkey record was not found. */
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
- {
- DEBUG(1, ("Deleting %s failed: %s\n", path,
- nt_errstr(status)));
- goto cancel;
- }
TALLOC_FREE(path);
}
@@ -764,7 +830,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
num_subkeys = regsubkey_ctr_numkeys(ctr);
if (num_subkeys == 0) {
- if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
goto cancel;
}
@@ -785,7 +852,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
if (!path) {
goto cancel;
}
- if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
goto cancel;
}
@@ -822,6 +890,139 @@ fail:
return false;
}
+static WERROR regdb_create_subkey(const char *key, const char *subkey)
+{
+ WERROR werr;
+ struct regsubkey_ctr *subkeys;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ werr = WERR_NOT_FOUND;
+ goto done;
+ }
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ if (regdb_fetch_keys(key, subkeys) < 0) {
+ werr = WERR_REG_IO_FAILURE;
+ goto done;
+ }
+
+ if (regsubkey_ctr_key_exists(subkeys, subkey)) {
+ werr = WERR_OK;
+ goto done;
+ }
+
+ talloc_free(subkeys);
+
+ werr = regdb_transaction_start();
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+ if (regdb_fetch_keys(key, subkeys) < 0) {
+ werr = WERR_REG_IO_FAILURE;
+ goto cancel;
+ }
+
+ werr = regsubkey_ctr_addkey(subkeys, subkey);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+ if (!regdb_store_keys_internal(key, subkeys)) {
+ DEBUG(0, (__location__ " failed to store new subkey list for "
+ "parent key %s\n", key));
+ werr = WERR_REG_IO_FAILURE;
+ goto cancel;
+ }
+
+ werr = regdb_transaction_commit();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, (__location__ " failed to commit transaction: %s\n",
+ win_errstr(werr)));
+ }
+
+ goto done;
+
+cancel:
+ werr = regdb_transaction_cancel();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
+ win_errstr(werr)));
+ }
+
+done:
+ talloc_free(mem_ctx);
+ return werr;
+}
+
+static WERROR regdb_delete_subkey(const char *key, const char *subkey)
+{
+ WERROR werr, werr2;
+ struct regsubkey_ctr *subkeys;
+ char *path;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ werr = WERR_NOT_FOUND;
+ goto done;
+ }
+
+ path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey);
+ if (path == NULL) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
+
+ if (!regdb_key_exists(path)) {
+ werr = WERR_OK;
+ goto done;
+ }
+
+ werr = regdb_transaction_start();
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_delete_key_lists(path);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+ if (regdb_fetch_keys(key, subkeys) < 0) {
+ werr = WERR_REG_IO_FAILURE;
+ goto cancel;
+ }
+
+ werr = regsubkey_ctr_delkey(subkeys, subkey);
+ W_ERROR_NOT_OK_GOTO(werr, cancel);
+
+ if (!regdb_store_keys_internal(key, subkeys)) {
+ DEBUG(0, (__location__ " failed to store new subkey_list for "
+ "parent key %s\n", key));
+ werr = WERR_REG_IO_FAILURE;
+ goto cancel;
+ }
+
+ werr = regdb_transaction_commit();
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, (__location__ " failed to commit transaction: %s\n",
+ win_errstr(werr)));
+ }
+
+ goto done;
+
+cancel:
+ werr2 = regdb_transaction_cancel();
+ if (!W_ERROR_IS_OK(werr2)) {
+ DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
+ win_errstr(werr2)));
+ }
+
+done:
+ talloc_free(mem_ctx);
+ return werr;
+}
static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
{
@@ -871,6 +1072,223 @@ done:
return ret;
}
+/*
+ * regdb_key_exists() is a very frequent operation. It can be quite
+ * time-consuming to fully fetch the parent's subkey list, talloc_strdup all
+ * subkeys and then compare the keyname linearly to all the parent's subkeys.
+ *
+ * The following code tries to make this operation as efficient as possible:
+ * Per registry key we create a list of subkeys that is very efficient to
+ * search for existence of a subkey. Its format is:
+ *
+ * 4 bytes num_subkeys
+ * 4*num_subkey bytes offset into the string array
+ * then follows a sorted list of subkeys in uppercase
+ *
+ * This record is created by create_sorted_subkeys() on demand if it does not
+ * exist. scan_parent_subkeys() uses regdb->parse_record to search the sorted
+ * list, the parsing code and the binary search can be found in
+ * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
+ * the potentially large subkey record.
+ *
+ * The sorted subkey record is deleted in regdb_store_keys_internal and
+ * recreated on demand.
+ */
+
+static int cmp_keynames(const void *p1, const void *p2)
+{
+ return StrCaseCmp(*((char **)p1), *((char **)p2));
+}
+
+static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+{
+ char **sorted_subkeys;
+ struct regsubkey_ctr *ctr;
+ bool result = false;
+ NTSTATUS status;
+ char *buf;
+ char *p;
+ int i, res;
+ size_t len;
+ int num_subkeys;
+ WERROR werr;
+
+ if (regdb->transaction_start(regdb) != 0) {
+ DEBUG(0, ("create_sorted_subkeys: transaction_start "
+ "failed\n"));
+ return false;
+ }
+
+ werr = regsubkey_ctr_init(talloc_tos(), &ctr);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto fail;
+ }
+
+ res = regdb_fetch_keys(key, ctr);
+ if (res == -1) {
+ goto fail;
+ }
+
+ num_subkeys = regsubkey_ctr_numkeys(ctr);
+ sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
+ if (sorted_subkeys == NULL) {
+ goto fail;
+ }
+
+ len = 4 + 4*num_subkeys;
+
+ for (i = 0; i < num_subkeys; i++) {
+ sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
+ regsubkey_ctr_specific_key(ctr, i));
+ if (sorted_subkeys[i] == NULL) {
+ goto fail;
+ }
+ len += strlen(sorted_subkeys[i])+1;
+ }
+
+ qsort(sorted_subkeys, num_subkeys, sizeof(char *), cmp_keynames);
+
+ buf = talloc_array(ctr, char, len);
+ if (buf == NULL) {
+ goto fail;
+ }
+ p = buf + 4 + 4*num_subkeys;
+
+ SIVAL(buf, 0, num_subkeys);
+
+ for (i=0; i < num_subkeys; i++) {
+ ptrdiff_t offset = p - buf;
+ SIVAL(buf, 4 + 4*i, offset);
+ strlcpy(p, sorted_subkeys[i], len-offset);
+ p += strlen(sorted_subkeys[i]) + 1;
+ }
+
+ status = dbwrap_store_bystring(
+ regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len),
+ TDB_REPLACE);
+ if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * Don't use a "goto fail;" here, this would commit the broken
+ * transaction. See below for an explanation.
+ */
+ if (regdb->transaction_cancel(regdb) == -1) {
+ DEBUG(0, ("create_sorted_subkeys: transaction_cancel "
+ "failed\n"));
+ }
+ TALLOC_FREE(ctr);
+ return false;
+ }
+
+ result = true;
+ fail:
+ /*
+ * We only get here via the "goto fail" when we did not write anything
+ * yet. Using transaction_commit even in a failure case is necessary
+ * because this (disposable) call might be nested in other
+ * transactions. Doing a cancel here would destroy the possibility of
+ * a transaction_commit for transactions that we might be wrapped in.
+ */
+ if (regdb->transaction_commit(regdb) == -1) {
+ DEBUG(0, ("create_sorted_subkeys: transaction_start "
+ "failed\n"));
+ goto fail;
+ }
+
+ TALLOC_FREE(ctr);
+ return result;
+}
+
+struct scan_subkey_state {
+ char *name;
+ bool scanned;
+ bool found;
+};
+
+static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data,
+ void *private_data)
+{
+ struct scan_subkey_state *state =
+ (struct scan_subkey_state *)private_data;
+ uint32_t num_subkeys;
+ uint32_t l, u;
+
+ if (data.dsize < sizeof(uint32_t)) {
+ return -1;
+ }
+
+ state->scanned = true;
+ state->found = false;
+
+ tdb_unpack(data.dptr, data.dsize, "d", &num_subkeys);
+
+ l = 0;
+ u = num_subkeys;
+
+ while (l < u) {
+ uint32_t idx = (l+u)/2;
+ char *s = (char *)data.dptr + IVAL(data.dptr, 4 + 4*idx);
+ int comparison = strcmp(state->name, s);
+
+ if (comparison < 0) {
+ u = idx;
+ } else if (comparison > 0) {
+ l = idx + 1;
+ } else {
+ state->found = true;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static bool scan_parent_subkeys(const char *parent, const char *name)
+{
+ char *path = NULL;
+ char *key = NULL;
+ struct scan_subkey_state state = { 0, };
+ bool result = false;
+ int res;
+
+ state.name = NULL;
+
+ path = normalize_reg_path(talloc_tos(), parent);
+ if (path == NULL) {
+ goto fail;
+ }
+
+ key = talloc_asprintf(talloc_tos(), "%s/%s",
+ REG_SORTED_SUBKEYS_PREFIX, path);
+ if (key == NULL) {
+ goto fail;
+ }
+
+ state.name = talloc_strdup_upper(talloc_tos(), name);
+ if (state.name == NULL) {
+ goto fail;
+ }
+ state.scanned = false;
+
+ res = regdb->parse_record(regdb, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
+
+ if (state.scanned) {
+ result = state.found;
+ } else {
+ if (!create_sorted_subkeys(path, key)) {
+ goto fail;
+ }
+ res = regdb->parse_record(regdb, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
+ if ((res == 0) && (state.scanned)) {
+ result = state.found;
+ }
+ }
+
+ fail:
+ TALLOC_FREE(path);
+ TALLOC_FREE(state.name);
+ return result;
+}
/**
* Check for the existence of a key.
@@ -907,26 +1325,8 @@ static bool regdb_key_exists(const char *key)
value = regdb_fetch_key_internal(mem_ctx, path);
ret = (value.dptr != NULL);
} else {
- /* get the list of subkeys of the parent key */
- uint32 num_items, len, i;
- fstring subkeyname;
-
*p = '\0';
- p++;
- value = regdb_fetch_key_internal(mem_ctx, path);
- if (value.dptr == NULL) {
- goto done;
- }
-
- len = tdb_unpack(value.dptr, value.dsize, "d", &num_items);
- for (i = 0; i < num_items; i++) {
- len += tdb_unpack(value.dptr +len, value.dsize -len,
- "f", &subkeyname);
- if (strequal(subkeyname, p)) {
- ret = true;
- goto done;
- }
- }
+ ret = scan_parent_subkeys(path, p+1);
}
done:
@@ -940,8 +1340,9 @@ done:
released by the caller.
***********************************************************************/
-int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
{
+ WERROR werr;
uint32 num_items;
uint8 *buf;
uint32 buflen, len;
@@ -957,7 +1358,10 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
goto done;
}
- ctr->seqnum = regdb_get_seqnum();
+ werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum());
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
value = regdb_fetch_key_internal(frame, key);
@@ -972,35 +1376,12 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
buflen = value.dsize;
len = tdb_unpack( buf, buflen, "d", &num_items);
- /*
- * The following code breaks the abstraction that reg_objects.c sets
- * up with regsubkey_ctr_addkey(). But if we use that with the current
- * data structure of ctr->subkeys being an unsorted array, we end up
- * with an O(n^2) algorithm for retrieving keys from the tdb
- * file. This is pretty pointless, as we have to trust the data
- * structure on disk not to have duplicates anyway. The alternative to
- * breaking this abstraction would be to set up a more sophisticated
- * data structure in REGSUBKEY_CTR.
- *
- * This makes "net conf list" for a registry with >1000 shares
- * actually usable :-)
- */
-
- ctr->subkeys = talloc_array(ctr, char *, num_items);
- if (ctr->subkeys == NULL) {
- DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n"));
- goto done;
- }
- ctr->num_subkeys = num_items;
-
for (i=0; i<num_items; i++) {
len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
- ctr->subkeys[i] = talloc_strdup(ctr->subkeys, subkeyname);
- if (ctr->subkeys[i] == NULL) {
- DEBUG(5, ("regdb_fetch_keys: could not allocate "
- "subkeyname\n"));
- TALLOC_FREE(ctr->subkeys);
- ctr->num_subkeys = 0;
+ werr = regsubkey_ctr_addkey(ctr, subkeyname);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
+ "failed: %s\n", win_errstr(werr)));
goto done;
}
}
@@ -1238,7 +1619,6 @@ static WERROR regdb_set_secdesc(const char *key,
{
TALLOC_CTX *mem_ctx = talloc_stackframe();
char *tdbkey;
- NTSTATUS status;
WERROR err = WERR_NOMEM;
TDB_DATA tdbdata;
@@ -1255,36 +1635,27 @@ static WERROR regdb_set_secdesc(const char *key,
if (secdesc == NULL) {
/* assuming a delete */
- status = dbwrap_trans_delete_bystring(regdb, tdbkey);
- if (NT_STATUS_IS_OK(status)) {
- err = WERR_OK;
- } else {
- err = ntstatus_to_werror(status);
- }
+ err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb,
+ tdbkey));
goto done;
}
err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc,
&tdbdata.dptr,
&tdbdata.dsize));
- if (!W_ERROR_IS_OK(err)) {
- goto done;
- }
+ W_ERROR_NOT_OK_GOTO_DONE(err);
- status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0);
- if (!NT_STATUS_IS_OK(status)) {
- err = ntstatus_to_werror(status);
- goto done;
- }
+ err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey,
+ tdbdata, 0));
done:
TALLOC_FREE(mem_ctx);
return err;
}
-bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys)
+bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys)
{
- return (regdb_get_seqnum() != subkeys->seqnum);
+ return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys));
}
bool regdb_values_need_update(REGVAL_CTR *values)
@@ -1301,6 +1672,8 @@ REGISTRY_OPS regdb_ops = {
.fetch_values = regdb_fetch_values,
.store_subkeys = regdb_store_keys,
.store_values = regdb_store_values,
+ .create_subkey = regdb_create_subkey,
+ .delete_subkey = regdb_delete_subkey,
.get_secdesc = regdb_get_secdesc,
.set_secdesc = regdb_set_secdesc,
.subkeys_need_update = regdb_subkeys_need_update,
diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c
index 2ed5e78e1c..c67f7b3ea4 100644
--- a/source3/registry/reg_backend_hkpt_params.c
+++ b/source3/registry/reg_backend_hkpt_params.c
@@ -59,7 +59,7 @@ static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals)
}
static int hkpt_params_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c
index 71f88144c8..17abf038a6 100644
--- a/source3/registry/reg_backend_netlogon_params.c
+++ b/source3/registry/reg_backend_netlogon_params.c
@@ -46,7 +46,7 @@ static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals)
}
static int netlogon_params_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_backend_perflib.c b/source3/registry/reg_backend_perflib.c
index 999bca2682..e23c87efe8 100644
--- a/source3/registry/reg_backend_perflib.c
+++ b/source3/registry/reg_backend_perflib.c
@@ -95,7 +95,7 @@ static int perflib_fetch_values(const char *key, REGVAL_CTR *regvals)
}
static int perflib_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c
index 5c1e6eb543..192bc78e09 100644
--- a/source3/registry/reg_backend_printing.c
+++ b/source3/registry/reg_backend_printing.c
@@ -42,8 +42,8 @@ struct reg_dyn_tree {
const char *path;
/* callbscks for fetch/store operations */
- int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
- bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys );
+ int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
+ bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
int (*fetch_values) ( const char *path, REGVAL_CTR *values );
bool (*store_values) ( const char *path, REGVAL_CTR *values );
};
@@ -77,7 +77,7 @@ static const char *dos_basename(const char *path)
*********************************************************************
*********************************************************************/
-static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys)
+static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys)
{
char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS));
@@ -196,7 +196,7 @@ static char *strip_printers_prefix(const char *key)
/*********************************************************************
*********************************************************************/
-static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
{
int n_services = lp_numservices();
int snum;
@@ -275,7 +275,7 @@ done:
keyname is the sharename and not the printer name.
*********************************************************************/
-static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys )
+static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
{
int i, num_keys, snum;
char *printername;
@@ -310,7 +310,7 @@ static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys )
/**********************************************************************
*********************************************************************/
-static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
{
char *printers_key;
char *printername, *printerdatakey;
@@ -738,7 +738,7 @@ static bool key_printers_store_values( const char *key, REGVAL_CTR *values )
*********************************************************************
*********************************************************************/
-static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
{
const char *environments[] = {
"Windows 4.0",
@@ -1085,7 +1085,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
*********************************************************************
*********************************************************************/
-static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
{
int key_len = strlen(key);
@@ -1192,7 +1192,7 @@ static int match_registry_path(const char *key)
/***********************************************************************
**********************************************************************/
-static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
{
int i = match_registry_path( key );
@@ -1208,7 +1208,7 @@ static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
/**********************************************************************
*********************************************************************/
-static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
{
int i = match_registry_path( key );
diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c
index 7ac5c5b4b9..3e9d32cd97 100644
--- a/source3/registry/reg_backend_prod_options.c
+++ b/source3/registry/reg_backend_prod_options.c
@@ -59,7 +59,7 @@ static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals)
}
static int prod_options_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_backend_shares.c b/source3/registry/reg_backend_shares.c
index ee9e5dc5a1..a30ae34b4e 100644
--- a/source3/registry/reg_backend_shares.c
+++ b/source3/registry/reg_backend_shares.c
@@ -66,7 +66,7 @@ static char* trim_reg_path( const char *path )
Caller is responsible for freeing memory to **subkeys
*********************************************************************/
-static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
+static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr )
{
char *path;
bool top_level = False;
@@ -134,7 +134,7 @@ static int shares_value_info( const char *key, REGVAL_CTR *val )
(for now at least)
*********************************************************************/
-static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
+static bool shares_store_subkey( const char *key, struct regsubkey_ctr *subkeys )
{
return False;
}
diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c
index 2e4a5f1c1d..8e1bbcab6f 100644
--- a/source3/registry/reg_backend_smbconf.c
+++ b/source3/registry/reg_backend_smbconf.c
@@ -25,16 +25,26 @@
extern REGISTRY_OPS regdb_ops; /* these are the default */
-static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr )
+static int smbconf_fetch_keys( const char *key, struct regsubkey_ctr *subkey_ctr )
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
-static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
+static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys )
{
return regdb_ops.store_subkeys(key, subkeys);
}
+static WERROR smbconf_create_subkey(const char *key, const char *subkey)
+{
+ return regdb_ops.create_subkey(key, subkey);
+}
+
+static WERROR smbconf_delete_subkey(const char *key, const char *subkey)
+{
+ return regdb_ops.delete_subkey(key, subkey);
+}
+
static int smbconf_fetch_values( const char *key, REGVAL_CTR *val )
{
return regdb_ops.fetch_values(key, val);
@@ -79,6 +89,8 @@ REGISTRY_OPS smbconf_reg_ops = {
.fetch_values = smbconf_fetch_values,
.store_subkeys = smbconf_store_keys,
.store_values = smbconf_store_values,
+ .create_subkey = smbconf_create_subkey,
+ .delete_subkey = smbconf_delete_subkey,
.reg_access_check = smbconf_reg_access_check,
.get_secdesc = smbconf_get_secdesc,
.set_secdesc = smbconf_set_secdesc,
diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c
index db7df5dd8f..a6aa2fc2ea 100644
--- a/source3/registry/reg_backend_tcpip_params.c
+++ b/source3/registry/reg_backend_tcpip_params.c
@@ -56,7 +56,7 @@ static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals)
}
static int tcpip_params_fetch_subkeys(const char *key,
- REGSUBKEY_CTR *subkey_ctr)
+ struct regsubkey_ctr *subkey_ctr)
{
return regdb_ops.fetch_subkeys(key, subkey_ctr);
}
diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c
index 7d950c3c4e..f8c382536f 100644
--- a/source3/registry/reg_dispatcher.c
+++ b/source3/registry/reg_dispatcher.c
@@ -39,7 +39,7 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
SEC_ACE ace[3];
size_t i = 0;
SEC_DESC *sd;
- SEC_ACL *acl;
+ SEC_ACL *theacl;
size_t sd_size;
/* basic access for Everyone */
@@ -59,14 +59,14 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
/* create the security descriptor */
- acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
- if (acl == NULL) {
+ theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
+ if (theacl == NULL) {
return WERR_NOMEM;
}
sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
&global_sid_Builtin_Administrators,
- &global_sid_System, NULL, acl,
+ &global_sid_System, NULL, theacl,
&sd_size);
if (sd == NULL) {
return WERR_NOMEM;
@@ -80,7 +80,7 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd)
High level wrapper function for storing registry subkeys
***********************************************************************/
-bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
+bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys )
{
if (key->ops && key->ops->store_subkeys)
return key->ops->store_subkeys(key->name, subkeys);
@@ -100,12 +100,30 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
return false;
}
+WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey)
+{
+ if (key->ops && key->ops->create_subkey) {
+ return key->ops->create_subkey(key->name, subkey);
+ }
+
+ return WERR_NOT_SUPPORTED;
+}
+
+WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey)
+{
+ if (key->ops && key->ops->delete_subkey) {
+ return key->ops->delete_subkey(key->name, subkey);
+ }
+
+ return WERR_NOT_SUPPORTED;
+}
+
/***********************************************************************
High level wrapper function for enumerating registry subkeys
Initialize the TALLOC_CTX if necessary
***********************************************************************/
-int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
+int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr )
{
int result = -1;
@@ -143,7 +161,6 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
SEC_DESC *sec_desc;
NTSTATUS status;
WERROR err;
- TALLOC_CTX *mem_ctx;
/* use the default security check if the backend has not defined its
* own */
@@ -153,30 +170,20 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
granted, token);
}
- /*
- * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
- */
-
- if (!(mem_ctx = talloc_init("regkey_access_check"))) {
- return false;
- }
-
- err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
+ err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);
if (!W_ERROR_IS_OK(err)) {
- TALLOC_FREE(mem_ctx);
return false;
}
se_map_generic( &requested, &reg_generic_map );
status =se_access_check(sec_desc, token, requested, granted);
+ TALLOC_FREE(sec_desc);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(mem_ctx);
return false;
}
- TALLOC_FREE(mem_ctx);
return NT_STATUS_IS_OK(status);
}
@@ -216,7 +223,7 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
* Check whether the in-memory version of the subkyes of a
* registry key needs update from disk.
*/
-bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
+bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys)
{
if (key->ops && key->ops->subkeys_need_update)
{
diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c
index 8994acf107..c02318beac 100644
--- a/source3/registry/reg_eventlog.c
+++ b/source3/registry/reg_eventlog.c
@@ -35,16 +35,18 @@ bool eventlog_init_keys(void)
const char **elogs = lp_eventlog_list();
char *evtlogpath = NULL;
char *evtfilepath = NULL;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
REGVAL_CTR *values;
uint32 uiMaxSize;
uint32 uiRetention;
uint32 uiCategoryCount;
UNISTR2 data;
TALLOC_CTX *ctx = talloc_tos();
+ WERROR werr;
while (elogs && *elogs) {
- if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG( 0, ( "talloc() failure!\n" ) );
return False;
}
@@ -70,7 +72,8 @@ bool eventlog_init_keys(void)
DEBUG( 5,
( "Adding key of [%s] to path of [%s]\n", *elogs,
evtlogpath ) );
- if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG( 0, ( "talloc() failure!\n" ) );
return False;
}
@@ -197,7 +200,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename,
const char **elogs = lp_eventlog_list( );
char **wrklist, **wp;
char *evtlogpath = NULL;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
REGVAL_CTR *values;
REGISTRY_VALUE *rval;
UNISTR2 data;
@@ -207,6 +210,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename,
int i;
int numsources;
TALLOC_CTX *ctx = talloc_tos();
+ WERROR werr;
if (!elogs) {
return False;
@@ -315,7 +319,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename,
TALLOC_FREE(values);
TALLOC_FREE(wrklist); /* */
- if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG( 0, ( "talloc() failure!\n" ) );
return False;
}
@@ -342,7 +347,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename,
/* now allocate room for the source's subkeys */
- if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) {
+ werr = regsubkey_ctr_init(ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG( 0, ( "talloc() failure!\n" ) );
return False;
}
diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c
index 47122ccad2..b975ced324 100644
--- a/source3/registry/reg_objects.c
+++ b/source3/registry/reg_objects.c
@@ -24,25 +24,135 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
+struct regsubkey_ctr {
+ uint32_t num_subkeys;
+ char **subkeys;
+ struct db_context *subkeys_hash;
+ int seqnum;
+};
+
/**********************************************************************
- Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d
- since the methods use the object pointer as the talloc context for
- internal private data.
+ Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be
+ talloc()'d since the methods use the object pointer as the talloc
+ context for internal private data.
- There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy()
+ There is no longer a regval_ctr_intit() and regval_ctr_destroy()
pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the
object.
**********************************************************************/
+WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr)
+{
+ if (ctr == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr);
+ if (*ctr == NULL) {
+ return WERR_NOMEM;
+ }
+
+ (*ctr)->subkeys_hash = db_open_rbt(*ctr);
+ if ((*ctr)->subkeys_hash == NULL) {
+ talloc_free(*ctr);
+ return WERR_NOMEM;
+ }
+
+ return WERR_OK;
+}
+
+WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
+{
+ if (ctr == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ ctr->seqnum = seqnum;
+
+ return WERR_OK;
+}
+
+int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr)
+{
+ if (ctr == NULL) {
+ return -1;
+ }
+
+ return ctr->seqnum;
+}
+
+static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
+ const char *keyname,
+ uint32 idx)
+{
+ WERROR werr;
+
+ werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash,
+ keyname,
+ make_tdb_data((uint8 *)&idx,
+ sizeof(idx)),
+ TDB_REPLACE));
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("error hashing new key '%s' in container: %s\n",
+ keyname, win_errstr(werr)));
+ }
+
+ return werr;
+}
+
+static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr,
+ const char *keyname)
+{
+ WERROR werr;
+
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash,
+ keyname));
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("error unhashing key '%s' in container: %s\n",
+ keyname, win_errstr(werr)));
+ }
+
+ return werr;
+}
+
+static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
+ const char *keyname,
+ uint32 *idx)
+{
+ TDB_DATA data;
+
+ if ((ctr == NULL) || (keyname == NULL)) {
+ return WERR_INVALID_PARAM;
+ }
+
+ data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname);
+ if (data.dptr == NULL) {
+ return WERR_NOT_FOUND;
+ }
+
+ if (data.dsize != sizeof(*idx)) {
+ talloc_free(data.dptr);
+ return WERR_INVALID_DATATYPE;
+ }
+
+ if (idx != NULL) {
+ *idx = *(uint32 *)data.dptr;
+ }
+
+ talloc_free(data.dptr);
+ return WERR_OK;
+}
+
/***********************************************************************
Add a new key to the array
**********************************************************************/
-WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
+WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname )
{
char **newkeys;
+ WERROR werr;
if ( !keyname ) {
return WERR_OK;
@@ -68,6 +178,10 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
*/
return WERR_NOMEM;
}
+
+ werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys);
+ W_ERROR_NOT_OK_RETURN(werr);
+
ctr->num_subkeys++;
return WERR_OK;
@@ -77,57 +191,64 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname )
Delete a key from the array
**********************************************************************/
-int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname )
+WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname )
{
- int i;
+ WERROR werr;
+ uint32 idx, j;
- if ( !keyname )
- return ctr->num_subkeys;
+ if (keyname == NULL) {
+ return WERR_INVALID_PARAM;
+ }
/* make sure the keyname is actually already there */
- for ( i=0; i<ctr->num_subkeys; i++ ) {
- if ( strequal( ctr->subkeys[i], keyname ) )
- break;
- }
+ werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx);
+ W_ERROR_NOT_OK_RETURN(werr);
- if ( i == ctr->num_subkeys )
- return ctr->num_subkeys;
+ werr = regsubkey_ctr_unhash_keyname(ctr, keyname);
+ W_ERROR_NOT_OK_RETURN(werr);
/* update if we have any keys left */
ctr->num_subkeys--;
- if ( i < ctr->num_subkeys )
- memmove(&ctr->subkeys[i], &ctr->subkeys[i+1],
- sizeof(char*) * (ctr->num_subkeys-i));
+ if (idx < ctr->num_subkeys) {
+ memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1],
+ sizeof(char *) * (ctr->num_subkeys - idx));
+
+ /* we have to re-hash rest of the array... :-( */
+ for (j = idx; j < ctr->num_subkeys; j++) {
+ werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j);
+ W_ERROR_NOT_OK_RETURN(werr);
+ }
+ }
- return ctr->num_subkeys;
+ return WERR_OK;
}
/***********************************************************************
Check for the existance of a key
**********************************************************************/
-bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
+bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname )
{
- int i;
+ WERROR werr;
if (!ctr->subkeys) {
return False;
}
- for ( i=0; i<ctr->num_subkeys; i++ ) {
- if ( strequal( ctr->subkeys[i],keyname ) )
- return True;
+ werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL);
+ if (!W_ERROR_IS_OK(werr)) {
+ return false;
}
- return False;
+ return true;
}
/***********************************************************************
How many keys does the container hold ?
**********************************************************************/
-int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
+int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr )
{
return ctr->num_subkeys;
}
@@ -136,7 +257,7 @@ int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
Retreive a specific key string
**********************************************************************/
-char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index )
+char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index )
{
if ( ! (key_index < ctr->num_subkeys) )
return NULL;
diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c
index 5395f225f1..d002bd72e7 100644
--- a/source3/registry/regfio.c
+++ b/source3/registry/regfio.c
@@ -1693,7 +1693,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
*******************************************************************/
REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name,
- REGVAL_CTR *values, REGSUBKEY_CTR *subkeys,
+ REGVAL_CTR *values, struct regsubkey_ctr *subkeys,
SEC_DESC *sec_desc, REGF_NK_REC *parent )
{
REGF_NK_REC *nk;
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
index 489b9ca2ff..d76d20c962 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -44,7 +44,8 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
ZERO_STRUCT(devmode_ctr);
level1.size = 28;
- level1.client = cli->srv_name_slash;
+ level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+ W_ERROR_HAVE_NO_MEMORY(level1.client);
level1.user = cli->auth->user_name;
level1.build = 1381;
level1.major = 2;
@@ -74,6 +75,211 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
return WERR_OK;
}
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetPrinterDriver2
+**********************************************************************/
+
+WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ const char *architecture,
+ uint32_t level,
+ uint32_t offered,
+ uint32_t client_major_version,
+ uint32_t client_minor_version,
+ union spoolss_DriverInfo *info,
+ uint32_t *server_major_version,
+ uint32_t *server_minor_version)
+{
+ NTSTATUS status;
+ WERROR werror;
+ uint32_t needed;
+ DATA_BLOB buffer;
+
+ if (offered > 0) {
+ buffer = data_blob_talloc_zero(mem_ctx, offered);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+ }
+
+ status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
+ handle,
+ architecture,
+ level,
+ (offered > 0) ? &buffer : NULL,
+ offered,
+ client_major_version,
+ client_minor_version,
+ info,
+ &needed,
+ server_major_version,
+ server_minor_version,
+ &werror);
+ if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+ offered = needed;
+ buffer = data_blob_talloc_zero(mem_ctx, needed);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+
+ status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
+ handle,
+ architecture,
+ level,
+ &buffer,
+ offered,
+ client_major_version,
+ client_minor_version,
+ info,
+ &needed,
+ server_major_version,
+ server_minor_version,
+ &werror);
+ }
+
+ return werror;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_AddPrinterEx
+**********************************************************************/
+
+WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct spoolss_SetPrinterInfoCtr *info_ctr)
+{
+ WERROR result;
+ NTSTATUS status;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ struct spoolss_UserLevelCtr userlevel_ctr;
+ struct spoolss_UserLevel1 level1;
+ struct policy_handle handle;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ level1.size = 28;
+ level1.build = 1381;
+ level1.major = 2;
+ level1.minor = 0;
+ level1.processor = 0;
+ level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+ W_ERROR_HAVE_NO_MEMORY(level1.client);
+ level1.user = cli->auth->user_name;
+
+ userlevel_ctr.level = 1;
+ userlevel_ctr.user_info.level1 = &level1;
+
+ status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
+ cli->srv_name_slash,
+ info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ &userlevel_ctr,
+ &handle,
+ &result);
+ return result;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetPrinter
+**********************************************************************/
+
+WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ uint32_t level,
+ uint32_t offered,
+ union spoolss_PrinterInfo *info)
+{
+ NTSTATUS status;
+ WERROR werror;
+ DATA_BLOB buffer;
+ uint32_t needed;
+
+ if (offered > 0) {
+ buffer = data_blob_talloc_zero(mem_ctx, offered);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+ }
+
+ status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
+ handle,
+ level,
+ (offered > 0) ? &buffer : NULL,
+ offered,
+ info,
+ &needed,
+ &werror);
+
+ if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+
+ offered = needed;
+ buffer = data_blob_talloc_zero(mem_ctx, offered);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+
+ status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
+ handle,
+ level,
+ &buffer,
+ offered,
+ info,
+ &needed,
+ &werror);
+ }
+
+ return werror;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetJob
+**********************************************************************/
+
+WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ uint32_t job_id,
+ uint32_t level,
+ uint32_t offered,
+ union spoolss_JobInfo *info)
+{
+ NTSTATUS status;
+ WERROR werror;
+ uint32_t needed;
+ DATA_BLOB buffer;
+
+ if (offered > 0) {
+ buffer = data_blob_talloc_zero(mem_ctx, offered);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+ }
+
+ status = rpccli_spoolss_GetJob(cli, mem_ctx,
+ handle,
+ job_id,
+ level,
+ (offered > 0) ? &buffer : NULL,
+ offered,
+ info,
+ &needed,
+ &werror);
+
+ if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+ offered = needed;
+ buffer = data_blob_talloc_zero(mem_ctx, needed);
+ W_ERROR_HAVE_NO_MEMORY(buffer.data);
+
+ status = rpccli_spoolss_GetJob(cli, mem_ctx,
+ handle,
+ job_id,
+ level,
+ &buffer,
+ offered,
+ info,
+ &needed,
+ &werror);
+ }
+
+ return werror;
+}
+
+
/*********************************************************************
Decode various spoolss rpc's and info levels
********************************************************************/
@@ -208,38 +414,6 @@ static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
- uint32 returned, PRINTER_INFO_7 **info)
-{
- uint32 i;
- PRINTER_INFO_7 *inf;
-
- if (returned) {
- inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
- if (!inf) {
- return False;
- }
- memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
- } else {
- inf = NULL;
- }
-
- prs_set_offset(&buffer->prs,0);
-
- for (i=0; i<returned; i++) {
- if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) {
- return False;
- }
- }
-
- *info=inf;
- return True;
-}
-
-
-/**********************************************************************
-**********************************************************************/
-
static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PORT_INFO_1 **info)
{
@@ -628,195 +802,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct
/**********************************************************************
**********************************************************************/
-WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- PRINTER_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTER in;
- SPOOL_R_GETPRINTER out;
- RPC_BUFFER buffer;
- uint32 offered;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- /* Initialise input parameters */
-
- offered = 0;
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getprinter,
- spoolss_io_r_getprinter,
- WERR_GENERAL_FAILURE );
-
- if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
- offered = out.needed;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getprinter,
- spoolss_io_r_getprinter,
- WERR_GENERAL_FAILURE );
- }
-
- if ( !W_ERROR_IS_OK(out.status) )
- return out.status;
-
- switch (level) {
- case 0:
- if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 1:
- if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 2:
- if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 3:
- if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 7:
- if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- default:
- return WERR_UNKNOWN_LEVEL;
- }
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- PRINTER_INFO_CTR *ctr, uint32 command)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_SETPRINTER in;
- SPOOL_R_SETPRINTER out;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_setprinter,
- spoolss_io_r_setprinter,
- WERR_GENERAL_FAILURE );
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 level,
- const char *env, int version, PRINTER_DRIVER_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETPRINTERDRIVER2 in;
- SPOOL_R_GETPRINTERDRIVER2 out;
- RPC_BUFFER buffer;
- fstring server;
- uint32 offered;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- fstrcpy(server, cli->desthost);
- strupper_m(server);
-
- offered = 0;
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getprinterdriver2( &in, pol, env, level,
- version, 2, &buffer, offered);
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getprinterdriver2,
- spoolss_io_r_getprinterdriver2,
- WERR_GENERAL_FAILURE );
-
- if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
- offered = out.needed;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getprinterdriver2( &in, pol, env, level,
- version, 2, &buffer, offered);
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getprinterdriver2,
- spoolss_io_r_getprinterdriver2,
- WERR_GENERAL_FAILURE );
- }
-
- if ( !W_ERROR_IS_OK(out.status) )
- return out.status;
-
- switch (level) {
- case 1:
- if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 2:
- if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 3:
- if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- default:
- return WERR_UNKNOWN_LEVEL;
- }
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 level, const char *env,
@@ -902,71 +887,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli,
/**********************************************************************
**********************************************************************/
-WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx, uint32 level,
- PRINTER_DRIVER_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ADDPRINTERDRIVER in;
- SPOOL_R_ADDPRINTERDRIVER out;
- fstring server;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper_m(server);
-
- make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_addprinterdriver,
- spoolss_io_r_addprinterdriver,
- WERR_GENERAL_FAILURE );
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- uint32 level, PRINTER_INFO_CTR*ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_ADDPRINTEREX in;
- SPOOL_R_ADDPRINTEREX out;
- fstring server, client, user;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname());
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-
- strupper_m(client);
- strupper_m(server);
-
- fstrcpy (user, cli->auth->user_name);
-
- make_spoolss_q_addprinterex( mem_ctx, &in, server, client,
- user, level, ctr);
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_addprinterex,
- spoolss_io_r_addprinterex,
- WERR_GENERAL_FAILURE );
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, int level, uint32 *num_forms,
FORM_1 **forms)
@@ -1097,73 +1017,6 @@ WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 jobid, uint32 level,
- JOB_INFO_CTR *ctr)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_GETJOB in;
- SPOOL_R_GETJOB out;
- RPC_BUFFER buffer;
- uint32 offered;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- offered = 0;
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getjob,
- spoolss_io_r_getjob,
- WERR_GENERAL_FAILURE );
-
- if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
- offered = out.needed;
-
- ZERO_STRUCT(in);
- ZERO_STRUCT(out);
-
- if (!rpcbuf_init(&buffer, offered, mem_ctx))
- return WERR_NOMEM;
- make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
- in, out,
- qbuf, rbuf,
- spoolss_io_q_getjob,
- spoolss_io_r_getjob,
- WERR_GENERAL_FAILURE );
- }
-
- if (!W_ERROR_IS_OK(out.status))
- return out.status;
-
- switch(level) {
- case 1:
- if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- case 2:
- if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) {
- return WERR_GENERAL_FAILURE;
- }
- break;
- default:
- return WERR_UNKNOWN_LEVEL;
- }
-
- return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *valuename,
REGISTRY_VALUE *value)
@@ -1405,5 +1258,4 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me
return out.status;
}
-
/** @} **/
diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c
deleted file mode 100644
index 8ae7835c4e..0000000000
--- a/source3/rpc_client/cli_spoolss_notify.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- RPC pipe client
-
- Copyright (C) Gerald Carter 2001-2002,
- Copyright (C) Tim Potter 2000-2002,
- Copyright (C) Andrew Tridgell 1994-2000,
- Copyright (C) Jean-Francois Micouleau 1999-2000.
- Copyright (C) Jeremy Allison 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"
-
-/*
- * SPOOLSS Client RPC's used by servers as the notification
- * back channel.
- */
-
-/*********************************************************************
- This SPOOLSS_REPLY_RRPCN function is used to send a change
- notification event when the registration **did** use
- SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor
- Also see cli_spoolss_routereplyprinter()
- *********************************************************************/
-
-WERROR rpccli_spoolss_rrpcn(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 notify_data_len,
- SPOOL_NOTIFY_INFO_DATA *notify_data,
- uint32 change_low, uint32 change_high)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_REPLY_RRPCN q;
- SPOOL_R_REPLY_RRPCN r;
- WERROR result = W_ERROR(ERRgeneral);
- SPOOL_NOTIFY_INFO notify_info;
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- ZERO_STRUCT(notify_info);
-
- /* Initialise input parameters */
-
- notify_info.version = 0x2;
- notify_info.flags = 0x00020000; /* ?? */
- notify_info.count = notify_data_len;
- notify_info.data = notify_data;
-
- /* create and send a MSRPC command with api */
- /* store the parameters */
-
- make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high,
- &notify_info);
-
- /* Marshall data and send request */
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_RRPCN,
- q, r,
- qbuf, rbuf,
- spoolss_io_q_reply_rrpcn,
- spoolss_io_r_reply_rrpcn,
- WERR_GENERAL_FAILURE );
-
- if (r.unknown0 == 0x00080000)
- DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
- else if ( r.unknown0 != 0x0 )
- DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0));
-
- result = r.status;
- return result;
-}
-
-/*********************************************************************
- *********************************************************************/
-
-WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 flags, uint32 options,
- const char *localmachine, uint32 printerlocal,
- SPOOL_NOTIFY_OPTION *option)
-{
- prs_struct qbuf, rbuf;
- SPOOL_Q_RFFPCNEX q;
- SPOOL_R_RFFPCNEX r;
- WERROR result = W_ERROR(ERRgeneral);
-
- ZERO_STRUCT(q);
- ZERO_STRUCT(r);
-
- /* Initialise input parameters */
-
- make_spoolss_q_rffpcnex(
- &q, pol, flags, options, localmachine, printerlocal,
- option);
-
- /* Marshall data and send request */
-
- CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_RFFPCNEX,
- q, r,
- qbuf, rbuf,
- spoolss_io_q_rffpcnex,
- spoolss_io_r_rffpcnex,
- WERR_GENERAL_FAILURE );
-
- result = r.status;
- return result;
-}
diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c
index c0fa41b0de..658ffe30d6 100644
--- a/source3/rpc_client/rpc_transport_sock.c
+++ b/source3/rpc_client/rpc_transport_sock.c
@@ -35,6 +35,12 @@ static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *
return 0;
}
+struct rpc_sock_read_state {
+ ssize_t received;
+};
+
+static void rpc_sock_read_done(struct tevent_req *subreq);
+
static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
uint8_t *data, size_t size,
@@ -42,25 +48,62 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
{
struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
priv, struct rpc_transport_sock_state);
- return async_recv(mem_ctx, ev, sock_transp->fd, data, size, 0);
+ struct async_req *result;
+ struct tevent_req *subreq;
+ struct rpc_sock_read_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_sock_read_state)) {
+ return NULL;
+ }
+
+ subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = rpc_sock_read_done;
+ subreq->async.private_data = result;
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
}
-static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived)
+static void rpc_sock_read_done(struct tevent_req *subreq)
{
- ssize_t received;
- int sys_errno;
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct async_req);
+ struct rpc_sock_read_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_read_state);
+ int err;
- received = async_syscall_result_ssize_t(req, &sys_errno);
- if (received == -1) {
- return map_nt_error_from_unix(sys_errno);
+ state->received = async_recv_recv(subreq, &err);
+ if (state->received == -1) {
+ async_req_nterror(req, map_nt_error_from_unix(err));
+ return;
}
- if (received == 0) {
- return NT_STATUS_END_OF_FILE;
+ async_req_done(req);
+}
+
+static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived)
+{
+ struct rpc_sock_read_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_read_state);
+ NTSTATUS status;
+
+ if (async_req_is_nterror(req, &status)) {
+ return status;
}
- *preceived = received;
+ *preceived = state->received;
return NT_STATUS_OK;
}
+struct rpc_sock_write_state {
+ ssize_t sent;
+};
+
+static void rpc_sock_write_done(struct tevent_req *subreq);
+
static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
const uint8_t *data, size_t size,
@@ -68,19 +111,52 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
{
struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
priv, struct rpc_transport_sock_state);
- return async_send(mem_ctx, ev, sock_transp->fd, data, size, 0);
+ struct async_req *result;
+ struct tevent_req *subreq;
+ struct rpc_sock_write_state *state;
+
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_sock_write_state)) {
+ return NULL;
+ }
+ subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = rpc_sock_write_done;
+ subreq->async.private_data = result;
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_sock_write_done(struct tevent_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct async_req);
+ struct rpc_sock_write_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_write_state);
+ int err;
+
+ state->sent = async_send_recv(subreq, &err);
+ if (state->sent == -1) {
+ async_req_nterror(req, map_nt_error_from_unix(err));
+ return;
+ }
+ async_req_done(req);
}
static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent)
{
- ssize_t sent;
- int sys_errno;
+ struct rpc_sock_write_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_write_state);
+ NTSTATUS status;
- sent = async_syscall_result_ssize_t(req, &sys_errno);
- if (sent == -1) {
- return map_nt_error_from_unix(sys_errno);
+ if (async_req_is_nterror(req, &status)) {
+ return status;
}
- *psent = sent;
+ *psent = state->sent;
return NT_STATUS_OK;
}
diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c
index 23c9610381..91d8591a05 100644
--- a/source3/rpc_parse/parse_sec.c
+++ b/source3/rpc_parse/parse_sec.c
@@ -73,11 +73,11 @@ static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps,
if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags))
return False;
- if (psa->object.object.flags & SEC_ACE_OBJECT_PRESENT)
+ if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth))
return False;
- if (psa->object.object.flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
+ if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)
if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth))
return False;
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 577ba73a42..78c041f863 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -71,459 +71,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
}
/*******************************************************************
-reads or writes an NOTIFY OPTION TYPE structure.
-********************************************************************/
-
-/* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
- structure. The _TYPE structure is really the deferred referrants (i.e
- the notify fields array) of the _TYPE structure. -tpot */
-
-static bool smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_notify_option_type");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if(!prs_uint16("type", ps, depth, &type->type))
- return False;
- if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
- return False;
- if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
- return False;
- if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
- return False;
- if(!prs_uint32("count", ps, depth, &type->count))
- return False;
- if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY OPTION TYPE DATA.
-********************************************************************/
-
-static bool smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
- depth++;
-
- /* if there are no fields just return */
- if (type->fields_ptr==0)
- return True;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("count2", ps, depth, &type->count2))
- return False;
-
- if (type->count2 != type->count)
- DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
-
- if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
- return False;
- }
-
- /* parse the option type data */
- for(i=0;i<type->count2;i++)
- if(!prs_uint16("fields",ps,depth,&type->fields[i]))
- return False;
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY OPTION structure.
-********************************************************************/
-
-static bool smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
- depth++;
-
- if(!prs_uint32("count", ps, depth, &ctr->count))
- return False;
-
- /* reading */
- if (UNMARSHALLING(ps) && ctr->count)
- if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
- return False;
-
- /* the option type struct */
- for(i=0;i<ctr->count;i++)
- if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
- return False;
-
- /* the type associated with the option type struct */
- for(i=0;i<ctr->count;i++)
- if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY OPTION structure.
-********************************************************************/
-
-static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_notify_option");
- depth++;
-
- if(!prs_uint32("version", ps, depth, &option->version))
- return False;
- if(!prs_uint32("flags", ps, depth, &option->flags))
- return False;
- if(!prs_uint32("count", ps, depth, &option->count))
- return False;
- if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
- return False;
-
- /* marshalling or unmarshalling, that would work */
- if (option->option_type_ptr!=0) {
- if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
- return False;
- }
- else {
- option->ctr.type=NULL;
- option->ctr.count=0;
- }
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY INFO DATA structure.
-********************************************************************/
-
-static bool smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
-{
- uint32 useless_ptr=0x0FF0ADDE;
-
- prs_debug(ps, depth, desc, "smb_io_notify_info_data");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint16("type", ps, depth, &data->type))
- return False;
- if(!prs_uint16("field", ps, depth, &data->field))
- return False;
-
- if(!prs_uint32("how many words", ps, depth, &data->size))
- return False;
- if(!prs_uint32("id", ps, depth, &data->id))
- return False;
- if(!prs_uint32("how many words", ps, depth, &data->size))
- return False;
-
- switch (data->enc_type) {
-
- /* One and two value data has two uint32 values */
-
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
-
- if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
- return False;
- if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
- return False;
- break;
-
- /* Pointers and strings have a string length and a
- pointer. For a string the length is expressed as
- the number of uint16 characters plus a trailing
- \0\0. */
-
- case NOTIFY_POINTER:
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
- return False;
- if(!prs_uint32("pointer", ps, depth, &useless_ptr))
- return False;
-
- break;
-
- case NOTIFY_STRING:
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
- return False;
-
- if(!prs_uint32("pointer", ps, depth, &useless_ptr))
- return False;
-
- break;
-
- case NOTIFY_SECDESC:
- if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
- return False;
- if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
- return False;
-
- break;
-
- default:
- DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
- data->enc_type));
- break;
- }
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY INFO DATA structure.
-********************************************************************/
-
-bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- switch(data->enc_type) {
-
- /* No data for values */
-
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
-
- break;
-
- /* Strings start with a length in uint16s */
-
- case NOTIFY_STRING:
-
- if (MARSHALLING(ps))
- data->notify_data.data.length /= 2;
-
- if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
- return False;
-
- if (UNMARSHALLING(ps) && data->notify_data.data.length) {
- data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
- data->notify_data.data.length);
-
- if (!data->notify_data.data.string)
- return False;
- }
-
- if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
- data->notify_data.data.length))
- return False;
-
- if (MARSHALLING(ps))
- data->notify_data.data.length *= 2;
-
- break;
-
- case NOTIFY_POINTER:
-
- if (UNMARSHALLING(ps) && data->notify_data.data.length) {
- data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
- data->notify_data.data.length);
-
- if (!data->notify_data.data.string)
- return False;
- }
-
- if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
- return False;
-
- break;
-
- case NOTIFY_SECDESC:
- if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
- return False;
- if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
- return False;
- break;
-
- default:
- DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
- data->enc_type));
- break;
- }
-
-#if 0
- if (isvalue==False) {
-
- /* length of string in unicode include \0 */
- x=data->notify_data.data.length+1;
-
- if (data->field != 16)
- if(!prs_uint32("string length", ps, depth, &x ))
- return False;
-
- if (MARSHALLING(ps)) {
- /* These are already in little endian format. Don't byte swap. */
- if (x == 1) {
-
- /* No memory allocated for this string
- therefore following the data.string
- pointer is a bad idea. Use a pointer to
- the uint32 length union member to
- provide a source for a unicode NULL */
-
- if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2))
- return False;
- } else {
-
- if (data->field == 16)
- x /= 2;
-
- if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
- return False;
- }
- } else {
-
- /* Tallocate memory for string */
-
- if (x) {
- data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
- if (!data->notify_data.data.string)
- return False;
- } else {
- data->notify_data.data.string = NULL;
- }
-
- if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
- return False;
- }
- }
-
-#endif
-
-#if 0 /* JERRY */
- /* Win2k does not seem to put this parse align here */
- if(!prs_align(ps))
- return False;
-#endif
-
- return True;
-}
-
-/*******************************************************************
-reads or writes an NOTIFY INFO structure.
-********************************************************************/
-
-static bool smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
-{
- int i;
-
- prs_debug(ps, depth, desc, "smb_io_notify_info");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("count", ps, depth, &info->count))
- return False;
- if(!prs_uint32("version", ps, depth, &info->version))
- return False;
- if(!prs_uint32("flags", ps, depth, &info->flags))
- return False;
- if(!prs_uint32("count", ps, depth, &info->count))
- return False;
-
- for (i=0;i<info->count;i++) {
- if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
- return False;
- }
-
- /* now do the strings at the end of the stream */
- for (i=0;i<info->count;i++) {
- if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
-{
- prs_debug(ps, depth, desc, "");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("size", ps, depth, &q_u->size))
- return False;
-
- if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
- return False;
- if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
- return False;
-
- if (!prs_uint32("build", ps, depth, &q_u->build))
- return False;
- if (!prs_uint32("major", ps, depth, &q_u->major))
- return False;
- if (!prs_uint32("minor", ps, depth, &q_u->minor))
- return False;
- if (!prs_uint32("processor", ps, depth, &q_u->processor))
- return False;
-
- if (!prs_io_unistr2("", ps, depth, q_u->client_name))
- return False;
- if (!prs_align(ps))
- return False;
-
- if (!prs_io_unistr2("", ps, depth, q_u->user_name))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
-{
- if (q_u==NULL)
- return False;
-
- prs_debug(ps, depth, desc, "spool_io_user_level");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- switch ( q_u->level )
- {
- case 1:
- if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1,
- sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 ))
- {
- return False;
- }
- break;
- default:
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
* read or write a DEVICEMODE struct.
* on reading allocate memory for the private member
********************************************************************/
@@ -712,220 +259,6 @@ bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE
}
/*******************************************************************
- Read or write a DEVICEMODE container
-********************************************************************/
-
-static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
-{
- if (dm_c==NULL)
- return False;
-
- prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if (!prs_uint32("size", ps, depth, &dm_c->size))
- return False;
-
- if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
- return False;
-
- if (dm_c->size==0 || dm_c->devmode_ptr==0) {
- if (UNMARSHALLING(ps))
- /* if while reading there is no DEVMODE ... */
- dm_c->devmode=NULL;
- return True;
- }
-
- /* so we have a DEVICEMODE to follow */
- if (UNMARSHALLING(ps)) {
- DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
- dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
- if(dm_c->devmode == NULL)
- return False;
- }
-
- /* this is bad code, shouldn't be there */
- if (!prs_uint32("size", ps, depth, &dm_c->size))
- return False;
-
- if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u,
- const char *srv_name, const char* clientname, const char* user_name,
- uint32 level, PRINTER_INFO_CTR *ctr)
-{
- DEBUG(5,("make_spoolss_q_addprinterex\n"));
-
- if (!ctr || !ctr->printers_2)
- return False;
-
- ZERO_STRUCTP(q_u);
-
- q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
- if (!q_u->server_name) {
- return False;
- }
- init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
-
- q_u->level = level;
-
- q_u->info.level = level;
- q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
- switch (level) {
- case 2:
- /* init q_u->info.info2 from *info */
- if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
- DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
- return False;
- }
- break;
- default :
- break;
- }
-
- q_u->user_switch=1;
-
- q_u->user_ctr.level = 1;
- q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
- if (!q_u->user_ctr.user.user1) {
- return False;
- }
- q_u->user_ctr.user.user1->build = 1381;
- q_u->user_ctr.user.user1->major = 2;
- q_u->user_ctr.user.user1->minor = 0;
- q_u->user_ctr.user.user1->processor = 0;
-
- q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
- if (!q_u->user_ctr.user.user1->client_name) {
- return False;
- }
- q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 );
- if (!q_u->user_ctr.user.user1->user_name) {
- return False;
- }
- init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
- init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
-
- q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
- q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
-
- return True;
-}
-
-/*******************************************************************
-create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
-*******************************************************************/
-
-bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
- PRINTER_INFO_2 *info)
-{
-
- SPOOL_PRINTER_INFO_LEVEL_2 *inf;
-
- /* allocate the necessary memory */
- if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
- DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
- return False;
- }
-
- inf->servername_ptr = (info->servername.buffer!=NULL)?1:0;
- inf->printername_ptr = (info->printername.buffer!=NULL)?1:0;
- inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0;
- inf->portname_ptr = (info->portname.buffer!=NULL)?1:0;
- inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0;
- inf->comment_ptr = (info->comment.buffer!=NULL)?1:0;
- inf->location_ptr = (info->location.buffer!=NULL)?1:0;
- inf->devmode_ptr = (info->devmode!=NULL)?1:0;
- inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0;
- inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
- inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0;
- inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0;
- inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
- inf->attributes = info->attributes;
- inf->priority = info->priority;
- inf->default_priority = info->defaultpriority;
- inf->starttime = info->starttime;
- inf->untiltime = info->untiltime;
- inf->cjobs = info->cjobs;
- inf->averageppm = info->averageppm;
- init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
- init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
- init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
- init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
- init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
- init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
- init_unistr2_from_unistr(inf, &inf->location, &info->location);
- init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
- init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
- init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
- init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
- init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
-
- *spool_info2 = inf;
-
- return True;
-}
-
-/*******************************************************************
-create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
-*******************************************************************/
-
-bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3,
- PRINTER_INFO_3 *info)
-{
-
- SPOOL_PRINTER_INFO_LEVEL_3 *inf;
-
- /* allocate the necessary memory */
- if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
- DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
- return False;
- }
-
- inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
-
- *spool_info3 = inf;
-
- return True;
-}
-
-/*******************************************************************
-create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
-*******************************************************************/
-
-bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7,
- PRINTER_INFO_7 *info)
-{
-
- SPOOL_PRINTER_INFO_LEVEL_7 *inf;
-
- /* allocate the necessary memory */
- if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
- DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
- return False;
- }
-
- inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
- inf->action = info->action;
- init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
-
- *spool_info7 = inf;
-
- return True;
-}
-
-/*******************************************************************
* make a structure.
********************************************************************/
@@ -1014,130 +347,6 @@ bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u,
}
/*******************************************************************
- * read a structure.
- * called from spoolss_q_rffpcnex (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
- if(!prs_uint32("flags", ps, depth, &q_u->flags))
- return False;
- if(!prs_uint32("options", ps, depth, &q_u->options))
- return False;
- if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
- return False;
- if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
- return False;
-
- if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
- return False;
-
- if (q_u->option_ptr!=0) {
-
- if (UNMARSHALLING(ps))
- if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
- return False;
-
- if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- * write a structure.
- * called from spoolss_r_rffpcnex (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
- depth++;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- * read a structure.
- * called from spoolss_q_rfnpcnex (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
- return False;
-
- if(!prs_uint32("change", ps, depth, &q_u->change))
- return False;
-
- if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
- return False;
-
- if (q_u->option_ptr!=0) {
-
- if (UNMARSHALLING(ps))
- if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
- return False;
-
- if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- * write a structure.
- * called from spoolss_r_rfnpcnex (srv_spoolss.c)
- ********************************************************************/
-
-bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
- return False;
-
- if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
* return the length of a uint16 (obvious, but the code is clean)
********************************************************************/
@@ -2556,33 +1765,6 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
}
/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
- const POLICY_HND *hnd,
- const fstring architecture,
- uint32 level, uint32 clientmajor, uint32 clientminor,
- RPC_BUFFER *buffer, uint32 offered)
-{
- if (q_u == NULL)
- return False;
-
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-
- init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
-
- q_u->level=level;
- q_u->clientmajorversion=clientmajor;
- q_u->clientminorversion=clientminor;
-
- q_u->buffer=buffer;
- q_u->offered=offered;
-
- return True;
-}
-
-/*******************************************************************
* read a structure.
* called from spoolss_getprinterdriver2 (srv_spoolss.c)
********************************************************************/
@@ -2823,211 +2005,6 @@ bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru
}
/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_getprinter(
- TALLOC_CTX *mem_ctx,
- SPOOL_Q_GETPRINTER *q_u,
- const POLICY_HND *hnd,
- uint32 level,
- RPC_BUFFER *buffer,
- uint32 offered
-)
-{
- if (q_u == NULL)
- {
- return False;
- }
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-
- q_u->level=level;
- q_u->buffer=buffer;
- q_u->offered=offered;
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
- const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
- uint32 command)
-{
- SEC_DESC *secdesc;
- DEVICEMODE *devmode;
-
- if (!q_u || !info)
- return False;
-
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-
- q_u->level = level;
- q_u->info.level = level;
- q_u->info.info_ptr = 1; /* Info is != NULL, see above */
- switch (level) {
-
- /* There's no such thing as a setprinter level 1 */
-
- case 2:
- secdesc = info->printers_2->secdesc;
- devmode = info->printers_2->devmode;
-
- make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
-#if 1 /* JERRY TEST */
- q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
- if (!q_u->secdesc_ctr)
- return False;
- q_u->secdesc_ctr->sd = secdesc;
- q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
-
- q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
- q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
- q_u->devmode_ctr.devmode = devmode;
-#else
- q_u->secdesc_ctr = NULL;
-
- q_u->devmode_ctr.devmode_ptr = 0;
- q_u->devmode_ctr.size = 0;
- q_u->devmode_ctr.devmode = NULL;
-#endif
- break;
- case 3:
- secdesc = info->printers_3->secdesc;
-
- make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
-
- q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
- if (!q_u->secdesc_ctr)
- return False;
- q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
- q_u->secdesc_ctr->sd = secdesc;
-
- break;
- case 7:
- make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
- break;
-
- default:
- DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
- break;
- }
-
-
- q_u->command = command;
-
- return True;
-}
-
-
-/*******************************************************************
-********************************************************************/
-
-bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
-********************************************************************/
-
-bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
-{
- uint32 ptr_sec_desc = 0;
-
- prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
- return False;
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- /* check for supported levels and structures we know about */
-
- switch ( q_u->level ) {
- case 0:
- case 2:
- case 3:
- case 7:
- /* supported levels */
- break;
- default:
- DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n",
- q_u->level));
- return True;
- }
-
-
- if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
- return False;
-
- if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- switch (q_u->level)
- {
- case 2:
- {
- ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
- break;
- }
- case 3:
- {
- /* FIXME ! Our parsing here is wrong I think,
- * but for a level3 it makes no sense for
- * ptr_sec_desc to be NULL. JRA. Based on
- * a Vista sniff from Martin Zielinski <mz@seh.de>.
- */
- if (UNMARSHALLING(ps)) {
- ptr_sec_desc = 1;
- } else {
- ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
- }
- break;
- }
- }
- if (ptr_sec_desc)
- {
- if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
- return False;
- } else {
- uint32 dummy = 0;
-
- /* Parse a NULL security descriptor. This should really
- happen inside the sec_io_desc_buf() function. */
-
- prs_debug(ps, depth, "", "sec_io_desc_buf");
- if (!prs_uint32("size", ps, depth + 1, &dummy))
- return False;
- if (!prs_uint32("ptr", ps, depth + 1, &dummy))
- return False;
- }
-
- if(!prs_uint32("command", ps, depth, &q_u->command))
- return False;
-
- return True;
-}
-
-/*******************************************************************
********************************************************************/
bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
@@ -3323,701 +2300,6 @@ bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct
}
/*******************************************************************
- Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
-********************************************************************/
-
-bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("flags", ps, depth, &il->flags))
- return False;
- if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
- return False;
- if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
- return False;
- if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
- return False;
-
- if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
-********************************************************************/
-
-bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
-********************************************************************/
-
-bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
- return False;
- if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
- return False;
- if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
- return False;
- if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
- return False;
-
- if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
- return False;
- if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
- return False;
- if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
- return False;
- if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
- return False;
- if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
- return False;
- if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
- return False;
- if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
- return False;
- if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
- return False;
- if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
- return False;
-
- if(!prs_uint32("attributes", ps, depth, &il->attributes))
- return False;
- if(!prs_uint32("priority", ps, depth, &il->priority))
- return False;
- if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
- return False;
- if(!prs_uint32("starttime", ps, depth, &il->starttime))
- return False;
- if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
- return False;
- if(!prs_uint32("status", ps, depth, &il->status))
- return False;
- if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
- return False;
- if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
- return False;
-
- if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
- return False;
-
- return True;
-}
-
-bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
- return False;
- if(!prs_uint32("action", ps, depth, &il->action))
- return False;
-
- if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
- return False;
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("level", ps, depth, &il->level))
- return False;
- if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
- return False;
-
- /* if no struct inside just return */
- if (il->info_ptr==0) {
- if (UNMARSHALLING(ps)) {
- il->info_1=NULL;
- il->info_2=NULL;
- }
- return True;
- }
-
- switch (il->level) {
- /*
- * level 0 is used by setprinter when managing the queue
- * (hold, stop, start a queue)
- */
- case 0:
- break;
- /* DOCUMENT ME!!! What is level 1 used for? */
- case 1:
- {
- if (UNMARSHALLING(ps)) {
- if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
- return False;
- }
- if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
- return False;
- break;
- }
- /*
- * level 2 is used by addprinter
- * and by setprinter when updating printer's info
- */
- case 2:
- if (UNMARSHALLING(ps)) {
- if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
- return False;
- }
- if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
- return False;
- break;
- /* DOCUMENT ME!!! What is level 3 used for? */
- case 3:
- {
- if (UNMARSHALLING(ps)) {
- if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
- return False;
- }
- if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
- return False;
- break;
- }
- case 7:
- if (UNMARSHALLING(ps))
- if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
- return False;
- if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
- return False;
- break;
- }
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
-{
- uint32 ptr_sec_desc = 0;
-
- prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
- return False;
- if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("info_level", ps, depth, &q_u->level))
- return False;
-
- if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
- return False;
-
- if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- switch (q_u->level) {
- case 2:
- ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
- break;
- case 3:
- ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
- break;
- }
- if (ptr_sec_desc) {
- if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
- return False;
- } else {
- uint32 dummy = 0;
-
- /* Parse a NULL security descriptor. This should really
- happen inside the sec_io_desc_buf() function. */
-
- prs_debug(ps, depth, "", "sec_io_desc_buf");
- if (!prs_uint32("size", ps, depth + 1, &dummy))
- return False;
- if (!prs_uint32("ptr", ps, depth + 1, &dummy))
- return False;
- }
-
- if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
- return False;
- if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u,
- prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
- depth++;
-
- if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
- return False;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
- prs_struct *ps, int depth)
-{
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
-
- prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
- depth++;
-
- /* reading */
- if (UNMARSHALLING(ps)) {
- il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
- if(il == NULL)
- return False;
- *q_u=il;
- }
- else {
- il=*q_u;
- }
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("cversion", ps, depth, &il->cversion))
- return False;
- if(!prs_uint32("name", ps, depth, &il->name_ptr))
- return False;
- if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
- return False;
- if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
- return False;
- if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
- return False;
- if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
- return False;
- if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
- return False;
- if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
- return False;
- if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
- return False;
- if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
- return False;
- if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if (il->dependentfiles_ptr)
- smb_io_buffer5("", &il->dependentfiles, ps, depth);
-
- return True;
-}
-
-/*******************************************************************
-parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
-********************************************************************/
-
-bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u,
- prs_struct *ps, int depth)
-{
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
-
- prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
- depth++;
-
- /* reading */
- if (UNMARSHALLING(ps)) {
- il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
- if(il == NULL)
- return False;
- *q_u=il;
- }
- else {
- il=*q_u;
- }
-
- if(!prs_align(ps))
- return False;
-
- /*
- * I know this seems weird, but I have no other explanation.
- * This is observed behavior on both NT4 and 2K servers.
- * --jerry
- */
-
- if (!prs_align_uint64(ps))
- return False;
-
- /* parse the main elements the packet */
-
- if(!prs_uint32("cversion ", ps, depth, &il->version))
- return False;
- if(!prs_uint32("name ", ps, depth, &il->name_ptr))
- return False;
- if(!prs_uint32("environment ", ps, depth, &il->environment_ptr))
- return False;
- if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr))
- return False;
- if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr))
- return False;
- if(!prs_uint32("configfile ", ps, depth, &il->configfile_ptr))
- return False;
- if(!prs_uint32("helpfile ", ps, depth, &il->helpfile_ptr))
- return False;
- if(!prs_uint32("monitorname ", ps, depth, &il->monitorname_ptr))
- return False;
- if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
- return False;
- if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
- return False;
- if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
- return False;
- if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_len))
- return False;
- if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_ptr))
- return False;
- if(!smb_io_time("driverdate ", &il->driverdate, ps, depth))
- return False;
- if(!prs_uint32("dummy4 ", ps, depth, &il->dummy4))
- return False;
- if(!prs_uint64("driverversion ", ps, depth, &il->driverversion))
- return False;
- if(!prs_uint32("mfgname ", ps, depth, &il->mfgname_ptr))
- return False;
- if(!prs_uint32("oemurl ", ps, depth, &il->oemurl_ptr))
- return False;
- if(!prs_uint32("hardwareid ", ps, depth, &il->hardwareid_ptr))
- return False;
- if(!prs_uint32("provider ", ps, depth, &il->provider_ptr))
- return False;
-
- /* parse the structures in the packet */
-
- if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if (il->dependentfiles_ptr) {
- if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- }
- if (il->previousnames_ptr) {
- if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- }
- if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- read a UNICODE array with null terminated strings
- and null terminated array
- and size of array at beginning
-********************************************************************/
-
-bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
-{
- if (buffer==NULL) return False;
-
- buffer->offset=0;
- buffer->uni_str_len=buffer->uni_max_len;
-
- if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
- return False;
-
- if(!prs_unistr2(True, "buffer ", ps, depth, buffer))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("level", ps, depth, &il->level))
- return False;
- if(!prs_uint32("ptr", ps, depth, &il->ptr))
- return False;
-
- if (il->ptr==0)
- return True;
-
- switch (il->level) {
- case 3:
- if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
- return False;
- break;
- case 6:
- if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
- return False;
- break;
- default:
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- init a SPOOL_Q_ADDPRINTERDRIVER struct
- ******************************************************************/
-
-bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
- SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name,
- uint32 level, PRINTER_DRIVER_CTR *info)
-{
- DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
-
- if (!srv_name || !info) {
- return False;
- }
-
- q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
- init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
-
- q_u->level = level;
-
- q_u->info.level = level;
- q_u->info.ptr = 1; /* Info is != NULL, see above */
- switch (level)
- {
- /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
- case 3 :
- make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
- break;
-
- default:
- DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
- break;
- }
-
- return True;
-}
-
-bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx,
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
- DRIVER_INFO_3 *info3)
-{
- uint32 len = 0;
- SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
-
- if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
- return False;
-
- inf->cversion = info3->version;
- inf->name_ptr = (info3->name.buffer!=NULL)?1:0;
- inf->environment_ptr = (info3->architecture.buffer!=NULL)?1:0;
- inf->driverpath_ptr = (info3->driverpath.buffer!=NULL)?1:0;
- inf->datafile_ptr = (info3->datafile.buffer!=NULL)?1:0;
- inf->configfile_ptr = (info3->configfile.buffer!=NULL)?1:0;
- inf->helpfile_ptr = (info3->helpfile.buffer!=NULL)?1:0;
- inf->monitorname_ptr = (info3->monitorname.buffer!=NULL)?1:0;
- inf->defaultdatatype_ptr = (info3->defaultdatatype.buffer!=NULL)?1:0;
-
- init_unistr2_from_unistr(inf, &inf->name, &info3->name);
- init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture);
- init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath);
- init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile);
- init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile);
- init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile);
- init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname);
- init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype);
-
- if (info3->dependentfiles) {
- bool done = False;
- bool null_char = False;
- uint16 *ptr = info3->dependentfiles;
-
- while (!done) {
- switch (*ptr) {
- case 0:
- /* the null_char bool is used to help locate
- two '\0's back to back */
- if (null_char) {
- done = True;
- } else {
- null_char = True;
- }
- break;
-
- default:
- null_char = False;
- break;
- }
- len++;
- ptr++;
- }
- }
-
- inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
- inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
- if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
- SAFE_FREE(inf);
- return False;
- }
-
- *spool_drv_info = inf;
-
- return True;
-}
-
-/*******************************************************************
make a BUFFER5 struct from a uint16*
******************************************************************/
@@ -4042,79 +2324,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16
}
/*******************************************************************
- fill in the prs_struct for a ADDPRINTERDRIVER request PDU
- ********************************************************************/
-
-bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
- return False;
- if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("info_level", ps, depth, &q_u->level))
- return False;
-
- if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
- depth++;
-
- if(!prs_werror("status", ps, depth, &q_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- ********************************************************************/
-
-bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
- NT_PRINTER_INFO_LEVEL_2 *d)
-{
- DEBUG(7,("Converting from UNICODE to ASCII\n"));
-
- d->attributes=uni->attributes;
- d->priority=uni->priority;
- d->default_priority=uni->default_priority;
- d->starttime=uni->starttime;
- d->untiltime=uni->untiltime;
- d->status=uni->status;
- d->cjobs=uni->cjobs;
-
- unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
- unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
- unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
- unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
- unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
- unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
- unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
- unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
- unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
- unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
- unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
-
- return True;
-}
-
-/*******************************************************************
********************************************************************/
bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
@@ -4619,170 +2828,6 @@ void free_job_info_2(JOB_INFO_2 *job)
free_devmode(job->devmode);
}
-#if 0 /* JERRY - not currently used but could be :-) */
-
-/*******************************************************************
- Deep copy a SPOOL_NOTIFY_INFO_DATA structure
- ******************************************************************/
-static bool copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst,
- SPOOL_NOTIFY_INFO_DATA *src, int n)
-{
- int i;
-
- memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
-
- for (i=0; i<n; i++) {
- int len;
- uint16 *s = NULL;
-
- if (src->size != POINTER)
- continue;
- len = src->notify_data.data.length;
- s = SMB_MALLOC_ARRAY(uint16, len);
- if (s == NULL) {
- DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
- return False;
- }
-
- memcpy(s, src->notify_data.data.string, len*2);
- dst->notify_data.data.string = s;
- }
-
- return True;
-}
-
-/*******************************************************************
- Deep copy a SPOOL_NOTIFY_INFO structure
- ******************************************************************/
-static bool copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
-{
- if (!dst) {
- DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
- return False;
- }
-
- dst->version = src->version;
- dst->flags = src->flags;
- dst->count = src->count;
-
- if (dst->count)
- {
- dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
-
- DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
- dst->count));
-
- if (dst->data == NULL) {
- DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n",
- dst->count));
- return False;
- }
-
- return (copy_spool_notify_info_data(dst->data, src->data, src->count));
- }
-
- return True;
-}
-#endif /* JERRY */
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
- uint32 change_low, uint32 change_high,
- SPOOL_NOTIFY_INFO *info)
-{
- if (q_u == NULL)
- return False;
-
- memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
-
- q_u->change_low=change_low;
- q_u->change_high=change_high;
-
- q_u->unknown0=0x0;
- q_u->unknown1=0x0;
-
- q_u->info_ptr=0x0FF0ADDE;
-
- q_u->info.version=2;
-
- if (info->count) {
- DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
- info->count));
- q_u->info.version = info->version;
- q_u->info.flags = info->flags;
- q_u->info.count = info->count;
- /* pointer field - be careful! */
- q_u->info.data = info->data;
- }
- else {
- q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
- q_u->info.count=0;
- }
-
- return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_Q_REPLY_RRPCN structure.
-********************************************************************/
-
-bool spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
- return False;
-
- if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
- return False;
-
- if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
- return False;
-
- if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
- return False;
-
- if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
- return False;
-
- if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
- return False;
-
- if(q_u->info_ptr!=0)
- if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Parse a SPOOL_R_REPLY_RRPCN structure.
-********************************************************************/
-
-bool spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
- return False;
-
- if (!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
/*******************************************************************
* read a structure.
********************************************************************/
@@ -5054,47 +3099,3 @@ bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
return True;
}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
- uint32 jobid, uint32 level, RPC_BUFFER *buffer,
- uint32 offered)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
- q_u->jobid = jobid;
- q_u->level = level;
- q_u->buffer = buffer;
- q_u->offered = offered;
-
- return True;
-}
-
-/*******************************************************************
- * init a structure.
- ********************************************************************/
-
-bool make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
- uint32 flags, uint32 options, const char *localmachine,
- uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
-{
- memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
-
- q_u->flags = flags;
- q_u->options = options;
-
- q_u->localmachine_ptr = 1;
-
- init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
-
- q_u->printerlocal = printerlocal;
-
- if (option)
- q_u->option_ptr = 1;
-
- q_u->option = option;
-
- return True;
-}
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index 697457888e..2f163a379f 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -706,7 +706,7 @@ NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClus
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r)
+NTSTATUS _eventlog_GetLogInformation(pipes_struct *p, struct eventlog_GetLogInformation *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index a38c717665..0c83144a90 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -990,13 +990,13 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p,
this to challenge/response for the auth subsystem to chew
on */
{
- const uint8 *chal;
+ uint8_t chal[8];
if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
return status;
}
- chal = auth_context->get_ntlm_challenge(auth_context);
+ auth_context->get_ntlm_challenge(auth_context, chal);
if (!make_user_info_netlogon_interactive(&user_info,
nt_username, nt_domain,
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 6dead2d264..33e89c8acb 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1171,13 +1171,12 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name,
struct np_write_state {
struct event_context *ev;
struct np_proxy_state *p;
- const uint8_t *data;
- size_t len;
+ struct iovec iov;
ssize_t nwritten;
};
static void np_write_trigger(struct async_req *req);
-static void np_write_done(struct async_req *subreq);
+static void np_write_done(struct tevent_req *subreq);
struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct fake_file_handle *handle,
@@ -1218,8 +1217,8 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
state->ev = ev;
state->p = p;
- state->data = data;
- state->len = len;
+ state->iov.iov_base = CONST_DISCARD(void *, data);
+ state->iov.iov_len = len;
if (!async_req_enqueue(p->write_queue, ev, result,
np_write_trigger)) {
@@ -1242,27 +1241,26 @@ static void np_write_trigger(struct async_req *req)
{
struct np_write_state *state = talloc_get_type_abort(
req->private_data, struct np_write_state);
- struct async_req *subreq;
+ struct tevent_req *subreq;
- subreq = sendall_send(state, state->ev, state->p->fd, state->data,
- state->len, 0);
+ subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1);
if (async_req_nomem(subreq, req)) {
return;
}
subreq->async.fn = np_write_done;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
}
-static void np_write_done(struct async_req *subreq)
+static void np_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct np_write_state *state = talloc_get_type_abort(
req->private_data, struct np_write_state);
ssize_t received;
int err;
- received = sendall_recv(subreq, &err);
+ received = writev_recv(subreq, &err);
if (received < 0) {
async_req_nterror(req, map_nt_error_from_unix(err));
return;
@@ -1316,7 +1314,7 @@ struct np_read_state {
};
static void np_read_trigger(struct async_req *req);
-static void np_read_done(struct async_req *subreq);
+static void np_read_done(struct tevent_req *subreq);
struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct fake_file_handle *handle,
@@ -1393,28 +1391,28 @@ static void np_read_trigger(struct async_req *req)
{
struct np_read_state *state = talloc_get_type_abort(
req->private_data, struct np_read_state);
- struct async_req *subreq;
+ struct tevent_req *subreq;
- subreq = read_pkt_send(state, state->ev, state->p->fd, RPC_HEADER_LEN,
- rpc_frag_more_fn, NULL);
+ subreq = read_packet_send(state, state->ev, state->p->fd,
+ RPC_HEADER_LEN, rpc_frag_more_fn, NULL);
if (async_req_nomem(subreq, req)) {
return;
}
subreq->async.fn = np_read_done;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
}
-static void np_read_done(struct async_req *subreq)
+static void np_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct np_read_state *state = talloc_get_type_abort(
req->private_data, struct np_read_state);
ssize_t received;
size_t thistime;
int err;
- received = read_pkt_recv(subreq, state->p, &state->p->msg, &err);
+ received = read_packet_recv(subreq, state->p, &state->p->msg, &err);
TALLOC_FREE(subreq);
if (received == -1) {
async_req_nterror(req, map_nt_error_from_unix(err));
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 7bb71ab89f..ee36f04c6d 100644
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -161,27 +161,7 @@ static bool api_spoolss_deleteprinterdriver(pipes_struct *p)
static bool api_spoolss_rffpcnex(pipes_struct *p)
{
- SPOOL_Q_RFFPCNEX q_u;
- SPOOL_R_RFFPCNEX 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 (!spoolss_io_q_rffpcnex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_rffpcnex: unable to unmarshall SPOOL_Q_RFFPCNEX.\n"));
- return False;
- }
-
- r_u.status = _spoolss_rffpcnex(p, &q_u, &r_u);
-
- if (!spoolss_io_r_rffpcnex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n"));
- return False;
- }
-
- return True;
+ return proxy_spoolss_call(p, NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX);
}
@@ -198,30 +178,7 @@ static bool api_spoolss_rffpcnex(pipes_struct *p)
static bool api_spoolss_rfnpcnex(pipes_struct *p)
{
- SPOOL_Q_RFNPCNEX q_u;
- SPOOL_R_RFNPCNEX 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 (!spoolss_io_q_rfnpcnex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_rfnpcnex: unable to unmarshall SPOOL_Q_RFNPCNEX.\n"));
- return False;
- }
-
- r_u.status = _spoolss_rfnpcnex(p, &q_u, &r_u);
-
- if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) {
- SAFE_FREE(r_u.info.data);
- DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n"));
- return False;
- }
-
- SAFE_FREE(r_u.info.data);
-
- return True;
+ return proxy_spoolss_call(p, NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY);
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 7439fe51a5..814f406e87 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -110,7 +110,7 @@ static int nt_printj_status(int v)
case LPQ_DELETED:
return JOB_STATUS_DELETED;
case LPQ_BLOCKED:
- return JOB_STATUS_BLOCKED;
+ return JOB_STATUS_BLOCKED_DEVQ;
case LPQ_USER_INTERVENTION:
return JOB_STATUS_USER_INTERVENTION;
}
@@ -130,19 +130,6 @@ static int nt_printq_status(int v)
return 0;
}
-/****************************************************************************
- Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
-****************************************************************************/
-
-static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
-{
- if (*pp == NULL)
- return;
-
- SAFE_FREE((*pp)->ctr.type);
- SAFE_FREE(*pp);
-}
-
/***************************************************************************
Disconnect from the client
****************************************************************************/
@@ -215,8 +202,7 @@ static int printer_entry_destructor(Printer_entry *Printer)
Printer->notify.options=0;
Printer->notify.localmachine[0]='\0';
Printer->notify.printerlocal=0;
- free_spool_notify_option(&Printer->notify.option);
- Printer->notify.option=NULL;
+ TALLOC_FREE(Printer->notify.option);
Printer->notify.client_connected=False;
free_nt_devicemode( &Printer->nt_devmode );
@@ -228,35 +214,6 @@ static int printer_entry_destructor(Printer_entry *Printer)
}
/****************************************************************************
- Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
-****************************************************************************/
-
-static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
-{
- SPOOL_NOTIFY_OPTION *new_sp = NULL;
-
- if (!sp)
- return NULL;
-
- new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
- if (!new_sp)
- return NULL;
-
- *new_sp = *sp;
-
- if (sp->ctr.count) {
- new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
-
- if (!new_sp->ctr.type) {
- SAFE_FREE(new_sp);
- return NULL;
- }
- }
-
- return new_sp;
-}
-
-/****************************************************************************
find printer index by handle
****************************************************************************/
@@ -633,7 +590,7 @@ static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
uint16 notify_field)
{
- SPOOL_NOTIFY_OPTION *option = p->notify.option;
+ struct spoolss_NotifyOption *option = p->notify.option;
uint32 i, j;
/*
@@ -655,13 +612,13 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
/* Check match for notify_type */
- if (option->ctr.type[i].type != notify_type)
+ if (option->types[i].type != notify_type)
continue;
/* Check match for field */
- for (j = 0; j < option->ctr.type[i].count; j++) {
- if (option->ctr.type[i].fields[j] == notify_field) {
+ for (j = 0; j < option->types[i].count; j++) {
+ if (option->types[i].fields[j] == notify_field) {
return True;
}
}
@@ -673,43 +630,93 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
return False;
}
-/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
+#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
+ _data->data.integer[0] = _integer; \
+ _data->data.integer[1] = 0;
+
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
+ _data->data.string.string = talloc_strdup(mem_ctx, _p); \
+ if (!_data->data.string.string) {\
+ _data->data.string.size = 0; \
+ } \
+ _data->data.string.size = strlen_m_term(_p) * 2;
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
+ _data->data.devmode.devmode = _devmode;
+
+#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
+ _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
+ if (!_data->data.sd.sd) { \
+ _data->data.sd.sd_size = 0; \
+ } \
+ _data->data.sd.sd_size = _size;
+
+static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
+ struct tm *t,
+ const char **pp,
+ uint32_t *plen)
+{
+ struct spoolss_Time st;
+ uint32_t len = 16;
+ char *p;
+
+ if (!init_systemtime(&st, t)) {
+ return;
+ }
+
+ p = talloc_array(mem_ctx, char, len);
+ if (!p) {
+ return;
+ }
+
+ /*
+ * Systemtime must be linearized as a set of UINT16's.
+ * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
+ */
+
+ SSVAL(p, 0, st.year);
+ SSVAL(p, 2, st.month);
+ SSVAL(p, 4, st.day_of_week);
+ SSVAL(p, 6, st.day);
+ SSVAL(p, 8, st.hour);
+ SSVAL(p, 10, st.minute);
+ SSVAL(p, 12, st.second);
+ SSVAL(p, 14, st.millisecond);
+
+ *pp = p;
+ *plen = len;
+}
+
+/* Convert a notification message to a struct spoolss_Notify */
static void notify_one_value(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = msg->notify.value[0];
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
}
static void notify_string(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- UNISTR2 unistr;
-
/* The length of the message includes the trailing \0 */
- init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
-
- data->notify_data.data.length = msg->len * 2;
- data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
-
- if (!data->notify_data.data.string) {
- data->notify_data.data.length = 0;
+ data->data.string.size = msg->len * 2;
+ data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
+ if (!data->data.string.string) {
+ data->data.string.size = 0;
return;
}
-
- memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
}
static void notify_system_time(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
TALLOC_CTX *mem_ctx)
{
- SYSTEMTIME systime;
- prs_struct ps;
+ data->data.string.string = NULL;
+ data->data.string.size = 0;
if (msg->len != sizeof(time_t)) {
DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
@@ -717,42 +724,15 @@ static void notify_system_time(struct spoolss_notify_msg *msg,
return;
}
- if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- DEBUG(5, ("notify_system_time: prs_init() failed\n"));
- return;
- }
-
- if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
- DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
- prs_mem_free(&ps);
- return;
- }
-
- if (!spoolss_io_system_time("", &ps, 0, &systime)) {
- prs_mem_free(&ps);
- return;
- }
-
- data->notify_data.data.length = prs_offset(&ps);
- if (prs_offset(&ps)) {
- data->notify_data.data.string = (uint16 *)
- TALLOC(mem_ctx, prs_offset(&ps));
- if (!data->notify_data.data.string) {
- prs_mem_free(&ps);
- return;
- }
- prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
- } else {
- data->notify_data.data.string = NULL;
- }
-
- prs_mem_free(&ps);
+ init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
+ &data->data.string.string,
+ &data->data.string.size);
}
struct notify2_message_table {
const char *name;
void (*fn)(struct spoolss_notify_msg *msg,
- SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
+ struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
};
static struct notify2_message_table printer_notify_table[] = {
@@ -966,9 +946,9 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
/* loop over all printers */
for (p = printers_list; p; p = p->next) {
- SPOOL_NOTIFY_INFO_DATA *data;
- uint32 data_len = 0;
- uint32 id;
+ struct spoolss_Notify *notifies;
+ uint32_t count = 0;
+ uint32_t id;
int i;
/* Is there notification on this handle? */
@@ -989,13 +969,11 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
/* allocate the max entries possible */
- data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
- if (!data) {
+ notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
+ if (!notifies) {
return;
}
- ZERO_STRUCTP(data);
-
/* build the array of change notifications */
sending_msg_count = 0;
@@ -1044,17 +1022,17 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
}
}
- construct_info_data( &data[data_len], msg->type, msg->field, id );
+ construct_info_data( &notifies[count], msg->type, msg->field, id );
switch(msg->type) {
case PRINTER_NOTIFY_TYPE:
if ( printer_notify_table[msg->field].fn )
- printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
+ printer_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
break;
case JOB_NOTIFY_TYPE:
if ( job_notify_table[msg->field].fn )
- job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
+ job_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
break;
default:
@@ -1062,12 +1040,46 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
goto done;
}
- data_len++;
+ count++;
}
if ( sending_msg_count ) {
- rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
- data_len, data, p->notify.change, 0 );
+ NTSTATUS status;
+ WERROR werr;
+ union spoolss_ReplyPrinterInfo info;
+ struct spoolss_NotifyInfo info0;
+ uint32_t reply_result;
+
+ info0.version = 0x2;
+ info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
+ info0.count = count;
+ info0.notifies = notifies;
+
+ info.info0 = &info0;
+
+ status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
+ &p->notify.client_hnd,
+ p->notify.change, /* color */
+ p->notify.flags,
+ &reply_result,
+ 0, /* reply_type, must be 0 */
+ info,
+ &werr);
+ if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
+ DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
+ notify_cli_pipe->srv_name_slash,
+ win_errstr(werr)));
+ }
+ switch (reply_result) {
+ case 0:
+ break;
+ case PRINTER_NOTIFY_INFO_DISCARDED:
+ case PRINTER_NOTIFY_INFO_DISCARDNOTED:
+ case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
+ break;
+ default:
+ break;
+ }
}
}
@@ -2830,26 +2842,73 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
return (W_ERROR_IS_OK(result));
}
-/********************************************************************
- * _spoolss_rffpcnex
- * ReplyFindFirstPrinterChangeNotifyEx
+/****************************************************************
+ ****************************************************************/
+
+static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
+ const struct spoolss_NotifyOption *r)
+{
+ struct spoolss_NotifyOption *option;
+ uint32_t i,k;
+
+ if (!r) {
+ return NULL;
+ }
+
+ option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
+ if (!option) {
+ return NULL;
+ }
+
+ *option = *r;
+
+ if (!option->count) {
+ return option;
+ }
+
+ option->types = talloc_zero_array(option,
+ struct spoolss_NotifyOptionType, option->count);
+ if (!option->types) {
+ talloc_free(option);
+ return NULL;
+ }
+
+ for (i=0; i < option->count; i++) {
+ option->types[i] = r->types[i];
+
+ if (option->types[i].count) {
+ option->types[i].fields = talloc_zero_array(option,
+ enum spoolss_Field, option->types[i].count);
+ if (!option->types[i].fields) {
+ talloc_free(option);
+ return NULL;
+ }
+ for (k=0; k<option->types[i].count; k++) {
+ option->types[i].fields[k] =
+ r->types[i].fields[k];
+ }
+ }
+ }
+
+ return option;
+}
+
+/****************************************************************
+ * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
*
* before replying OK: status=0 a rpc call is made to the workstation
* asking ReplyOpenPrinter
*
* in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
* called from api_spoolss_rffpcnex
- ********************************************************************/
+****************************************************************/
-WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
+WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
+ struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
{
- POLICY_HND *handle = &q_u->handle;
- uint32 flags = q_u->flags;
- uint32 options = q_u->options;
- UNISTR2 *localmachine = &q_u->localmachine;
- uint32 printerlocal = q_u->printerlocal;
+ POLICY_HND *handle = r->in.handle;
int snum = -1;
- SPOOL_NOTIFY_OPTION *option = q_u->option;
+ struct spoolss_NotifyOption *option = r->in.notify_options;
struct sockaddr_storage client_ss;
/* store the notify value in the printer struct */
@@ -2857,21 +2916,19 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
+ "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
- Printer->notify.flags=flags;
- Printer->notify.options=options;
- Printer->notify.printerlocal=printerlocal;
-
- if (Printer->notify.option)
- free_spool_notify_option(&Printer->notify.option);
+ Printer->notify.flags = r->in.flags;
+ Printer->notify.options = r->in.options;
+ Printer->notify.printerlocal = r->in.printer_local;
- Printer->notify.option=dup_spool_notify_option(option);
+ TALLOC_FREE(Printer->notify.option);
+ Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
- unistr2_to_ascii(Printer->notify.localmachine, localmachine,
- sizeof(Printer->notify.localmachine));
+ fstrcpy(Printer->notify.localmachine, r->in.local_machine);
/* Connect to the client machine and send a ReplyOpenPrinter */
@@ -2901,25 +2958,12 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
********************************************************************/
void spoolss_notify_server_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
}
/*******************************************************************
@@ -2927,14 +2971,11 @@ void spoolss_notify_server_name(int snum,
********************************************************************/
void spoolss_notify_printer_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
/* the notify name should not contain the \\server\ part */
char *p = strrchr(printer->info_2->printername, '\\');
@@ -2944,17 +2985,7 @@ void spoolss_notify_printer_name(int snum,
p++;
}
- len = rpcstr_push_talloc(mem_ctx, &temp, p);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
}
/*******************************************************************
@@ -2962,26 +2993,12 @@ void spoolss_notify_printer_name(int snum,
********************************************************************/
void spoolss_notify_share_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
-
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
}
/*******************************************************************
@@ -2989,27 +3006,12 @@ void spoolss_notify_share_name(int snum,
********************************************************************/
void spoolss_notify_port_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- /* even if it's strange, that's consistant in all the code */
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
}
/*******************************************************************
@@ -3018,25 +3020,12 @@ void spoolss_notify_port_name(int snum,
********************************************************************/
void spoolss_notify_driver_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
}
/*******************************************************************
@@ -3044,28 +3033,20 @@ void spoolss_notify_driver_name(int snum,
********************************************************************/
void spoolss_notify_comment(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- if (*printer->info_2->comment == '\0')
- len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
- else
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
+ char *p;
- if (len == (uint32)-1) {
- len = 0;
- }
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
+ if (*printer->info_2->comment == '\0') {
+ p = lp_comment(snum);
} else {
- data->notify_data.data.string = NULL;
+ p = printer->info_2->comment;
}
+
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
}
/*******************************************************************
@@ -3074,25 +3055,12 @@ void spoolss_notify_comment(int snum,
********************************************************************/
void spoolss_notify_location(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
}
/*******************************************************************
@@ -3101,14 +3069,13 @@ void spoolss_notify_location(int snum,
********************************************************************/
static void spoolss_notify_devmode(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
/* for a dummy implementation we have to zero the fields */
- data->notify_data.data.length = 0;
- data->notify_data.data.string = NULL;
+ SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
}
/*******************************************************************
@@ -3116,25 +3083,12 @@ static void spoolss_notify_devmode(int snum,
********************************************************************/
void spoolss_notify_sepfile(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
}
/*******************************************************************
@@ -3143,25 +3097,12 @@ void spoolss_notify_sepfile(int snum,
********************************************************************/
void spoolss_notify_print_processor(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
}
/*******************************************************************
@@ -3170,25 +3111,12 @@ void spoolss_notify_print_processor(int snum,
********************************************************************/
void spoolss_notify_parameters(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
}
/*******************************************************************
@@ -3197,25 +3125,12 @@ void spoolss_notify_parameters(int snum,
********************************************************************/
void spoolss_notify_datatype(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
}
/*******************************************************************
@@ -3225,13 +3140,14 @@ void spoolss_notify_datatype(int snum,
********************************************************************/
static void spoolss_notify_security_desc(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
- data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
+ SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
+ printer->info_2->secdesc_buf->sd_size,
+ printer->info_2->secdesc_buf->sd);
}
/*******************************************************************
@@ -3240,13 +3156,12 @@ static void spoolss_notify_security_desc(int snum,
********************************************************************/
void spoolss_notify_attributes(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->attributes;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
}
/*******************************************************************
@@ -3254,13 +3169,12 @@ void spoolss_notify_attributes(int snum,
********************************************************************/
static void spoolss_notify_priority(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->priority;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
}
/*******************************************************************
@@ -3268,13 +3182,12 @@ static void spoolss_notify_priority(int snum,
********************************************************************/
static void spoolss_notify_default_priority(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->default_priority;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
}
/*******************************************************************
@@ -3282,13 +3195,12 @@ static void spoolss_notify_default_priority(int snum,
********************************************************************/
static void spoolss_notify_start_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->starttime;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
}
/*******************************************************************
@@ -3296,13 +3208,12 @@ static void spoolss_notify_start_time(int snum,
********************************************************************/
static void spoolss_notify_until_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = printer->info_2->untiltime;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
}
/*******************************************************************
@@ -3310,7 +3221,7 @@ static void spoolss_notify_until_time(int snum,
********************************************************************/
static void spoolss_notify_status(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
@@ -3318,8 +3229,7 @@ static void spoolss_notify_status(int snum,
print_status_struct status;
print_queue_length(snum, &status);
- data->notify_data.value[0]=(uint32) status.status;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
}
/*******************************************************************
@@ -3327,13 +3237,12 @@ static void spoolss_notify_status(int snum,
********************************************************************/
void spoolss_notify_cjobs(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0] = print_queue_length(snum, NULL);
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
}
/*******************************************************************
@@ -3341,15 +3250,14 @@ void spoolss_notify_cjobs(int snum,
********************************************************************/
static void spoolss_notify_average_ppm(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
/* always respond 8 pages per minutes */
/* a little hard ! */
- data->notify_data.value[0] = printer->info_2->averageppm;
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
}
/*******************************************************************
@@ -3357,25 +3265,12 @@ static void spoolss_notify_average_ppm(int snum,
********************************************************************/
static void spoolss_notify_username(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
}
/*******************************************************************
@@ -3383,13 +3278,12 @@ static void spoolss_notify_username(int snum,
********************************************************************/
static void spoolss_notify_job_status(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=nt_printj_status(queue->status);
- data->notify_data.value[1] = 0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
}
/*******************************************************************
@@ -3397,25 +3291,12 @@ static void spoolss_notify_job_status(int snum,
********************************************************************/
static void spoolss_notify_job_name(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- smb_ucs2_t *temp = NULL;
- uint32 len;
-
- len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
}
/*******************************************************************
@@ -3423,7 +3304,7 @@ static void spoolss_notify_job_name(int snum,
********************************************************************/
static void spoolss_notify_job_status_string(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
@@ -3433,8 +3314,6 @@ static void spoolss_notify_job_status_string(int snum,
*/
const char *p = "";
- smb_ucs2_t *temp = NULL;
- uint32 len;
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
p = "unknown";
@@ -3455,17 +3334,7 @@ static void spoolss_notify_job_status_string(int snum,
}
#endif /* NO LONGER NEEDED. */
- len = rpcstr_push_talloc(mem_ctx, &temp, p);
- if (len == (uint32)-1) {
- len = 0;
- }
-
- data->notify_data.data.length = len;
- if (len) {
- data->notify_data.data.string = (uint16 *)temp;
- } else {
- data->notify_data.data.string = NULL;
- }
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
}
/*******************************************************************
@@ -3473,13 +3342,12 @@ static void spoolss_notify_job_status_string(int snum,
********************************************************************/
static void spoolss_notify_job_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=0x0;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
}
/*******************************************************************
@@ -3487,39 +3355,37 @@ static void spoolss_notify_job_time(int snum,
********************************************************************/
static void spoolss_notify_job_size(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->size;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
}
/*******************************************************************
* fill a notify_info_data with page info
********************************************************************/
static void spoolss_notify_total_pages(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->page_count;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
}
/*******************************************************************
* fill a notify_info_data with pages printed info.
********************************************************************/
static void spoolss_notify_pages_printed(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=0; /* Add code when back-end tracks this */
- data->notify_data.value[1]=0;
+ /* Add code when back-end tracks this */
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
}
/*******************************************************************
@@ -3527,13 +3393,12 @@ static void spoolss_notify_pages_printed(int snum,
********************************************************************/
static void spoolss_notify_job_position(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- data->notify_data.value[0]=queue->job;
- data->notify_data.value[1]=0;
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
}
/*******************************************************************
@@ -3541,53 +3406,27 @@ static void spoolss_notify_job_position(int snum,
********************************************************************/
static void spoolss_notify_submitted_time(int snum,
- SPOOL_NOTIFY_INFO_DATA *data,
+ struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- struct tm *t;
- uint32 len;
- SYSTEMTIME st;
- char *p;
+ data->data.string.string = NULL;
+ data->data.string.size = 0;
- t=gmtime(&queue->time);
+ init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
+ &data->data.string.string,
+ &data->data.string.size);
- len = sizeof(SYSTEMTIME);
-
- data->notify_data.data.length = len;
- data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
- if (!data->notify_data.data.string) {
- data->notify_data.data.length = 0;
- return;
- }
-
- make_systemtime(&st, t);
-
- /*
- * Systemtime must be linearized as a set of UINT16's.
- * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
- */
-
- p = (char *)data->notify_data.data.string;
- SSVAL(p, 0, st.year);
- SSVAL(p, 2, st.month);
- SSVAL(p, 4, st.dayofweek);
- SSVAL(p, 6, st.day);
- SSVAL(p, 8, st.hour);
- SSVAL(p, 10, st.minute);
- SSVAL(p, 12, st.second);
- SSVAL(p, 14, st.milliseconds);
}
struct s_notify_info_data_table
{
- uint16 type;
- uint16 field;
+ enum spoolss_NotifyType type;
+ enum spoolss_Field field;
const char *name;
- uint32 size;
- void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
+ enum spoolss_NotifyTable variable_type;
+ void (*fn) (int snum, struct spoolss_Notify *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
};
@@ -3598,86 +3437,70 @@ struct s_notify_info_data_table
static const struct s_notify_info_data_table notify_info_data_table[] =
{
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
-{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
-{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
-{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
+{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
+{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
};
/*******************************************************************
- Return the size of info_data structure.
+ Return the variable_type of info_data structure.
********************************************************************/
-static uint32 size_of_notify_info_data(uint16 type, uint16 field)
+static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
+ enum spoolss_Field field)
{
int i=0;
- for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
- if ( (notify_info_data_table[i].type == type)
- && (notify_info_data_table[i].field == field) ) {
- switch(notify_info_data_table[i].size) {
- case NOTIFY_ONE_VALUE:
- case NOTIFY_TWO_VALUE:
- return 1;
- case NOTIFY_STRING:
- return 2;
-
- /* The only pointer notify data I have seen on
- the wire is the submitted time and this has
- the notify size set to 4. -tpot */
-
- case NOTIFY_POINTER:
- return 4;
-
- case NOTIFY_SECDESC:
- return 5;
- }
+ for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
+ if ( (notify_info_data_table[i].type == type) &&
+ (notify_info_data_table[i].field == field) ) {
+ return notify_info_data_table[i].variable_type;
}
}
@@ -3686,31 +3509,16 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
return 0;
}
-/*******************************************************************
- Return the type of notify_info_data.
-********************************************************************/
-
-static uint32 type_of_notify_info_data(uint16 type, uint16 field)
-{
- uint32 i=0;
-
- for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
- if (notify_info_data_table[i].type == type &&
- notify_info_data_table[i].field == field)
- return notify_info_data_table[i].size;
- }
-
- return 0;
-}
-
/****************************************************************************
****************************************************************************/
-static bool search_notify(uint16 type, uint16 field, int *value)
+static bool search_notify(enum spoolss_NotifyType type,
+ enum spoolss_Field field,
+ int *value)
{
int i;
- for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
+ for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
if (notify_info_data_table[i].type == type &&
notify_info_data_table[i].field == field &&
notify_info_data_table[i].fn != NULL) {
@@ -3725,16 +3533,15 @@ static bool search_notify(uint16 type, uint16 field, int *value)
/****************************************************************************
****************************************************************************/
-void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
+void construct_info_data(struct spoolss_Notify *info_data,
+ enum spoolss_NotifyType type,
+ enum spoolss_Field field,
+ int id)
{
- info_data->type = type;
- info_data->field = field;
- info_data->reserved = 0;
-
- info_data->size = size_of_notify_info_data(type, field);
- info_data->enc_type = type_of_notify_info_data(type, field);
-
- info_data->id = id;
+ info_data->type = type;
+ info_data->field = field;
+ info_data->variable_type = variable_type_of_notify_info_data(type, field);
+ info_data->job_id = id;
}
/*******************************************************************
@@ -3743,29 +3550,31 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
*
********************************************************************/
-static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
- snum, SPOOL_NOTIFY_OPTION_TYPE
- *option_type, uint32 id,
+static bool construct_notify_printer_info(Printer_entry *print_hnd,
+ struct spoolss_NotifyInfo *info,
+ int snum,
+ const struct spoolss_NotifyOptionType *option_type,
+ uint32_t id,
TALLOC_CTX *mem_ctx)
{
int field_num,j;
- uint16 type;
- uint16 field;
+ enum spoolss_NotifyType type;
+ enum spoolss_Field field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ struct spoolss_Notify *current_data;
NT_PRINTER_INFO_LEVEL *printer = NULL;
print_queue_struct *queue=NULL;
- type=option_type->type;
+ type = option_type->type;
DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
- (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
+ (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
option_type->count, lp_servicename(snum)));
if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
return False;
- for(field_num=0; field_num<option_type->count; field_num++) {
+ for(field_num=0; field_num < option_type->count; field_num++) {
field = option_type->fields[field_num];
DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
@@ -3773,13 +3582,16 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
if (!search_notify(type, field, &j) )
continue;
- if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
+ info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
+ struct spoolss_Notify,
+ info->count + 1);
+ if (info->notifies == NULL) {
DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
free_a_printer(&printer, 2);
return False;
}
- current_data = &info->data[info->count];
+ current_data = &info->notifies[info->count];
construct_info_data(current_data, type, field, id);
@@ -3803,24 +3615,24 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
********************************************************************/
static bool construct_notify_jobs_info(print_queue_struct *queue,
- SPOOL_NOTIFY_INFO *info,
+ struct spoolss_NotifyInfo *info,
NT_PRINTER_INFO_LEVEL *printer,
- int snum, SPOOL_NOTIFY_OPTION_TYPE
- *option_type, uint32 id,
+ int snum,
+ const struct spoolss_NotifyOptionType *option_type,
+ uint32_t id,
TALLOC_CTX *mem_ctx)
{
int field_num,j;
- uint16 type;
- uint16 field;
-
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ enum spoolss_NotifyType type;
+ enum spoolss_Field field;
+ struct spoolss_Notify *current_data;
DEBUG(4,("construct_notify_jobs_info\n"));
type = option_type->type;
DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
- (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
+ (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
option_type->count));
for(field_num=0; field_num<option_type->count; field_num++) {
@@ -3829,12 +3641,15 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
if (!search_notify(type, field, &j) )
continue;
- if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
+ info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
+ struct spoolss_Notify,
+ info->count + 1);
+ if (info->notifies == NULL) {
DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
return False;
}
- current_data=&(info->data[info->count]);
+ current_data=&(info->notifies[info->count]);
construct_info_data(current_data, type, field, id);
notify_info_data_table[j].fn(snum, current_data, queue,
@@ -3876,25 +3691,26 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
********************************************************************/
static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
- SPOOL_NOTIFY_INFO *info,
+ struct spoolss_NotifyInfo *info,
TALLOC_CTX *mem_ctx)
{
int snum;
Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
int n_services=lp_numservices();
int i;
- SPOOL_NOTIFY_OPTION *option;
- SPOOL_NOTIFY_OPTION_TYPE *option_type;
+ struct spoolss_NotifyOption *option;
+ struct spoolss_NotifyOptionType option_type;
DEBUG(4,("printserver_notify_info\n"));
if (!Printer)
return WERR_BADFID;
- option=Printer->notify.option;
- info->version=2;
- info->data=NULL;
- info->count=0;
+ option = Printer->notify.option;
+
+ info->version = 2;
+ info->notifies = NULL;
+ info->count = 0;
/* a bug in xp sp2 rc2 causes it to send a fnpcn request without
sending a ffpcn() request first */
@@ -3903,15 +3719,15 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
return WERR_BADFID;
for (i=0; i<option->count; i++) {
- option_type=&(option->ctr.type[i]);
+ option_type = option->types[i];
- if (option_type->type!=PRINTER_NOTIFY_TYPE)
+ if (option_type.type != PRINTER_NOTIFY_TYPE)
continue;
for (snum=0; snum<n_services; snum++)
{
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
+ construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
}
}
@@ -3940,15 +3756,15 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
*
********************************************************************/
-static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
+static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
TALLOC_CTX *mem_ctx)
{
int snum;
Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
int i;
uint32 id;
- SPOOL_NOTIFY_OPTION *option;
- SPOOL_NOTIFY_OPTION_TYPE *option_type;
+ struct spoolss_NotifyOption *option;
+ struct spoolss_NotifyOptionType option_type;
int count,j;
print_queue_struct *queue=NULL;
print_status_struct status;
@@ -3958,11 +3774,12 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
if (!Printer)
return WERR_BADFID;
- option=Printer->notify.option;
+ option = Printer->notify.option;
id = 0x0;
- info->version=2;
- info->data=NULL;
- info->count=0;
+
+ info->version = 2;
+ info->notifies = NULL;
+ info->count = 0;
/* a bug in xp sp2 rc2 causes it to send a fnpcn request without
sending a ffpcn() request first */
@@ -3973,12 +3790,12 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
get_printer_snum(p, hnd, &snum, NULL);
for (i=0; i<option->count; i++) {
- option_type=&option->ctr.type[i];
+ option_type = option->types[i];
- switch ( option_type->type ) {
+ switch (option_type.type) {
case PRINTER_NOTIFY_TYPE:
if(construct_notify_printer_info(Printer, info, snum,
- option_type, id,
+ &option_type, id,
mem_ctx))
id--;
break;
@@ -3994,7 +3811,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
for (j=0; j<count; j++) {
construct_notify_jobs_info(&queue[j], info,
printer, snum,
- option_type,
+ &option_type,
queue[j].job,
mem_ctx);
}
@@ -4025,24 +3842,31 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
return WERR_OK;
}
-/********************************************************************
- * spoolss_rfnpcnex
- ********************************************************************/
+/****************************************************************
+ _spoolss_RouterRefreshPrinterChangeNotify
+****************************************************************/
-WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
+WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
+ struct spoolss_RouterRefreshPrinterChangeNotify *r)
{
- POLICY_HND *handle = &q_u->handle;
- SPOOL_NOTIFY_INFO *info = &r_u->info;
+ POLICY_HND *handle = r->in.handle;
+ struct spoolss_NotifyInfo *info;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
WERROR result = WERR_BADFID;
- /* we always have a NOTIFY_INFO struct */
- r_u->info_ptr=0x1;
+ /* we always have a spoolss_NotifyInfo struct */
+ info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
+ if (!info) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ *r->out.info = info;
if (!Printer) {
- DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
- OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
+ "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
goto done;
}
@@ -4061,11 +3885,13 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
Printer->notify.fnpcn = True;
if (Printer->notify.client_connected) {
- DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
- Printer->notify.change = q_u->change;
+ DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
+ "Saving change value in request [%x]\n",
+ r->in.change_low));
+ Printer->notify.change = r->in.change_low;
}
- /* just ignore the SPOOL_NOTIFY_OPTION */
+ /* just ignore the spoolss_NotifyOption */
switch (Printer->printer_type) {
case SPLHND_SERVER:
@@ -4527,10 +4353,10 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
strupper_m(guid_str);
init_unistr(&printer->guid, guid_str);
SAFE_FREE(guid_str);
- printer->action = SPOOL_DS_PUBLISH;
+ printer->action = DSPRINT_PUBLISH;
} else {
init_unistr(&printer->guid, "");
- printer->action = SPOOL_DS_UNPUBLISH;
+ printer->action = DSPRINT_UNPUBLISH;
}
return True;
@@ -6772,8 +6598,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
Printer->notify.options=0;
Printer->notify.localmachine[0]='\0';
Printer->notify.printerlocal=0;
- if (Printer->notify.option)
- free_spool_notify_option(&Printer->notify.option);
+ TALLOC_FREE(Printer->notify.option);
Printer->notify.client_connected=False;
return WERR_OK;
@@ -6793,6 +6618,10 @@ WERROR _spoolss_AddJob(pipes_struct *p,
/* this is what a NT server returns for AddJob. AddJob must fail on
* non-local printers */
+ if (r->in.level != 1) {
+ return WERR_UNKNOWN_LEVEL;
+ }
+
return WERR_INVALID_PARAM;
}
@@ -8233,45 +8062,106 @@ WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
/****************************************************************************
****************************************************************************/
-static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
+struct _spoolss_paths {
+ int type;
+ const char *share;
+ const char *dir;
+};
+
+enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
+
+static const struct _spoolss_paths spoolss_paths[]= {
+ { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
+ { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
+};
+
+static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
const char *servername,
const char *environment,
- struct spoolss_DriverDirectoryInfo1 *info1,
- uint32_t offered,
- uint32_t *needed)
+ int component,
+ char **path)
{
- char *path = NULL;
const char *pservername = NULL;
const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
const char *short_archi;
- if (environment) {
+ *path = NULL;
+
+ /* environment may be empty */
+ if (environment && strlen(environment)) {
long_archi = environment;
}
- pservername = canon_servername(servername);
+ /* servername may be empty */
+ if (servername && strlen(servername)) {
+ pservername = canon_servername(servername);
- if ( !is_myname_or_ipaddr(pservername))
- return WERR_INVALID_PARAM;
+ if (!is_myname_or_ipaddr(pservername)) {
+ return WERR_INVALID_PARAM;
+ }
+ }
- if (!(short_archi = get_short_archi(long_archi)))
+ if (!(short_archi = get_short_archi(long_archi))) {
return WERR_INVALID_ENVIRONMENT;
+ }
- path = talloc_asprintf(mem_ctx,
- "\\\\%s\\print$\\%s", pservername, short_archi);
- if (!path) {
+ switch (component) {
+ case SPOOLSS_PRTPROCS_PATH:
+ case SPOOLSS_DRIVER_PATH:
+ if (pservername) {
+ *path = talloc_asprintf(mem_ctx,
+ "\\\\%s\\%s\\%s",
+ pservername,
+ spoolss_paths[component].share,
+ short_archi);
+ } else {
+ *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
+ SPOOLSS_DEFAULT_SERVER_PATH,
+ spoolss_paths[component].dir,
+ short_archi);
+ }
+ break;
+ default:
+ return WERR_INVALID_PARAM;
+ }
+
+ if (!*path) {
return WERR_NOMEM;
}
+ return WERR_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *environment,
+ struct spoolss_DriverDirectoryInfo1 *r,
+ uint32_t offered,
+ uint32_t *needed)
+{
+ WERROR werr;
+ char *path = NULL;
+
+ werr = compose_spoolss_server_path(mem_ctx,
+ servername,
+ environment,
+ SPOOLSS_DRIVER_PATH,
+ &path);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
DEBUG(4,("printer driver directory: [%s]\n", path));
- info1->directory_name = path;
+ r->directory_name = path;
- *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
+ *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0);
if (*needed > offered) {
talloc_free(path);
- ZERO_STRUCTP(info1);
return WERR_INSUFFICIENT_BUFFER;
}
@@ -8293,28 +8183,21 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
return WERR_INVALID_PARAM;
}
- if (r->in.offered > MAX_RPC_DATA_SIZE) {
- return WERR_INVALID_PARAM;
- }
-
- DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
+ DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
+ r->in.level));
*r->out.needed = 0;
- switch (r->in.level) {
- case 1:
- werror = getprinterdriverdir_level_1(p->mem_ctx,
- r->in.server,
- r->in.environment,
- &r->out.info->info1,
- r->in.offered,
- r->out.needed);
- if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
- TALLOC_FREE(r->out.info);
- }
- break;
- default:
- return WERR_UNKNOWN_LEVEL;
+ /* r->in.level is ignored */
+
+ werror = getprinterdriverdir_level_1(p->mem_ctx,
+ r->in.server,
+ r->in.environment,
+ &r->out.info->info1,
+ r->in.offered,
+ r->out.needed);
+ if (!W_ERROR_IS_OK(werror)) {
+ TALLOC_FREE(r->out.info);
}
return werror;
@@ -9902,36 +9785,30 @@ done:
static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
const char *servername,
const char *environment,
- struct spoolss_PrintProcessorDirectoryInfo1 *info1,
+ struct spoolss_PrintProcessorDirectoryInfo1 *r,
uint32_t offered,
uint32_t *needed)
{
- const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
- const char *short_archi;
-
- if (environment) {
- long_archi = environment;
- }
+ WERROR werr;
+ char *path = NULL;
- short_archi = get_short_archi(long_archi);
- if (!short_archi) {
- return WERR_INVALID_ENVIRONMENT;
+ werr = compose_spoolss_server_path(mem_ctx,
+ servername,
+ environment,
+ SPOOLSS_PRTPROCS_PATH,
+ &path);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
}
- /* I think this should look like this - gd
- info1->directory_name = talloc_asprintf(mem_ctx,
- "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
- */
- info1->directory_name = talloc_strdup(mem_ctx,
- "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
+ DEBUG(4,("print processor directory: [%s]\n", path));
- if (!info1->directory_name) {
- return WERR_NOMEM;
- }
+ r->directory_name = path;
- *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
+ *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0);
if (*needed > offered) {
+ talloc_free(path);
return WERR_INSUFFICIENT_BUFFER;
}
@@ -9953,28 +9830,21 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
return WERR_INVALID_PARAM;
}
- if (r->in.offered > MAX_RPC_DATA_SIZE) {
- return WERR_INVALID_PARAM;
- }
-
- DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
+ DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
+ r->in.level));
*r->out.needed = 0;
- switch (r->in.level) {
- case 1:
- result = getprintprocessordirectory_level_1(p->mem_ctx,
- r->in.server,
- r->in.environment,
- &r->out.info->info1,
- r->in.offered,
- r->out.needed);
- if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
- TALLOC_FREE(r->out.info);
- }
- break;
- default:
- result = WERR_UNKNOWN_LEVEL;
+ /* r->in.level is ignored */
+
+ result = getprintprocessordirectory_level_1(p->mem_ctx,
+ r->in.server,
+ r->in.environment,
+ &r->out.info->info1,
+ r->in.offered,
+ r->out.needed);
+ if (!W_ERROR_IS_OK(result)) {
+ TALLOC_FREE(r->out.info);
}
return result;
@@ -10762,17 +10632,6 @@ WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
}
/****************************************************************
- _spoolss_RemoteFindFirstPrinterChangeNotifyEx
-****************************************************************/
-
-WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
- struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
_spoolss_RouterReplyPrinterEx
****************************************************************/
@@ -10784,17 +10643,6 @@ WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
}
/****************************************************************
- _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
-****************************************************************/
-
-WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
- struct spoolss_RouterRefreshPrinterChangeNotify *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
_spoolss_44
****************************************************************/
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 33bf3d0098..b90a189f7e 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -139,7 +139,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
SEC_ACE ace[2];
size_t i = 0;
SEC_DESC *sd;
- SEC_ACL *acl;
+ SEC_ACL *theacl;
size_t sd_size;
/* basic access for Everyone */
@@ -155,12 +155,12 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
/* create the security descriptor */
- if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
- acl, &sd_size)) )
+ theacl, &sd_size)) )
return NULL;
return sd;
diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c
index e212452e5d..d839bf4263 100644
--- a/source3/rpcclient/cmd_eventlog.c
+++ b/source3/rpcclient/cmd_eventlog.c
@@ -454,7 +454,7 @@ static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli,
return status;
}
- status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx,
+ status = rpccli_eventlog_GetLogInformation(cli, mem_ctx,
&handle,
0, /* level */
buffer,
@@ -472,7 +472,7 @@ static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli,
goto done;
}
- status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx,
+ status = rpccli_eventlog_GetLogInformation(cli, mem_ctx,
&handle,
0, /* level */
buffer,
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index 9955d2d3fa..45df488018 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -1107,6 +1107,49 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli,
return status;
}
+static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ struct netr_Authenticator credential;
+ struct netr_Authenticator return_authenticator;
+ union netr_Capabilities capabilities;
+ uint32_t level = 1;
+
+ if (argc > 2) {
+ fprintf(stderr, "Usage: %s <level>\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if (argc == 2) {
+ level = atoi(argv[1]);
+ }
+
+#if 0
+ netlogon_creds_client_step(cli->dc, &credential);
+#else
+ ZERO_STRUCT(credential);
+#endif
+
+ status = rpccli_netr_LogonGetCapabilities(cli, mem_ctx,
+ cli->desthost,
+ global_myname(),
+ &credential,
+ &return_authenticator,
+ level,
+ &capabilities);
+#if 0
+ if (!netlogon_creds_client_check(cli->dc,
+ &return_authenticator.cred)) {
+ DEBUG(0,("credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+#endif
+
+ return status;
+}
+
/* List of commands exported by this module */
struct cmd_set netlogon_commands[] = {
@@ -1134,6 +1177,7 @@ struct cmd_set netlogon_commands[] = {
{ "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" },
{ "getdcsitecoverage", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcsitecoverage, &ndr_table_netlogon.syntax_id, NULL, "Get the Site-Coverage from a DC", "" },
{ "database_redo", RPC_RTYPE_NTSTATUS, cmd_netlogon_database_redo, NULL, &ndr_table_netlogon.syntax_id, NULL, "Replicate single object from a DC", "" },
+ { "capabilities", RPC_RTYPE_NTSTATUS, cmd_netlogon_capabilities, NULL, &ndr_table_netlogon.syntax_id, NULL, "Return Capabilities", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index 31977e9554..936c2081f3 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -789,7 +789,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
struct samr_SamArray *dom_users = NULL;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
uint32 acb_mask = ACB_NORMAL;
- bool got_connect_pol = False, got_domain_pol = False;
if ((argc < 1) || (argc > 3)) {
printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
@@ -811,8 +810,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_connect_pol = True;
-
/* Get domain policy handle */
result = rpccli_samr_OpenDomain(cli, mem_ctx,
@@ -824,8 +821,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_domain_pol = True;
-
/* Enumerate domain users */
start_idx = 0;
@@ -852,10 +847,10 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
done:
- if (got_domain_pol)
+ if (is_valid_policy_hnd(&domain_pol))
rpccli_samr_Close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol)
+ if (is_valid_policy_hnd(&connect_pol))
rpccli_samr_Close(cli, mem_ctx, &connect_pol);
return result;
@@ -872,7 +867,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
uint32 start_idx, size, num_dom_groups, i;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
struct samr_SamArray *dom_groups = NULL;
- bool got_connect_pol = False, got_domain_pol = False;
if ((argc < 1) || (argc > 2)) {
printf("Usage: %s [access_mask]\n", argv[0]);
@@ -891,8 +885,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_connect_pol = True;
-
/* Get domain policy handle */
result = rpccli_samr_OpenDomain(cli, mem_ctx,
@@ -904,8 +896,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_domain_pol = True;
-
/* Enumerate domain groups */
start_idx = 0;
@@ -930,10 +920,10 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
done:
- if (got_domain_pol)
+ if (is_valid_policy_hnd(&domain_pol))
rpccli_samr_Close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol)
+ if (is_valid_policy_hnd(&connect_pol))
rpccli_samr_Close(cli, mem_ctx, &connect_pol);
return result;
@@ -950,7 +940,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
uint32 start_idx, size, num_als_groups, i;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
struct samr_SamArray *als_groups = NULL;
- bool got_connect_pol = False, got_domain_pol = False;
if ((argc < 2) || (argc > 3)) {
printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
@@ -969,8 +958,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_connect_pol = True;
-
/* Get domain policy handle */
result = get_domain_handle(cli, mem_ctx, argv[1],
@@ -982,8 +969,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- got_domain_pol = True;
-
/* Enumerate alias groups */
start_idx = 0;
@@ -1008,10 +993,10 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
done:
- if (got_domain_pol)
+ if (is_valid_policy_hnd(&domain_pol))
rpccli_samr_Close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol)
+ if (is_valid_policy_hnd(&connect_pol))
rpccli_samr_Close(cli, mem_ctx, &connect_pol);
return result;
@@ -1027,7 +1012,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx, size, num_entries, i;
uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- bool got_connect_pol = false;
struct samr_SamArray *sam = NULL;
if ((argc < 1) || (argc > 2)) {
@@ -1049,8 +1033,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
goto done;
}
- got_connect_pol = true;
-
/* Enumerate alias groups */
start_idx = 0;
@@ -1075,7 +1057,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli,
} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
done:
- if (got_connect_pol) {
+ if (is_valid_policy_hnd(&connect_pol)) {
rpccli_samr_Close(cli, mem_ctx, &connect_pol);
}
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 944bac7731..c68cf00530 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -283,12 +283,10 @@ static void display_print_info_3(PRINTER_INFO_3 *i3)
/****************************************************************************
****************************************************************************/
-static void display_print_info_7(PRINTER_INFO_7 *i7)
+static void display_print_info7(struct spoolss_PrinterInfo7 *r)
{
- fstring guid = "";
- rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE);
- printf("\tguid:[%s]\n", guid);
- printf("\taction:[0x%x]\n", i7->action);
+ printf("\tguid:[%s]\n", r->guid);
+ printf("\taction:[0x%x]\n", r->action);
}
@@ -469,10 +467,13 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
{
POLICY_HND pol;
WERROR result;
+ NTSTATUS status;
uint32 info_level = 2;
- bool opened_hnd = False;
- PRINTER_INFO_CTR ctr;
+ union spoolss_PrinterInfo info;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
const char *printername, *comment = NULL;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
if (argc == 1 || argc > 3) {
printf("Usage: %s printername comment\n", argv[0]);
@@ -485,6 +486,9 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
comment = argv[2];
}
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
/* get a printer handle */
@@ -495,26 +499,34 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ info_level,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result))
goto done;
/* Modify the comment. */
- init_unistr(&ctr.printers_2->comment, comment);
- ctr.printers_2->devmode = NULL;
- ctr.printers_2->secdesc = NULL;
+ info.info2.comment = comment;
- result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ info_ctr.level = 2;
+ info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
+
+ status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
+ &pol,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ 0, /* command */
+ &result);
if (W_ERROR_IS_OK(result))
printf("Success in setting comment.\n");
done:
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -529,11 +541,17 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
{
POLICY_HND pol;
WERROR result;
+ NTSTATUS status;
uint32 info_level = 2;
- bool opened_hnd = False;
- PRINTER_INFO_CTR ctr;
+ union spoolss_PrinterInfo info;
const char *printername,
*new_printername = NULL;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
if (argc == 1 || argc > 3) {
printf("Usage: %s printername new_printername\n", argv[0]);
@@ -556,25 +574,35 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ info_level,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result))
goto done;
/* Modify the printername. */
- init_unistr(&ctr.printers_2->printername, new_printername);
- ctr.printers_2->devmode = NULL;
- ctr.printers_2->secdesc = NULL;
-
- result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ info.info2.printername = new_printername;
+ info.info2.devmode = NULL;
+ info.info2.secdesc = NULL;
+
+ info_ctr.level = info_level;
+ info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
+
+ status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
+ &pol,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ 0, /* command */
+ &result);
if (W_ERROR_IS_OK(result))
printf("Success in setting printername.\n");
done:
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -590,9 +618,8 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
POLICY_HND pol;
WERROR result;
uint32 info_level = 1;
- bool opened_hnd = False;
- PRINTER_INFO_CTR ctr;
const char *printername;
+ union spoolss_PrinterInfo info;
if (argc == 1 || argc > 3) {
printf("Usage: %s <printername> [level]\n", argv[0]);
@@ -615,18 +642,19 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ info_level,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result))
goto done;
/* Display printer info */
-
switch (info_level) {
+#if 0 /* FIXME GD */
case 0:
display_print_info_0(ctr.printers_0);
break;
@@ -639,16 +667,16 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
case 3:
display_print_info_3(ctr.printers_3);
break;
+#endif
case 7:
- display_print_info_7(ctr.printers_7);
+ display_print_info7(&info.info7);
break;
default:
printf("unknown info level %d\n", info_level);
break;
}
-
done:
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -724,7 +752,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
{
POLICY_HND pol;
WERROR result;
- bool opened_hnd = False;
fstring printername;
const char *valuename;
REGISTRY_VALUE value;
@@ -753,8 +780,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
@@ -769,7 +794,7 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
done:
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -785,7 +810,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
POLICY_HND pol;
WERROR result;
NTSTATUS status;
- bool opened_hnd = False;
fstring printername;
const char *valuename, *keyname;
REGISTRY_VALUE value;
@@ -821,8 +845,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
@@ -870,7 +892,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
display_reg_value(value);
done:
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -989,6 +1011,68 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
/****************************************************************************
****************************************************************************/
+static void display_print_driver1(struct spoolss_DriverInfo1 *r)
+{
+ if (!r) {
+ return;
+ }
+
+ printf("Printer Driver Info 1:\n");
+ printf("\tDriver Name: [%s]\n\n", r->driver_name);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static void display_print_driver2(struct spoolss_DriverInfo2 *r)
+{
+ if (!r) {
+ return;
+ }
+
+ printf("Printer Driver Info 2:\n");
+ printf("\tVersion: [%x]\n", r->version);
+ printf("\tDriver Name: [%s]\n", r->driver_name);
+ printf("\tArchitecture: [%s]\n", r->architecture);
+ printf("\tDriver Path: [%s]\n", r->driver_path);
+ printf("\tDatafile: [%s]\n", r->data_file);
+ printf("\tConfigfile: [%s]\n\n", r->config_file);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static void display_print_driver3(struct spoolss_DriverInfo3 *r)
+{
+ int i;
+
+ if (!r) {
+ return;
+ }
+
+ printf("Printer Driver Info 3:\n");
+ printf("\tVersion: [%x]\n", r->version);
+ printf("\tDriver Name: [%s]\n", r->driver_name);
+ printf("\tArchitecture: [%s]\n", r->architecture);
+ printf("\tDriver Path: [%s]\n", r->driver_path);
+ printf("\tDatafile: [%s]\n", r->data_file);
+ printf("\tConfigfile: [%s]\n\n", r->config_file);
+ printf("\tHelpfile: [%s]\n\n", r->help_file);
+
+ for (i=0; r->dependent_files[i] != NULL; i++) {
+ printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
+ }
+
+ printf("\n");
+
+ printf("\tMonitorname: [%s]\n", r->monitor_name);
+ printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
@@ -996,11 +1080,12 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
POLICY_HND pol;
WERROR werror;
uint32 info_level = 3;
- bool opened_hnd = False;
- PRINTER_DRIVER_CTR ctr;
const char *printername;
uint32 i;
bool success = False;
+ union spoolss_DriverInfo info;
+ uint32_t server_major_version;
+ uint32_t server_minor_version;
if ((argc == 1) || (argc > 3))
{
@@ -1026,16 +1111,20 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
return werror;
}
- opened_hnd = True;
-
/* loop through and print driver info level for each architecture */
for (i=0; archi_table[i].long_archi!=NULL; i++) {
- werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
- archi_table[i].long_archi, archi_table[i].version,
- &ctr);
-
+ werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
+ &pol,
+ archi_table[i].long_archi,
+ info_level,
+ 0, /* offered */
+ archi_table[i].version,
+ 2,
+ &info,
+ &server_major_version,
+ &server_minor_version);
if (!W_ERROR_IS_OK(werror))
continue;
@@ -1047,13 +1136,13 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
switch (info_level) {
case 1:
- display_print_driver_1 (ctr.info1);
+ display_print_driver1(&info.info1);
break;
case 2:
- display_print_driver_2 (ctr.info2);
+ display_print_driver2(&info.info2);
break;
case 3:
- display_print_driver_3 (ctr.info3);
+ display_print_driver3(&info.info3);
break;
default:
printf("unknown info level %d\n", info_level);
@@ -1063,7 +1152,7 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
/* Cleanup */
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
if ( success )
@@ -1219,7 +1308,9 @@ static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
/****************************************************************************
****************************************************************************/
-void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
+static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
+ struct spoolss_AddDriverInfo3 *info,
+ const char *arch)
{
int i;
@@ -1229,7 +1320,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
if (strcmp(arch, archi_table[i].short_archi) == 0)
{
info->version = archi_table[i].version;
- init_unistr (&info->architecture, archi_table[i].long_archi);
+ info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
break;
}
}
@@ -1248,8 +1339,9 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
Needed to handle the empty parameter string denoted by "NULL"
*************************************************************************/
-static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest,
- char **saveptr)
+static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
+ const char *delim, const char **dest,
+ char **saveptr)
{
char *ptr;
@@ -1260,70 +1352,80 @@ static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest,
parameter because two consecutive delimiters
will not return an empty string. See man strtok(3)
for details */
- if (ptr && (StrCaseCmp(ptr, "NULL") == 0))
+ if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
ptr = NULL;
+ }
- if (dest != NULL)
- init_unistr(dest, ptr);
+ if (dest != NULL) {
+ *dest = talloc_strdup(mem_ctx, ptr);
+ }
return ptr;
}
/********************************************************************************
- fill in the members of a DRIVER_INFO_3 struct using a character
+ fill in the members of a spoolss_AddDriverInfo3 struct using a character
string in the form of
<Long Printer Name>:<Driver File Name>:<Data File Name>:\
<Config File Name>:<Help File Name>:<Language Monitor Name>:\
<Default Data Type>:<Comma Separated list of Files>
*******************************************************************************/
-static bool init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
- char *args )
+
+static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
+ char *args)
{
char *str, *str2;
- uint32 len, i;
+ int count = 0;
char *saveptr = NULL;
+ struct spoolss_StringArray *deps;
+ const char **file_array = NULL;
+ int i;
/* fill in the UNISTR fields */
- str = get_driver_3_param (args, ":", &info->name, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->driverpath, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->datafile, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->configfile, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->helpfile, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->monitorname, &saveptr);
- str = get_driver_3_param (NULL, ":", &info->defaultdatatype, &saveptr);
+ str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
+ str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
/* <Comma Separated List of Dependent Files> */
/* save the beginning of the string */
- str2 = get_driver_3_param (NULL, ":", NULL, &saveptr);
+ str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
str = str2;
/* begin to strip out each filename */
str = strtok_r(str, ",", &saveptr);
- len = 0;
- while (str != NULL)
- {
- /* keep a cumlative count of the str lengths */
- len += strlen(str)+1;
+
+ /* no dependent files, we are done */
+ if (!str) {
+ return true;
+ }
+
+ deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
+ if (!deps) {
+ return false;
+ }
+
+ while (str != NULL) {
+ add_string_to_array(deps, str, &file_array, &count);
str = strtok_r(NULL, ",", &saveptr);
}
- /* allocate the space; add one extra slot for a terminating NULL.
- Each filename is NULL terminated and the end contains a double
- NULL */
- if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL)
- {
- DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
- return False;
+ deps->string = talloc_zero_array(deps, const char *, count + 1);
+ if (!deps->string) {
+ return false;
}
- for (i=0; i<len; i++)
- {
- SSVAL(&info->dependentfiles[i], 0, str2[i]);
+
+ for (i=0; i < count; i++) {
+ deps->string[i] = file_array[i];
}
- info->dependentfiles[len] = '\0';
- return True;
-}
+ r->dependent_files = deps;
+ return true;
+}
/****************************************************************************
****************************************************************************/
@@ -1333,11 +1435,11 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
int argc, const char **argv)
{
WERROR result;
+ NTSTATUS status;
uint32 level = 3;
- PRINTER_DRIVER_CTR ctr;
- DRIVER_INFO_3 info3;
+ struct spoolss_AddDriverInfoCtr info_ctr;
+ struct spoolss_AddDriverInfo3 info3;
const char *arch;
- fstring driver_name;
char *driver_args;
/* parse the command arguments */
@@ -1352,15 +1454,16 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
return WERR_OK;
}
- /* Fill in the DRIVER_INFO_3 struct */
+ /* Fill in the spoolss_AddDriverInfo3 struct */
ZERO_STRUCT(info3);
- if (!(arch = cmd_spoolss_get_short_archi(argv[1])))
- {
+
+ arch = cmd_spoolss_get_short_archi(argv[1]);
+ if (!arch) {
printf ("Error Unknown architechture [%s]\n", argv[1]);
return WERR_INVALID_PARAM;
}
- else
- set_drv_info_3_env(&info3, arch);
+
+ set_drv_info_3_env(mem_ctx, &info3, arch);
driver_args = talloc_strdup( mem_ctx, argv[2] );
if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
@@ -1378,14 +1481,19 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
}
- ctr.info3 = &info3;
- result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
+ info_ctr.level = level;
+ info_ctr.info.info3 = &info3;
+ status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
+ cli->srv_name_slash,
+ &info_ctr,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ntstatus_to_werror(status);
+ }
if (W_ERROR_IS_OK(result)) {
- rpcstr_pull(driver_name, info3.name.buffer,
- sizeof(driver_name), -1, STR_TERMINATE);
printf ("Printer Driver %s successfully installed.\n",
- driver_name);
+ info3.driver_name);
}
return result;
@@ -1400,14 +1508,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
int argc, const char **argv)
{
WERROR result;
- NTSTATUS status;
struct spoolss_SetPrinterInfoCtr info_ctr;
struct spoolss_SetPrinterInfo2 info2;
- struct policy_handle handle;
- struct spoolss_DevmodeContainer devmode_ctr;
- struct sec_desc_buf sd;
- struct spoolss_UserLevelCtr userlevel_ctr;
- struct spoolss_UserLevel1 level1;
/* parse the command arguments */
if (argc != 5)
@@ -1417,9 +1519,7 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
}
/* Fill in the DRIVER_INFO_2 struct */
- ZERO_STRUCT(devmode_ctr);
ZERO_STRUCT(info2);
- ZERO_STRUCT(sd);
info2.printername = argv[1];
info2.drivername = argv[3];
@@ -1447,25 +1547,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
info_ctr.level = 2;
info_ctr.info.info2 = &info2;
- level1.size = 28; /* wild guess */
- level1.build = 1381;
- level1.major = 2;
- level1.minor = 0;
- level1.processor = 0;
- level1.client = global_myname();
- level1.user = cli->auth->user_name;
-
- userlevel_ctr.level = 1;
- userlevel_ctr.user_info.level1 = &level1;
-
- status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
- cli->srv_name_slash,
- &info_ctr,
- &devmode_ctr,
- &sd,
- &userlevel_ctr,
- &handle,
- &result);
+ result = rpccli_spoolss_addprinterex(cli, mem_ctx,
+ &info_ctr);
if (W_ERROR_IS_OK(result))
printf ("Printer %s successfully installed.\n", argv[1]);
@@ -1481,11 +1564,16 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
{
POLICY_HND pol;
WERROR result;
+ NTSTATUS status;
uint32 level = 2;
- bool opened_hnd = False;
- PRINTER_INFO_CTR ctr;
- PRINTER_INFO_2 info2;
const char *printername;
+ union spoolss_PrinterInfo info;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
/* parse the command arguments */
if (argc != 3)
@@ -1505,15 +1593,13 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
/* Get printer info */
- ZERO_STRUCT (info2);
- ctr.printers_2 = &info2;
-
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ level,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result)) {
printf ("Unable to retrieve printer information!\n");
goto done;
@@ -1521,10 +1607,17 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
/* Set the printer driver */
- init_unistr(&ctr.printers_2->drivername, argv[2]);
-
- result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
-
+ info.info2.drivername = argv[2];
+ info_ctr.level = 2;
+ info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
+
+ status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
+ &pol,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ 0, /* command */
+ &result);
if (!W_ERROR_IS_OK(result)) {
printf("SetPrinter call failed!\n");
goto done;;
@@ -1535,7 +1628,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
done:
/* Cleanup */
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -1719,14 +1812,15 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
WERROR werror;
NTSTATUS status;
const char *printername;
- bool got_handle = False;
union spoolss_AddFormInfo info;
struct spoolss_AddFormInfo1 info1;
+ struct spoolss_AddFormInfo2 info2;
+ uint32_t level = 1;
/* Parse the command arguments */
- if (argc != 3) {
- printf ("Usage: %s <printer> <formname>\n", argv[0]);
+ if (argc < 3 || argc > 5) {
+ printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
return WERR_OK;
}
@@ -1741,32 +1835,58 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
if (!W_ERROR_IS_OK(werror))
goto done;
- got_handle = True;
-
/* Dummy up some values for the form data */
- info1.flags = FORM_USER;
- info1.form_name = argv[2];
- info1.size.width = 100;
- info1.size.height = 100;
- info1.area.left = 0;
- info1.area.top = 10;
- info1.area.right = 20;
- info1.area.bottom = 30;
+ if (argc == 4) {
+ level = atoi(argv[3]);
+ }
- info.info1 = &info1;
+ switch (level) {
+ case 1:
+ info1.flags = FORM_USER;
+ info1.form_name = argv[2];
+ info1.size.width = 100;
+ info1.size.height = 100;
+ info1.area.left = 0;
+ info1.area.top = 10;
+ info1.area.right = 20;
+ info1.area.bottom = 30;
+
+ info.info1 = &info1;
+
+ break;
+ case 2:
+ info2.flags = FORM_USER;
+ info2.form_name = argv[2];
+ info2.size.width = 100;
+ info2.size.height = 100;
+ info2.area.left = 0;
+ info2.area.top = 10;
+ info2.area.right = 20;
+ info2.area.bottom = 30;
+ info2.keyword = argv[2];
+ info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
+ info2.mui_dll = NULL;
+ info2.ressource_id = 0;
+ info2.display_name = argv[2];
+ info2.lang_id = 0;
+
+ info.info2 = &info2;
+
+ break;
+ }
/* Add the form */
status = rpccli_spoolss_AddForm(cli, mem_ctx,
&handle,
- 1,
+ level,
info,
&werror);
done:
- if (got_handle)
+ if (is_valid_policy_hnd(&handle))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
return werror;
@@ -1782,7 +1902,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
WERROR werror;
NTSTATUS status;
const char *printername;
- bool got_handle = False;
union spoolss_AddFormInfo info;
struct spoolss_AddFormInfo1 info1;
@@ -1804,8 +1923,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
if (!W_ERROR_IS_OK(werror))
goto done;
- got_handle = True;
-
/* Dummy up some values for the form data */
info1.flags = FORM_PRINTER;
@@ -1829,7 +1946,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
&werror);
done:
- if (got_handle)
+ if (is_valid_policy_hnd(&handle))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
return werror;
@@ -1891,6 +2008,28 @@ static void display_form_info1(struct spoolss_FormInfo1 *r)
/****************************************************************************
****************************************************************************/
+static void display_form_info2(struct spoolss_FormInfo2 *r)
+{
+ printf("%s\n" \
+ "\tflag: %s (%d)\n" \
+ "\twidth: %d, length: %d\n" \
+ "\tleft: %d, right: %d, top: %d, bottom: %d\n",
+ r->form_name, get_form_flag(r->flags), r->flags,
+ r->size.width, r->size.height,
+ r->area.left, r->area.right,
+ r->area.top, r->area.bottom);
+ printf("\tkeyword: %s\n", r->keyword);
+ printf("\tstring_type: 0x%08x\n", r->string_type);
+ printf("\tmui_dll: %s\n", r->mui_dll);
+ printf("\tressource_id: 0x%08x\n", r->ressource_id);
+ printf("\tdisplay_name: %s\n", r->display_name);
+ printf("\tlang_id: %d\n", r->lang_id);
+ printf("\n");
+}
+
+/****************************************************************************
+****************************************************************************/
+
static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1898,16 +2037,16 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
WERROR werror;
NTSTATUS status;
const char *printername;
- bool got_handle = False;
DATA_BLOB buffer;
uint32_t offered = 0;
union spoolss_FormInfo info;
uint32_t needed;
+ uint32_t level = 1;
/* Parse the command arguments */
- if (argc != 3) {
- printf ("Usage: %s <printer> <formname>\n", argv[0]);
+ if (argc < 3 || argc > 5) {
+ printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
return WERR_OK;
}
@@ -1922,26 +2061,28 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
if (!W_ERROR_IS_OK(werror))
goto done;
- got_handle = True;
+ if (argc == 4) {
+ level = atoi(argv[3]);
+ }
/* Get the form */
status = rpccli_spoolss_GetForm(cli, mem_ctx,
&handle,
argv[2],
- 1,
+ level,
NULL,
offered,
&info,
&needed,
&werror);
if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
- buffer = data_blob_talloc(mem_ctx, NULL, needed);
+ buffer = data_blob_talloc_zero(mem_ctx, needed);
offered = needed;
status = rpccli_spoolss_GetForm(cli, mem_ctx,
&handle,
argv[2],
- 1,
+ level,
&buffer,
offered,
&info,
@@ -1953,9 +2094,17 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c
return werror;
}
- display_form_info1(&info.info1);
+ switch (level) {
+ case 1:
+ display_form_info1(&info.info1);
+ break;
+ case 2:
+ display_form_info2(&info.info2);
+ break;
+ }
+
done:
- if (got_handle)
+ if (is_valid_policy_hnd(&handle))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
return werror;
@@ -1972,7 +2121,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
WERROR werror;
NTSTATUS status;
const char *printername;
- bool got_handle = False;
/* Parse the command arguments */
@@ -1992,8 +2140,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(werror))
goto done;
- got_handle = True;
-
/* Delete the form */
status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
@@ -2005,7 +2151,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
}
done:
- if (got_handle)
+ if (is_valid_policy_hnd(&handle))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
return werror;
@@ -2021,7 +2167,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
POLICY_HND handle;
WERROR werror;
const char *printername;
- bool got_handle = False;
uint32 num_forms, level = 1, i;
FORM_1 *forms;
@@ -2043,8 +2188,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(werror))
goto done;
- got_handle = True;
-
/* Enumerate forms */
werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
@@ -2061,7 +2204,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
}
done:
- if (got_handle)
+ if (is_valid_policy_hnd(&handle))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
return werror;
@@ -2077,9 +2220,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
WERROR result;
const char *printername;
POLICY_HND pol;
- bool opened_hnd = False;
- PRINTER_INFO_CTR ctr;
- PRINTER_INFO_0 info;
+ union spoolss_PrinterInfo info;
REGISTRY_VALUE value;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
@@ -2127,17 +2268,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- opened_hnd = True;
-
- ctr.printers_0 = &info;
-
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ 0,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result))
goto done;
printf("%s\n", current_timestring(tmp_ctx, True));
- printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id);
+ printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
/* Set the printer data */
@@ -2217,18 +2357,21 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
}
printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
- result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
-
+ result = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &pol,
+ 0,
+ 0,
+ &info);
if (!W_ERROR_IS_OK(result))
goto done;
printf("%s\n", current_timestring(tmp_ctx, True));
- printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id);
+ printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
done:
/* cleanup */
TALLOC_FREE(tmp_ctx);
- if (opened_hnd)
+ if (is_valid_policy_hnd(&pol))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
return result;
@@ -2279,13 +2422,53 @@ static void display_job_info_2(JOB_INFO_2 *job)
/****************************************************************************
****************************************************************************/
+static void display_job_info1(struct spoolss_JobInfo1 *r)
+{
+ printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
+ r->user_name, r->document_name, r->text_status, r->pages_printed,
+ r->total_pages);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static void display_job_info2(struct spoolss_JobInfo2 *r)
+{
+ printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
+ r->position, r->job_id,
+ r->user_name, r->document_name, r->text_status, r->pages_printed,
+ r->total_pages, r->size);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static void display_job_info3(struct spoolss_JobInfo3 *r)
+{
+ printf("jobid[%d], next_jobid[%d]\n",
+ r->job_id, r->next_job_id);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static void display_job_info4(struct spoolss_JobInfo4 *r)
+{
+ printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
+ r->position, r->job_id,
+ r->user_name, r->document_name, r->text_status, r->pages_printed,
+ r->total_pages, r->size, r->size_high);
+}
+
+/****************************************************************************
+****************************************************************************/
+
static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
WERROR result;
uint32 level = 1, num_jobs, i;
- bool got_hnd = False;
const char *printername;
POLICY_HND hnd;
JOB_INFO_CTR ctr;
@@ -2309,8 +2492,6 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- got_hnd = True;
-
/* Enumerate ports */
result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
@@ -2334,12 +2515,89 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
}
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
+ rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+
+ return result;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ WERROR result;
+ const char *printername;
+ struct policy_handle hnd;
+ uint32_t job_id;
+ uint32_t level = 1;
+ union spoolss_JobInfo info;
+
+ if (argc < 3 || argc > 4) {
+ printf("Usage: %s printername job_id [level]\n", argv[0]);
+ return WERR_OK;
+ }
+
+ job_id = atoi(argv[2]);
+
+ if (argc == 4) {
+ level = atoi(argv[3]);
+ }
+
+ /* Open printer handle */
+
+ RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
+
+ result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
+ printername,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Enumerate ports */
+
+ result = rpccli_spoolss_getjob(cli, mem_ctx,
+ &hnd,
+ job_id,
+ level,
+ 0,
+ &info);
+
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+
+ switch (level) {
+ case 1:
+ display_job_info1(&info.info1);
+ break;
+ case 2:
+ display_job_info2(&info.info2);
+ break;
+ case 3:
+ display_job_info3(&info.info3);
+ break;
+ case 4:
+ display_job_info4(&info.info4);
+ break;
+ default:
+ d_printf("unknown info level %d\n", level);
+ break;
+ }
+
+done:
+ if (is_valid_policy_hnd(&hnd)) {
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
+ }
return result;
}
+
/****************************************************************************
****************************************************************************/
@@ -2349,7 +2607,6 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
{
WERROR result;
uint32 i=0, val_needed, data_needed;
- bool got_hnd = False;
const char *printername;
POLICY_HND hnd;
@@ -2369,8 +2626,6 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- got_hnd = True;
-
/* Enumerate data */
result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
@@ -2388,7 +2643,7 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
result = W_ERROR(ERRsuccess);
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
return result;
@@ -2403,7 +2658,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
{
WERROR result;
uint32 i;
- bool got_hnd = False;
const char *printername;
const char *keyname = NULL;
POLICY_HND hnd;
@@ -2427,8 +2681,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- got_hnd = True;
-
/* Enumerate subkeys */
if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
@@ -2446,7 +2698,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
TALLOC_FREE( ctr );
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
return result;
@@ -2460,7 +2712,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
const char **argv)
{
WERROR result;
- bool got_hnd = False;
const char *printername;
const char *keyname = NULL;
POLICY_HND hnd;
@@ -2487,8 +2738,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
if (!W_ERROR_IS_OK(result))
goto done;
- got_hnd = True;
-
/* Enumerate subkeys */
result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
@@ -2512,7 +2761,7 @@ done:
SAFE_FREE(keylist);
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
return result;
@@ -2526,8 +2775,8 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
const char **argv)
{
const char *printername;
+ const char *clientname;
POLICY_HND hnd;
- bool got_hnd = False;
WERROR result;
NTSTATUS status;
struct spoolss_NotifyOption option;
@@ -2551,8 +2800,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
goto done;
}
- got_hnd = True;
-
/* Create spool options */
option.version = 2;
@@ -2582,13 +2829,19 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
}
option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
+ clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+ if (!clientname) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
/* Send rffpcnex */
status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
&hnd,
0,
0,
- cli->srv_name_slash,
+ clientname,
123,
&option,
&result);
@@ -2598,7 +2851,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
}
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
return result;
@@ -2610,12 +2863,16 @@ done:
static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
{
- PRINTER_INFO_CTR ctr1, ctr2;
+ union spoolss_PrinterInfo info1, info2;
WERROR werror;
TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
printf("Retrieving printer propertiesfor %s...", cli1->desthost);
- werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1);
+ werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
+ hnd1,
+ 2,
+ 0,
+ &info1);
if ( !W_ERROR_IS_OK(werror) ) {
printf("failed (%s)\n", win_errstr(werror));
talloc_destroy(mem_ctx);
@@ -2624,7 +2881,11 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
printf("ok\n");
printf("Retrieving printer properties for %s...", cli2->desthost);
- werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2);
+ werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
+ hnd2,
+ 2,
+ 0,
+ &info2);
if ( !W_ERROR_IS_OK(werror) ) {
printf("failed (%s)\n", win_errstr(werror));
talloc_destroy(mem_ctx);
@@ -2643,7 +2904,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
{
- PRINTER_INFO_CTR ctr1, ctr2;
+ union spoolss_PrinterInfo info1, info2;
WERROR werror;
TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
SEC_DESC *sd1, *sd2;
@@ -2651,7 +2912,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
printf("Retrieving printer security for %s...", cli1->desthost);
- werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1);
+ werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
+ hnd1,
+ 3,
+ 0,
+ &info1);
if ( !W_ERROR_IS_OK(werror) ) {
printf("failed (%s)\n", win_errstr(werror));
result = False;
@@ -2660,7 +2925,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
printf("ok\n");
printf("Retrieving printer security for %s...", cli2->desthost);
- werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2);
+ werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
+ hnd2,
+ 3,
+ 0,
+ &info2);
if ( !W_ERROR_IS_OK(werror) ) {
printf("failed (%s)\n", win_errstr(werror));
result = False;
@@ -2671,14 +2940,8 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h
printf("++ ");
- if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) {
- printf("NULL PRINTER_INFO_3!\n");
- result = False;
- goto done;
- }
-
- sd1 = ctr1.printers_3->secdesc;
- sd2 = ctr2.printers_3->secdesc;
+ sd1 = info1.info3.secdesc;
+ sd2 = info2.info3.secdesc;
if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
printf("NULL secdesc!\n");
@@ -2809,6 +3072,7 @@ struct cmd_set spoolss_commands[] = {
{ "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" },
{ "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" },
{ "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" },
+ { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &syntax_spoolss, NULL, "Get print job", "" },
{ "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" },
{ "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" },
{ "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" },
diff --git a/source3/services/services_db.c b/source3/services/services_db.c
index 6d1b5d5b95..7a4b90c7cf 100644
--- a/source3/services/services_db.c
+++ b/source3/services/services_db.c
@@ -91,7 +91,7 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
SEC_ACE ace[4];
size_t i = 0;
SEC_DESC *sd = NULL;
- SEC_ACL *acl = NULL;
+ SEC_ACL *theacl = NULL;
size_t sd_size;
/* basic access for Everyone */
@@ -109,12 +109,12 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
/* create the security descriptor */
- if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ if ( !(theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
if ( !(sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
- acl, &sd_size)) )
+ theacl, &sd_size)) )
return NULL;
return sd;
@@ -332,14 +332,14 @@ static void fill_service_values( const char *name, REGVAL_CTR *values )
/********************************************************************
********************************************************************/
-static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
+static void add_new_svc_name( REGISTRY_KEY *key_parent, struct regsubkey_ctr *subkeys,
const char *name )
{
REGISTRY_KEY *key_service = NULL, *key_secdesc = NULL;
WERROR wresult;
char *path = NULL;
REGVAL_CTR *values = NULL;
- REGSUBKEY_CTR *svc_subkeys = NULL;
+ struct regsubkey_ctr *svc_subkeys = NULL;
SEC_DESC *sd = NULL;
DATA_BLOB sd_blob;
NTSTATUS status;
@@ -366,7 +366,8 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
/* add the 'Security' key */
- if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) {
+ wresult = regsubkey_ctr_init(key_service, &svc_subkeys);
+ if (!W_ERROR_IS_OK(wresult)) {
DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
TALLOC_FREE( key_service );
return;
@@ -444,7 +445,7 @@ void svcctl_init_keys( void )
{
const char **service_list = lp_svcctl_list();
int i;
- REGSUBKEY_CTR *subkeys = NULL;
+ struct regsubkey_ctr *subkeys = NULL;
REGISTRY_KEY *key = NULL;
WERROR wresult;
@@ -461,7 +462,8 @@ void svcctl_init_keys( void )
/* lookup the available subkeys */
- if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
+ wresult = regsubkey_ctr_init(key, &subkeys);
+ if (!W_ERROR_IS_OK(wresult)) {
DEBUG(0,("svcctl_init_keys: talloc() failed!\n"));
TALLOC_FREE( key );
return;
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 78b8123680..d23b509af2 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -471,6 +471,7 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
SMB_STRUCT_STAT sbuf;
struct smb_file_time ft;
NTSTATUS status;
+ int ret = -1;
ZERO_STRUCT(sbuf);
ZERO_STRUCT(ft);
@@ -485,15 +486,19 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf) == -1) {
- return map_nt_error_from_unix(errno);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name,&sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf);
}
}
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
if (!VALID_STAT(sbuf)) {
/* if it doesn't seem to be a real file */
return NT_STATUS_OK;
@@ -581,6 +586,13 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
*/
saved_status4 = update_write_time_on_close(fsp);
+ if (NT_STATUS_EQUAL(saved_status4, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ /* Someone renamed the file or a parent directory containing
+ * this file. We can't do anything about this, we don't have
+ * an "update timestamp by fd" call in POSIX. Eat the error. */
+
+ saved_status4 = NT_STATUS_OK;
+ }
if (NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_IS_OK(saved_status1)) {
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index a9a97a2d14..adf664b396 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -256,10 +256,9 @@ ssize_t write_file(struct smb_request *req,
int write_path = -1;
if (fsp->print_file) {
- fstring sharename;
uint32 jobid;
- if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
+ if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n",
(unsigned int)fsp->rap_print_jobid ));
errno = EBADF;
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index efaadffc06..36e80a086a 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -356,6 +356,49 @@ files_struct *file_find_print(void)
}
/****************************************************************************
+ Find any fsp open with a pathname below that of an already open path.
+****************************************************************************/
+
+bool file_find_subpath(files_struct *dir_fsp)
+{
+ files_struct *fsp;
+ size_t dlen;
+ char *d_fullname = talloc_asprintf(talloc_tos(),
+ "%s/%s",
+ dir_fsp->conn->connectpath,
+ dir_fsp->fsp_name);
+
+ if (!d_fullname) {
+ return false;
+ }
+
+ dlen = strlen(d_fullname);
+
+ for (fsp=Files;fsp;fsp=fsp->next) {
+ char *d1_fullname;
+
+ if (fsp == dir_fsp) {
+ continue;
+ }
+
+ d1_fullname = talloc_asprintf(talloc_tos(),
+ "%s/%s",
+ fsp->conn->connectpath,
+ fsp->fsp_name);
+
+ if (strnequal(d_fullname, d1_fullname, dlen)) {
+ TALLOC_FREE(d_fullname);
+ TALLOC_FREE(d1_fullname);
+ return true;
+ }
+ TALLOC_FREE(d1_fullname);
+ }
+
+ TALLOC_FREE(d_fullname);
+ return false;
+}
+
+/****************************************************************************
Sync open files on a connection.
****************************************************************************/
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 3f8cb411e5..9e7d103562 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -66,7 +66,8 @@ struct fsp_singleton_cache fsp_fi_cache = {
.fsp = NULL,
.id = {
.devid = 0,
- .inode = 0
+ .inode = 0,
+ .extid = 0
}
};
unsigned long file_gen_counter = 0;
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 57608a9b40..a921954c49 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -27,7 +27,6 @@ extern enum protocol_types Protocol;
static void get_challenge(uint8 buff[8])
{
NTSTATUS nt_status;
- const uint8 *cryptkey;
/* We might be called more than once, multiple negprots are
* permitted */
@@ -42,8 +41,8 @@ static void get_challenge(uint8 buff[8])
smb_panic("cannot make_negprot_global_auth_context!");
}
DEBUG(10, ("get challenge: getting challenge\n"));
- cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
- memcpy(buff, cryptkey, 8);
+ negprot_global_auth_context->get_ntlm_challenge(
+ negprot_global_auth_context, buff);
}
/****************************************************************************
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 1d4f5e8c5b..8ceeaf5f55 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -214,6 +214,8 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
ZERO_STRUCT(e);
e.path = fullpath;
+ e.dir_fd = fsp->fh->fd;
+ e.dir_id = fsp->file_id;
e.filter = filter;
e.subdir_filter = 0;
if (recursive) {
@@ -370,13 +372,26 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
if ((fsp->notify->num_changes > 1000) || (name == NULL)) {
/*
* The real number depends on the client buf, just provide a
- * guard against a DoS here.
+ * guard against a DoS here. If name == NULL the CN backend is
+ * alerting us to a problem. Possibly dropped events. Clear
+ * queued changes and send the catch-all response to the client
+ * if a request is pending.
*/
TALLOC_FREE(fsp->notify->changes);
fsp->notify->num_changes = -1;
+ if (fsp->notify->requests != NULL) {
+ change_notify_reply(fsp->conn,
+ fsp->notify->requests->req,
+ fsp->notify->requests->max_param,
+ fsp->notify);
+ change_notify_remove_request(fsp->notify->requests);
+ }
return;
}
+ /* If we've exceeded the server side queue or received a NULL name
+ * from the underlying CN implementation, don't queue up any more
+ * requests until we can send a catch-all response to the client */
if (fsp->notify->num_changes == -1) {
return;
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index ad2366efae..86a46505a2 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1856,6 +1856,8 @@ static void call_nt_transact_ioctl(connection_struct *conn,
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
+
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16(pdata, &fsp->file_id);
memcpy(pdata+16,create_volume_objectid(conn,objid),16);
push_file_id_16(pdata+32, &fsp->file_id);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 9971ffa679..569c260319 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -132,6 +132,18 @@ static NTSTATUS fd_open(struct connection_struct *conn,
fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode);
if (fsp->fh->fd == -1) {
status = map_nt_error_from_unix(errno);
+ if (errno == EMFILE) {
+ static time_t last_warned = 0L;
+
+ if (time((time_t *) NULL) > last_warned) {
+ DEBUG(0,("Too many open files, unable "
+ "to open more! smbd's max "
+ "open files = %d\n",
+ lp_max_open_files()));
+ last_warned = time((time_t *) NULL);
+ }
+ }
+
}
DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
@@ -1428,7 +1440,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
"create_disposition = 0x%x create_options=0x%x "
"unix mode=0%o oplock_request=%d\n",
fname, new_dos_attributes, access_mask, share_access,
- create_disposition, create_options, unx_mode,
+ create_disposition, create_options, (unsigned int)unx_mode,
oplock_request));
if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
@@ -2445,6 +2457,25 @@ static NTSTATUS open_directory(connection_struct *conn,
fname,
access_mask,
&access_granted);
+
+ /* Were we trying to do a directory 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. */
+
+ if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+ (access_mask & DELETE_ACCESS) &&
+ (access_granted == DELETE_ACCESS) &&
+ can_delete_file_in_directory(conn, fname))) {
+ DEBUG(10,("open_directory: overrode ACCESS_DENIED "
+ "on directory %s\n",
+ fname ));
+ status = NT_STATUS_OK;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("open_directory: check_open_rights on "
"file %s failed with %s\n",
@@ -2597,8 +2628,8 @@ void msg_file_was_renamed(struct messaging_context *msg,
}
/* Unpack the message. */
- pull_file_id_16(frm, &id);
- sharepath = &frm[16];
+ pull_file_id_24(frm, &id);
+ sharepath = &frm[24];
newname = sharepath + strlen(sharepath) + 1;
sp_len = strlen(sharepath);
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index b39e5bf634..22870283fa 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -40,8 +40,8 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp)
uint8_t 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);
+ push_file_id_24((char *)msg, &fsp->file_id);
+ SIVAL(msg,24,fsp->fh->gen_id);
/* Don't need to be root here as we're only ever
sending to ourselves. */
@@ -583,8 +583,8 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
}
/* Pull the data from the message. */
- pull_file_id_16((char *)data->data, &id);
- file_id = (unsigned long)IVAL(data->data, 16);
+ pull_file_id_24((char *)data->data, &id);
+ file_id = (unsigned long)IVAL(data->data, 24);
DEBUG(10, ("Got kernel oplock break message from pid %d: %s/%u\n",
(int)procid_to_pid(&src), file_id_string_tos(&id),
@@ -865,12 +865,12 @@ void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e)
SIVAL(msg,16,e->private_options);
SIVAL(msg,20,(uint32)e->time.tv_sec);
SIVAL(msg,24,(uint32)e->time.tv_usec);
- push_file_id_16(msg+28, &e->id);
- SIVAL(msg,44,e->share_file_id);
- SIVAL(msg,48,e->uid);
- SSVAL(msg,52,e->flags);
+ push_file_id_24(msg+28, &e->id);
+ SIVAL(msg,52,e->share_file_id);
+ SIVAL(msg,56,e->uid);
+ SSVAL(msg,60,e->flags);
#ifdef CLUSTER_SUPPORT
- SIVAL(msg,54,e->pid.vnn);
+ SIVAL(msg,62,e->pid.vnn);
#endif
}
@@ -888,12 +888,12 @@ void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
e->private_options = IVAL(msg,16);
e->time.tv_sec = (time_t)IVAL(msg,20);
e->time.tv_usec = (int)IVAL(msg,24);
- pull_file_id_16(msg+28, &e->id);
- e->share_file_id = (unsigned long)IVAL(msg,44);
- e->uid = (uint32)IVAL(msg,48);
- e->flags = (uint16)SVAL(msg,52);
+ pull_file_id_24(msg+28, &e->id);
+ e->share_file_id = (unsigned long)IVAL(msg,52);
+ e->uid = (uint32)IVAL(msg,56);
+ e->flags = (uint16)SVAL(msg,60);
#ifdef CLUSTER_SUPPORT
- e->pid.vnn = IVAL(msg,54);
+ e->pid.vnn = IVAL(msg,62);
#endif
}
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index bbc9132a08..89b8e0f7b5 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -103,6 +103,24 @@ static bool irix_oplocks_available(void)
return True;
}
+/*
+ * This is bad because the file_id should always be created through the vfs
+ * layer! Unfortunately, a conn struct isn't available here.
+ */
+static struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode)
+{
+ struct file_id key;
+
+ /* the ZERO_STRUCT ensures padding doesn't break using the key as a
+ * blob */
+ ZERO_STRUCT(key);
+
+ key.devid = dev;
+ key.inode = inode;
+
+ return key;
+}
+
/****************************************************************************
* Deal with the IRIX kernel <--> smbd
* oplock break protocol.
diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c
index 0908ce4386..d4f181fc47 100644
--- a/source3/smbd/oplock_onefs.c
+++ b/source3/smbd/oplock_onefs.c
@@ -744,13 +744,13 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
po.po_flags_on |= P_NON_BLOCKING_SEMLOCK;
if (setprocoptions(&po) != 0) {
DEBUG(0, ("setprocoptions failed: %s.\n", strerror(errno)));
- goto err_out;
+ return NULL;
}
/* Setup the oplock contexts */
_ctx = talloc_zero(mem_ctx, struct kernel_oplocks);
if (!_ctx) {
- goto err_out;
+ return NULL;
}
ctx = talloc_zero(_ctx, struct onefs_oplocks_context);
@@ -788,7 +788,6 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx)
err_out:
talloc_free(_ctx);
- talloc_free(ctx);
return NULL;
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index e9b581efe8..2f84a831c6 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -719,12 +719,12 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn,
Count a linked list of canonical ACE entries.
****************************************************************************/
-static size_t count_canon_ace_list( canon_ace *list_head )
+static size_t count_canon_ace_list( canon_ace *l_head )
{
size_t count = 0;
canon_ace *ace;
- for (ace = list_head; ace; ace = ace->next)
+ for (ace = l_head; ace; ace = ace->next)
count++;
return count;
@@ -734,13 +734,13 @@ static size_t count_canon_ace_list( canon_ace *list_head )
Free a linked list of canonical ACE entries.
****************************************************************************/
-static void free_canon_ace_list( canon_ace *list_head )
+static void free_canon_ace_list( canon_ace *l_head )
{
canon_ace *list, *next;
- for (list = list_head; list; list = next) {
+ for (list = l_head; list; list = next) {
next = list->next;
- DLIST_REMOVE(list_head, list);
+ DLIST_REMOVE(l_head, list);
SAFE_FREE(list);
}
}
@@ -916,7 +916,7 @@ static bool identity_in_ace_equal(canon_ace *ace1, canon_ace *ace2)
static void merge_aces( canon_ace **pp_list_head )
{
- canon_ace *list_head = *pp_list_head;
+ canon_ace *l_head = *pp_list_head;
canon_ace *curr_ace_outer;
canon_ace *curr_ace_outer_next;
@@ -925,7 +925,7 @@ static void merge_aces( canon_ace **pp_list_head )
* with identical SIDs.
*/
- for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
+ for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
canon_ace *curr_ace;
canon_ace *curr_ace_next;
@@ -947,7 +947,7 @@ static void merge_aces( canon_ace **pp_list_head )
/* Merge two allow or two deny ACE's. */
curr_ace_outer->perms |= curr_ace->perms;
- DLIST_REMOVE(list_head, curr_ace);
+ DLIST_REMOVE(l_head, curr_ace);
SAFE_FREE(curr_ace);
curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
}
@@ -960,7 +960,7 @@ static void merge_aces( canon_ace **pp_list_head )
* appears only once in the list.
*/
- for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
+ for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) {
canon_ace *curr_ace;
canon_ace *curr_ace_next;
@@ -992,7 +992,7 @@ static void merge_aces( canon_ace **pp_list_head )
* The deny overrides the allow. Remove the allow.
*/
- DLIST_REMOVE(list_head, curr_ace);
+ DLIST_REMOVE(l_head, curr_ace);
SAFE_FREE(curr_ace);
curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
@@ -1008,7 +1008,7 @@ static void merge_aces( canon_ace **pp_list_head )
* before we can get to an allow ace.
*/
- DLIST_REMOVE(list_head, curr_ace_outer);
+ DLIST_REMOVE(l_head, curr_ace_outer);
SAFE_FREE(curr_ace_outer);
break;
}
@@ -1019,7 +1019,7 @@ static void merge_aces( canon_ace **pp_list_head )
/* We may have modified the list. */
- *pp_list_head = list_head;
+ *pp_list_head = l_head;
}
/****************************************************************************
@@ -2305,12 +2305,12 @@ static bool unpack_canon_ace(files_struct *fsp,
static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head)
{
- canon_ace *list_head = *pp_list_head;
+ canon_ace *l_head = *pp_list_head;
canon_ace *owner_ace = NULL;
canon_ace *other_ace = NULL;
canon_ace *ace = NULL;
- for (ace = list_head; ace; ace = ace->next) {
+ for (ace = l_head; ace; ace = ace->next) {
if (ace->type == SMB_ACL_USER_OBJ)
owner_ace = ace;
else if (ace->type == SMB_ACL_OTHER) {
@@ -2331,16 +2331,16 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head)
*/
if (owner_ace) {
- DLIST_PROMOTE(list_head, owner_ace);
+ DLIST_PROMOTE(l_head, owner_ace);
}
if (other_ace) {
- DLIST_DEMOTE(list_head, other_ace, canon_ace *);
+ DLIST_DEMOTE(l_head, other_ace, canon_ace *);
}
/* We have probably changed the head of the list. */
- *pp_list_head = list_head;
+ *pp_list_head = l_head;
}
/****************************************************************************
@@ -2353,7 +2353,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
{
mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR);
- canon_ace *list_head = NULL;
+ canon_ace *l_head = NULL;
canon_ace *ace = NULL;
canon_ace *next_ace = NULL;
int entry_id = SMB_ACL_FIRST_ENTRY;
@@ -2457,14 +2457,14 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
ace->owner_type = owner_type;
ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
- DLIST_ADD(list_head, ace);
+ DLIST_ADD(l_head, ace);
}
/*
* This next call will ensure we have at least a user/group/world set.
*/
- if (!ensure_canon_entry_valid(&list_head, conn->params,
+ if (!ensure_canon_entry_valid(&l_head, conn->params,
S_ISDIR(psbuf->st_mode), powner, pgroup,
psbuf, False))
goto fail;
@@ -2476,7 +2476,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" ));
- for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) {
+ for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) {
next_ace = ace->next;
/* Masks are only applied to entries other than USER_OBJ and OTHER. */
@@ -2484,7 +2484,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
ace->perms &= acl_mask;
if (ace->perms == 0) {
- DLIST_PROMOTE(list_head, ace);
+ DLIST_PROMOTE(l_head, ace);
}
if( DEBUGLVL( 10 ) ) {
@@ -2492,15 +2492,15 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
}
}
- arrange_posix_perms(fname,&list_head );
+ arrange_posix_perms(fname,&l_head );
- print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head );
+ print_canon_ace_list( "canonicalise_acl: ace entries after arrange", l_head );
- return list_head;
+ return l_head;
fail:
- free_canon_ace_list(list_head);
+ free_canon_ace_list(l_head);
return NULL;
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 457f9412a9..22e4c1aad7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2214,6 +2214,16 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
}
if (S_ISDIR(pst->st_mode)) {
+ if (fsp->posix_open) {
+ return NT_STATUS_OK;
+ }
+
+ /* If no pathnames are open below this
+ directory, allow the rename. */
+
+ if (file_find_subpath(fsp)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
return NT_STATUS_OK;
}
@@ -2788,6 +2798,18 @@ static void send_file_readbraw(connection_struct *conn,
DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readbraw sendfile failed");
+ } else if (sendfile_read == 0) {
+ /*
+ * Some sendfile implementations return 0 to indicate
+ * that there was a short read, but nothing was
+ * actually written to the socket. In this case,
+ * fallback to the normal read path so the header gets
+ * the correct byte count.
+ */
+ DEBUG(3, ("send_file_readbraw: sendfile sent zero "
+ "bytes falling back to the normal read: "
+ "%s\n", fsp->fsp_name));
+ goto normal_readbraw;
}
/* Deal with possible short send. */
@@ -2796,9 +2818,9 @@ static void send_file_readbraw(connection_struct *conn,
}
return;
}
-#endif
normal_readbraw:
+#endif
outbuf = TALLOC_ARRAY(NULL, char, nread+4);
if (!outbuf) {
@@ -3284,6 +3306,18 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readX sendfile failed");
+ } else if (nread == 0) {
+ /*
+ * Some sendfile implementations return 0 to indicate
+ * that there was a short read, but nothing was
+ * actually written to the socket. In this case,
+ * fallback to the normal read path so the header gets
+ * the correct byte count.
+ */
+ DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
+ "falling back to the normal read: %s\n",
+ fsp->fsp_name));
+ goto normal_read;
}
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index e8ccba0873..538e04938e 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -212,7 +212,7 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown)
/* a child terminated uncleanly so tickle all processes to see
if they can grab any of the pending locks
*/
- DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", pid));
+ DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid));
messaging_send_buf(smbd_messaging_context(), procid_self(),
MSG_SMB_BRL_VALIDATE, NULL, 0);
message_send_all(smbd_messaging_context(),
@@ -359,10 +359,6 @@ static void smbd_accept_connection(struct tevent_context *ev,
/* Child code ... */
am_parent = 0;
-#ifdef WITH_MADVISE_PROTECTED
- madvise(NULL,0,MADV_PROTECT);
-#endif
-
/* Stop zombies, the parent explicitly handles
* them, counting worker smbds. */
CatchChild();
@@ -451,7 +447,6 @@ static bool smbd_open_one_socket(struct smbd_parent_context *parent,
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
@@ -735,7 +730,7 @@ void reload_printers(void)
DEBUG(3, ("removing stale printer %s\n", pname));
if (is_printer_published(NULL, snum, NULL))
- nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH);
+ nt_printer_publish(NULL, snum, DSPRINT_UNPUBLISH);
del_a_printer(pname);
lp_killservice(snum);
}
@@ -1135,9 +1130,6 @@ extern void build_options(bool screen);
if (is_daemon && !interactive) {
DEBUG( 3, ( "Becoming a daemon.\n" ) );
become_daemon(Fork, no_process_group);
-#ifdef WITH_MADVISE_PROTECTED
- madvise(NULL,0,MADV_PROTECT);
-#endif
}
#if HAVE_SETPGID
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 7a03ef7f3c..2c29192220 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1352,8 +1352,8 @@ static int shutdown_other_smbds(struct db_record *rec,
return 0;
}
- DEBUG(0,("shutdown_other_smbds: shutting down pid %d "
- "(IP %s)\n", procid_to_pid(&crec->pid), ip));
+ DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
+ "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip));
messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN,
&data_blob_null);
@@ -1691,14 +1691,15 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
} else {
struct auth_context *plaintext_auth_context = NULL;
- const uint8 *chal;
nt_status = make_auth_context_subsystem(
&plaintext_auth_context);
if (NT_STATUS_IS_OK(nt_status)) {
- chal = plaintext_auth_context->get_ntlm_challenge(
- plaintext_auth_context);
+ uint8_t chal[8];
+
+ plaintext_auth_context->get_ntlm_challenge(
+ plaintext_auth_context, chal);
if (!make_user_info_for_reply(&user_info,
user, domain, chal,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 759e520866..ee1dda98b2 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4972,6 +4972,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
+ files_struct *fsp,
const char *fname,
SMB_STRUCT_STAT *psbuf,
uint32 dosmode)
@@ -4980,6 +4981,14 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ if (fsp) {
+ if (fsp->base_fsp) {
+ fname = fsp->base_fsp->fsp_name;
+ } else {
+ fname = fsp->fsp_name;
+ }
+ }
+
if (dosmode) {
if (S_ISDIR(psbuf->st_mode)) {
dosmode |= aDIR;
@@ -5723,12 +5732,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
/* Set the attributes */
dosmode = IVAL(pdata,32);
- status = smb_set_file_dosmode(conn, fname, psbuf, dosmode);
+ status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
-
/* access time */
ft.atime = interpret_long_date(pdata+8);
@@ -6415,6 +6423,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
create_disp = FILE_OVERWRITE_IF;
} else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) {
create_disp = FILE_OPEN_IF;
+ } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) {
+ create_disp = FILE_OPEN;
} else {
DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
(unsigned int)wire_open_mode ));
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 9580247368..426772889c 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -766,18 +766,13 @@ int vfs_ChDir(connection_struct *conn, const char *path)
format. Note this can be called with conn == NULL.
********************************************************************/
-struct getwd_cache_key {
- SMB_DEV_T dev;
- SMB_INO_T ino;
-};
-
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
{
char s[PATH_MAX+1];
SMB_STRUCT_STAT st, st2;
char *result;
DATA_BLOB cache_value;
- struct getwd_cache_key key;
+ struct file_id key;
*s = 0;
@@ -797,9 +792,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
goto nocache;
}
- ZERO_STRUCT(key); /* unlikely, but possible padding */
- key.dev = st.st_dev;
- key.ino = st.st_ino;
+ key = vfs_file_id_from_sbuf(conn, &st);
if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
data_blob_const(&key, sizeof(key)),
@@ -838,9 +831,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
}
if (lp_getwd_cache() && VALID_STAT(st)) {
- ZERO_STRUCT(key); /* unlikely, but possible padding */
- key.dev = st.st_dev;
- key.ino = st.st_ino;
+ key = vfs_file_id_from_sbuf(conn, &st);
memcache_add(smbd_memcache(), GETWD_CACHE,
data_blob_const(&key, sizeof(key)),
diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 0c2cd24fb2..05b552c00d 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -331,6 +331,12 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
"would import the following configuration:\n\n");
}
+ werr = smbconf_transaction_start(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error starting transaction: %s\n", win_errstr(werr));
+ goto done;
+ }
+
if (servicename != NULL) {
struct smbconf_service *service = NULL;
@@ -338,11 +344,11 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
servicename,
&service);
if (!W_ERROR_IS_OK(werr)) {
- goto done;
+ goto cancel;
}
werr = import_process_service(c, conf_ctx, service);
if (!W_ERROR_IS_OK(werr)) {
- goto done;
+ goto cancel;
}
} else {
struct smbconf_service **services = NULL;
@@ -352,24 +358,39 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
&num_shares,
&services);
if (!W_ERROR_IS_OK(werr)) {
- goto done;
+ goto cancel;
}
if (!c->opt_testmode) {
werr = smbconf_drop(conf_ctx);
if (!W_ERROR_IS_OK(werr)) {
- goto done;
+ goto cancel;
}
}
for (sidx = 0; sidx < num_shares; sidx++) {
werr = import_process_service(c, conf_ctx,
services[sidx]);
if (!W_ERROR_IS_OK(werr)) {
- goto done;
+ goto cancel;
}
}
}
- ret = 0;
+ werr = smbconf_transaction_commit(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error committing transaction: %s\n",
+ win_errstr(werr));
+ } else {
+ ret = 0;
+ }
+
+ goto done;
+
+cancel:
+ werr = smbconf_transaction_cancel(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error cancelling transaction: %s\n",
+ win_errstr(werr));
+ }
done:
TALLOC_FREE(mem_ctx);
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index bb8747ede3..8116764d9b 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -50,6 +50,33 @@ static const struct table_node archi_table[]= {
Printer info level 3 display function.
****************************************************************************/
+static void display_print_driver3(struct spoolss_DriverInfo3 *r)
+{
+ int i;
+
+ if (!r) {
+ return;
+ }
+
+ printf("Printer Driver Info 3:\n");
+ printf("\tVersion: [%x]\n", r->version);
+ printf("\tDriver Name: [%s]\n", r->driver_name);
+ printf("\tArchitecture: [%s]\n", r->architecture);
+ printf("\tDriver Path: [%s]\n", r->driver_path);
+ printf("\tDatafile: [%s]\n", r->data_file);
+ printf("\tConfigfile: [%s]\n\n", r->config_file);
+ printf("\tHelpfile: [%s]\n\n", r->help_file);
+
+ for (i=0; r->dependent_files[i] != NULL; i++) {
+ printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
+ }
+
+ printf("\n");
+
+ printf("\tMonitorname: [%s]\n", r->monitor_name);
+ printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
+}
+
static void display_print_driver_3(DRIVER_INFO_3 *i1)
{
fstring name = "";
@@ -513,7 +540,7 @@ static NTSTATUS net_copy_driverfile(struct net_context *c,
TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
- char *file, const char *short_archi) {
+ const char *file, const char *short_archi) {
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
const char *p;
@@ -523,6 +550,10 @@ static NTSTATUS net_copy_driverfile(struct net_context *c,
char *filename;
char *tok;
+ if (!file) {
+ return NT_STATUS_OK;
+ }
+
/* scroll through the file until we have the part
beyond archi_table.short_archi */
p = file;
@@ -617,67 +648,47 @@ static NTSTATUS copy_print_driver_3(struct net_context *c,
TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
- const char *short_archi, DRIVER_INFO_3 *i1)
+ const char *short_archi,
+ struct spoolss_DriverInfo3 *r)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int length = 0;
- bool valid = true;
-
- fstring name = "";
- fstring driverpath = "";
- fstring datafile = "";
- fstring configfile = "";
- fstring helpfile = "";
- fstring dependentfiles = "";
+ int i;
- if (i1 == NULL)
+ if (r == NULL) {
return nt_status;
-
- rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
- rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
- rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
- rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
- rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
-
+ }
if (c->opt_verbose)
d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n",
- name, short_archi, i1->version);
+ r->driver_name, short_archi, r->version);
nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
- driverpath, short_archi);
+ r->driver_path, short_archi);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
- datafile, short_archi);
+ r->data_file, short_archi);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
- configfile, short_archi);
+ r->config_file, short_archi);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
- helpfile, short_archi);
+ r->help_file, short_archi);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
- while (valid) {
-
- rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
- length += strlen(dependentfiles)+1;
+ for (i=0; r->dependent_files[i] != NULL; i++) {
- if (strlen(dependentfiles) > 0) {
-
- nt_status = net_copy_driverfile(c, mem_ctx,
- cli_share_src, cli_share_dst,
- dependentfiles, short_archi);
- if (!NT_STATUS_IS_OK(nt_status))
- return nt_status;
- } else {
- valid = false;
+ nt_status = net_copy_driverfile(c, mem_ctx,
+ cli_share_src, cli_share_dst,
+ r->dependent_files[i], short_archi);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
}
}
@@ -764,13 +775,16 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
POLICY_HND *hnd,
uint32 level,
- PRINTER_INFO_CTR *ctr)
+ union spoolss_PrinterInfo *info)
{
WERROR result;
/* getprinter call */
- result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr);
-
+ result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx,
+ hnd,
+ level,
+ 0, /* offered */
+ info);
if (!W_ERROR_IS_OK(result)) {
printf("cannot get printer-info: %s\n", win_errstr(result));
return false;
@@ -783,12 +797,64 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
POLICY_HND *hnd,
uint32 level,
- PRINTER_INFO_CTR *ctr)
+ union spoolss_PrinterInfo *info)
{
WERROR result;
+ NTSTATUS status;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
/* setprinter call */
- result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0);
+
+ info_ctr.level = level;
+ switch (level) {
+ case 0:
+ info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0;
+ break;
+ case 1:
+ info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1;
+ break;
+ case 2:
+ info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2;
+ break;
+ case 3:
+ info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3;
+ break;
+ case 4:
+ info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4;
+ break;
+ case 5:
+ info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5;
+ break;
+ case 6:
+ info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6;
+ break;
+ case 7:
+ info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7;
+ break;
+#if 0 /* FIXME GD */
+ case 8:
+ info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8;
+ break;
+ case 9:
+ info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9;
+ break;
+#endif
+ default:
+ break; /* FIXME */
+ }
+
+ status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
+ hnd,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ 0, /* command */
+ &result);
if (!W_ERROR_IS_OK(result)) {
printf("cannot set printer-info: %s\n", win_errstr(result));
@@ -930,15 +996,23 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 level,
const char *env, int version,
- PRINTER_DRIVER_CTR *ctr)
+ union spoolss_DriverInfo *info)
{
WERROR result;
+ uint32_t server_major_version;
+ uint32_t server_minor_version;
/* getprinterdriver call */
- result = rpccli_spoolss_getprinterdriver(
- pipe_hnd, mem_ctx, hnd, level,
- env, version, ctr);
-
+ result = rpccli_spoolss_getprinterdriver2(pipe_hnd, mem_ctx,
+ hnd,
+ env,
+ level,
+ 0,
+ version,
+ 2,
+ info,
+ &server_major_version,
+ &server_minor_version);
if (!W_ERROR_IS_OK(result)) {
DEBUG(1,("cannot get driver (for architecture: %s): %s\n",
env, win_errstr(result)));
@@ -955,13 +1029,31 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx, uint32 level,
- PRINTER_DRIVER_CTR *ctr)
+ union spoolss_DriverInfo *info)
{
WERROR result;
+ NTSTATUS status;
+ struct spoolss_AddDriverInfoCtr info_ctr;
- /* addprinterdriver call */
- result = rpccli_spoolss_addprinterdriver(pipe_hnd, mem_ctx, level, ctr);
+ info_ctr.level = level;
+
+ switch (level) {
+ case 2:
+ info_ctr.info.info2 = (struct spoolss_AddDriverInfo2 *)&info->info2;
+ break;
+ case 3:
+ info_ctr.info.info3 = (struct spoolss_AddDriverInfo3 *)&info->info3;
+ break;
+ default:
+ printf("unsupported info level: %d\n", level);
+ return false;
+ }
+ /* addprinterdriver call */
+ status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx,
+ pipe_hnd->srv_name_slash,
+ &info_ctr,
+ &result);
/* be more verbose */
if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
printf("You are not allowed to add drivers\n");
@@ -990,6 +1082,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
{
POLICY_HND hnd;
+ union spoolss_PrinterInfo info;
/* no arguments given, enumerate all printers */
if (argc == 0) {
@@ -1002,6 +1095,8 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
goto out;
}
+ /* FIXME GD */
+ return false;
/* argument given, get a single printer by name */
if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0],
@@ -1010,7 +1105,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
&hnd))
return false;
- if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, ctr)) {
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
return false;
}
@@ -1179,9 +1274,12 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
uint32 i, num_printers;
uint32 level = 7;
char *printername, *sharename;
- PRINTER_INFO_CTR ctr, ctr_pub;
+ PRINTER_INFO_CTR ctr;
+ union spoolss_PrinterInfo info;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
POLICY_HND hnd;
- bool got_hnd = false;
WERROR result;
const char *action_str;
@@ -1209,21 +1307,19 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd))
goto done;
- got_hnd = true;
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
goto done;
/* check action and set string */
switch (action) {
- case SPOOL_DS_PUBLISH:
+ case DSPRINT_PUBLISH:
action_str = "published";
break;
- case SPOOL_DS_UPDATE:
+ case DSPRINT_UPDATE:
action_str = "updated";
break;
- case SPOOL_DS_UNPUBLISH:
+ case DSPRINT_UNPUBLISH:
action_str = "unpublished";
break;
default:
@@ -1232,9 +1328,21 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
break;
}
- ctr_pub.printers_7->action = action;
+ info.info7.action = action;
+ info_ctr.level = 7;
+ info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
+ &hnd,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ 0, /* command */
+ &result);
- result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0);
if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) {
printf("cannot set printer-info: %s\n", win_errstr(result));
goto done;
@@ -1246,7 +1354,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_
nt_status = NT_STATUS_OK;
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
return nt_status;
@@ -1261,7 +1369,7 @@ NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c,
int argc,
const char **argv)
{
- return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_PUBLISH);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_PUBLISH);
}
NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c,
@@ -1273,7 +1381,7 @@ NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c,
int argc,
const char **argv)
{
- return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UNPUBLISH);
}
NTSTATUS rpc_printer_publish_update_internals(struct net_context *c,
@@ -1285,7 +1393,7 @@ NTSTATUS rpc_printer_publish_update_internals(struct net_context *c,
int argc,
const char **argv)
{
- return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UPDATE);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UPDATE);
}
/**
@@ -1318,10 +1426,9 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
uint32 i, num_printers;
uint32 level = 7;
char *printername, *sharename;
- char *guid;
PRINTER_INFO_CTR ctr, ctr_pub;
+ union spoolss_PrinterInfo info;
POLICY_HND hnd;
- bool got_hnd = false;
int state;
if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr))
@@ -1350,32 +1457,25 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
PRINTER_ALL_ACCESS, cli->user_name, &hnd))
goto done;
- got_hnd = true;
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
goto done;
- rpcstr_pull_talloc(mem_ctx,
- &guid,
- ctr_pub.printers_7->guid.buffer,
- -1,
- STR_TERMINATE);
- if (!guid) {
+ if (!info.info7.guid) {
goto done;
}
- state = ctr_pub.printers_7->action;
+ state = info.info7.action;
switch (state) {
- case SPOOL_DS_PUBLISH:
+ case DSPRINT_PUBLISH:
printf("printer [%s] is published", sharename);
if (c->opt_verbose)
- printf(", guid: %s", guid);
+ printf(", guid: %s", info.info7.guid);
printf("\n");
break;
- case SPOOL_DS_UNPUBLISH:
+ case DSPRINT_UNPUBLISH:
printf("printer [%s] is unpublished\n", sharename);
break;
- case SPOOL_DS_UPDATE:
+ case DSPRINT_UPDATE:
printf("printer [%s] is currently updating\n", sharename);
break;
default:
@@ -1387,7 +1487,7 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
nt_status = NT_STATUS_OK;
done:
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
return nt_status;
@@ -1427,12 +1527,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
uint32 num_printers;
uint32 level = 2;
char *printername, *sharename;
- bool got_hnd_src = false;
- bool got_hnd_dst = false;
struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
- PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum;
+ PRINTER_INFO_CTR ctr_src, ctr_enum;
struct cli_state *cli_dst = NULL;
+ union spoolss_PrinterInfo info_src, info_dst;
ZERO_STRUCT(ctr_src);
@@ -1493,47 +1592,41 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
- got_hnd_src = true;
-
/* open dst printer handle */
if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
goto done;
- got_hnd_dst = true;
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
goto done;
/* check for existing src printer */
- if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &ctr_src))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src))
goto done;
/* Copy Security Descriptor */
/* copy secdesc (info level 2) */
- ctr_dst.printers_2->devmode = NULL;
- ctr_dst.printers_2->secdesc = dup_sec_desc(mem_ctx, ctr_src.printers_3->secdesc);
+ info_dst.info2.devmode = NULL;
+ info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc);
if (c->opt_verbose)
- display_sec_desc(ctr_dst.printers_2->secdesc);
+ display_sec_desc(info_dst.info2.secdesc);
- if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &ctr_dst))
+ if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
goto done;
DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n"));
/* close printer handles here */
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- got_hnd_src = false;
}
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
}
@@ -1542,11 +1635,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
done:
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
}
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
}
@@ -1588,11 +1681,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
uint32 num_printers;
uint32 level = 1;
char *printername, *sharename;
- bool got_hnd_src = false;
- bool got_hnd_dst = false;
struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
- PRINTER_INFO_CTR ctr_enum, ctr_dst;
+ PRINTER_INFO_CTR ctr_enum;
+ union spoolss_PrinterInfo info_dst;
uint32 num_forms;
FORM_1 *forms;
struct cli_state *cli_dst = NULL;
@@ -1649,19 +1741,13 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
- got_hnd_src = true;
-
-
/* open dst printer handle */
if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
goto done;
- got_hnd_dst = true;
-
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
goto done;
/* finally migrate forms */
@@ -1721,14 +1807,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
/* close printer handles here */
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- got_hnd_src = false;
}
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
}
@@ -1736,10 +1820,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
done:
- if (got_hnd_src)
+ if (is_valid_policy_hnd(&hnd_src))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- if (got_hnd_dst)
+ if (is_valid_policy_hnd(&hnd_dst))
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
if (cli_dst) {
@@ -1779,21 +1863,18 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
uint32 num_printers;
uint32 level = 3;
char *printername, *sharename;
- bool got_hnd_src = false;
- bool got_hnd_dst = false;
bool got_src_driver_share = false;
bool got_dst_driver_share = false;
struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
- PRINTER_DRIVER_CTR drv_ctr_src, drv_ctr_dst;
+ union spoolss_DriverInfo drv_info_src;
PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst;
+ union spoolss_PrinterInfo info_dst;
struct cli_state *cli_dst = NULL;
struct cli_state *cli_share_src = NULL;
struct cli_state *cli_share_dst = NULL;
- fstring drivername = "";
+ const char *drivername = NULL;
- ZERO_STRUCT(drv_ctr_src);
- ZERO_STRUCT(drv_ctr_dst);
ZERO_STRUCT(info_ctr_enum);
ZERO_STRUCT(info_ctr_dst);
@@ -1865,10 +1946,8 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
goto done;
- got_hnd_dst = true;
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
goto done;
@@ -1879,9 +1958,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
&hnd_src))
goto done;
- got_hnd_src = true;
-
-
/* in a first step call getdriver for each shared printer (per arch)
to get a list of all files that have to be copied */
@@ -1890,15 +1966,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
/* getdriver src */
if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src,
level, archi_table[i].long_archi,
- archi_table[i].version, &drv_ctr_src))
+ archi_table[i].version, &drv_info_src))
continue;
- rpcstr_pull(drivername, drv_ctr_src.info3->name.buffer,
- sizeof(drivername), -1, STR_TERMINATE);
+ drivername = drv_info_src.info3.driver_name;
if (c->opt_verbose)
- display_print_driver_3(drv_ctr_src.info3);
-
+ display_print_driver3(&drv_info_src.info3);
/* check arch dir */
nt_status = check_arch_dir(cli_share_dst, archi_table[i].short_archi);
@@ -1909,13 +1983,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
/* copy driver-files */
nt_status = copy_print_driver_3(c, mem_ctx, cli_share_src, cli_share_dst,
archi_table[i].short_archi,
- drv_ctr_src.info3);
+ &drv_info_src.info3);
if (!NT_STATUS_IS_OK(nt_status))
goto done;
/* adddriver dst */
- if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_ctr_src)) {
+ if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_info_src)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1932,9 +2006,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
}
/* setdriver dst */
- init_unistr(&info_ctr_dst.printers_2->drivername, drivername);
+ info_dst.info2.drivername = drivername;
- if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) {
+ if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1943,15 +2017,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
drivername, printername));
/* close dst */
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
/* close src */
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- got_hnd_src = false;
}
}
@@ -1959,10 +2031,10 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
done:
- if (got_hnd_src)
+ if (is_valid_policy_hnd(&hnd_src))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- if (got_hnd_dst)
+ if (is_valid_policy_hnd(&hnd_dst))
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
if (cli_dst) {
@@ -2010,13 +2082,13 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i = 0, num_printers;
uint32 level = 2;
- PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum;
+ PRINTER_INFO_CTR ctr_enum;
+ union spoolss_PrinterInfo info_dst, info_src;
struct cli_state *cli_dst = NULL;
POLICY_HND hnd_dst, hnd_src;
char *printername, *sharename;
- bool got_hnd_src = false;
- bool got_hnd_dst = false;
struct rpc_pipe_client *pipe_hnd_dst = NULL;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
DEBUG(3,("copying printers\n"));
@@ -2067,19 +2139,16 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) {
DEBUG(1,("could not open printer: %s\n", sharename));
- } else {
- got_hnd_dst = true;
}
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) {
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) {
printf ("could not get printer, creating printer.\n");
} else {
DEBUG(1,("printer already exists: %s\n", sharename));
/* close printer handle here - dst only, not got src yet. */
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
continue;
}
@@ -2092,16 +2161,20 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
- got_hnd_src = true;
-
/* getprinter on the src server */
- if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src))
goto done;
/* copy each src printer to a dst printer 1:1,
maybe some values have to be changed though */
d_printf("creating printer: %s\n", printername);
- result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src);
+
+ info_ctr.level = level;
+ info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2;
+
+ result = rpccli_spoolss_addprinterex(pipe_hnd_dst,
+ mem_ctx,
+ &info_ctr);
if (W_ERROR_IS_OK(result))
d_printf ("printer [%s] successfully added.\n", printername);
@@ -2113,24 +2186,22 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
}
/* close printer handles here */
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- got_hnd_src = false;
}
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
}
nt_status = NT_STATUS_OK;
done:
- if (got_hnd_src)
+ if (is_valid_policy_hnd(&hnd_src))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- if (got_hnd_dst)
+ if (is_valid_policy_hnd(&hnd_dst))
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
if (cli_dst) {
@@ -2175,11 +2246,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
uint32 num_printers, val_needed, data_needed;
uint32 level = 2;
char *printername, *sharename;
- bool got_hnd_src = false;
- bool got_hnd_dst = false;
struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
- PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish;
+ PRINTER_INFO_CTR ctr_enum;
+ union spoolss_PrinterInfo info_dst_publish, info_dst;
REGVAL_CTR *reg_ctr;
struct cli_state *cli_dst = NULL;
char *devicename = NULL, *unc_name = NULL, *url = NULL;
@@ -2188,6 +2258,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
uint16 *keylist = NULL, *curkey;
ZERO_STRUCT(ctr_enum);
+ /* FIXME GD */
+ ZERO_STRUCT(info_dst_publish);
DEBUG(3,("copying printer settings\n"));
@@ -2247,44 +2319,39 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
- got_hnd_src = true;
-
-
/* open dst printer handle */
if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
goto done;
- got_hnd_dst = true;
-
-
/* check for existing dst printer */
if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
- level, &ctr_dst))
+ level, &info_dst))
goto done;
+#if 0 /* FIXME GD */
/* STEP 1: COPY DEVICE-MODE and other
PRINTER_INFO_2-attributes
*/
- ctr_dst.printers_2 = &ctr_enum.printers_2[i];
+ info_dst.info2 = &ctr_enum.printers_2[i];
/* why is the port always disconnected when the printer
is correctly installed (incl. driver ???) */
- init_unistr( &ctr_dst.printers_2->portname, SAMBA_PRINTER_PORT_NAME);
+ info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME;
/* check if printer is published */
if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
/* check for existing dst printer */
- if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish))
goto done;
- ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH;
+ info_dst_publish.info7.action = DSPRINT_PUBLISH;
/* ignore false from setprinter due to WERR_IO_PENDING */
- net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish);
+ net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish);
DEBUG(3,("republished printer\n"));
}
@@ -2292,14 +2359,14 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
if (ctr_enum.printers_2[i].devmode != NULL) {
/* copy devmode (info level 2) */
- ctr_dst.printers_2->devmode = (DEVICEMODE *)
+ info_dst.info2.devmode = (DEVICEMODE *)
TALLOC_MEMDUP(mem_ctx,
ctr_enum.printers_2[i].devmode,
sizeof(DEVICEMODE));
/* do not copy security descriptor (we have another
* command for that) */
- ctr_dst.printers_2->secdesc = NULL;
+ info_dst.info2.secdesc = NULL;
#if 0
if (asprintf(&devicename, "\\\\%s\\%s", longname,
@@ -2312,12 +2379,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
devicename);
#endif
if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
- level, &ctr_dst))
+ level, &info_dst))
goto done;
DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n"));
}
-
+#endif
/* STEP 2: COPY REGISTRY VALUES */
/* please keep in mind that samba parse_spools gives horribly
@@ -2496,14 +2563,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
SAFE_FREE(keylist);
/* close printer handles here */
- if (got_hnd_src) {
+ if (is_valid_policy_hnd(&hnd_src)) {
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- got_hnd_src = false;
}
- if (got_hnd_dst) {
+ if (is_valid_policy_hnd(&hnd_dst)) {
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
- got_hnd_dst = false;
}
}
@@ -2515,10 +2580,10 @@ done:
SAFE_FREE(url);
SAFE_FREE(unc_name);
- if (got_hnd_src)
+ if (is_valid_policy_hnd(&hnd_src))
rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
- if (got_hnd_dst)
+ if (is_valid_policy_hnd(&hnd_dst))
rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
if (cli_dst) {
diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c
index 005e3ca556..00c827928e 100644
--- a/source3/utils/net_rpc_registry.c
+++ b/source3/utils/net_rpc_registry.c
@@ -971,12 +971,15 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
{
REGF_NK_REC *key, *subkey;
REGVAL_CTR *values = NULL;
- REGSUBKEY_CTR *subkeys = NULL;
+ struct regsubkey_ctr *subkeys = NULL;
int i;
char *path = NULL;
+ WERROR werr;
- if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
- DEBUG(0,("write_registry_tree: talloc() failed!\n"));
+ werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
+ "%s\n", win_errstr(werr)));
return false;
}
@@ -993,7 +996,7 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
(const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
}
- /* copy subkeys into the REGSUBKEY_CTR */
+ /* copy subkeys into the struct regsubkey_ctr */
while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
regsubkey_ctr_addkey( subkeys, subkey->keyname );
diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c
index 5dd788ad5f..0ac93dedeb 100644
--- a/source3/utils/profiles.c
+++ b/source3/utils/profiles.c
@@ -57,7 +57,7 @@ static void verbose_output(const char *format, ...)
static bool swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 )
{
- SEC_ACL *acl;
+ SEC_ACL *theacl;
int i;
bool update = False;
@@ -78,30 +78,30 @@ static bool swap_sid_in_acl( SEC_DESC *sd, DOM_SID *s1, DOM_SID *s2 )
sid_string_tos(sd->group_sid));
}
- acl = sd->dacl;
- verbose_output(" DACL: %d entries:\n", acl->num_aces);
- for ( i=0; i<acl->num_aces; i++ ) {
+ theacl = sd->dacl;
+ verbose_output(" DACL: %d entries:\n", theacl->num_aces);
+ for ( i=0; i<theacl->num_aces; i++ ) {
verbose_output(" Trustee SID: %s\n",
- sid_string_tos(&acl->aces[i].trustee));
- if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
- sid_copy( &acl->aces[i].trustee, s2 );
+ sid_string_tos(&theacl->aces[i].trustee));
+ if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) {
+ sid_copy( &theacl->aces[i].trustee, s2 );
update = True;
verbose_output(" New Trustee SID: %s\n",
- sid_string_tos(&acl->aces[i].trustee));
+ sid_string_tos(&theacl->aces[i].trustee));
}
}
#if 0
- acl = sd->sacl;
- verbose_output(" SACL: %d entries: \n", acl->num_aces);
- for ( i=0; i<acl->num_aces; i++ ) {
+ theacl = sd->sacl;
+ verbose_output(" SACL: %d entries: \n", theacl->num_aces);
+ for ( i=0; i<theacl->num_aces; i++ ) {
verbose_output(" Trustee SID: %s\n",
- sid_string_tos(&acl->aces[i].trustee));
- if ( sid_equal( &acl->aces[i].trustee, s1 ) ) {
- sid_copy( &acl->aces[i].trustee, s2 );
+ sid_string_tos(&theacl->aces[i].trustee));
+ if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) {
+ sid_copy( &theacl->aces[i].trustee, s2 );
update = True;
verbose_output(" New Trustee SID: %s\n",
- sid_string_tos(&acl->aces[i].trustee));
+ sid_string_tos(&theacl->aces[i].trustee));
}
}
#endif
@@ -118,9 +118,10 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
REGF_NK_REC *key, *subkey;
SEC_DESC *new_sd;
REGVAL_CTR *values;
- REGSUBKEY_CTR *subkeys;
+ struct regsubkey_ctr *subkeys;
int i;
char *path;
+ WERROR werr;
/* swap out the SIDs in the security descriptor */
@@ -132,7 +133,8 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname);
swap_sid_in_acl( new_sd, &old_sid, &new_sid );
- if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
+ werr = regsubkey_ctr_init(NULL, &subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("copy_registry_tree: talloc() failure!\n"));
return False;
}
@@ -150,7 +152,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
(const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
}
- /* copy subkeys into the REGSUBKEY_CTR */
+ /* copy subkeys into the struct regsubkey_ctr */
while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
regsubkey_ctr_addkey( subkeys, subkey->keyname );
diff --git a/source3/utils/sharesec.c b/source3/utils/sharesec.c
index ae2a9adf64..4be77ecadd 100644
--- a/source3/utils/sharesec.c
+++ b/source3/utils/sharesec.c
@@ -298,7 +298,7 @@ static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t
{
SEC_DESC *sd = NULL;
SEC_ACE *ace;
- SEC_ACL *acl;
+ SEC_ACL *theacl;
int num_ace;
const char *pacl;
int i;
@@ -326,11 +326,11 @@ static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t
pacl++;
}
- if ( !(acl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) )
+ if ( !(theacl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) )
return NULL;
sd = make_sec_desc( mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- NULL, NULL, NULL, acl, sd_size);
+ NULL, NULL, NULL, theacl, sd_size);
return sd;
}
diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c
index 1fdea818d6..39a264011e 100644
--- a/source3/utils/smbfilter.c
+++ b/source3/utils/smbfilter.c
@@ -91,8 +91,15 @@ static void filter_request(char *buf)
d_printf("sesion_request: %s -> %s\n",
name1, name2);
if (netbiosname) {
- /* replace the destination netbios name */
- name_mangle(netbiosname, buf+4, 0x20);
+ char *mangled = name_mangle(
+ talloc_tos(), netbiosname, 0x20);
+ if (mangled != NULL) {
+ /* replace the destination netbios
+ * name */
+ memcpy(buf+4, mangled,
+ name_len(mangled));
+ TALLOC_FREE(mangled);
+ }
}
}
return;
diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c
index c062134a55..042f3a98f7 100644
--- a/source3/utils/smbget.c
+++ b/source3/utils/smbget.c
@@ -194,7 +194,8 @@ static int smb_download_dir(const char *base, const char *name, int resume)
}
if(chmod(relname, remotestat.st_mode) < 0) {
- fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode);
+ fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname,
+ (unsigned int)remotestat.st_mode);
smbc_closedir(dirhandle);
return 0;
}
@@ -471,7 +472,8 @@ static int smb_download_file(const char *base, const char *name, int recursive,
if(keep_permissions && !send_stdout) {
if(fchmod(localhandle, remotestat.st_mode) < 0) {
- fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode);
+ fprintf(stderr, "Unable to change mode of local file %s to %o\n", path,
+ (unsigned int)remotestat.st_mode);
smbc_close(remotehandle);
close(localhandle);
return 0;
@@ -487,7 +489,8 @@ static void clean_exit(void)
{
char bs[100];
human_readable(total_bytes, bs, sizeof(bs));
- if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, time(NULL) - total_start_time);
+ if(!quiet)fprintf(stderr, "Downloaded %s in %lu seconds\n", bs,
+ (unsigned long)(time(NULL) - total_start_time));
exit(0);
}
diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c
index c86a5023d0..7224589076 100644
--- a/source3/winbindd/idmap_ldap.c
+++ b/source3/winbindd/idmap_ldap.c
@@ -935,6 +935,10 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
multi = True;
}
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
again:
if (multi) {
@@ -1156,6 +1160,10 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
multi = True;
}
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
again:
if (multi) {
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index be91611bfb..dbe83152dd 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -386,7 +386,7 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
if (child_pid != 0) {
/* parent */
DEBUG(5, ("winbind_msg_validate_cache: child created with "
- "pid %d.\n", child_pid));
+ "pid %d.\n", (int)child_pid));
return;
}
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 8326aba40a..02d0b5bc4e 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -2625,9 +2625,9 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
return;
DEBUG(10, ("Storing response for pid %d, len %d\n",
- pid, response->length));
+ (int)pid, response->length));
- fstr_sprintf(key_str, "DR/%d", pid);
+ fstr_sprintf(key_str, "DR/%d", (int)pid);
if (tdb_store(wcache->tdb, string_tdb_data(key_str),
make_tdb_data((uint8 *)response, sizeof(*response)),
TDB_REPLACE) == -1)
@@ -2641,7 +2641,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
DEBUG(10, ("Storing extra data: len=%d\n",
(int)(response->length - sizeof(*response))));
- fstr_sprintf(key_str, "DE/%d", pid);
+ fstr_sprintf(key_str, "DE/%d", (int)pid);
if (tdb_store(wcache->tdb, string_tdb_data(key_str),
make_tdb_data((uint8 *)response->extra_data.data,
response->length - sizeof(*response)),
@@ -2651,7 +2651,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
/* We could not store the extra data, make sure the tdb does not
* contain a main record with wrong dangling extra data */
- fstr_sprintf(key_str, "DR/%d", pid);
+ fstr_sprintf(key_str, "DR/%d", (int)pid);
tdb_delete(wcache->tdb, string_tdb_data(key_str));
return;
@@ -2665,9 +2665,9 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response)
if (!init_wcache())
return false;
- DEBUG(10, ("Retrieving response for pid %d\n", pid));
+ DEBUG(10, ("Retrieving response for pid %d\n", (int)pid));
- fstr_sprintf(key_str, "DR/%d", pid);
+ fstr_sprintf(key_str, "DR/%d", (int)pid);
data = tdb_fetch(wcache->tdb, string_tdb_data(key_str));
if (data.dptr == NULL)
@@ -2689,7 +2689,7 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response)
DEBUG(10, ("Retrieving extra data length=%d\n",
(int)(response->length - sizeof(*response))));
- fstr_sprintf(key_str, "DE/%d", pid);
+ fstr_sprintf(key_str, "DE/%d", (int)pid);
data = tdb_fetch(wcache->tdb, string_tdb_data(key_str));
if (data.dptr == NULL) {
@@ -2716,10 +2716,10 @@ void cache_cleanup_response(pid_t pid)
if (!init_wcache())
return;
- fstr_sprintf(key_str, "DR/%d", pid);
+ fstr_sprintf(key_str, "DR/%d", (int)pid);
tdb_delete(wcache->tdb, string_tdb_data(key_str));
- fstr_sprintf(key_str, "DE/%d", pid);
+ fstr_sprintf(key_str, "DE/%d", (int)pid);
tdb_delete(wcache->tdb, string_tdb_data(key_str));
return;
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index d40bab94ef..f56a63faa0 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -183,7 +183,7 @@ static void async_request_timeout_handler(struct event_context *ctx,
DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. "
"Closing connection to it.\n",
- state->child_pid ));
+ (unsigned int)state->child_pid ));
/* Deal with the reply - set to error. */
async_reply_recv(private_data, False);