summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in25
-rw-r--r--source3/auth/auth_util.c14
-rw-r--r--source3/auth/auth_wbc.c (renamed from source3/auth/auth_onefs_wb.c)32
-rw-r--r--source3/client/mount.cifs.c4
-rw-r--r--source3/configure.in37
-rw-r--r--source3/include/charset.h128
-rw-r--r--source3/include/dbwrap.h4
-rw-r--r--source3/include/includes.h10
-rw-r--r--source3/include/proto.h146
-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.h5
-rw-r--r--source3/include/rpc_spoolss.h175
-rw-r--r--source3/include/smb.h24
-rw-r--r--source3/include/smbprofile.h28
-rw-r--r--source3/lib/charcnv.c2
-rw-r--r--source3/lib/dbwrap.c26
-rw-r--r--source3/lib/dbwrap_ctdb.c12
-rw-r--r--source3/lib/dbwrap_rbt.c8
-rw-r--r--source3/lib/dbwrap_tdb.c12
-rw-r--r--source3/lib/display_sec.c8
-rw-r--r--source3/lib/events.c7
-rw-r--r--source3/lib/fault.c173
-rw-r--r--source3/lib/iconv.c4
-rw-r--r--source3/lib/secace.c293
-rw-r--r--source3/lib/secacl.c118
-rw-r--r--source3/lib/smbconf/smbconf_reg.c174
-rw-r--r--source3/lib/util.c7
-rw-r--r--source3/lib/util_nttoken.c16
-rw-r--r--source3/lib/util_reg_api.c2
-rw-r--r--source3/lib/util_sock.c92
-rw-r--r--source3/lib/util_str.c112
-rw-r--r--source3/lib/wb_reqtrans.c30
-rw-r--r--source3/lib/wbclient.c7
-rw-r--r--source3/libads/disp_sec.c8
-rw-r--r--source3/libgpo/gpo_ini.c2
-rw-r--r--source3/libgpo/gpo_sec.c4
-rw-r--r--source3/libnet/libnet_join.c6
-rw-r--r--source3/modules/gpfs.c6
-rw-r--r--source3/modules/onefs.h110
-rw-r--r--source3/modules/onefs_acl.c21
-rw-r--r--source3/modules/onefs_cbrl.c27
-rw-r--r--source3/modules/onefs_config.c276
-rw-r--r--source3/modules/onefs_config.h160
-rw-r--r--source3/modules/onefs_dir.c2
-rw-r--r--source3/modules/onefs_notify.c1
-rw-r--r--source3/modules/onefs_open.c5
-rw-r--r--source3/modules/onefs_streams.c28
-rw-r--r--source3/modules/onefs_system.c22
-rw-r--r--source3/modules/vfs_acl_tdb.c89
-rw-r--r--source3/modules/vfs_acl_xattr.c12
-rw-r--r--source3/modules/vfs_gpfs.c5
-rw-r--r--source3/modules/vfs_onefs.c122
-rw-r--r--source3/modules/vfs_streams_depot.c14
-rw-r--r--source3/modules/vfs_streams_xattr.c15
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/passdb/lookup_sid.c38
-rw-r--r--source3/passdb/pdb_wbc_sam.c (renamed from source3/passdb/pdb_onefs_sam.c)135
-rw-r--r--source3/printing/nt_printing.c18
-rw-r--r--source3/printing/printfsp.c3
-rw-r--r--source3/printing/printing.c6
-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.c651
-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.c39
-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.c388
-rw-r--r--source3/rpc_client/rpc_transport_sock.c108
-rw-r--r--source3/rpc_parse/parse_sec.c4
-rw-r--r--source3/rpc_parse/parse_spoolss.c849
-rw-r--r--source3/rpc_server/srv_eventlog_lib.c2
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c14
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c75
-rw-r--r--source3/rpcclient/cmd_netlogon.c44
-rw-r--r--source3/rpcclient/cmd_samr.c32
-rw-r--r--source3/rpcclient/cmd_spoolss.c525
-rw-r--r--source3/services/services_db.c12
-rw-r--r--source3/smbd/close.c22
-rw-r--r--source3/smbd/conn.c1
-rw-r--r--source3/smbd/file_access.c5
-rw-r--r--source3/smbd/fileio.c3
-rw-r--r--source3/smbd/files.c43
-rw-r--r--source3/smbd/open.c28
-rw-r--r--source3/smbd/reply.c12
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/smbd/service.c8
-rw-r--r--source3/smbd/trans2.c14
-rw-r--r--source3/smbd/uid.c11
-rw-r--r--source3/utils/net_conf.c58
-rw-r--r--source3/utils/net_rpc_printer.c294
-rw-r--r--source3/utils/net_rpc_registry.c11
-rw-r--r--source3/utils/profiles.c8
-rw-r--r--source3/winbindd/idmap_ad.c10
-rw-r--r--source3/winbindd/idmap_adex/idmap_adex.c10
-rw-r--r--source3/winbindd/idmap_hash/idmap_hash.c10
-rw-r--r--source3/winbindd/idmap_ldap.c8
-rw-r--r--source3/winbindd/idmap_nss.c10
-rw-r--r--source3/winbindd/idmap_rid.c10
-rw-r--r--source3/winbindd/idmap_tdb.c10
-rw-r--r--source3/winbindd/idmap_tdb2.c10
112 files changed, 3219 insertions, 3452 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 73b2989421..6aabcf0c8d 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -340,7 +340,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
../lib/util/params.o ../lib/util/talloc_stack.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_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 \
@@ -366,11 +366,12 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/substitute.o lib/dbwrap_util.o \
lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
- lib/iconv.o lib/pam_errors.o intl/lang_tdb.o lib/conn_tdb.o \
- lib/adt_tree.o lib/gencache.o \
+ lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \
+ lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \
lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \
lib/ldap_escape.o @CHARSET_STATIC@ \
- lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \
+ lib/secdesc.o lib/util_seaccess.o ../libcli/security/secace.o \
+ ../libcli/security/secacl.o \
libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \
lib/file_id.o lib/idmap_cache.o \
../libcli/security/dom_sid.o
@@ -671,8 +672,8 @@ VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
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_notify.o
+ modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.o \
+ modules/onefs_cbrl.o modules/onefs_notify.o modules/onefs_config.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
@@ -689,7 +690,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_ONEFS_WB_OBJ = auth/auth_onefs_wb.o
+AUTH_WBC_OBJ = auth/auth_wbc.o
AUTH_SCRIPT_OBJ = auth/auth_script.o
AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o
@@ -2207,7 +2208,7 @@ installliblua:: installdirs liblua
@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR)
-$(INSTALLLIBCMD_SH) $(LIBLUA_SHARED_TARGET_SONAME) $(DESTDIR)$(LIBDIR)
@rm -f $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)`
- -if test -e $(LIBLUA_SHARED_TARGET_SONAME) ; then \
+ -if test -f $(LIBLUA_SHARED_TARGET_SONAME) ; then \
ln -f -s `basename $(LIBLUA_SHARED_TARGET_SONAME)` \
$(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` ; \
fi
@@ -2355,9 +2356,9 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(AUTH_WINBIND_OBJ)
-bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ)
+bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ)
@echo "Building plugin $@"
- @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ)
+ @$(SHLD_MODULE) $(AUTH_WBC_OBJ)
bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ)
@echo "Building plugin $@"
@@ -2375,9 +2376,9 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o
@echo "Building plugin $@"
@$(SHLD_MODULE) passdb/pdb_tdb.o
-bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o
+bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o
@echo "Building plugin $@"
- @$(SHLD_MODULE) passdb/pdb_onefs_sam.o
+ @$(SHLD_MODULE) passdb/pdb_wbc_sam.o
bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o
@echo "Building plugin $@"
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 1f00e22a3c..c39aa8501d 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -806,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
@@ -859,12 +859,6 @@ 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)) {
bool ret;
@@ -922,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);
diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_wbc.c
index 49de6966b0..580c8b550d 100644
--- a/source3/auth/auth_onefs_wb.c
+++ b/source3/auth/auth_wbc.c
@@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
- Winbind authentication mechnism, customized for onefs
+ Winbind client authentication mechanism designed to defer all
+ authentication to the winbind daemon.
Copyright (C) Tim Potter 2000
Copyright (C) Andrew Bartlett 2001 - 2002
@@ -21,6 +22,21 @@
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
@@ -28,7 +44,7 @@
/* Authenticate a user with a challenge/response */
-static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context,
+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,
@@ -58,7 +74,7 @@ static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context,
user_info->internal_username));
params.level = WBC_AUTH_USER_LEVEL_PLAIN;
- params.password.plaintext = user_info->plaintext_password.data;
+ params.password.plaintext = (char *)user_info->plaintext_password.data;
} else {
DEBUG(3,("Checking encrypted password for %s.\n",
user_info->internal_username));
@@ -116,19 +132,19 @@ static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context,
}
/* module initialisation */
-static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+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 = "onefs_wb";
- (*auth_method)->auth = check_onefs_wb_security;
+ (*auth_method)->name = "wbc";
+ (*auth_method)->auth = check_wbc_security;
return NT_STATUS_OK;
}
-NTSTATUS auth_onefs_wb_init(void)
+NTSTATUS auth_wbc_init(void)
{
- return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb);
+ return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc);
}
diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c
index ae8a7fd186..8623d3c04b 100644
--- a/source3/client/mount.cifs.c
+++ b/source3/client/mount.cifs.c
@@ -649,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) {
diff --git a/source3/configure.in b/source3/configure.in
index bd3d4af40b..e48ff34554 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"
@@ -1088,7 +1088,7 @@ 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 vfs_onefs_shadow_copy perfcount_onefs"
- default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam"
+ 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"
@@ -4723,35 +4723,6 @@ SMB_LIBRARY(addns, 0, no, [undefined API])
#################################################
-# check to see if we should set the protected madvise flag,
-# which will keep smbd alive in low memory conditions
-AC_MSG_CHECKING(whether to protect smbd from being killed in low memory)
-AC_ARG_WITH(madvise-protect,
-[AS_HELP_STRING([--with-madvise-protect], [Include low memory madvise protection (default=no)])],
-[ case "$withval" in
- yes)
- AC_TRY_COMPILE([
- #include <sys/mman.h>
- ],[
- int a = MADV_PROTECT;
- ],
- [samba_cv_madvise_protect=yes],
- [samba_cv_madvise_protect=no])
- if test x"$samba_cv_madvise_protect" = x"yes"; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_MADVISE_PROTECTED,1,[Whether to include low memory protection support])
- else
- AC_MSG_ERROR(Low memory protection supporte requires availability of MADVISE_PROTECT flag.)
- fi
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
- esac ],
- AC_MSG_RESULT(no)
-)
-
-#################################################
# these tests are taken from the GNU fileutils package
AC_CHECKING(how to get filesystem space usage)
space=no
@@ -6130,7 +6101,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_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB)
+SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB)
SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o)
@@ -6173,7 +6144,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_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$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)
diff --git a/source3/include/charset.h b/source3/include/charset.h
deleted file mode 100644
index 1c2a5fb5f0..0000000000
--- a/source3/include/charset.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- charset defines
- Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jelmer Vernooij 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/>.
-*/
-
-struct smb_iconv_convenience;
-
-/* this defines the charset types used in samba */
-typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UTF16BE=5} charset_t;
-
-#define NUM_CHARSETS 6
-
-/*
- * for each charset we have a function that pushes from that charset to a ucs2
- * buffer, and a function that pulls from ucs2 buffer to that charset.
- * */
-
-struct charset_functions {
- const char *name;
- size_t (*pull)(void *, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- struct charset_functions *prev, *next;
-};
-
-/*
- * This is auxiliary struct used by source/script/gen-8-bit-gap.sh script
- * during generation of an encoding table for charset module
- * */
-
-struct charset_gap_table {
- uint16 start;
- uint16 end;
- int32 idx;
-};
-
-/*
- * Define stub for charset module which implements 8-bit encoding with gaps.
- * Encoding tables for such module should be produced from glibc's CHARMAPs
- * using script source/script/gen-8bit-gap.sh
- * CHARSETNAME is CAPITALIZED charset name
- *
- * */
-#define SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CHARSETNAME) \
-static size_t CHARSETNAME ## _push(void *cd, const char **inbuf, size_t *inbytesleft, \
- char **outbuf, size_t *outbytesleft) \
-{ \
- while (*inbytesleft >= 2 && *outbytesleft >= 1) { \
- int i; \
- int done = 0; \
- \
- uint16 ch = SVAL(*inbuf,0); \
- \
- for (i=0; from_idx[i].start != 0xffff; i++) { \
- if ((from_idx[i].start <= ch) && (from_idx[i].end >= ch)) { \
- ((unsigned char*)(*outbuf))[0] = from_ucs2[from_idx[i].idx+ch]; \
- (*inbytesleft) -= 2; \
- (*outbytesleft) -= 1; \
- (*inbuf) += 2; \
- (*outbuf) += 1; \
- done = 1; \
- break; \
- } \
- } \
- if (!done) { \
- errno = EINVAL; \
- return -1; \
- } \
- \
- } \
- \
- if (*inbytesleft == 1) { \
- errno = EINVAL; \
- return -1; \
- } \
- \
- if (*inbytesleft > 1) { \
- errno = E2BIG; \
- return -1; \
- } \
- \
- return 0; \
-} \
- \
-static size_t CHARSETNAME ## _pull(void *cd, const char **inbuf, size_t *inbytesleft, \
- char **outbuf, size_t *outbytesleft) \
-{ \
- while (*inbytesleft >= 1 && *outbytesleft >= 2) { \
- *(uint16*)(*outbuf) = to_ucs2[((unsigned char*)(*inbuf))[0]]; \
- (*inbytesleft) -= 1; \
- (*outbytesleft) -= 2; \
- (*inbuf) += 1; \
- (*outbuf) += 2; \
- } \
- \
- if (*inbytesleft > 0) { \
- errno = E2BIG; \
- return -1; \
- } \
- \
- return 0; \
-} \
- \
-struct charset_functions CHARSETNAME ## _functions = \
- {#CHARSETNAME, CHARSETNAME ## _pull, CHARSETNAME ## _push}; \
- \
-NTSTATUS charset_ ## CHARSETNAME ## _init(void); \
-NTSTATUS charset_ ## CHARSETNAME ## _init(void) \
-{ \
- return smb_register_charset(& CHARSETNAME ## _functions); \
-} \
-
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 80d7bfc6cf..b48a75526a 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -577,22 +577,20 @@ 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"
#include "../lib/util/asn1.h"
-/* And a little extension. Abort on type mismatch */
-#define talloc_get_type_abort(ptr, type) \
- (type *)talloc_check_name_abort(ptr, #type)
-
#include "ads.h"
#include "ads_dns.h"
#include "interfaces.h"
#include "trans2.h"
#include "../libcli/util/error.h"
#include "ntioctl.h"
-#include "charset.h"
+#include "../lib/util/charset/charset.h"
#include "dynconfig.h"
#include "util_getent.h"
#include "debugparse.h"
@@ -701,6 +699,8 @@ enum flush_reason_enum {
#ifndef NO_PROTO_H
#include "proto.h"
#endif
+#include "libcli/security/secace.h"
+#include "libcli/security/secacl.h"
#if defined(HAVE_POSIX_ACLS)
#include "modules/vfs_posixacl.h"
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 9366607995..78110161c5 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -336,6 +336,7 @@ int bitmap_find(struct bitmap *bm, unsigned ofs);
/* The following definitions come from lib/charcnv.c */
+NTSTATUS smb_register_charset(struct charset_functions *funcs);
char lp_failed_convert_char(void);
void lazy_initialize_conv(void);
void gfree_charcnv(void);
@@ -347,7 +348,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
void const *src, size_t srclen, void *dst,
size_t *converted_size, bool allow_bad_conv);
bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
- void const *src, size_t srclen, void *dst,
+ void const *src, size_t srclen, void **dst,
size_t *converted_size, bool allow_bad_conv);
size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen);
char *strdup_upper(const char *s);
@@ -528,15 +529,6 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
int gencache_lock_entry( const char *key );
void gencache_unlock_entry( const char *key );
-/* The following definitions come from lib/iconv.c */
-
-NTSTATUS smb_register_charset(struct charset_functions *funcs) ;
-size_t smb_iconv(smb_iconv_t cd,
- const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
-smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode);
-int smb_iconv_close (smb_iconv_t cd);
-
/* The following definitions come from lib/interface.c */
bool ismyaddr(const struct sockaddr *ip);
@@ -659,28 +651,6 @@ ssize_t sys_recvfile(int fromfd,
size_t count);
ssize_t drain_socket(int sockfd, size_t count);
-/* The following definitions come from lib/secace.c */
-
-bool sec_ace_object(uint8 type);
-void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src);
-void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type,
- uint32 mask, uint8 flag);
-NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask);
-NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask);
-NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid);
-bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2);
-int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2);
-int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2);
-void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces);
-bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace);
-
-/* The following definitions come from lib/secacl.c */
-
-SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, enum security_acl_revision revision,
- int num_aces, SEC_ACE *ace_list);
-SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src);
-bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2);
-
/* The following definitions come from lib/secdesc.c */
bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2);
@@ -1203,7 +1173,6 @@ bool mask_match_search(const char *string, const char *pattern, bool is_case_sen
bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive);
bool unix_wild_match(const char *pattern, const char *string);
bool name_to_fqdn(fstring fqdn, const char *name);
-void *talloc_check_name_abort(const void *ptr, const char *name);
void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob);
uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options);
pid_t procid_to_pid(const struct server_id *proc);
@@ -1261,6 +1230,7 @@ NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx,
const struct nt_user_token *token_1,
const struct nt_user_token *token_2,
struct nt_user_token **token_out);
+bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace);
/* The following definitions come from lib/util_pw.c */
@@ -1423,12 +1393,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,
@@ -4693,6 +4663,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);
@@ -5045,12 +5019,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 */
@@ -5086,9 +5063,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 );
@@ -5096,7 +5075,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 */
@@ -5122,11 +5101,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 );
@@ -5476,33 +5458,38 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
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_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_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);
@@ -5804,17 +5791,7 @@ 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 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);
@@ -5884,19 +5861,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,
@@ -5916,17 +5880,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 make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
-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);
@@ -5966,9 +5920,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);
/* The following definitions come from rpc_server/srv_eventlog_lib.c */
@@ -6540,6 +6491,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..c74d621f35 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.
*/
@@ -72,7 +69,6 @@
/* SEC_ACE */
typedef struct security_ace SEC_ACE;
-#define SEC_ACE_HEADER_SIZE (2 * sizeof(uint8) + sizeof(uint16) + sizeof(uint32))
#ifndef ACL_REVISION
#define ACL_REVISION 0x3
@@ -81,7 +77,6 @@ typedef struct security_ace SEC_ACE;
#ifndef _SEC_ACL
/* SEC_ACL */
typedef struct security_acl SEC_ACL;
-#define SEC_ACL_HEADER_SIZE (2 * sizeof(uint16) + sizeof(uint32))
#define _SEC_ACL
#endif
diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h
index 48609a3cd6..2b4a036ce8 100644
--- a/source3/include/rpc_spoolss.h
+++ b/source3/include/rpc_spoolss.h
@@ -121,41 +121,10 @@
#define SPL_XCV_MONITOR_LOCALMON ",XcvMonitor Local Port"
#define SPL_XCV_MONITOR_TCPMON ",XcvMonitor Standard TCP/IP Port"
-
-#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
@@ -261,25 +230,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
*/
@@ -343,19 +293,6 @@ PRINTER_DEFAULT;
/********************************************/
-typedef struct s_header_type
-{
- uint32 type;
- union
- {
- uint32 value;
- UNISTR string;
- }
- data;
-}
-HEADER_TYPE;
-
-
typedef struct spool_q_getprinterdata
{
POLICY_HND handle;
@@ -488,11 +425,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 */
@@ -872,115 +804,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_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_enumprintprocessors
{
uint32 name_ptr;
diff --git a/source3/include/smb.h b/source3/include/smb.h
index f02088731d..a0140fe081 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -149,8 +149,6 @@ typedef union unid_t {
* smb_ucs2_t is *always* in little endian format.
*/
-typedef uint16 smb_ucs2_t;
-
#ifdef WORDS_BIGENDIAN
#define UCS2_SHIFT 8
#else
@@ -167,10 +165,6 @@ typedef uint16 smb_ucs2_t;
#define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((unsigned char *)(src))[0],\
((unsigned char *)(dest))[1] = ((unsigned char *)(src))[1], (dest))
-/* Large data type for manipulating uint32 unicode codepoints */
-typedef uint32 codepoint_t;
-#define INVALID_CODEPOINT ((codepoint_t)-1)
-
/* pipe string names */
#define PIPE_LANMAN "\\PIPE\\LANMAN"
@@ -579,6 +573,12 @@ typedef struct connection_struct {
*/
struct auth_serversupplied_info *server_info;
+ /*
+ * If the "force group" parameter is set, this is the primary gid that
+ * may be used in the users token, depending on the vuid using this tid.
+ */
+ gid_t force_group_gid;
+
char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */
uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
@@ -1831,18 +1831,6 @@ struct unix_error_map {
#define SAFE_NETBIOS_CHARS ". -_"
-/* generic iconv conversion structure */
-typedef struct _smb_iconv_t {
- size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- size_t (*push)(void *cd, const char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft);
- void *cd_direct, *cd_pull, *cd_push;
- char *from_name, *to_name;
-} *smb_iconv_t;
-
/* The maximum length of a trust account password.
Used when we randomly create it, 15 char passwords
exceed NT4's max password length */
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/lib/charcnv.c b/source3/lib/charcnv.c
index c3b345142f..81cb9a5094 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -763,7 +763,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
* converted.
*/
bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
- void const *src, size_t srclen, void *dst,
+ void const *src, size_t srclen, void **dst,
size_t *converted_size, bool allow_bad_conv)
{
void **dest = (void **)dst;
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_ctdb.c b/source3/lib/dbwrap_ctdb.c
index 03667ff355..4a5bf6d81a 100644
--- a/source3/lib/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap_ctdb.c
@@ -121,9 +121,9 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
{
struct ctdb_rec_data *r;
size_t m_size, r_size;
- struct ctdb_marshall_buffer *m2;
+ struct ctdb_marshall_buffer *m2 = NULL;
- r = db_ctdb_marshall_record(mem_ctx, reqid, key, header, data);
+ r = db_ctdb_marshall_record(talloc_tos(), reqid, key, header, data);
if (r == NULL) {
talloc_free(m);
return NULL;
@@ -133,7 +133,7 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
m = (struct ctdb_marshall_buffer *)talloc_zero_size(
mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
if (m == NULL) {
- return NULL;
+ goto done;
}
m->db_id = db_id;
}
@@ -145,15 +145,15 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
mem_ctx, m, m_size + r_size);
if (m2 == NULL) {
talloc_free(m);
- return NULL;
+ goto done;
}
memcpy(m_size + (uint8_t *)m2, r, r_size);
- talloc_free(r);
-
m2->count++;
+done:
+ talloc_free(r);
return m2;
}
diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c
index 6e09627223..cf4faa25b9 100644
--- a/source3/lib/dbwrap_rbt.c
+++ b/source3/lib/dbwrap_rbt.c
@@ -131,12 +131,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
*/
}
- node = (struct db_rbt_node *)SMB_MALLOC(
+ node = (struct db_rbt_node *)talloc_size(rec_priv->db_ctx,
offsetof(struct db_rbt_node, data) + rec->key.dsize
+ data.dsize);
if (node == NULL) {
- SAFE_FREE(rec_priv->node);
+ TALLOC_FREE(rec_priv->node);
return NT_STATUS_NO_MEMORY;
}
@@ -148,7 +148,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
db_rbt_parse_node(node, &this_key, &this_val);
memcpy(this_key.dptr, rec->key.dptr, node->keysize);
- SAFE_FREE(rec_priv->node);
+ TALLOC_FREE(rec_priv->node);
memcpy(this_val.dptr, data.dptr, node->valuesize);
@@ -194,7 +194,7 @@ static NTSTATUS db_rbt_delete(struct db_record *rec)
}
rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree);
- SAFE_FREE(rec_priv->node);
+ TALLOC_FREE(rec_priv->node);
return NT_STATUS_OK;
}
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..f875e0dc0c 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -282,12 +282,13 @@ 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;
};
- vasprintf(&s, fmt, ap);
- if (!s) return;
+ if (vasprintf(&s, fmt, ap) == -1) {
+ return;
+ }
DEBUG(samba_level, ("s3_event: %s", s));
free(s);
}
diff --git a/source3/lib/fault.c b/source3/lib/fault.c
index 8c4a45bbc9..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,49 +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(logbase);
#ifdef HAVE_GETRLIMIT
#ifdef RLIMIT_CORE
@@ -184,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/iconv.c b/source3/lib/iconv.c
index 3ceb637b8e..44500542f2 100644
--- a/source3/lib/iconv.c
+++ b/source3/lib/iconv.c
@@ -207,12 +207,12 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
from = charsets;
to = charsets;
- ret = SMB_MALLOC_P(struct _smb_iconv_t);
+ ret = SMB_MALLOC_P(struct smb_iconv_s);
if (!ret) {
errno = ENOMEM;
return (smb_iconv_t)-1;
}
- memset(ret, 0, sizeof(struct _smb_iconv_t));
+ memset(ret, 0, sizeof(struct smb_iconv_s));
ret->from_name = SMB_STRDUP(fromcode);
ret->to_name = SMB_STRDUP(tocode);
diff --git a/source3/lib/secace.c b/source3/lib/secace.c
deleted file mode 100644
index 878fac252b..0000000000
--- a/source3/lib/secace.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_ACE handling functions
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-
-/*******************************************************************
- Check if ACE has OBJECT type.
-********************************************************************/
-
-bool sec_ace_object(uint8 type)
-{
- if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
- type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
- type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
- type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
- return True;
- }
- return False;
-}
-
-/*******************************************************************
- copy a SEC_ACE structure.
-********************************************************************/
-void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
-{
- ace_dest->type = ace_src->type;
- ace_dest->flags = ace_src->flags;
- ace_dest->size = ace_src->size;
- ace_dest->access_mask = ace_src->access_mask;
- ace_dest->object = ace_src->object;
- sid_copy(&ace_dest->trustee, &ace_src->trustee);
-}
-
-/*******************************************************************
- Sets up a SEC_ACE structure.
-********************************************************************/
-
-void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type,
- uint32_t mask, uint8 flag)
-{
- t->type = type;
- t->flags = flag;
- t->size = ndr_size_dom_sid(sid, NULL, 0) + 8;
- t->access_mask = mask;
-
- ZERO_STRUCTP(&t->trustee);
- sid_copy(&t->trustee, sid);
-}
-
-/*******************************************************************
- adds new SID with its permissions to ACE list
-********************************************************************/
-
-NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
-{
- unsigned int i = 0;
-
- if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
-
- *num += 1;
-
- if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
- return NT_STATUS_NO_MEMORY;
-
- for (i = 0; i < *num - 1; i ++)
- sec_ace_copy(&(*pp_new)[i], &old[i]);
-
- (*pp_new)[i].type = SEC_ACE_TYPE_ACCESS_ALLOWED;
- (*pp_new)[i].flags = 0;
- (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + ndr_size_dom_sid(sid, NULL, 0);
- (*pp_new)[i].access_mask = mask;
- sid_copy(&(*pp_new)[i].trustee, sid);
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- modify SID's permissions at ACL
-********************************************************************/
-
-NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
-{
- unsigned int i = 0;
-
- if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER;
-
- for (i = 0; i < num; i ++) {
- if (sid_compare(&ace[i].trustee, sid) == 0) {
- ace[i].access_mask = mask;
- return NT_STATUS_OK;
- }
- }
- return NT_STATUS_NOT_FOUND;
-}
-
-/*******************************************************************
- delete SID from ACL
-********************************************************************/
-
-NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid)
-{
- unsigned int i = 0;
- unsigned int n_del = 0;
-
- if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER;
-
- if (*num) {
- if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
- return NT_STATUS_NO_MEMORY;
- } else {
- pp_new[0] = NULL;
- }
-
- for (i = 0; i < *num; i ++) {
- if (sid_compare(&old[i].trustee, sid) != 0)
- sec_ace_copy(&(*pp_new)[i], &old[i]);
- else
- n_del ++;
- }
- if (n_del == 0)
- return NT_STATUS_NOT_FOUND;
- else {
- *num -= n_del;
- return NT_STATUS_OK;
- }
-}
-
-/*******************************************************************
- Compares two SEC_ACE structures
-********************************************************************/
-
-bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
-{
- /* Trivial case */
-
- if (!s1 && !s2) {
- return True;
- }
-
- if (!s1 || !s2) {
- return False;
- }
-
- /* Check top level stuff */
-
- if (s1->type != s2->type || s1->flags != s2->flags ||
- s1->access_mask != s2->access_mask) {
- return False;
- }
-
- /* Check SID */
-
- if (!sid_equal(&s1->trustee, &s2->trustee)) {
- return False;
- }
-
- return True;
-}
-
-int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
-{
- int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
- int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
-
- if (a1_inh == a2_inh)
- return 0;
-
- if (!a1_inh && a2_inh)
- return -1;
- return 1;
-}
-
-/*******************************************************************
- Comparison function to apply the order explained below in a group.
-*******************************************************************/
-
-int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
-{
- if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
- (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
- return -1;
-
- if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
- (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
- return 1;
-
- /* Both access denied or access allowed. */
-
- /* 1. ACEs that apply to the object itself */
-
- if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
- (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
- return -1;
- else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
- (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
- return 1;
-
- /* 2. ACEs that apply to a subobject of the object, such as
- * a property set or property. */
-
- if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
- !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
- return -1;
- else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
- !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
- return 1;
-
- return 0;
-}
-
-/*******************************************************************
- Functions to convert a SEC_DESC ACE DACL list into canonical order.
- JRA.
-
---- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
-
-The following describes the preferred order:
-
- To ensure that noninherited ACEs have precedence over inherited ACEs,
- place all noninherited ACEs in a group before any inherited ACEs.
- This ordering ensures, for example, that a noninherited access-denied ACE
- is enforced regardless of any inherited ACE that allows access.
-
- Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
- 1. Access-denied ACEs that apply to the object itself
- 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
- 3. Access-allowed ACEs that apply to the object itself
- 4. Access-allowed ACEs that apply to a subobject of the object"
-
-********************************************************************/
-
-void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
-{
- unsigned int i;
-
- if (!srclist || num_aces == 0)
- return;
-
- /* Sort so that non-inherited ACE's come first. */
- qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
-
- /* Find the boundary between non-inherited ACEs. */
- for (i = 0; i < num_aces; i++ ) {
- SEC_ACE *curr_ace = &srclist[i];
-
- if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
- break;
- }
-
- /* i now points at entry number of the first inherited ACE. */
-
- /* Sort the non-inherited ACEs. */
- if (i)
- qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
-
- /* Now sort the inherited ACEs. */
- if (num_aces - i)
- qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
-}
-
-/*******************************************************************
- Check if this ACE has a SID in common with the token.
-********************************************************************/
-
-bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
-{
- size_t i;
-
- for (i = 0; i < token->num_sids; i++) {
- if (sid_equal(&ace->trustee, &token->user_sids[i]))
- return True;
- }
-
- return False;
-}
diff --git a/source3/lib/secacl.c b/source3/lib/secacl.c
deleted file mode 100644
index 5e82242e1b..0000000000
--- a/source3/lib/secacl.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_ACL handling routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-
-/*******************************************************************
- Create a SEC_ACL structure.
-********************************************************************/
-
-SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, enum security_acl_revision revision,
- int num_aces, SEC_ACE *ace_list)
-{
- SEC_ACL *dst;
- int i;
-
- if((dst = TALLOC_ZERO_P(ctx,SEC_ACL)) == NULL)
- return NULL;
-
- dst->revision = revision;
- dst->num_aces = num_aces;
- dst->size = SEC_ACL_HEADER_SIZE;
-
- /* Now we need to return a non-NULL address for the ace list even
- if the number of aces required is zero. This is because there
- is a distinct difference between a NULL ace and an ace with zero
- entries in it. This is achieved by checking that num_aces is a
- positive number. */
-
- if ((num_aces) &&
- ((dst->aces = TALLOC_ARRAY(ctx, SEC_ACE, num_aces))
- == NULL)) {
- return NULL;
- }
-
- for (i = 0; i < num_aces; i++) {
- dst->aces[i] = ace_list[i]; /* Structure copy. */
- dst->size += ace_list[i].size;
- }
-
- return dst;
-}
-
-/*******************************************************************
- Duplicate a SEC_ACL structure.
-********************************************************************/
-
-SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_acl(ctx, src->revision, src->num_aces, src->aces);
-}
-
-/*******************************************************************
- Compares two SEC_ACL structures
-********************************************************************/
-
-bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
-{
- unsigned int i, j;
-
- /* Trivial cases */
-
- if (!s1 && !s2) return True;
- if (!s1 || !s2) return False;
-
- /* Check top level stuff */
-
- if (s1->revision != s2->revision) {
- DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n",
- s1->revision, s2->revision));
- return False;
- }
-
- if (s1->num_aces != s2->num_aces) {
- DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n",
- s1->revision, s2->revision));
- return False;
- }
-
- /* The ACEs could be in any order so check each ACE in s1 against
- each ACE in s2. */
-
- for (i = 0; i < s1->num_aces; i++) {
- bool found = False;
-
- for (j = 0; j < s2->num_aces; j++) {
- if (sec_ace_equal(&s1->aces[i], &s2->aces[j])) {
- found = True;
- break;
- }
- }
-
- if (!found) return False;
- }
-
- return True;
-}
diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c
index e36fa8a2a1..ae6a41151d 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,40 +80,23 @@ 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;
+ WERROR werr;
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 = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
+ desired_access, key);
- werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key);
+ if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
+ werr = WERR_NO_SUCH_SERVICE;
+ }
-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);
-}
-
-/**
* check if a value exists in a given registry key
*/
static bool smbconf_value_exists(struct registry_key *key, const char *param)
@@ -189,7 +124,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 +132,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 +143,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 +535,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 +548,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 +560,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 +663,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 +678,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 +712,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 +723,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 +744,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 +807,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;
}
@@ -934,21 +874,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 +1071,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 +1106,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/util.c b/source3/lib/util.c
index 89f7be8e6c..ec794ca74e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -899,13 +899,6 @@ 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"));
diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c
index 774ef498b7..76e7402422 100644
--- a/source3/lib/util_nttoken.c
+++ b/source3/lib/util_nttoken.c
@@ -115,3 +115,19 @@ NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+
+/*******************************************************************
+ Check if this ACE has a SID in common with the token.
+********************************************************************/
+
+bool token_sid_in_ace(const NT_USER_TOKEN *token, const struct security_ace *ace)
+{
+ size_t i;
+
+ for (i = 0; i < token->num_sids; i++) {
+ if (sid_equal(&ace->trustee, &token->user_sids[i]))
+ return true;
+ }
+
+ return false;
+}
diff --git a/source3/lib/util_reg_api.c b/source3/lib/util_reg_api.c
index 8f28e9c282..9313193f10 100644
--- a/source3/lib/util_reg_api.c
+++ b/source3/lib/util_reg_api.c
@@ -92,7 +92,7 @@ WERROR registry_pull_value(TALLOC_CTX *mem_ctx,
}
if (!convert_string_talloc(value, CH_UTF16LE, CH_UNIX, tmp,
- length+2, &value->v.sz.str,
+ length+2, (void **)&value->v.sz.str,
&value->v.sz.len, False)) {
SAFE_FREE(tmp);
err = WERR_INVALID_PARAM;
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 83e8a9d355..3604be369f 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -967,20 +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;
- struct tevent_req *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;
@@ -996,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;
}
@@ -1030,18 +1031,14 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
|| !tevent_req_set_endtime(
subreq, state->ev,
timeval_current_ofs(0, state->wait_nsec))) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ goto fail;
}
- subreq->async.fn = open_socket_out_connected;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, open_socket_out_connected, 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;
@@ -1049,17 +1046,17 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
static void open_socket_out_connected(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
- struct open_socket_out_state *state = talloc_get_type_abort(
- req->private_data, struct open_socket_out_state);
+ struct tevent_req *req =
+ tevent_req_callback_data(subreq, struct tevent_req);
+ struct open_socket_out_state *state =
+ tevent_req_data(req, struct open_socket_out_state);
int ret;
int sys_errno;
ret = async_connect_recv(subreq, &sys_errno);
TALLOC_FREE(subreq);
if (ret == 0) {
- async_req_done(req);
+ tevent_req_done(req);
return;
}
@@ -1082,39 +1079,38 @@ static void open_socket_out_connected(struct tevent_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 (!tevent_req_set_endtime(
subreq, state->ev,
timeval_current_ofs(0, state->wait_nsec))) {
- async_req_error(req, ENOMEM);
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- subreq->async.fn = open_socket_out_connected;
- subreq->async.private_data = req;
+ tevent_req_set_callback(subreq, open_socket_out_connected, 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;
+ struct open_socket_out_state *state =
+ tevent_req_data(req, 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;
@@ -1126,7 +1122,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);
@@ -1138,10 +1134,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);
@@ -1157,7 +1153,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,
@@ -1204,6 +1200,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);
@@ -1213,19 +1210,18 @@ 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;
+ tevent_req_set_callback(subreq2, open_socket_out_defer_connected, 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);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, 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 a5adf8f108..222b64667c 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -103,8 +103,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
goto nomem;
}
- subreq->async.fn = wb_req_read_done;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, wb_req_read_done, result);
return result;
nomem:
TALLOC_FREE(result);
@@ -140,8 +139,8 @@ 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 *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
req->private_data, struct req_read_state);
int err;
@@ -213,8 +212,7 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- subreq->async.fn = wb_req_write_done;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, wb_req_write_done, result);
return result;
fail:
@@ -224,8 +222,8 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
static void wb_req_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
int err;
ssize_t ret;
@@ -266,8 +264,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto nomem;
}
- subreq->async.fn = wb_resp_read_done;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, wb_resp_read_done, result);
return result;
nomem:
@@ -288,13 +285,13 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
return -1;
}
}
- return resp->length - 4;
+ return resp->length - buflen;
}
static void wb_resp_read_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
struct resp_read_state *state = talloc_get_type_abort(
req->private_data, struct resp_read_state);
uint8_t *buf;
@@ -367,8 +364,7 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto fail;
}
- subreq->async.fn = wb_resp_write_done;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, wb_resp_write_done, result);
return result;
fail:
@@ -378,8 +374,8 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
static void wb_resp_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
int err;
ssize_t ret;
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index b8d55a944a..7034e668ed 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -224,8 +224,7 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
if (subreq == NULL) {
goto nomem;
}
- subreq->async.fn = wbc_connect_connected;
- subreq->async.private_data = result;
+ tevent_req_set_callback(subreq, wbc_connect_connected, result);
if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
goto nomem;
@@ -245,8 +244,8 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
static void wbc_connect_connected(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
int res, err;
res = async_connect_recv(subreq, &err);
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_ini.c b/source3/libgpo/gpo_ini.c
index aa8f7c7770..edca85530b 100644
--- a/source3/libgpo/gpo_ini.c
+++ b/source3/libgpo/gpo_ini.c
@@ -83,7 +83,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
}
if (!convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX, data_in, n,
- &data_out, &converted_size, False))
+ (void **)&data_out, &converted_size, False))
{
status = NT_STATUS_INVALID_BUFFER_SIZE;
goto out;
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/modules/gpfs.c b/source3/modules/gpfs.c
index 16599005b9..9fc4524654 100644
--- a/source3/modules/gpfs.c
+++ b/source3/modules/gpfs.c
@@ -26,6 +26,7 @@
static bool gpfs_share_modes;
static bool gpfs_leases;
+static bool gpfs_getrealfilename;
static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny);
static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType);
@@ -139,7 +140,8 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl)
int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep,
int *buflen)
{
- if (gpfs_get_realfilename_path_fn == NULL) {
+ if ((!gpfs_getrealfilename)
+ || (gpfs_get_realfilename_path_fn == NULL)) {
errno = ENOSYS;
return -1;
}
@@ -208,6 +210,8 @@ void init_gpfs(void)
gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True);
gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True);
+ gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename",
+ True);
return;
}
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 418e13d9d2..ebeece40ad 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -21,112 +21,6 @@
#ifndef _ONEFS_H
#define _ONEFS_H
-#include "includes.h"
-#include "oplock_onefs.h"
-#include <sys/isi_acl.h>
-
-/* OneFS Module smb.conf parameters and defaults */
-
-/**
-* Specifies when ACLs presented to Windows should be canonicalized
-* into the ordering which Explorer expects.
-*/
-enum onefs_acl_wire_format
-{
- ACL_FORMAT_RAW, /**< Never canonicalize */
- ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */
- ACL_FORMAT_ALWAYS /**< Always canonicalize */
-};
-
-#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_IGNORE_SACLS "ignore sacls"
-#define PARM_IGNORE_SACLS_DEFAULT false
-#define PARM_MTIME_NOW "mtime now files"
-#define PARM_MTIME_NOW_DEFAULT NULL
-#define PARM_MTIME_STATIC "mtime static files"
-#define PARM_MTIME_STATIC_DEFAULT NULL
-#define PARM_MTIME_SLOP "mtime now slop"
-#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"
-#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false
-#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids"
-#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false
-#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list"
-#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL
-
-#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
- (cfg)->ctime_now_list,(conn)->case_sensitive))
-#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
- (cfg)->mtime_now_list,(conn)->case_sensitive))
-#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
- (cfg)->atime_now_list,(conn)->case_sensitive))
-#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
- (cfg)->mtime_static_list,(conn)->case_sensitive))
-#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
- (cfg)->atime_static_list,(conn)->case_sensitive))
-
-/*
- * Store some commonly evaluated parameters to avoid loadparm pain.
- */
-
-#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000
-
-#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001
-
-struct onefs_vfs_config
-{
- int32 init_flags;
-
- /* data for fake timestamps */
- int atime_slop;
- int ctime_slop;
- int mtime_slop;
-
- /* Per-share list of files to fake the create time for. */
- name_compare_entry *ctime_now_list;
-
- /* Per-share list of files to fake the modification time for. */
- name_compare_entry *mtime_now_list;
-
- /* Per-share list of files to fake the access time for. */
- name_compare_entry *atime_now_list;
-
- /* Per-share list of files to fake the modification time for. */
- name_compare_entry *mtime_static_list;
-
- /* The access time will equal the create time. */
- /* The modification time will equal the create time.*/
-
- /* Per-share list of files to fake the access time for. */
- name_compare_entry *atime_static_list;
-};
-
/*
* vfs interface handlers
*/
@@ -233,15 +127,13 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
/*
* Utility functions
*/
+struct ifs_security_descriptor;
NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
struct ifs_security_descriptor *sd, int snum);
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);
-
int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp);
/*
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 7bc4a1728f..6f23d608d4 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -19,10 +19,13 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
#include <isi_acl/isi_acl_util.h>
#include <ifs/ifs_syscalls.h>
+#include <sys/isi_acl.h>
const struct enum_list enum_onefs_acl_wire_format[] = {
{ACL_FORMAT_RAW, "No Format"},
@@ -273,9 +276,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 +614,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 +755,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 +893,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 +945,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..7311e1961e 100644
--- a/source3/modules/onefs_cbrl.c
+++ b/source3/modules/onefs_cbrl.c
@@ -18,6 +18,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
#include <ifs/ifs_syscalls.h>
@@ -255,6 +256,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 +304,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 +349,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 +364,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 +383,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 +392,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 +421,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 +435,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 +447,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_config.c b/source3/modules/onefs_config.c
new file mode 100644
index 0000000000..06f4b16ac1
--- /dev/null
+++ b/source3/modules/onefs_config.c
@@ -0,0 +1,276 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Support for OneFS
+ *
+ * Copyright (C) Todd Stecher, 2009
+ * 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 "includes.h"
+#include "onefs_config.h"
+
+#include <ifs/ifs_syscalls.h>
+
+#define ONEFS_DATA_FASTBUF 10
+
+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 connection_struct *conn,
+ struct onefs_vfs_share_config *cfg)
+{
+ const char **parm;
+ int snum = SNUM(conn);
+
+ parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
+ PARM_ATIME_NOW_DEFAULT);
+
+ if (parm) {
+ cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
+ set_namearray(&cfg->atime_now_list,*parm);
+ }
+
+ parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW,
+ PARM_CTIME_NOW_DEFAULT);
+
+ if (parm) {
+ cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
+ set_namearray(&cfg->ctime_now_list,*parm);
+ }
+
+ parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW,
+ PARM_MTIME_NOW_DEFAULT);
+
+ if (parm) {
+ cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
+ set_namearray(&cfg->mtime_now_list,*parm);
+ }
+
+ parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC,
+ PARM_ATIME_STATIC_DEFAULT);
+
+ if (parm) {
+ cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
+ set_namearray(&cfg->atime_static_list,*parm);
+ }
+
+ parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC,
+ PARM_MTIME_STATIC_DEFAULT);
+
+ if (parm) {
+ cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
+ set_namearray(&cfg->mtime_static_list,*parm);
+ }
+
+ cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP,
+ PARM_ATIME_SLOP_DEFAULT);
+ cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP,
+ PARM_CTIME_SLOP_DEFAULT);
+ cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP,
+ 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);
+ }
+
+ /* If the dot snap tilde option has changed update the process. */
+ if (reconfig_tilde) {
+ onefs_sys_config_tilde(&global_config);
+ }
+}
+
+int onefs_load_config(connection_struct *conn)
+{
+ int snum = SNUM(conn);
+ int share_count = lp_numservices();
+
+ /* Share config */
+ if (!pvfs_share_config) {
+
+ if (share_count <= ONEFS_DATA_FASTBUF)
+ pvfs_share_config = vfs_share_config;
+ else {
+ pvfs_share_config =
+ SMB_MALLOC_ARRAY(struct onefs_vfs_share_config,
+ share_count);
+ if (!pvfs_share_config) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ memset(pvfs_share_config, 0,
+ (sizeof(struct onefs_vfs_share_config) *
+ share_count));
+ }
+ }
+
+ if ((pvfs_share_config[snum].init_flags &
+ ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
+ pvfs_share_config[snum].init_flags =
+ ONEFS_VFS_CONFIG_INITIALIZED;
+ 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_share_config *cfg)
+{
+ if (vfs_share_config[snum].init_flags & config_type)
+ *cfg = vfs_share_config[snum];
+ else
+ return false;
+
+ return true;
+}
+
+
+/**
+ * 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/onefs_config.h b/source3/modules/onefs_config.h
new file mode 100644
index 0000000000..f0f48e6379
--- /dev/null
+++ b/source3/modules/onefs_config.h
@@ -0,0 +1,160 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * OneFS vfs module configuration and defaults
+ *
+ * Copyright (C) Steven Danneman, 2008
+ * 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_CONFIG_H
+#define _ONEFS_CONFIG_H
+
+/**
+* Specifies when ACLs presented to Windows should be canonicalized
+* into the ordering which Explorer expects.
+*/
+enum onefs_acl_wire_format
+{
+ ACL_FORMAT_RAW, /**< Never canonicalize */
+ ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */
+ ACL_FORMAT_ALWAYS /**< Always canonicalize */
+};
+
+#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_IGNORE_STREAMS "ignore streams"
+#define PARM_IGNORE_STREAMS_DEFAULT false
+#define PARM_MTIME_NOW "mtime now files"
+#define PARM_MTIME_NOW_DEFAULT NULL
+#define PARM_MTIME_STATIC "mtime static files"
+#define PARM_MTIME_STATIC_DEFAULT NULL
+#define PARM_MTIME_SLOP "mtime now slop"
+#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"
+#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL
+
+#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
+ (cfg)->ctime_now_list,(conn)->case_sensitive))
+#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
+ (cfg)->mtime_now_list,(conn)->case_sensitive))
+#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
+ (cfg)->atime_now_list,(conn)->case_sensitive))
+#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
+ (cfg)->mtime_static_list,(conn)->case_sensitive))
+#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\
+ (cfg)->atime_static_list,(conn)->case_sensitive))
+
+/*
+ * Store some commonly evaluated parameters to avoid loadparm pain.
+ */
+
+#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000
+
+#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001
+
+struct onefs_vfs_share_config
+{
+ uint32_t init_flags;
+
+ /* data for fake timestamps */
+ int atime_slop;
+ int ctime_slop;
+ int mtime_slop;
+
+ /* Per-share list of files to fake the create time for. */
+ name_compare_entry *ctime_now_list;
+
+ /* Per-share list of files to fake the modification time for. */
+ name_compare_entry *mtime_now_list;
+
+ /* Per-share list of files to fake the access time for. */
+ name_compare_entry *atime_now_list;
+
+ /* Per-share list of files to fake the modification time for. */
+ name_compare_entry *mtime_static_list;
+
+ /* The access time will equal the create time. */
+ /* The modification time will equal the create time.*/
+
+ /* Per-share list of files to fake the access time for. */
+ 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;
+};
+
+int onefs_load_config(connection_struct *conn);
+
+bool onefs_get_config(int snum, int config_type,
+ struct onefs_vfs_share_config *cfg);
+
+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_CONFIG_H */
diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c
index 83622b2bcd..68a58b3bb2 100644
--- a/source3/modules/onefs_dir.c
+++ b/source3/modules/onefs_dir.c
@@ -19,7 +19,9 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
#include <ifs/ifs_syscalls.h>
diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c
index 40f690876d..3455afd4ab 100644
--- a/source3/modules/onefs_notify.c
+++ b/source3/modules/onefs_notify.c
@@ -33,6 +33,7 @@
* CompletionFilter and WatchTree of open SMB requests, and return notify
* events back to the proper SMB requests */
+#include "includes.h"
#include "onefs.h"
#include <ifs/ifs_types.h>
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index 382ecc60a3..d3ba0ac979 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -32,7 +32,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
+#include "oplock_onefs.h"
#include "smbd/globals.h"
extern const struct generic_mapping file_generic_mapping;
@@ -193,7 +196,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
&base, &stream);
}
/* It's a stream, so pass in the base_fd */
- if (stream != NULL) {
+ if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
SMB_ASSERT(fsp->base_fsp);
/*
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 9616ca48d5..05b36d7d3c 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -19,7 +19,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
+
#include <sys/isi_enc.h>
/*
@@ -160,18 +163,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 +203,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 +233,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;
@@ -658,6 +671,11 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
state.streams = NULL;
state.num_streams = 0;
+ if (lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
+ PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) {
+ goto out;
+ }
+
/* Add the default stream. */
if (S_ISREG(sbuf.st_mode)) {
if (!add_one_stream(mem_ctx,
@@ -689,7 +707,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
return state.status;
}
}
-
+ out:
*num_streams = state.num_streams;
*streams = state.streams;
return NT_STATUS_OK;
diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c
index 76df006d82..b8b059bce9 100644
--- a/source3/modules/onefs_system.c
+++ b/source3/modules/onefs_system.c
@@ -18,10 +18,14 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
+#include "oplock_onefs.h"
#include <ifs/ifs_syscalls.h>
#include <isi_acl/isi_acl_util.h>
+#include <sys/isi_acl.h>
/*
* Initialize the sm_lock struct before passing it to ifs_createfile.
@@ -95,6 +99,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;
@@ -196,6 +202,7 @@ int onefs_sys_create_file(connection_struct *conn,
}
out:
+ END_PROFILE(syscall_createfile);
aclu_free_sd(pifs_sd, false);
return ret_fd;
@@ -307,6 +314,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
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)) {
@@ -320,6 +329,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
/* 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;
}
@@ -391,6 +401,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
/* Handle case 1: short read -> truncated file. */
if (ret == 0) {
+ END_PROFILE(syscall_sendfile);
return ret;
}
@@ -402,6 +413,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
PARM_SENDFILE_LARGE_READS_DEFAULT)) {
DEBUG(3, ("Not attempting non-atomic large sendfile: "
"%lu bytes\n", count));
+ END_PROFILE(syscall_sendfile);
return 0;
}
@@ -421,6 +433,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
DEBUG(1, ("error on non-atomic large sendfile "
"(%lu bytes): %s\n", count,
strerror(errno)));
+ END_PROFILE(syscall_sendfile);
return ret;
}
@@ -439,9 +452,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
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;
}
@@ -455,6 +470,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
count, strerror(errno)));
}
+ END_PROFILE(syscall_sendfile);
return ret;
}
@@ -509,10 +525,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;
}
@@ -624,6 +643,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;
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 909de9d7c8..a77f6d60f4 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -186,20 +186,26 @@ 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 && 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. */
@@ -270,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));
@@ -278,14 +285,19 @@ 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. */
@@ -316,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",
@@ -324,7 +337,13 @@ 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);
}
@@ -494,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 && 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);
@@ -583,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;
}
@@ -626,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;
}
@@ -728,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);
}
@@ -813,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;
}
@@ -848,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..49e4899879 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 && 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_gpfs.c b/source3/modules/vfs_gpfs.c
index 1d7cdba014..3c061ece79 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -96,6 +96,11 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
TALLOC_FREE(full_path);
+ if ((result == -1) && (errno == ENOSYS)) {
+ return SMB_VFS_NEXT_GET_REAL_FILENAME(
+ handle, path, name, mem_ctx, found_name);
+ }
+
if (result == -1) {
DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n",
strerror(errno)));
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 60c2c977a4..2ec6e069c3 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -20,122 +20,21 @@
#include "includes.h"
#include "onefs.h"
+#include "onefs_config.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
-#define ONEFS_DATA_FASTBUF 10
-
-struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF];
-struct onefs_vfs_config *pshare_config;
-
-static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle,
- struct onefs_vfs_config *cfg)
-{
- const char **parm;
- int snum = SNUM(handle->conn);
-
- parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
- PARM_ATIME_NOW_DEFAULT);
-
- if (parm) {
- cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
- set_namearray(&cfg->atime_now_list,*parm);
- }
-
- parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW,
- PARM_CTIME_NOW_DEFAULT);
-
- if (parm) {
- cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
- set_namearray(&cfg->ctime_now_list,*parm);
- }
-
- parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW,
- PARM_MTIME_NOW_DEFAULT);
-
- if (parm) {
- cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
- set_namearray(&cfg->mtime_now_list,*parm);
- }
-
- parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC,
- PARM_ATIME_STATIC_DEFAULT);
-
- if (parm) {
- cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
- set_namearray(&cfg->atime_static_list,*parm);
- }
-
- parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC,
- PARM_MTIME_STATIC_DEFAULT);
-
- if (parm) {
- cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS;
- set_namearray(&cfg->mtime_static_list,*parm);
- }
-
- cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP,
- PARM_ATIME_SLOP_DEFAULT);
- cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP,
- PARM_CTIME_SLOP_DEFAULT);
- cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP,
- PARM_MTIME_SLOP_DEFAULT);
-}
-
-
-static int onefs_load_config(struct vfs_handle_struct *handle)
-{
- int snum = SNUM(handle->conn);
- int share_count = lp_numservices();
-
- if (!pshare_config) {
-
- if (share_count <= ONEFS_DATA_FASTBUF)
- pshare_config = share_config;
- else {
- pshare_config =
- SMB_MALLOC_ARRAY(struct onefs_vfs_config,
- share_count);
- if (!pshare_config) {
- errno = ENOMEM;
- return -1;
- }
-
- memset(pshare_config, 0,
- (sizeof(struct onefs_vfs_config) * share_count));
- }
- }
-
- if ((pshare_config[snum].init_flags &
- ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
- pshare_config[snum].init_flags =
- ONEFS_VFS_CONFIG_INITIALIZED;
- onefs_load_faketimestamp_config(handle,
- &pshare_config[snum]);
- }
-
- return 0;
-}
-
-bool onefs_get_config(int snum, int config_type,
- struct onefs_vfs_config *cfg)
-{
- if (share_config[snum].init_flags & config_type)
- *cfg = share_config[snum];
- else
- return false;
-
- return true;
-}
-
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);
}
@@ -323,7 +222,14 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
{
- return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
+ uint32_t result = 0;
+
+ if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
+ PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) {
+ result |= FILE_NAMED_STREAMS;
+ }
+
+ return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle);
}
static vfs_op_tuple onefs_ops[] = {
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 9329be7a9c..023d2b9ec0 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -494,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;
}
@@ -678,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/param/loadparm.c b/source3/param/loadparm.c
index 89c706d874..f49a1bc4c9 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4668,7 +4668,9 @@ static int max_open_files(void)
#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
{
- struct rlimit rl = {};
+ struct rlimit rl;
+
+ ZERO_STRUCT(rl);
if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
rlimit_max = rl.rlim_cur;
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 53845117e2..9c20042a62 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -1308,13 +1308,20 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
if (!ret || expired) {
/* Not in cache. Ask winbindd. */
if (!winbind_uid_to_sid(psid, uid)) {
- if (!winbind_ping()) {
- legacy_uid_to_sid(psid, uid);
- return;
- }
+ /*
+ * We shouldn't return the NULL SID
+ * here if winbind was running and
+ * couldn't map, as winbind will have
+ * added a negative entry that will
+ * cause us to go though the
+ * legacy_uid_to_sid()
+ * function anyway in the case above
+ * the next time we ask.
+ */
+ DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
+ "for uid %u\n", uid));
- DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n",
- uid));
+ legacy_uid_to_sid(psid, uid);
return;
}
}
@@ -1354,13 +1361,20 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
if (!ret || expired) {
/* Not in cache. Ask winbindd. */
if (!winbind_gid_to_sid(psid, gid)) {
- if (!winbind_ping()) {
- legacy_gid_to_sid(psid, gid);
- return;
- }
+ /*
+ * We shouldn't return the NULL SID
+ * here if winbind was running and
+ * couldn't map, as winbind will have
+ * added a negative entry that will
+ * cause us to go though the
+ * legacy_gid_to_sid()
+ * function anyway in the case above
+ * the next time we ask.
+ */
+ DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
+ "for gid %u\n", gid));
- DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n",
- gid));
+ legacy_gid_to_sid(psid, gid);
return;
}
}
diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_wbc_sam.c
index 51b8618aad..d2c7fda293 100644
--- a/source3/passdb/pdb_onefs_sam.c
+++ b/source3/passdb/pdb_wbc_sam.c
@@ -1,6 +1,8 @@
/*
Unix SMB/CIFS implementation.
- Password and authentication handling for wbclient
+
+ Password and authentication handling by wbclient
+
Copyright (C) Andrew Bartlett 2002
Copyright (C) Jelmer Vernooij 2002
Copyright (C) Simo Sorce 2003
@@ -21,12 +23,25 @@
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_onefs_sam_getsampw(struct pdb_methods *methods,
+static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods,
struct samu *user,
const struct passwd *pwd)
{
@@ -44,29 +59,29 @@ static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods,
return result;
}
-static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname)
+static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname)
{
- return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname));
+ return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname));
}
-static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid)
+static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid)
{
- return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid));
+ return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid));
}
-static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
+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_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
+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_onefs_sam_sid_to_id(struct pdb_methods *methods,
+static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods,
const DOM_SID *sid,
union unid_t *id, enum lsa_SidType *type)
{
@@ -82,7 +97,7 @@ static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods,
return true;
}
-static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods,
+static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const DOM_SID *group,
uint32 **pp_member_rids,
@@ -91,7 +106,7 @@ static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods,
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods,
+static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
struct samu *user,
DOM_SID **pp_sids,
@@ -100,10 +115,12 @@ static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods
{
size_t i;
const char *username = pdb_get_username(user);
+ uint32_t num_groups;
- if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) {
+ 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");
@@ -123,7 +140,7 @@ static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods
return NT_STATUS_OK;
}
-static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods,
+static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods,
const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
@@ -164,23 +181,23 @@ done:
return result;
}
-static NTSTATUS pdb_onefs_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
{
return NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS pdb_onefs_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
{
return NT_STATUS_UNSUCCESSFUL;
}
-static bool pdb_onefs_sam_search_groups(struct pdb_methods *methods,
+static bool pdb_wbc_sam_search_groups(struct pdb_methods *methods,
struct pdb_search *search)
{
return false;
}
-static bool pdb_onefs_sam_search_aliases(struct pdb_methods *methods,
+static bool pdb_wbc_sam_search_aliases(struct pdb_methods *methods,
struct pdb_search *search,
const DOM_SID *sid)
{
@@ -188,7 +205,7 @@ static bool pdb_onefs_sam_search_aliases(struct pdb_methods *methods,
return false;
}
-static bool pdb_onefs_sam_get_trusteddom_pw(struct pdb_methods *methods,
+static bool pdb_wbc_sam_get_trusteddom_pw(struct pdb_methods *methods,
const char *domain,
char **pwd,
DOM_SID *sid,
@@ -198,7 +215,7 @@ static bool pdb_onefs_sam_get_trusteddom_pw(struct pdb_methods *methods,
}
-static bool pdb_onefs_sam_set_trusteddom_pw(struct pdb_methods *methods,
+static bool pdb_wbc_sam_set_trusteddom_pw(struct pdb_methods *methods,
const char *domain,
const char *pwd,
const DOM_SID *sid)
@@ -206,13 +223,13 @@ static bool pdb_onefs_sam_set_trusteddom_pw(struct pdb_methods *methods,
return false;
}
-static bool pdb_onefs_sam_del_trusteddom_pw(struct pdb_methods *methods,
+static bool pdb_wbc_sam_del_trusteddom_pw(struct pdb_methods *methods,
const char *domain)
{
return false;
}
-static NTSTATUS pdb_onefs_sam_enum_trusteddoms(struct pdb_methods *methods,
+static NTSTATUS pdb_wbc_sam_enum_trusteddoms(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 *num_domains,
struct trustdom_info ***domains)
@@ -230,7 +247,7 @@ static bool _make_group_map(struct pdb_methods *methods, const char *domain, con
return true;
}
-static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
+static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
DOM_SID sid)
{
NTSTATUS result = NT_STATUS_OK;
@@ -269,7 +286,7 @@ done:
return result;
}
-static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
+static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
gid_t gid)
{
NTSTATUS result = NT_STATUS_OK;
@@ -309,7 +326,7 @@ done:
return result;
}
-static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
+static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
const char *name)
{
NTSTATUS result = NT_STATUS_OK;
@@ -347,7 +364,7 @@ done:
return result;
}
-static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods,
+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)
@@ -355,21 +372,21 @@ static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods,
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods,
+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_onefs_sam_enum_aliasmem(struct pdb_methods *methods,
+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_onefs_sam_alias_memberships(struct pdb_methods *methods,
+static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
const DOM_SID *members,
@@ -384,7 +401,7 @@ static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods,
return NT_STATUS_OK;
}
-static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location)
+static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location)
{
NTSTATUS result;
@@ -392,34 +409,34 @@ static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *
return result;
}
- (*pdb_method)->name = "onefs_sam";
-
- (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam;
- (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid;
-
- (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid;
- (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid;
- (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam;
- (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping;
- (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members;
- (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships;
- (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo;
- (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem;
- (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships;
- (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids;
- (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy;
- (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy;
- (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid;
- (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid;
- (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id;
-
- (*pdb_method)->search_groups = pdb_onefs_sam_search_groups;
- (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases;
-
- (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw;
- (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw;
- (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw;
- (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms;
+ (*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;
@@ -427,7 +444,7 @@ static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *
return NT_STATUS_OK;
}
-NTSTATUS pdb_onefs_sam_init(void)
+NTSTATUS pdb_wbc_sam_init(void)
{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam);
+ return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam);
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index bbe8ebc2bc..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;
}
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/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 8ef83a19a1..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;
@@ -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 c160622054..f8c382536f 100644
--- a/source3/registry/reg_dispatcher.c
+++ b/source3/registry/reg_dispatcher.c
@@ -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 19e9aae0f8..d76d20c962 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -137,6 +137,149 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
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
********************************************************************/
@@ -271,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)
{
@@ -691,116 +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_enumprinterdrivers (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 level, const char *env,
@@ -886,41 +887,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli,
/**********************************************************************
**********************************************************************/
-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)
@@ -1051,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)
@@ -1359,5 +1258,4 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me
return out.status;
}
-
/** @} **/
diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c
index c0fa41b0de..b1d9d8fbe1 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,61 @@ 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;
+ }
+ tevent_req_set_callback(subreq, rpc_sock_read_done, 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 =
+ tevent_req_callback_data(subreq, struct async_req);
+ struct rpc_sock_read_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_read_state);
+ 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 +110,51 @@ 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;
+ }
+ tevent_req_set_callback(subreq, rpc_sock_write_done, result);
+ return result;
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_sock_write_done(struct tevent_req *subreq)
+{
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
+ struct rpc_sock_write_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_sock_write_state);
+ 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 12c7af49cf..78c041f863 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -71,78 +71,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
}
/*******************************************************************
-********************************************************************/
-
-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
********************************************************************/
@@ -331,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.
********************************************************************/
@@ -2291,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)
@@ -2791,316 +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;
-}
-
-/*******************************************************************
make a BUFFER5 struct from a uint16*
******************************************************************/
@@ -3125,37 +2324,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16
}
/*******************************************************************
- ********************************************************************/
-
-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)
@@ -3931,20 +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;
-}
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
index edd1cfacb8..f83c4fc3b8 100644
--- a/source3/rpc_server/srv_eventlog_lib.c
+++ b/source3/rpc_server/srv_eventlog_lib.c
@@ -936,7 +936,7 @@ NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx,
size_t len;
if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
t->sid.data, t->sid.length,
- &sid_str, &len, false)) {
+ (void **)&sid_str, &len, false)) {
return NT_STATUS_INVALID_SID;
}
if (len > 0) {
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 33e89c8acb..a5d059c06a 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1247,14 +1247,13 @@ static void np_write_trigger(struct async_req *req)
if (async_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = np_write_done;
- subreq->async.private_data = req;
+ tevent_req_set_callback(subreq, np_write_done, req);
}
static void np_write_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
struct np_write_state *state = talloc_get_type_abort(
req->private_data, struct np_write_state);
ssize_t received;
@@ -1398,14 +1397,13 @@ static void np_read_trigger(struct async_req *req)
if (async_req_nomem(subreq, req)) {
return;
}
- subreq->async.fn = np_read_done;
- subreq->async.private_data = req;
+ tevent_req_set_callback(subreq, np_read_done, req);
}
static void np_read_done(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.private_data, struct async_req);
+ struct async_req *req =
+ tevent_req_callback_data(subreq, struct async_req);
struct np_read_state *state = talloc_get_type_abort(
req->private_data, struct np_read_state);
ssize_t received;
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 62301c001b..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;
}
@@ -3486,7 +3486,6 @@ static const struct s_notify_info_data_table notify_info_data_table[] =
{ 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 },
-{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
};
/*******************************************************************
@@ -3519,7 +3518,7 @@ static bool search_notify(enum spoolss_NotifyType type,
{
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) {
@@ -4354,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;
@@ -6619,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;
}
@@ -8180,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_IS_OK(werror)) {
- 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;
@@ -9834,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_IS_OK(result)) {
- 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;
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 17ff818de6..5b55ac3e2a 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,36 @@ 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;
+ info.info2.secdesc = NULL;
+ info.info2.devmode = NULL;
- 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 +543,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 +576,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 +620,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 +644,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 +669,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 +754,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 +782,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 +796,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 +812,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 +847,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 +894,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;
@@ -1058,7 +1082,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
POLICY_HND pol;
WERROR werror;
uint32 info_level = 3;
- bool opened_hnd = False;
const char *printername;
uint32 i;
bool success = False;
@@ -1090,8 +1113,6 @@ 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++) {
@@ -1133,7 +1154,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 )
@@ -1489,14 +1510,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)
@@ -1506,9 +1521,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];
@@ -1536,25 +1549,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]);
@@ -1570,11 +1566,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)
@@ -1594,15 +1595,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;
@@ -1610,10 +1609,20 @@ 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.info2.devmode = NULL;
+ info.info2.secdesc = NULL;
+ 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;;
@@ -1624,7 +1633,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;
@@ -1808,14 +1817,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;
}
@@ -1830,32 +1840,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;
@@ -1871,7 +1907,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;
@@ -1893,8 +1928,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;
@@ -1918,7 +1951,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;
@@ -1980,6 +2013,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)
{
@@ -1987,16 +2042,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;
}
@@ -2011,26 +2066,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,
@@ -2042,9 +2099,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;
@@ -2061,7 +2126,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 */
@@ -2081,8 +2145,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,
@@ -2094,7 +2156,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;
@@ -2110,7 +2172,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;
@@ -2132,8 +2193,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);
@@ -2150,7 +2209,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;
@@ -2166,9 +2225,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();
@@ -2216,17 +2273,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 */
@@ -2306,18 +2362,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;
@@ -2368,13 +2427,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;
@@ -2398,8 +2497,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,
@@ -2423,7 +2520,7 @@ 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;
@@ -2432,13 +2529,89 @@ done:
/****************************************************************************
****************************************************************************/
+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;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
WERROR result;
uint32 i=0, val_needed, data_needed;
- bool got_hnd = False;
const char *printername;
POLICY_HND hnd;
@@ -2458,8 +2631,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,
@@ -2477,7 +2648,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;
@@ -2492,7 +2663,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;
@@ -2516,8 +2686,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 )) )
@@ -2535,7 +2703,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;
@@ -2549,7 +2717,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;
@@ -2576,8 +2743,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);
@@ -2601,7 +2766,7 @@ done:
SAFE_FREE(keylist);
- if (got_hnd)
+ if (is_valid_policy_hnd(&hnd))
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
return result;
@@ -2617,7 +2782,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
const char *printername;
const char *clientname;
POLICY_HND hnd;
- bool got_hnd = False;
WERROR result;
NTSTATUS status;
struct spoolss_NotifyOption option;
@@ -2641,8 +2805,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
goto done;
}
- got_hnd = True;
-
/* Create spool options */
option.version = 2;
@@ -2694,7 +2856,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;
@@ -2706,12 +2868,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);
@@ -2720,7 +2886,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);
@@ -2739,7 +2909,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;
@@ -2747,7 +2917,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;
@@ -2756,7 +2930,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;
@@ -2767,14 +2945,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");
@@ -2905,6 +3077,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 ef975cfbc4..7a4b90c7cf 100644
--- a/source3/services/services_db.c
+++ b/source3/services/services_db.c
@@ -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/conn.c b/source3/smbd/conn.c
index 4b467b0312..a52f2d2e96 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -140,6 +140,7 @@ find_again:
return NULL;
}
conn->cnum = i;
+ conn->force_group_gid = (gid_t)-1;
bitmap_set(bmap, i);
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index fe7ba1cc46..abffcd2f4f 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -34,6 +34,11 @@ bool can_access_file_acl(struct connection_struct *conn,
uint32_t access_granted;
struct security_descriptor *secdesc = NULL;
+ if (conn->server_info->utok.uid == 0 || conn->admin_user) {
+ /* I'm sorry sir, I didn't know you were root... */
+ return true;
+ }
+
status = SMB_VFS_GET_NT_ACL(conn, fname,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
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/open.c b/source3/smbd/open.c
index a42705adb6..acd347520d 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -76,6 +76,15 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
*access_granted = 0;
+ if (conn->server_info->utok.uid == 0 || conn->admin_user) {
+ /* I'm sorry sir, I didn't know you were root... */
+ *access_granted = access_mask;
+ if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
+ *access_granted |= FILE_GENERIC_ALL;
+ }
+ return NT_STATUS_OK;
+ }
+
status = SMB_VFS_GET_NT_ACL(conn, fname,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
@@ -2457,6 +2466,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",
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b30ef23c0e..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;
}
@@ -2808,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) {
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 346e8973de..538e04938e 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -730,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);
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index dcdd69f997..eb16a2601e 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -833,6 +833,14 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*pstatus = status;
return NULL;
}
+
+ /*
+ * We need to cache this gid, to use within
+ * change_to_user() separately from the conn->server_info
+ * struct. We only use conn->server_info directly if
+ * "force_user" was set.
+ */
+ conn->force_group_gid = conn->server_info->utok.gid;
}
conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID;
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/uid.c b/source3/smbd/uid.c
index 4f059bdb59..f8c55b1b8f 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -254,6 +254,8 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
if((group_c = *lp_force_group(snum))) {
+ SMB_ASSERT(conn->force_group_gid != (gid_t)-1);
+
if(group_c == '+') {
/*
@@ -266,15 +268,18 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
int i;
for (i = 0; i < num_groups; i++) {
if (group_list[i]
- == conn->server_info->utok.gid) {
- gid = conn->server_info->utok.gid;
+ == conn->force_group_gid) {
+ conn->server_info->utok.gid =
+ conn->force_group_gid;
+ gid = conn->force_group_gid;
gid_to_sid(&conn->server_info->ptok
->user_sids[1], gid);
break;
}
}
} else {
- gid = conn->server_info->utok.gid;
+ conn->server_info->utok.gid = conn->force_group_gid;
+ gid = conn->force_group_gid;
gid_to_sid(&conn->server_info->ptok->user_sids[1],
gid);
}
diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 0c2cd24fb2..38a2553e53 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -338,11 +338,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 +352,72 @@ 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;
}
}
+
+ /*
+ * Wrap the importing of shares into a transaction,
+ * but only 100 at a time, in order to serve memory.
+ * The allocated memory accumulates across the actions
+ * within the transaction, and for me, some 1500
+ * imported shares, the MAX_TALLOC_SIZE of 256 MB
+ * was exceeded.
+ */
+ werr = smbconf_transaction_start(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error starting transaction: %s\n",
+ win_errstr(werr));
+ goto done;
+ }
+
for (sidx = 0; sidx < num_shares; sidx++) {
werr = import_process_service(c, conf_ctx,
services[sidx]);
if (!W_ERROR_IS_OK(werr)) {
+ goto cancel;
+ }
+
+ if (sidx % 100) {
+ continue;
+ }
+
+ werr = smbconf_transaction_commit(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error committing transaction: %s\n",
+ win_errstr(werr));
+ goto done;
+ }
+ werr = smbconf_transaction_start(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error starting transaction: %s\n",
+ win_errstr(werr));
goto done;
}
}
}
- 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 17df69597f..8116764d9b 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -775,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;
@@ -794,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));
@@ -1027,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) {
@@ -1039,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],
@@ -1047,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;
}
@@ -1216,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;
@@ -1246,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:
@@ -1269,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;
@@ -1283,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;
@@ -1298,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,
@@ -1310,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,
@@ -1322,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);
}
/**
@@ -1355,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))
@@ -1387,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:
@@ -1424,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;
@@ -1464,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);
@@ -1530,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;
}
}
@@ -1579,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);
}
@@ -1625,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;
@@ -1686,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 */
@@ -1758,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;
}
}
@@ -1773,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) {
@@ -1816,14 +1863,13 @@ 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;
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;
@@ -1900,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;
@@ -1914,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 */
@@ -1965,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;
}
@@ -1976,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;
}
}
@@ -1992,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) {
@@ -2043,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"));
@@ -2100,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;
}
@@ -2125,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);
@@ -2146,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) {
@@ -2208,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;
@@ -2221,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"));
@@ -2280,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"));
}
@@ -2325,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,
@@ -2345,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
@@ -2529,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;
}
}
@@ -2548,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 bbbaaf089f..0ac93dedeb 100644
--- a/source3/utils/profiles.c
+++ b/source3/utils/profiles.c
@@ -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/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c
index b22e5af94a..5c29ba0b22 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -304,6 +304,11 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
char *u_filter = NULL;
char *g_filter = NULL;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
/* Only do query if we are online */
if (idmap_is_offline()) {
return NT_STATUS_FILE_IS_OFFLINE;
@@ -516,6 +521,11 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
int i;
char *sidstr;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
/* Only do query if we are online */
if (idmap_is_offline()) {
return NT_STATUS_FILE_IS_OFFLINE;
diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c
index 7e186ca8a1..e2fcda83d3 100644
--- a/source3/winbindd/idmap_adex/idmap_adex.c
+++ b/source3/winbindd/idmap_adex/idmap_adex.c
@@ -159,6 +159,11 @@ static NTSTATUS _idmap_adex_get_sid_from_id(struct
NTSTATUS nt_status;
struct likewise_cell *cell;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
nt_status = _idmap_adex_init(dom, NULL);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
@@ -207,6 +212,11 @@ static NTSTATUS _idmap_adex_get_id_from_sid(struct
NTSTATUS nt_status;
struct likewise_cell *cell;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
nt_status = _idmap_adex_init(dom, NULL);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index 7dd94aede0..42830720f3 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -160,6 +160,11 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
nt_status = be_init(dom, NULL);
BAIL_ON_NTSTATUS_ERROR(nt_status);
@@ -206,6 +211,11 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
nt_status = be_init(dom, NULL);
BAIL_ON_NTSTATUS_ERROR(nt_status);
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/idmap_nss.c b/source3/winbindd/idmap_nss.c
index 156fdc7cc9..f50e6172ba 100644
--- a/source3/winbindd/idmap_nss.c
+++ b/source3/winbindd/idmap_nss.c
@@ -44,6 +44,11 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
@@ -130,6 +135,11 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
diff --git a/source3/winbindd/idmap_rid.c b/source3/winbindd/idmap_rid.c
index 9d1898708c..359bbfd411 100644
--- a/source3/winbindd/idmap_rid.c
+++ b/source3/winbindd/idmap_rid.c
@@ -171,6 +171,11 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
@@ -205,6 +210,11 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index 3a64979f33..22c17578e6 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -775,6 +775,11 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
@@ -813,6 +818,11 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c
index fb90dd097e..b2723270eb 100644
--- a/source3/winbindd/idmap_tdb2.c
+++ b/source3/winbindd/idmap_tdb2.c
@@ -655,6 +655,11 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
@@ -692,6 +697,11 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
+ /* initialize the status to avoid suprise */
+ for (i = 0; ids[i]; i++) {
+ ids[i]->status = ID_UNKNOWN;
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {