summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2008-01-16 23:24:44 +0300
committerAlexander Bokovoy <ab@samba.org>2008-01-16 23:24:44 +0300
commitfd03ea4a903b79a0a7894315b3b43fb08108f938 (patch)
tree0dbce899aca9e727977b2a0becbcc78c6c2de6a4 /source3
parente2ffd5110173c6c7d9c15853646988e536331ed0 (diff)
parent60c3ec3fca08b7d36df760cd6093adb5a807afa0 (diff)
downloadsamba-fd03ea4a903b79a0a7894315b3b43fb08108f938.tar.gz
samba-fd03ea4a903b79a0a7894315b3b43fb08108f938.tar.bz2
samba-fd03ea4a903b79a0a7894315b3b43fb08108f938.zip
Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
(This used to be commit b01f34141509c90b12003786957790866c286cba)
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in49
-rw-r--r--source3/client/cifs.spnego.c63
-rw-r--r--source3/configure.in17
-rw-r--r--source3/groupdb/mapping_ldb.c2
-rw-r--r--source3/groupdb/mapping_tdb.c2
-rw-r--r--source3/include/ctdbd_conn.h6
-rw-r--r--source3/include/dbwrap.h1
-rw-r--r--source3/include/libsmbclient.h2
-rw-r--r--source3/include/rpc_lsa.h19
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/include/vfs.h19
-rw-r--r--source3/include/vfs_macros.h18
-rw-r--r--source3/lib/conn_tdb.c2
-rw-r--r--source3/lib/ctdbd_conn.c36
-rw-r--r--source3/lib/dbwrap.c12
-rw-r--r--source3/lib/dbwrap_ctdb.c178
-rw-r--r--source3/lib/dbwrap_file.c5
-rw-r--r--source3/lib/dbwrap_tdb.c21
-rw-r--r--source3/lib/dbwrap_util.c90
-rw-r--r--source3/lib/messages_ctdbd.c4
-rw-r--r--source3/lib/netapi/serverinfo.c2
-rw-r--r--source3/lib/tdb/common/open.c3
-rw-r--r--source3/lib/tdb/common/tdb_private.h1
-rw-r--r--source3/lib/tdb/common/transaction.c29
-rw-r--r--source3/lib/util.c13
-rw-r--r--source3/lib/util_reg.c1
-rw-r--r--source3/libads/ads_struct.c16
-rw-r--r--source3/libnet/libnet.h2
-rw-r--r--source3/libnet/libnet_join.c201
-rw-r--r--source3/libnet/libnet_join.h75
-rw-r--r--source3/librpc/gen_ndr/cli_lsa.c26
-rw-r--r--source3/librpc/gen_ndr/cli_lsa.h16
-rw-r--r--source3/librpc/gen_ndr/libnet_join.h73
-rw-r--r--source3/librpc/gen_ndr/lsa.h135
-rw-r--r--source3/librpc/gen_ndr/ndr_libnet_join.c103
-rw-r--r--source3/librpc/gen_ndr/ndr_libnet_join.h20
-rw-r--r--source3/librpc/gen_ndr/ndr_lsa.c679
-rw-r--r--source3/librpc/gen_ndr/ndr_lsa.h46
-rw-r--r--source3/librpc/gen_ndr/ndr_xattr.c102
-rw-r--r--source3/librpc/gen_ndr/ndr_xattr.h16
-rw-r--r--source3/librpc/gen_ndr/srv_lsa.c21
-rw-r--r--source3/librpc/gen_ndr/srv_lsa.h2
-rw-r--r--source3/librpc/gen_ndr/xattr.h18
-rw-r--r--source3/librpc/idl/libnet_join.idl60
-rw-r--r--source3/librpc/idl/lsa.idl127
-rw-r--r--source3/librpc/idl/xattr.idl23
-rw-r--r--source3/librpc/ndr/libndr.h10
-rw-r--r--source3/librpc/ndr/ndr_basic.c11
-rw-r--r--source3/librpc/ndr/ndr_misc.c81
-rw-r--r--source3/libsmb/clireadwrite.c9
-rw-r--r--source3/libsmb/libsmbclient.c593
-rw-r--r--source3/libsmb/namequery.c10
-rw-r--r--source3/libsmb/smbencrypt.c2
-rw-r--r--source3/locking/brlock.c29
-rw-r--r--source3/modules/gpfs.c20
-rw-r--r--source3/modules/nfs4_acls.c187
-rw-r--r--source3/modules/vfs_default.c42
-rw-r--r--source3/modules/vfs_gpfs.c281
-rw-r--r--source3/modules/vfs_gpfs.h32
-rw-r--r--source3/modules/vfs_prealloc.c8
-rw-r--r--source3/modules/vfs_shadow_copy2.c637
-rw-r--r--source3/modules/vfs_tsmsm.c338
-rw-r--r--source3/modules/vfs_xattr_tdb.c737
-rw-r--r--source3/nsswitch/libwbclient/wbc_err.h51
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h27
-rw-r--r--source3/nsswitch/winbind_nss_config.h8
-rw-r--r--source3/pam_smbpass/pam_smb_acct.c2
-rw-r--r--source3/pam_smbpass/pam_smb_passwd.c2
-rw-r--r--source3/param/loadparm.c128
-rw-r--r--source3/pkgconfig/wbclient.pc.in13
-rw-r--r--source3/printing/nt_printing.c7
-rw-r--r--source3/registry/reg_api.c25
-rw-r--r--source3/rpc_client/cli_lsarpc.c8
-rw-r--r--source3/rpc_server/srv_lsa_nt.c2
-rw-r--r--source3/rpc_server/srv_wkssvc_nt.c25
-rw-r--r--source3/rpcclient/cmd_lsarpc.c22
-rw-r--r--source3/rpcclient/rpcclient.c2
-rwxr-xr-xsource3/script/fix_bool.pl19
-rwxr-xr-xsource3/script/tests/selftest.sh1
-rwxr-xr-xsource3/script/tests/test_posix_s3.sh2
-rw-r--r--source3/smbd/connection.c9
-rw-r--r--source3/smbd/dmapi.c71
-rw-r--r--source3/smbd/dosmode.c44
-rw-r--r--source3/smbd/oplock_linux.c22
-rw-r--r--source3/smbd/posix_acls.c31
-rw-r--r--source3/smbd/reply.c19
-rw-r--r--source3/smbd/server.c67
-rw-r--r--source3/smbd/service.c84
-rw-r--r--source3/smbd/trans2.c23
-rw-r--r--source3/utils/net.h2
-rw-r--r--source3/utils/net_ads.c18
-rw-r--r--source3/utils/net_dns.c3
-rw-r--r--source3/utils/net_domain.c2
-rw-r--r--source3/utils/net_rpc.c11
-rw-r--r--source3/utils/net_rpc_join.c4
-rw-r--r--source3/winbindd/idmap_tdb2.c1017
-rw-r--r--source3/winbindd/winbindd_cm.c6
97 files changed, 6109 insertions, 1053 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index c34f3283db..265d14547c 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -268,7 +268,8 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \
librpc/gen_ndr/ndr_srvsvc.o \
librpc/gen_ndr/ndr_svcctl.o \
librpc/gen_ndr/ndr_eventlog.o \
- librpc/gen_ndr/ndr_notify.o
+ librpc/gen_ndr/ndr_notify.o \
+ librpc/gen_ndr/ndr_libnet_join.o
RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o
@@ -307,7 +308,7 @@ LIB_WITH_PROTO_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \
lib/util_unistr.o lib/util_file.o lib/data_blob.o \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
- lib/substitute.o lib/fsusage.o \
+ lib/substitute.o lib/fsusage.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/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
@@ -340,13 +341,13 @@ LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsutils.o libaddns/dnssock.o \
libaddns/dnsgss.o libaddns/dnsmarshall.o
LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ)
-LIBWBCLIENT_OBJ = nsswitch/libwbclient/wbclient.o \
+LIBWBCLIENT_OBJ0 = nsswitch/libwbclient/wbclient.o \
nsswitch/libwbclient/wbc_util.o \
nsswitch/libwbclient/wbc_pwd.o \
nsswitch/libwbclient/wbc_idmap.o \
nsswitch/libwbclient/wbc_sid.o \
nsswitch/libwbclient/wbc_pam.o
-
+LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) $(TALLOC_OBJ) $(LIBREPLACE_OBJ)
LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_ini.o libgpo/gpo_util.o \
libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o
@@ -502,7 +503,9 @@ VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
VFS_CAP_OBJ = modules/vfs_cap.o
VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
+VFS_SHADOW_COPY2_OBJ = modules/vfs_shadow_copy2.o
VFS_AFSACL_OBJ = modules/vfs_afsacl.o
+VFS_XATTR_TDB_OBJ = modules/vfs_xattr_tdb.o librpc/gen_ndr/ndr_xattr.o
VFS_POSIXACL_OBJ = modules/vfs_posixacl.o
VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o
VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o
@@ -518,6 +521,7 @@ VFS_COMMIT_OBJ = modules/vfs_commit.o
VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o modules/nfs4_acls.o
VFS_NOTIFY_FAM_OBJ = modules/vfs_notify_fam.o
VFS_READAHEAD_OBJ = modules/vfs_readahead.o
+VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
VFS_FILEID_OBJ = modules/vfs_fileid.o
VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
@@ -671,7 +675,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ)
PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
- $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) @BUILD_INIPARSER@
+ $(LIBREPLACE_OBJ) @BUILD_INIPARSER@
LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
libsmb/libsmb_cache.o \
@@ -928,7 +932,7 @@ WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(SECRETS_OBJ) $(POPT_LIB_OBJ) $(AFS_SETTOKEN_OBJ) $(RPC_PARSE_OBJ1) \
$(DOSERR_OBJ) lib/winbind_util.o @LIBWBCLIENT_STATIC@
-WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) @WINBIND_NSS_EXTRA_OBJS@
+WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) @WINBIND_NSS_EXTRA_OBJS@
LDB_COMMON_OBJ=lib/ldb/common/ldb.o lib/ldb/common/ldb_ldif.o \
lib/ldb/common/ldb_parse.o lib/ldb/common/ldb_msg.o lib/ldb/common/ldb_utf8.o \
@@ -966,7 +970,7 @@ LDBDEL_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbdel.o
LDBMODIFY_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbmodify.o
WINBIND_KRB5_LOCATOR_OBJ1 = nsswitch/winbind_krb5_locator.o
-WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ)
+WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ)
POPT_OBJ=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
@@ -1060,7 +1064,7 @@ modules: SHOWFLAGS $(MODULES)
## Perl IDL Compiler
IDL_FILES = unixinfo.idl lsa.idl dfs.idl echo.idl winreg.idl initshutdown.idl \
srvsvc.idl svcctl.idl eventlog.idl wkssvc.idl netlogon.idl notify.idl \
- epmapper.idl messaging.idl
+ epmapper.idl messaging.idl xattr.idl
idl:
@IDL_FILES="$(IDL_FILES)" CPP="$(CPP)" PERL="$(PERL)" \
@@ -1396,15 +1400,15 @@ bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@
@POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \
$(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@
-bin/libwbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ) nsswitch/wb_common.o $(LIBSAMBAUTIL_OBJ)
+bin/libwbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ)
@echo Linking shared library $@
- @$(SHLD_DSO) $(LIBWBCLIENT_OBJ) nsswitch/wb_common.o $(LIBSAMBAUTIL_OBJ) \
+ @$(SHLD_DSO) $(LIBWBCLIENT_OBJ) \
@SONAMEFLAG@`basename $@`.$(SONAME_VER)
@ln -s -f `basename $@` $@.$(SONAME_VER)
-bin/libwbclient.a: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ)
+bin/libwbclient.a: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ0)
@echo Linking non-shared library $@
- @-$(AR) -rc $@ $(LIBWBCLIENT_OBJ)
+ @-$(AR) -rc $@ $(LIBWBCLIENT_OBJ0)
bin/libaddns.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBADDNS_OBJ)
@echo Linking shared library $@
@@ -1609,6 +1613,10 @@ bin/ad.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ad.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_ad.o
+bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) winbindd/idmap_tdb2.o
+
bin/ldap.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ldap.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_ldap.o
@@ -1668,6 +1676,10 @@ bin/shadow_copy.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SHADOW_COPY_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SHADOW_COPY_OBJ)
+bin/shadow_copy2.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SHADOW_COPY2_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_SHADOW_COPY2_OBJ)
+
bin/syncops.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SYNCOPS_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SYNCOPS_OBJ)
@@ -1684,6 +1696,10 @@ bin/afsacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AFSACL_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_AFSACL_OBJ)
+bin/xattr_tdb.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_XATTR_TDB_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_XATTR_TDB_OBJ)
+
bin/posixacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_POSIXACL_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_POSIXACL_OBJ)
@@ -1744,6 +1760,10 @@ bin/readahead.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_READAHEAD_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_READAHEAD_OBJ)
+bin/tsmsm.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_TSMSM_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_TSMSM_OBJ)
+
bin/fileid.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_FILEID_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_FILEID_OBJ)
@@ -1884,9 +1904,10 @@ installlibaddns: installdirs libaddns
-$(INSTALLLIBCMD_A) bin/libaddns.a $(DESTDIR)$(LIBDIR)
installlibwbclient: installdirs libwbclient
- @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) $(INCLUDEDIR)/samba
+ @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR)
-$(INSTALLLIBCMD_SH) bin/libwbclient.@SHLIBEXT@ $(DESTDIR)$(LIBDIR)
- -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(srcdir)/nsswitch/libwbclient/wbclient.h $(DESTDIR)${prefix}/include/samba
+ @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) ${prefix}/include
+ -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(srcdir)/nsswitch/libwbclient/wbclient.h $(DESTDIR)${prefix}/include
installlibnetapi: installdirs libnetapi
@$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR)
diff --git a/source3/client/cifs.spnego.c b/source3/client/cifs.spnego.c
index caa22276c4..d10d19da96 100644
--- a/source3/client/cifs.spnego.c
+++ b/source3/client/cifs.spnego.c
@@ -3,11 +3,13 @@
* Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
*
* Used by /sbin/request-key for handling
-* cifs upcall for kerberos authorization of access to share.
+* cifs upcall for kerberos authorization of access to share and
+* cifs upcall for DFS srver name resolving (IPv4/IPv6 aware).
* You should have keyutils installed and add following line to
* /etc/request-key.conf file
create cifs.spnego * * /usr/local/sbin/cifs.spnego [-v][-c] %k
+create cifs.resolver * * /usr/local/sbin/cifs.spnego [-v] %k
* 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
@@ -27,7 +29,7 @@ create cifs.spnego * * /usr/local/sbin/cifs.spnego [-v][-c] %k
#include "cifs_spnego.h"
-const char* CIFSSPNEGO_VERSION="1.0";
+const char *CIFSSPNEGO_VERSION = "1.1";
static const char *prog = "cifs.spnego";
typedef enum _secType {
KRB5,
@@ -146,6 +148,58 @@ int decode_key_description(const char *desc, int *ver, secType_t * sec,
return retval;
}
+int cifs_resolver(const key_serial_t key, const char *key_descr)
+{
+ int c;
+ struct addrinfo *addr;
+ char ip[INET6_ADDRSTRLEN];
+ void *p;
+ const char *keyend = key_descr;
+ /* skip next 4 ';' delimiters to get to description */
+ for (c = 1; c <= 4; c++) {
+ keyend = index(keyend+1, ';');
+ if (!keyend) {
+ syslog(LOG_WARNING, "invalid key description: %s",
+ key_descr);
+ return 1;
+ }
+ }
+ keyend++;
+
+ /* resolve name to ip */
+ c = getaddrinfo(keyend, NULL, NULL, &addr);
+ if (c) {
+ syslog(LOG_WARNING, "unable to resolve hostname: %s [%s]",
+ keyend, gai_strerror(c));
+ return 1;
+ }
+
+ /* conver ip to string form */
+ if (addr->ai_family == AF_INET) {
+ p = &(((struct sockaddr_in *)addr->ai_addr)->sin_addr);
+ } else {
+ p = &(((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr);
+ }
+ if (!inet_ntop(addr->ai_family, p, ip, sizeof(ip))) {
+ syslog(LOG_WARNING, "%s: inet_ntop: %s",
+ __FUNCTION__, strerror(errno));
+ freeaddrinfo(addr);
+ return 1;
+ }
+
+ /* setup key */
+ c = keyctl_instantiate(key, ip, strlen(ip)+1, 0);
+ if (c == -1) {
+ syslog(LOG_WARNING, "%s: keyctl_instantiate: %s",
+ __FUNCTION__, strerror(errno));
+ freeaddrinfo(addr);
+ return 1;
+ }
+
+ freeaddrinfo(addr);
+ return 0;
+}
+
int main(const int argc, char *const argv[])
{
struct cifs_spnego_msg *keydata = NULL;
@@ -199,6 +253,11 @@ int main(const int argc, char *const argv[])
goto out;
}
+ if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver")-1) == 0) {
+ rc = cifs_resolver(key, buf);
+ goto out;
+ }
+
rc = decode_key_description(buf, &kernel_upcall_version, &sectype,
&hostname, &uid);
if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
diff --git a/source3/configure.in b/source3/configure.in
index 4222d93227..f65eb3c204 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -707,7 +707,7 @@ dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_lsa_ds rpc_wkssvc rpc_svcctl2 rpc_ntsvcs rpc_net rpc_netdfs rpc_srvsvc2 rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin 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 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops"
+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_syncops vfs_xattr_tdb"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_rpcecho"
@@ -2751,6 +2751,12 @@ AC_SUBST(SMB_FAM_LIBS)
SMB_CHECK_DMAPI([], AC_MSG_NOTICE(DMAPI support not present) )
+# Add TSM SM VFS module only if there are both GPFS and DMAPI support
+# Theoretically it should work with AIX JFS2 too but this needs testing
+if test x"$samba_cv_HAVE_GPFS" = x"yes" && test x"$samba_dmapi_libs" != x"" ; then
+ default_shared_modules="$default_shared_modules vfs_tsmsm"
+fi
+
AC_CACHE_CHECK([for kernel share modes],samba_cv_HAVE_KERNEL_SHARE_MODES,[
AC_TRY_RUN([
#include <sys/types.h>
@@ -6452,6 +6458,7 @@ SMB_SUBSYSTEM(RPC,smbd/server.o)
SMB_MODULE(idmap_ldap, winbindd/idmap_ldap.o, "bin/ldap.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_tdb, winbindd/idmap_tdb.o, "bin/tdb.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_tdb2, winbindd/idmap_tdb2.o, "bin/tdb2.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_passdb, winbindd/idmap_passdb.o, "bin/passdb.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
@@ -6488,7 +6495,9 @@ SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_shadow_copy2, \$(VFS_SHADOW_COPY2_OBJ), "bin/shadow_copy2.$SHLIBEXT", VFS)
SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_xattr_tdb, \$(VFS_XATTR_TDB_OBJ), "bin/xattr_tdb.$SHLIBEXT", VFS)
SMB_MODULE(vfs_posixacl, \$(VFS_POSIXACL_OBJ), "bin/posixacl.$SHLIBEXT", VFS)
SMB_MODULE(vfs_aixacl, \$(VFS_AIXACL_OBJ), "bin/aixacl.$SHLIBEXT", VFS)
SMB_MODULE(vfs_aixacl2, \$(VFS_AIXACL2_OBJ), "bin/aixacl2.$SHLIBEXT", VFS)
@@ -6502,6 +6511,7 @@ SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS)
SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS)
SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS)
SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
@@ -6656,7 +6666,10 @@ AC_SUBST(SMBD_LIBS)
AC_OUTPUT(Makefile library-versions
script/findsmb smbadduser script/gen-8bit-gap.sh script/installbin.sh script/uninstallbin.sh
lib/netapi/examples/Makefile
- pkgconfig/smbclient.pc pkgconfig/netapi.pc pkgconfig/smbsharemodes.pc
+ pkgconfig/smbclient.pc
+ pkgconfig/wbclient.pc
+ pkgconfig/netapi.pc
+ pkgconfig/smbsharemodes.pc
)
#################################################
diff --git a/source3/groupdb/mapping_ldb.c b/source3/groupdb/mapping_ldb.c
index 05056eabd2..454fe467a9 100644
--- a/source3/groupdb/mapping_ldb.c
+++ b/source3/groupdb/mapping_ldb.c
@@ -492,7 +492,7 @@ static NTSTATUS enum_aliasmem(const DOM_SID *alias, DOM_SID **sids, size_t *num)
NULL
};
int ret, i;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
struct ldb_result *res=NULL;
struct ldb_dn *dn;
struct ldb_message_element *el;
diff --git a/source3/groupdb/mapping_tdb.c b/source3/groupdb/mapping_tdb.c
index 21a4f95383..67e377c338 100644
--- a/source3/groupdb/mapping_tdb.c
+++ b/source3/groupdb/mapping_tdb.c
@@ -394,7 +394,7 @@ static NTSTATUS one_alias_membership(const DOM_SID *member,
char *string_sid;
TDB_DATA dbuf;
const char *p;
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *frame;
slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX,
diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h
index 425cc65a00..6e1b2f737a 100644
--- a/source3/include/ctdbd_conn.h
+++ b/source3/include/ctdbd_conn.h
@@ -17,6 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef _CTDBD_CONN_H
+#define _CTDBD_CONN_H
+
struct ctdbd_connection;
NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
@@ -62,3 +65,6 @@ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn);
+NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data);
+
+#endif /* _CTDBD_CONN_H */
diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h
index 3bb378c841..4eb174fef1 100644
--- a/source3/include/dbwrap.h
+++ b/source3/include/dbwrap.h
@@ -43,6 +43,7 @@ struct db_context {
void *private_data);
int (*get_seqnum)(struct db_context *db);
void *private_data;
+ bool persistent;
};
struct db_context *db_open(TALLOC_CTX *mem_ctx,
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 9175b33d60..07242f7956 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -1961,7 +1961,7 @@ int smbc_fremovexattr(int fd,
* extended attributes
*
* @note This function always returns all attribute names supported
- * by NT file systems, regardless of wether the referenced
+ * by NT file systems, regardless of whether the referenced
* file system supports extended attributes (e.g. a Windows
* 2000 machine supports extended attributes if NTFS is used,
* but not if FAT is used, and Windows 98 doesn't support
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
index ef6ff6db28..72aabc310e 100644
--- a/source3/include/rpc_lsa.h
+++ b/source3/include/rpc_lsa.h
@@ -87,27 +87,8 @@
#define LSA_AUDIT_NUM_CATEGORIES_NT4 7
#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
-
#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
-#define LSA_AUDIT_POLICY_NONE 0x00
-#define LSA_AUDIT_POLICY_SUCCESS 0x01
-#define LSA_AUDIT_POLICY_FAILURE 0x02
-#define LSA_AUDIT_POLICY_ALL (LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE)
-#define LSA_AUDIT_POLICY_CLEAR 0x04
-
-enum lsa_audit_categories {
- LSA_AUDIT_CATEGORY_SYSTEM = 0,
- LSA_AUDIT_CATEGORY_LOGON = 1,
- LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS,
- LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS,
- LSA_AUDIT_CATEGORY_PROCCESS_TRACKING,
- LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES,
- LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT,
- LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS, /* only in win2k/2k3 */
- LSA_AUDIT_CATEGORY_ACCOUNT_LOGON /* only in win2k/2k3 */
-};
-
/* level 1 is auditing settings */
typedef struct dom_query_1
{
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 49245eaa83..744acd719f 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -322,6 +322,8 @@ struct id_map {
#include "librpc/gen_ndr/wkssvc.h"
#include "librpc/gen_ndr/echo.h"
#include "librpc/gen_ndr/svcctl.h"
+#include "librpc/gen_ndr/libnet_join.h"
+
struct lsa_dom_info {
bool valid;
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 0be3886227..be3cd91520 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -70,6 +70,7 @@
* timestamp resolition. JRA. */
/* Changed to version21 to add chflags operation -- jpeach */
/* Changed to version22 to add lchown operation -- jra */
+/* Additional change: add operations for offline files and remote storage volume abstraction -- ab*/
/* Leave at 22 - not yet released. But change set_nt_acl to return an NTSTATUS. jra. */
/* Leave at 22 - not yet released. Add file_id_create operation. --metze */
/* Leave at 22 - not yet released. Change all BOOL parameters (int) to bool. jra. */
@@ -257,6 +258,12 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_AIO_ERROR,
SMB_VFS_OP_AIO_FSYNC,
SMB_VFS_OP_AIO_SUSPEND,
+ SMB_VFS_OP_AIO_FORCE,
+
+ /* offline operations */
+ SMB_VFS_OP_IS_OFFLINE,
+ SMB_VFS_OP_SET_OFFLINE,
+ SMB_VFS_OP_IS_REMOTESTORAGE,
/* This should always be last enum value */
@@ -405,6 +412,12 @@ struct vfs_ops {
int (*aio_error_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb);
int (*aio_fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb);
int (*aio_suspend)(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout);
+ bool (*aio_force)(struct vfs_handle_struct *handle, struct files_struct *fsp);
+
+ /* offline operations */
+ int (*is_offline)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, bool *offline);
+ int (*set_offline)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
+ bool (*is_remotestorage)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
} ops;
@@ -526,6 +539,12 @@ struct vfs_ops {
struct vfs_handle_struct *aio_error;
struct vfs_handle_struct *aio_fsync;
struct vfs_handle_struct *aio_suspend;
+ struct vfs_handle_struct *aio_force;
+
+ /* offline operations */
+ struct vfs_handle_struct *is_offline;
+ struct vfs_handle_struct *set_offline;
+ struct vfs_handle_struct *is_remotestorage;
} handles;
};
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 9232e94a42..dbba781377 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -138,6 +138,12 @@
#define SMB_VFS_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_error_fn((fsp)->conn->vfs.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs.ops.aio_fsync((fsp)->conn->vfs.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs.ops.aio_suspend((fsp)->conn->vfs.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
+#define SMB_VFS_AIO_FORCE(fsp) ((fsp)->conn->vfs.ops.aio_force((fsp)->conn->vfs.handles.aio_force,(fsp)))
+
+/* Offline operations */
+#define SMB_VFS_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs.ops.is_offline((conn)->vfs.handles.is_offline,(conn),(path),(sbuf),(offline)))
+#define SMB_VFS_SET_OFFLINE(conn,path) ((conn)->vfs.ops.set_offline((conn)->vfs.handles.set_offline,(conn),(path)))
+#define SMB_VFS_IS_REMOTESTORAGE(conn,path) ((conn)->vfs.ops.is_remotestorage((conn)->vfs.handles.is_remotestorage,(conn),(path)))
/*******************************************************************
Don't access conn->vfs_opaque.ops directly!!!
@@ -257,6 +263,12 @@
#define SMB_VFS_OPAQUE_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_error_fn((fsp)->conn->vfs_opaque.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_OPAQUE_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_fsync((fsp)->conn->vfs_opaque.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_OPAQUE_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs_opaque.ops.aio_suspend((fsp)->conn->vfs_opaque.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
+#define SMB_VFS_OPAQUE_AIO_FORCE(fsp) ((fsp)->conn->vfs_opaque.ops.aio_force((fsp)->conn->vfs_opaque.handles.aio_force,(fsp)))
+
+/* Offline operations */
+#define SMB_VFS_OPAQUE_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs_opaque.ops.is_offline((conn)->vfs_opaque.handles.is_offline,(conn),(path),(sbuf),(offline)))
+#define SMB_VFS_OPAQUE_SET_OFFLINE(conn,path) ((conn)->vfs_opaque.ops.set_offline((conn)->vfs_opaque.handles.set_offline,(conn),(path)))
+#define SMB_VFS_OPAQUE_IS_REMOTESTORAGE(conn,path) ((conn)->vfs_opaque.ops.is_remotestorage((conn)->vfs_opaque.handles.is_remotestorage,(conn),(path)))
/*******************************************************************
Don't access handle->vfs_next.ops.* directly!!!
@@ -377,5 +389,11 @@
#define SMB_VFS_NEXT_AIO_ERROR(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_error_fn((handle)->vfs_next.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_NEXT_AIO_FSYNC(handle,fsp,op,aiocb) ((handle)->vfs_next.ops.aio_fsync((handle)->vfs_next.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_NEXT_AIO_SUSPEND(handle,fsp,aiocb,n,ts) ((handle)->vfs_next.ops.aio_suspend((handle)->vfs_next.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
+#define SMB_VFS_NEXT_AIO_FORCE(handle,fsp) ((handle)->vfs_next.ops.aio_force((handle)->vfs_next.handles.aio_force,(fsp)))
+
+/* Offline operations */
+#define SMB_VFS_NEXT_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs_next.ops.is_offline((conn)->vfs_next.handles.is_offline,(conn),(path),(sbuf),(offline)))
+#define SMB_VFS_NEXT_SET_OFFLINE(conn,path) ((conn)->vfs_next.ops.set_offline((conn)->vfs_next.handles.set_offline,(conn),(path)))
+#define SMB_VFS_NEXT_IS_REMOTESTORAGE(conn,path) ((conn)->vfs_next.ops.is_remotestorage((conn)->vfs_next.handles.is_remotestorage,(conn),(path)))
#endif /* _VFS_MACROS_H */
diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c
index dd0a354a85..22d85c873d 100644
--- a/source3/lib/conn_tdb.c
+++ b/source3/lib/conn_tdb.c
@@ -34,7 +34,7 @@ static struct db_context *connections_db_ctx(bool rw)
}
else {
db_ctx = db_open(NULL, lock_path("connections.tdb"), 0,
- TDB_DEFAULT, O_RDONLY, 0);
+ TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDONLY, 0);
}
return db_ctx;
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 899bbcfcce..18e9879601 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -1203,6 +1203,42 @@ NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn)
return register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE);
}
+/*
+ persstent store. Used when we update a record in a persistent database
+ */
+NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
+{
+ int cstatus=0;
+ struct ctdb_rec_data *rec;
+ TDB_DATA recdata;
+ size_t length;
+ NTSTATUS status;
+
+ length = offsetof(struct ctdb_rec_data, data) + key.dsize + data.dsize;
+
+ rec = (struct ctdb_rec_data *)talloc_size(conn, length);
+ NT_STATUS_HAVE_NO_MEMORY(rec);
+
+ rec->length = length;
+ rec->reqid = db_id;
+ rec->keylen = key.dsize;
+ rec->datalen= data.dsize;
+ memcpy(&rec->data[0], key.dptr, key.dsize);
+ memcpy(&rec->data[key.dsize], data.dptr, data.dsize);
+
+ recdata.dptr = (uint8_t *)rec;
+ recdata.dsize = length;
+
+ status = ctdbd_control(conn, CTDB_CURRENT_NODE,
+ CTDB_CONTROL_PERSISTENT_STORE,
+ 0, recdata, NULL, NULL, &cstatus);
+ if (cstatus != 0) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ return status;
+}
+
+
#else
NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c
index 4e16d18682..001424a6c0 100644
--- a/source3/lib/dbwrap.c
+++ b/source3/lib/dbwrap.c
@@ -20,7 +20,9 @@
*/
#include "includes.h"
-
+#ifdef CLUSTER_SUPPORT
+#include "ctdb_private.h"
+#endif
/*
* Fall back using fetch_locked if no genuine fetch operation is provided
*/
@@ -46,10 +48,16 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
int open_flags, mode_t mode)
{
struct db_context *result = NULL;
+#ifdef CLUSTER_SUPPORT
+ const char *sockname = lp_ctdbd_socket();
+#endif
#ifdef CLUSTER_SUPPORT
+ if(!sockname || !*sockname) {
+ sockname = CTDB_PATH;
+ }
- if (lp_clustering()) {
+ if (lp_clustering() && socket_exist(sockname)) {
const char *partname;
/* ctdb only wants the file part of the name */
partname = strrchr(name, '/');
diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c
index 90d0b260c5..f497f871d2 100644
--- a/source3/lib/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap_ctdb.c
@@ -18,16 +18,14 @@
*/
#include "includes.h"
-
#ifdef CLUSTER_SUPPORT
-
#include "ctdb.h"
#include "ctdb_private.h"
+#include "ctdbd_conn.h"
struct db_ctdb_ctx {
struct tdb_wrap *wtdb;
uint32 db_id;
- struct ctdbd_connection *conn;
};
struct db_ctdb_rec {
@@ -35,8 +33,6 @@ struct db_ctdb_rec {
struct ctdb_ltdb_header header;
};
-static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx);
-
static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_ctdb_rec *crec = talloc_get_type_abort(
@@ -60,6 +56,42 @@ static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
}
+
+/* for persistent databases the store is a bit different. We have to
+ ask the ctdb daemon to push the record to all nodes after the
+ store */
+static NTSTATUS db_ctdb_store_persistent(struct db_record *rec, TDB_DATA data, int flag)
+{
+ struct db_ctdb_rec *crec = talloc_get_type_abort(
+ rec->private_data, struct db_ctdb_rec);
+ TDB_DATA cdata;
+ int ret;
+ NTSTATUS status;
+
+ cdata.dsize = sizeof(crec->header) + data.dsize;
+
+ if (!(cdata.dptr = SMB_MALLOC_ARRAY(uint8, cdata.dsize))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ crec->header.rsn++;
+
+ memcpy(cdata.dptr, &crec->header, sizeof(crec->header));
+ memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize);
+
+ ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE);
+ status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
+
+ /* now tell ctdbd to update this record on all other nodes */
+ if (NT_STATUS_IS_OK(status)) {
+ status = ctdbd_persistent_store(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata);
+ }
+
+ SAFE_FREE(cdata.dptr);
+
+ return status;
+}
+
static NTSTATUS db_ctdb_delete(struct db_record *rec)
{
struct db_ctdb_rec *crec = talloc_get_type_abort(
@@ -110,6 +142,7 @@ static struct db_record *db_ctdb_fetch_locked(struct db_context *db,
struct db_ctdb_rec *crec;
NTSTATUS status;
TDB_DATA ctdb_data;
+ int migrate_attempts = 0;
if (!(result = talloc(mem_ctx, struct db_record))) {
DEBUG(0, ("talloc failed\n"));
@@ -153,7 +186,11 @@ again:
return NULL;
}
- result->store = db_ctdb_store;
+ if (db->persistent) {
+ result->store = db_ctdb_store_persistent;
+ } else {
+ result->store = db_ctdb_store;
+ }
result->delete_rec = db_ctdb_delete;
talloc_set_destructor(result, db_ctdb_record_destr);
@@ -175,12 +212,14 @@ again:
tdb_chainunlock(ctx->wtdb->tdb, key);
talloc_set_destructor(result, NULL);
+ migrate_attempts += 1;
+
DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u)\n",
ctdb_data.dptr, ctdb_data.dptr ?
((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster : -1,
get_my_vnn()));
- status = ctdbd_migrate(db_ctdbd_conn(ctx), ctx->db_id, key);
+ status = ctdbd_migrate(messaging_ctdbd_connection(),ctx->db_id, key);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("ctdb_migrate failed: %s\n",
nt_errstr(status)));
@@ -191,6 +230,11 @@ again:
goto again;
}
+ if (migrate_attempts > 10) {
+ DEBUG(0, ("db_ctdb_fetch_locked needed %d attempts\n",
+ migrate_attempts));
+ }
+
memcpy(&crec->header, ctdb_data.dptr, sizeof(crec->header));
result->value.dsize = ctdb_data.dsize - sizeof(crec->header);
@@ -226,10 +270,12 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
/*
* See if we have a valid record and we are the dmaster. If so, we can
* take the shortcut and just return it.
+ * we bypass the dmaster check for persistent databases
*/
if ((ctdb_data.dptr != NULL) &&
(ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)) &&
- ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn()) {
+ (db->persistent ||
+ ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn())) {
/* we are the dmaster - avoid the ctdb protocol op */
data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header);
@@ -254,8 +300,7 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
SAFE_FREE(ctdb_data.dptr);
/* we weren't able to get it locally - ask ctdb to fetch it for us */
- status = ctdbd_fetch(db_ctdbd_conn(ctx), ctx->db_id, key, mem_ctx,
- data);
+ status = ctdbd_fetch(messaging_ctdbd_connection(),ctx->db_id, key, mem_ctx, data);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status)));
return -1;
@@ -283,6 +328,22 @@ static void traverse_callback(TDB_DATA key, TDB_DATA data, void *private_data)
talloc_free(tmp_ctx);
}
+static int traverse_persistent_callback(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void *private_data)
+{
+ struct traverse_state *state = (struct traverse_state *)private_data;
+ struct db_record *rec;
+ TALLOC_CTX *tmp_ctx = talloc_new(state->db);
+ int ret = 0;
+ /* we have to give them a locked record to prevent races */
+ rec = db_ctdb_fetch_locked(state->db, tmp_ctx, kbuf);
+ if (rec && rec->value.dsize > 0) {
+ ret = state->fn(rec, state->private_data);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
static int db_ctdb_traverse(struct db_context *db,
int (*fn)(struct db_record *rec,
void *private_data),
@@ -296,6 +357,13 @@ static int db_ctdb_traverse(struct db_context *db,
state.fn = fn;
state.private_data = private_data;
+ if (db->persistent) {
+ /* for persistent databases we don't need to do a ctdb traverse,
+ we can do a faster local traverse */
+ return tdb_traverse(ctx->wtdb->tdb, traverse_persistent_callback, &state);
+ }
+
+
ctdbd_traverse(ctx->db_id, traverse_callback, &state);
return 0;
}
@@ -322,6 +390,27 @@ static void traverse_read_callback(TDB_DATA key, TDB_DATA data, void *private_da
state->fn(&rec, state->private_data);
}
+static int traverse_persistent_callback_read(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void *private_data)
+{
+ struct traverse_state *state = (struct traverse_state *)private_data;
+ struct db_record rec;
+ rec.key = kbuf;
+ rec.value = dbuf;
+ rec.store = db_ctdb_store_deny;
+ rec.delete_rec = db_ctdb_delete_deny;
+ rec.private_data = state->db;
+
+ if (rec.value.dsize <= sizeof(struct ctdb_ltdb_header)) {
+ /* a deleted record */
+ return 0;
+ }
+ rec.value.dsize -= sizeof(struct ctdb_ltdb_header);
+ rec.value.dptr += sizeof(struct ctdb_ltdb_header);
+
+ return state->fn(&rec, state->private_data);
+}
+
static int db_ctdb_traverse_read(struct db_context *db,
int (*fn)(struct db_record *rec,
void *private_data),
@@ -335,6 +424,12 @@ static int db_ctdb_traverse_read(struct db_context *db,
state.fn = fn;
state.private_data = private_data;
+ if (db->persistent) {
+ /* for persistent databases we don't need to do a ctdb traverse,
+ we can do a faster local traverse */
+ return tdb_traverse_read(ctx->wtdb->tdb, traverse_persistent_callback_read, &state);
+ }
+
ctdbd_traverse(ctx->db_id, traverse_read_callback, &state);
return 0;
}
@@ -346,41 +441,6 @@ static int db_ctdb_get_seqnum(struct db_context *db)
return tdb_get_seqnum(ctx->wtdb->tdb);
}
-/*
- * Get the ctdbd connection for a database. If possible, re-use the messaging
- * ctdbd connection
- */
-static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx)
-{
- struct ctdbd_connection *result;
-
- result = messaging_ctdbd_connection();
-
- if (result != NULL) {
-
- if (ctx->conn == NULL) {
- /*
- * Someone has initialized messaging since we
- * initialized our own connection, we don't need it
- * anymore.
- */
- TALLOC_FREE(ctx->conn);
- }
-
- return result;
- }
-
- if (ctx->conn == NULL) {
- NTSTATUS status;
- status = ctdbd_init_connection(ctx, &ctx->conn);
- if (!NT_STATUS_IS_OK(status)) {
- return NULL;
- }
- set_my_vnn(ctdbd_vnn(ctx->conn));
- }
-
- return ctx->conn;
-}
struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
const char *name,
@@ -390,7 +450,6 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
struct db_context *result;
struct db_ctdb_ctx *db_ctdb;
char *db_path;
- NTSTATUS status;
if (!lp_clustering()) {
DEBUG(10, ("Clustering disabled -- no ctdb\n"));
@@ -409,20 +468,15 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
return NULL;
}
- db_ctdb->conn = NULL;
-
- status = ctdbd_db_attach(db_ctdbd_conn(db_ctdb), name,
- &db_ctdb->db_id, tdb_flags);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("ctdbd_db_attach failed for %s: %s\n", name,
- nt_errstr(status)));
+ if (!NT_STATUS_IS_OK(ctdbd_db_attach(messaging_ctdbd_connection(),name, &db_ctdb->db_id, tdb_flags))) {
+ DEBUG(0, ("ctdbd_db_attach failed for %s\n", name));
TALLOC_FREE(result);
return NULL;
}
- db_path = ctdbd_dbpath(db_ctdbd_conn(db_ctdb), db_ctdb,
- db_ctdb->db_id);
+ db_path = ctdbd_dbpath(messaging_ctdbd_connection(), db_ctdb, db_ctdb->db_id);
+
+ result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
/* only pass through specific flags */
tdb_flags &= TDB_SEQNUM;
@@ -447,16 +501,4 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
return result;
}
-
-#else
-
-struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
- const char *name,
- int hash_size, int tdb_flags,
- int open_flags, mode_t mode)
-{
- DEBUG(0, ("no clustering compiled in\n"));
- return NULL;
-}
-
#endif
diff --git a/source3/lib/dbwrap_file.c b/source3/lib/dbwrap_file.c
index 5b41f5941b..e3779de1e4 100644
--- a/source3/lib/dbwrap_file.c
+++ b/source3/lib/dbwrap_file.c
@@ -17,10 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * Be aware that this is just sample code that has not seen too much testing
- */
-
#include "includes.h"
struct db_file_ctx {
@@ -367,6 +363,7 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx,
result->fetch_locked = db_file_fetch_locked;
result->traverse = db_file_traverse;
result->traverse_read = db_file_traverse;
+ result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
ctx->locked_record = NULL;
if (!(ctx->dirname = talloc_strdup(ctx, name))) {
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index 710e45de6b..e87ceb428f 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -31,6 +31,11 @@ static int db_tdb_record_destr(struct db_record* data)
struct db_tdb_ctx *ctx =
talloc_get_type_abort(data->private_data, struct db_tdb_ctx);
+ /* This hex_encode() call allocates memory on data context. By way how current
+ __talloc_free() code works, it is OK to allocate in the destructor as
+ the children of data will be freed after call to the destructor and this
+ new 'child' will be caught and freed correctly.
+ */
DEBUG(10, (DEBUGLEVEL > 10
? "Unlocking key %s\n" : "Unlocking key %.20s\n",
hex_encode(data, (unsigned char *)data->key.dptr,
@@ -88,8 +93,9 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
struct tdb_fetch_locked_state state;
int res;
- if (DEBUGLEVEL >= 10) {
- char *keystr = hex_encode(NULL, key.dptr, key.dsize);
+ /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
+ if(DEBUGLEVEL >= 10) {
+ char *keystr = hex_encode(NULL, (unsigned char*)key.dptr, key.dsize);
DEBUG(10, (DEBUGLEVEL > 10
? "Locking key %s\n" : "Locking key %.20s\n",
keystr));
@@ -191,15 +197,9 @@ static NTSTATUS db_tdb_delete(struct db_record *rec)
{
struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
struct db_tdb_ctx);
- int res;
-
- res = tdb_delete(ctx->wtdb->tdb, rec->key);
- if (res == 0) {
- return NT_STATUS_OK;
- }
-
- return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb));
+ return (tdb_delete(ctx->wtdb->tdb, rec->key) == 0) ?
+ NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
struct db_tdb_traverse_ctx {
@@ -318,6 +318,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
result->traverse = db_tdb_traverse;
result->traverse_read = db_tdb_traverse_read;
result->get_seqnum = db_tdb_get_seqnum;
+ result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
return result;
fail:
diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c
new file mode 100644
index 0000000000..002d572019
--- /dev/null
+++ b/source3/lib/dbwrap_util.c
@@ -0,0 +1,90 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility functions for the dbwrap API
+ Copyright (C) Volker Lendecke 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr)
+{
+ TDB_DATA dbuf;
+ int32 ret;
+
+ if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) {
+ return -1;
+ }
+
+ if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(int32_t))) {
+ TALLOC_FREE(dbuf.dptr);
+ return -1;
+ }
+
+ ret = IVAL(dbuf.dptr, 0);
+ TALLOC_FREE(dbuf.dptr);
+ return ret;
+}
+
+int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v)
+{
+ struct db_record *rec;
+ int32 v_store;
+ NTSTATUS status;
+
+ rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr));
+ if (rec == NULL) {
+ return -1;
+ }
+
+ SIVAL(&v_store, 0, v);
+
+ status = rec->store(rec, make_tdb_data((const uint8 *)&v_store,
+ sizeof(v_store)),
+ TDB_REPLACE);
+ TALLOC_FREE(rec);
+ return NT_STATUS_IS_OK(status) ? 0 : -1;
+}
+
+uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
+ uint32_t *oldval, uint32_t change_val)
+{
+ struct db_record *rec;
+ uint32 val = -1;
+ TDB_DATA data;
+
+ if (!(rec = db->fetch_locked(db, NULL,
+ string_term_tdb_data(keystr)))) {
+ return -1;
+ }
+
+ if ((rec->value.dptr != NULL)
+ && (rec->value.dsize == sizeof(val))) {
+ val = IVAL(rec->value.dptr, 0);
+ }
+
+ val += change_val;
+
+ data.dsize = sizeof(val);
+ data.dptr = (uint8 *)&val;
+
+ rec->store(rec, data, TDB_REPLACE);
+
+ TALLOC_FREE(rec);
+
+ return 0;
+}
+
diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c
index 6e9b934a75..f1a02e6af9 100644
--- a/source3/lib/messages_ctdbd.c
+++ b/source3/lib/messages_ctdbd.c
@@ -22,6 +22,10 @@
#ifdef CLUSTER_SUPPORT
#include "librpc/gen_ndr/messaging.h"
+#include "ctdb.h"
+#include "ctdb_private.h"
+#include "ctdbd_conn.h"
+
struct messaging_ctdbd_context {
struct ctdbd_connection *conn;
diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c
index 67680ba55a..6cd074615b 100644
--- a/source3/lib/netapi/serverinfo.c
+++ b/source3/lib/netapi/serverinfo.c
@@ -167,7 +167,7 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
return WERR_INVALID_PARAM;
}
- if (!lp_include_registry_globals()) {
+ if (!lp_config_backend_is_registry()) {
return WERR_NOT_SUPPORTED;
}
diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c
index 94140a4baa..b19e4cea29 100644
--- a/source3/lib/tdb/common/open.c
+++ b/source3/lib/tdb/common/open.c
@@ -179,7 +179,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
tdb->page_size = 0x2000;
}
- tdb->max_dead_records = (open_flags & TDB_VOLATILE) ? 5 : 0;
+ tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0;
if ((open_flags & O_ACCMODE) == O_WRONLY) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
@@ -227,6 +227,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
/* we need to zero database if we are the only one with it open */
if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
+ (!tdb->read_only) &&
(locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) {
open_flags |= O_CREAT;
if (ftruncate(tdb->fd, 0) == -1) {
diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h
index 63a6d04e72..dd69903015 100644
--- a/source3/lib/tdb/common/tdb_private.h
+++ b/source3/lib/tdb/common/tdb_private.h
@@ -178,6 +178,7 @@ struct tdb_context {
int tdb_munmap(struct tdb_context *tdb);
void tdb_mmap(struct tdb_context *tdb);
int tdb_lock(struct tdb_context *tdb, int list, int ltype);
+int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype);
int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c
index 0ecfb9b7ff..c3e7a4e2c0 100644
--- a/source3/lib/tdb/common/transaction.c
+++ b/source3/lib/tdb/common/transaction.c
@@ -219,9 +219,12 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off,
uint8_t **new_blocks;
/* expand the blocks array */
if (tdb->transaction->blocks == NULL) {
- new_blocks = malloc((blk+1)*sizeof(uint8_t *));
+ new_blocks = (uint8_t **)malloc(
+ (blk+1)*sizeof(uint8_t *));
} else {
- new_blocks = realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *));
+ new_blocks = (uint8_t **)realloc(
+ tdb->transaction->blocks,
+ (blk+1)*sizeof(uint8_t *));
}
if (new_blocks == NULL) {
tdb->ecode = TDB_ERR_OOM;
@@ -316,25 +319,15 @@ static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off,
return 0;
}
- /* overwrite part of an existing block */
- if (buf == NULL) {
- memset(tdb->transaction->blocks[blk] + off, 0, len);
- } else {
- memcpy(tdb->transaction->blocks[blk] + off, buf, len);
- }
- if (blk == tdb->transaction->num_blocks-1) {
- if (len + off > tdb->transaction->last_block_size) {
- tdb->transaction->last_block_size = len + off;
- }
+ if (blk == tdb->transaction->num_blocks-1 &&
+ off + len > tdb->transaction->last_block_size) {
+ len = tdb->transaction->last_block_size - off;
}
- return 0;
+ /* overwrite part of an existing block */
+ memcpy(tdb->transaction->blocks[blk] + off, buf, len);
-fail:
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n",
- (blk*tdb->transaction->block_size) + off, len));
- tdb->transaction->transaction_error = 1;
- return -1;
+ return 0;
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 0653fc9d3f..bc3eaa8d5e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -506,6 +506,19 @@ bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
}
/*******************************************************************
+ Check if a unix domain socket exists - call vfs_file_exist for samba files.
+********************************************************************/
+
+bool socket_exist(const char *fname)
+{
+ SMB_STRUCT_STAT st;
+ if (sys_stat(fname,&st) != 0)
+ return(False);
+
+ return S_ISSOCK(st.st_mode);
+}
+
+/*******************************************************************
Check a files mod time.
********************************************************************/
diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c
index 956f0475a5..2d7d70c63f 100644
--- a/source3/lib/util_reg.c
+++ b/source3/lib/util_reg.c
@@ -130,6 +130,7 @@ bool registry_smbconf_valname_forbidden(const char *valname)
"include",
"lock directory",
"lock dir",
+ "config backend",
NULL
};
const char **forbidden = NULL;
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c
index 041878916e..44bcdf76ea 100644
--- a/source3/libads/ads_struct.c
+++ b/source3/libads/ads_struct.c
@@ -32,18 +32,23 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int
r = SMB_STRDUP(realm);
- if (!r || !*r)
+ if (!r || !*r) {
return r;
+ }
- for (p=r; *p; p++)
- if (strchr(sep, *p))
+ for (p=r; *p; p++) {
+ if (strchr(sep, *p)) {
numbits++;
+ }
+ }
len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
ret = (char *)SMB_MALLOC(len);
- if (!ret)
+ if (!ret) {
+ free(r);
return NULL;
+ }
strlcpy(ret,field, len);
p=strtok(r,sep);
@@ -57,7 +62,8 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int
else
asprintf(&s, "%s,%s%s", ret, field, p);
free(ret);
- ret = s;
+ ret = SMB_STRDUP(s);
+ free(s);
}
}
diff --git a/source3/libnet/libnet.h b/source3/libnet/libnet.h
index d6238ca982..97e720f617 100644
--- a/source3/libnet/libnet.h
+++ b/source3/libnet/libnet.h
@@ -20,7 +20,7 @@
#ifndef __LIBNET_H__
#define __LIBNET_H__
-#include "libnet/libnet_join.h"
+#include "librpc/gen_ndr/libnet_join.h"
#include "libnet/libnet_conf.h"
#include "libnet/libnet_proto.h"
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index eaf851ccec..a9978ba4b8 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -24,6 +24,35 @@
/****************************************************************
****************************************************************/
+#define LIBNET_JOIN_DUMP_CTX(ctx, r, f) \
+ do { \
+ char *str = NULL; \
+ str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_JoinCtx, f, r); \
+ DEBUG(1,("libnet_Join:\n%s", str)); \
+ talloc_free(str); \
+ } while (0)
+
+#define LIBNET_JOIN_IN_DUMP_CTX(ctx, r) \
+ LIBNET_JOIN_DUMP_CTX(ctx, r, NDR_IN | NDR_SET_VALUES)
+#define LIBNET_JOIN_OUT_DUMP_CTX(ctx, r) \
+ LIBNET_JOIN_DUMP_CTX(ctx, r, NDR_OUT)
+
+#define LIBNET_UNJOIN_DUMP_CTX(ctx, r, f) \
+ do { \
+ char *str = NULL; \
+ str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_UnjoinCtx, f, r); \
+ DEBUG(1,("libnet_Unjoin:\n%s", str)); \
+ talloc_free(str); \
+ } while (0)
+
+#define LIBNET_UNJOIN_IN_DUMP_CTX(ctx, r) \
+ LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_IN | NDR_SET_VALUES)
+#define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \
+ LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT)
+
+/****************************************************************
+****************************************************************/
+
static void libnet_join_set_error_string(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r,
const char *format, ...)
@@ -107,10 +136,6 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx,
{
ADS_STATUS status;
- if (r->in.ads) {
- ads_destroy(&r->in.ads);
- }
-
status = libnet_connect_ads(r->in.domain_name,
r->in.domain_name,
r->in.dc_name,
@@ -134,10 +159,6 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx,
{
ADS_STATUS status;
- if (r->in.ads) {
- ads_destroy(&r->in.ads);
- }
-
status = libnet_connect_ads(r->in.domain_name,
r->in.domain_name,
r->in.dc_name,
@@ -244,7 +265,6 @@ static ADS_STATUS libnet_join_find_machine_acct(TALLOC_CTX *mem_ctx,
goto done;
}
- TALLOC_FREE(r->out.dn);
r->out.dn = talloc_strdup(mem_ctx, dn);
if (!r->out.dn) {
status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
@@ -1013,6 +1033,58 @@ static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r)
/****************************************************************
****************************************************************/
+static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+
+ if (!r->in.domain_name) {
+ return WERR_INVALID_PARAM;
+ }
+
+ if (r->in.modify_config && !lp_config_backend_is_registry()) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ if (IS_DC) {
+ return WERR_SETUP_DOMAIN_CONTROLLER;
+ }
+
+ if (!secrets_init()) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "Unable to open secrets database");
+ return WERR_CAN_NOT_COMPLETE;
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+ WERROR werr;
+
+ if (!W_ERROR_IS_OK(r->out.result)) {
+ return r->out.result;
+ }
+
+ werr = do_JoinConfig(r);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
+ saf_store(r->in.domain_name, r->in.dc_name);
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
static int libnet_destroy_JoinCtx(struct libnet_JoinCtx *r)
{
if (r->in.ads) {
@@ -1104,8 +1176,9 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
&info);
if (!NT_STATUS_IS_OK(status)) {
libnet_join_set_error_string(mem_ctx, r,
- "failed to find DC: %s",
- nt_errstr(status));
+ "failed to find DC for domain %s",
+ r->in.domain_name,
+ get_friendly_nt_error_msg(status));
return WERR_DOMAIN_CONTROLLER_NOT_FOUND;
}
@@ -1139,7 +1212,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
libnet_join_set_error_string(mem_ctx, r,
"failed to join domain over rpc: %s",
- nt_errstr(status));
+ get_friendly_nt_error_msg(status));
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
return WERR_SETUP_ALREADY_JOINED;
}
@@ -1170,30 +1243,32 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
{
WERROR werr;
- if (!r->in.domain_name) {
- return WERR_INVALID_PARAM;
+ if (r->in.debug) {
+ LIBNET_JOIN_IN_DUMP_CTX(mem_ctx, r);
}
- if (r->in.modify_config && !lp_include_registry_globals()) {
- return WERR_NOT_SUPPORTED;
- }
-
- if (IS_DC) {
- return WERR_SETUP_DOMAIN_CONTROLLER;
+ werr = libnet_join_pre_processing(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
}
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
werr = libnet_DomainJoin(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
}
}
- werr = do_JoinConfig(r);
+ werr = libnet_join_post_processing(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
}
+ done:
+ r->out.result = werr;
+ if (r->in.debug) {
+ LIBNET_JOIN_OUT_DUMP_CTX(mem_ctx, r);
+ }
return werr;
}
@@ -1205,11 +1280,46 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
+ if (!r->in.domain_sid) {
+ struct dom_sid sid;
+ if (!secrets_fetch_domain_sid(lp_workgroup(), &sid)) {
+ libnet_unjoin_set_error_string(mem_ctx, r,
+ "Unable to fetch domain sid: are we joined?");
+ return WERR_SETUP_NOT_JOINED;
+ }
+ r->in.domain_sid = sid_dup_talloc(mem_ctx, &sid);
+ W_ERROR_HAVE_NO_MEMORY(r->in.domain_sid);
+ }
+
+ if (!r->in.dc_name) {
+ struct DS_DOMAIN_CONTROLLER_INFO *info;
+ status = dsgetdcname(mem_ctx,
+ NULL,
+ r->in.domain_name,
+ NULL,
+ NULL,
+ DS_DIRECTORY_SERVICE_REQUIRED |
+ DS_WRITABLE_REQUIRED |
+ DS_RETURN_DNS_NAME,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ libnet_unjoin_set_error_string(mem_ctx, r,
+ "failed to find DC for domain %s",
+ r->in.domain_name,
+ get_friendly_nt_error_msg(status));
+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND;
+ }
+
+ r->in.dc_name = talloc_strdup(mem_ctx,
+ info->domain_controller_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
+ }
+
status = libnet_join_unjoindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
libnet_unjoin_set_error_string(mem_ctx, r,
- "failed to unjoin domain: %s",
- nt_errstr(status));
+ "failed to disable machine account via rpc: %s",
+ get_friendly_nt_error_msg(status));
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
return WERR_SETUP_NOT_JOINED;
}
@@ -1237,26 +1347,57 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
+static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ if (r->in.modify_config && !lp_config_backend_is_registry()) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ if (!secrets_init()) {
+ libnet_unjoin_set_error_string(mem_ctx, r,
+ "Unable to open secrets database");
+ return WERR_CAN_NOT_COMPLETE;
+ }
+
+ return WERR_OK;
+}
+
+
+/****************************************************************
+****************************************************************/
+
WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
{
WERROR werr;
- if (r->in.modify_config && !lp_include_registry_globals()) {
- return WERR_NOT_SUPPORTED;
+ if (r->in.debug) {
+ LIBNET_UNJOIN_IN_DUMP_CTX(mem_ctx, r);
+ }
+
+ werr = libnet_unjoin_pre_processing(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
}
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
werr = libnet_DomainUnjoin(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- do_UnjoinConfig(r);
- return werr;
+ goto done;
}
}
werr = do_UnjoinConfig(r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
+ }
+
+ done:
+ r->out.result = werr;
+
+ if (r->in.debug) {
+ LIBNET_UNJOIN_OUT_DUMP_CTX(mem_ctx, r);
}
return werr;
diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h
deleted file mode 100644
index c47e8d934c..0000000000
--- a/source3/libnet/libnet_join.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * libnet Join Support
- * Copyright (C) Guenther Deschner 2007-2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LIBNET_JOIN_H__
-#define __LIBNET_JOIN_H__
-
-struct libnet_JoinCtx {
- struct {
- const char *dc_name;
- const char *machine_name;
- const char *domain_name;
- const char *account_ou;
- const char *admin_account;
- const char *admin_password;
- const char *machine_password;
- uint32_t join_flags;
- const char *os_version;
- const char *os_name;
- bool create_upn;
- const char *upn;
- bool modify_config;
- struct ads_struct *ads;
- bool debug;
- } in;
-
- struct {
- char *account_name;
- char *netbios_domain_name;
- char *dns_domain_name;
- char *dn;
- struct dom_sid *domain_sid;
- bool modified_config;
- WERROR result;
- char *error_string;
- bool domain_is_ad;
- } out;
-};
-
-struct libnet_UnjoinCtx {
- struct {
- const char *dc_name;
- const char *machine_name;
- const char *domain_name;
- const char *admin_account;
- const char *admin_password;
- uint32_t unjoin_flags;
- bool modify_config;
- struct dom_sid *domain_sid;
- struct ads_struct *ads;
- } in;
-
- struct {
- bool modified_config;
- WERROR result;
- char *error_string;
- } out;
-};
-
-#endif
diff --git a/source3/librpc/gen_ndr/cli_lsa.c b/source3/librpc/gen_ndr/cli_lsa.c
index 92ba8bdfee..76370cabf1 100644
--- a/source3/librpc/gen_ndr/cli_lsa.c
+++ b/source3/librpc/gen_ndr/cli_lsa.c
@@ -609,7 +609,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count)
{
struct lsa_LookupNames r;
@@ -2528,7 +2528,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray2 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)
@@ -2920,7 +2920,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)
@@ -3120,16 +3120,23 @@ NTSTATUS rpccli_lsa_LSARUNREGISTERAUDITEVENT(struct rpc_pipe_client *cli,
return r.out.result;
}
-NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx)
+NTSTATUS rpccli_lsa_lsaRQueryForestTrustInformation(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ struct lsa_String *trusted_domain_name,
+ uint16_t unknown,
+ struct lsa_ForestTrustInformation **forest_trust_info)
{
- struct lsa_LSARQUERYFORESTTRUSTINFORMATION r;
+ struct lsa_lsaRQueryForestTrustInformation r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.trusted_domain_name = trusted_domain_name;
+ r.in.unknown = unknown;
if (DEBUGLEVEL >= 10) {
- NDR_PRINT_IN_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, &r);
+ NDR_PRINT_IN_DEBUG(lsa_lsaRQueryForestTrustInformation, &r);
}
status = cli_do_rpc_ndr(cli,
@@ -3144,7 +3151,7 @@ NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
}
if (DEBUGLEVEL >= 10) {
- NDR_PRINT_OUT_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, &r);
+ NDR_PRINT_OUT_DEBUG(lsa_lsaRQueryForestTrustInformation, &r);
}
if (NT_STATUS_IS_ERR(status)) {
@@ -3152,6 +3159,7 @@ NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
}
/* Return variables */
+ *forest_trust_info = *r.out.forest_trust_info;
/* Return result */
return r.out.result;
@@ -3292,7 +3300,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)
diff --git a/source3/librpc/gen_ndr/cli_lsa.h b/source3/librpc/gen_ndr/cli_lsa.h
index 4ab8be9939..c45aed1d37 100644
--- a/source3/librpc/gen_ndr/cli_lsa.h
+++ b/source3/librpc/gen_ndr/cli_lsa.h
@@ -71,7 +71,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count);
NTSTATUS rpccli_lsa_LookupSids(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
@@ -280,7 +280,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray2 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);
@@ -309,7 +309,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);
@@ -321,8 +321,12 @@ NTSTATUS rpccli_lsa_LSARGENAUDITEVENT(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_LSARUNREGISTERAUDITEVENT(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
-NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx);
+NTSTATUS rpccli_lsa_lsaRQueryForestTrustInformation(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle,
+ struct lsa_String *trusted_domain_name,
+ uint16_t unknown,
+ struct lsa_ForestTrustInformation **forest_trust_info);
NTSTATUS rpccli_lsa_LSARSETFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_CREDRRENAME(struct rpc_pipe_client *cli,
@@ -342,7 +346,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
- uint16_t level,
+ enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);
diff --git a/source3/librpc/gen_ndr/libnet_join.h b/source3/librpc/gen_ndr/libnet_join.h
new file mode 100644
index 0000000000..40759cb489
--- /dev/null
+++ b/source3/librpc/gen_ndr/libnet_join.h
@@ -0,0 +1,73 @@
+/* header auto-generated by pidl */
+
+#include <stdint.h>
+
+#include "librpc/gen_ndr/wkssvc.h"
+#include "librpc/gen_ndr/security.h"
+#ifndef _HEADER_libnetjoin
+#define _HEADER_libnetjoin
+
+;
+
+
+struct libnet_JoinCtx {
+ struct {
+ const char * dc_name;
+ const char * machine_name;
+ const char * domain_name;/* [ref] */
+ const char * account_ou;
+ const char * admin_account;
+ const char * admin_password;
+ const char * machine_password;
+ uint32_t join_flags;
+ const char * os_version;
+ const char * os_name;
+ uint8_t create_upn;
+ const char * upn;
+ uint8_t modify_config;
+ struct ads_struct *ads;/* [ref] */
+ uint8_t debug;
+ } in;
+
+ struct {
+ const char * account_name;
+ const char * netbios_domain_name;
+ const char * dns_domain_name;
+ const char * dn;
+ struct dom_sid *domain_sid;/* [ref] */
+ uint8_t modified_config;
+ const char * error_string;
+ uint8_t domain_is_ad;
+ WERROR result;
+ } out;
+
+};
+
+
+struct libnet_UnjoinCtx {
+ struct {
+ const char * dc_name;
+ const char * machine_name;
+ const char * domain_name;
+ const char * account_ou;
+ const char * admin_account;
+ const char * admin_password;
+ const char * machine_password;
+ uint32_t unjoin_flags;
+ uint8_t modify_config;
+ struct dom_sid *domain_sid;/* [ref] */
+ struct ads_struct *ads;/* [ref] */
+ uint8_t debug;
+ } in;
+
+ struct {
+ const char * netbios_domain_name;
+ const char * dns_domain_name;
+ uint8_t modified_config;
+ const char * error_string;
+ WERROR result;
+ } out;
+
+};
+
+#endif /* _HEADER_libnetjoin */
diff --git a/source3/librpc/gen_ndr/lsa.h b/source3/librpc/gen_ndr/lsa.h
index 513d17b5df..cbaa9083e4 100644
--- a/source3/librpc/gen_ndr/lsa.h
+++ b/source3/librpc/gen_ndr/lsa.h
@@ -75,9 +75,55 @@ struct lsa_AuditLogInfo {
uint32_t unknown;
};
+enum lsa_PolicyAuditPolicy
+#ifndef USE_UINT_ENUMS
+ {
+ LSA_AUDIT_POLICY_NONE=0,
+ LSA_AUDIT_POLICY_SUCCESS=1,
+ LSA_AUDIT_POLICY_FAILURE=2,
+ LSA_AUDIT_POLICY_ALL=(LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE),
+ LSA_AUDIT_POLICY_CLEAR=4
+}
+#else
+ { __donnot_use_enum_lsa_PolicyAuditPolicy=0x7FFFFFFF}
+#define LSA_AUDIT_POLICY_NONE ( 0 )
+#define LSA_AUDIT_POLICY_SUCCESS ( 1 )
+#define LSA_AUDIT_POLICY_FAILURE ( 2 )
+#define LSA_AUDIT_POLICY_ALL ( (LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE) )
+#define LSA_AUDIT_POLICY_CLEAR ( 4 )
+#endif
+;
+
+enum lsa_PolicyAuditEventType
+#ifndef USE_UINT_ENUMS
+ {
+ LSA_AUDIT_CATEGORY_SYSTEM=0,
+ LSA_AUDIT_CATEGORY_LOGON=1,
+ LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS=2,
+ LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS=3,
+ LSA_AUDIT_CATEGORY_PROCCESS_TRACKING=4,
+ LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES=5,
+ LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT=6,
+ LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS=7,
+ LSA_AUDIT_CATEGORY_ACCOUNT_LOGON=8
+}
+#else
+ { __donnot_use_enum_lsa_PolicyAuditEventType=0x7FFFFFFF}
+#define LSA_AUDIT_CATEGORY_SYSTEM ( 0 )
+#define LSA_AUDIT_CATEGORY_LOGON ( 1 )
+#define LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS ( 2 )
+#define LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS ( 3 )
+#define LSA_AUDIT_CATEGORY_PROCCESS_TRACKING ( 4 )
+#define LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES ( 5 )
+#define LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT ( 6 )
+#define LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS ( 7 )
+#define LSA_AUDIT_CATEGORY_ACCOUNT_LOGON ( 8 )
+#endif
+;
+
struct lsa_AuditEventsInfo {
uint32_t auditing_mode;
- uint32_t *settings;/* [unique,size_is(count)] */
+ enum lsa_PolicyAuditPolicy *settings;/* [unique,size_is(count)] */
uint32_t count;
};
@@ -240,6 +286,27 @@ struct lsa_RefDomainList {
uint32_t max_size;
};
+enum lsa_LookupNamesLevel
+#ifndef USE_UINT_ENUMS
+ {
+ LSA_LOOKUP_NAMES_ALL=1,
+ LSA_LOOKUP_NAMES_DOMAINS_ONLY=2,
+ LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY=3,
+ LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY=4,
+ LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY=5,
+ LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2=6
+}
+#else
+ { __donnot_use_enum_lsa_LookupNamesLevel=0x7FFFFFFF}
+#define LSA_LOOKUP_NAMES_ALL ( 1 )
+#define LSA_LOOKUP_NAMES_DOMAINS_ONLY ( 2 )
+#define LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY ( 3 )
+#define LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY ( 4 )
+#define LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY ( 5 )
+#define LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 ( 6 )
+#endif
+;
+
struct lsa_TranslatedName {
enum lsa_SidType sid_type;
struct lsa_String name;
@@ -464,6 +531,53 @@ struct lsa_TransSidArray3 {
struct lsa_TranslatedSid3 *sids;/* [unique,size_is(count)] */
};
+struct lsa_ForestTrustBinaryData {
+ uint32_t length;/* [range(0 131072)] */
+ uint8_t *data;/* [unique,size_is(length)] */
+};
+
+struct lsa_ForestTrustDomainInfo {
+ struct dom_sid2 *domain_sid;/* [unique] */
+ struct lsa_StringLarge dns_domain_name;
+ struct lsa_StringLarge netbios_domain_name;
+};
+
+union lsa_ForestTrustData {
+ struct lsa_String top_level_name;/* [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME)] */
+ struct lsa_StringLarge top_level_name_ex;/* [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX)] */
+ struct lsa_ForestTrustDomainInfo domain_info;/* [case(LSA_FOREST_TRUST_DOMAIN_INFO)] */
+ struct lsa_ForestTrustBinaryData data;/* [default] */
+}/* [switch_type(uint32)] */;
+
+enum lsa_ForestTrustRecordType
+#ifndef USE_UINT_ENUMS
+ {
+ LSA_FOREST_TRUST_TOP_LEVEL_NAME=0,
+ LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX=1,
+ LSA_FOREST_TRUST_DOMAIN_INFO=2,
+ LSA_FOREST_TRUST_RECORD_TYPE_LAST=3
+}
+#else
+ { __donnot_use_enum_lsa_ForestTrustRecordType=0x7FFFFFFF}
+#define LSA_FOREST_TRUST_TOP_LEVEL_NAME ( 0 )
+#define LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX ( 1 )
+#define LSA_FOREST_TRUST_DOMAIN_INFO ( 2 )
+#define LSA_FOREST_TRUST_RECORD_TYPE_LAST ( 3 )
+#endif
+;
+
+struct lsa_ForestTrustRecord {
+ uint32_t flags;
+ enum lsa_ForestTrustRecordType level;
+ uint64_t unknown;
+ union lsa_ForestTrustData forest_trust_data;/* [switch_is(level)] */
+};
+
+struct lsa_ForestTrustInformation {
+ uint32_t count;/* [range(0 4000)] */
+ struct lsa_ForestTrustRecord **entries;/* [unique,size_is(count)] */
+}/* [public] */;
+
struct lsa_Close {
struct {
@@ -636,7 +750,7 @@ struct lsa_CreateTrustedDomain {
struct lsa_EnumTrustDom {
struct {
struct policy_handle *handle;/* [ref] */
- uint32_t max_size;/* [range(0 1000)] */
+ uint32_t max_size;
uint32_t *resume_handle;/* [ref] */
} in;
@@ -654,7 +768,7 @@ struct lsa_LookupNames {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
- uint16_t level;
+ enum lsa_LookupNamesLevel level;
struct lsa_TransSidArray *sids;/* [ref] */
uint32_t *count;/* [ref] */
} in;
@@ -1241,7 +1355,7 @@ struct lsa_LookupNames2 {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
- uint16_t level;
+ enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray2 *sids;/* [ref] */
@@ -1335,7 +1449,7 @@ struct lsa_LookupNames3 {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
- uint16_t level;
+ enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray3 *sids;/* [ref] */
@@ -1384,8 +1498,15 @@ struct lsa_LSARUNREGISTERAUDITEVENT {
};
-struct lsa_LSARQUERYFORESTTRUSTINFORMATION {
+struct lsa_lsaRQueryForestTrustInformation {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct lsa_String *trusted_domain_name;/* [ref] */
+ uint16_t unknown;
+ } in;
+
+ struct {
+ struct lsa_ForestTrustInformation **forest_trust_info;/* [ref] */
NTSTATUS result;
} out;
@@ -1432,7 +1553,7 @@ struct lsa_LookupNames4 {
struct {
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
- uint16_t level;
+ enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray3 *sids;/* [ref] */
diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.c b/source3/librpc/gen_ndr/ndr_libnet_join.c
new file mode 100644
index 0000000000..5345bc0ad4
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_libnet_join.c
@@ -0,0 +1,103 @@
+/* parser auto-generated by pidl */
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_libnet_join.h"
+
+#include "librpc/gen_ndr/ndr_wkssvc.h"
+#include "librpc/gen_ndr/ndr_security.h"
+_PUBLIC_ void ndr_print_libnet_JoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_JoinCtx *r)
+{
+ ndr_print_struct(ndr, name, "libnet_JoinCtx");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "libnet_JoinCtx");
+ ndr->depth++;
+ ndr_print_string(ndr, "dc_name", r->in.dc_name);
+ ndr_print_string(ndr, "machine_name", r->in.machine_name);
+ ndr_print_ptr(ndr, "domain_name", r->in.domain_name);
+ ndr->depth++;
+ ndr_print_string(ndr, "domain_name", r->in.domain_name);
+ ndr->depth--;
+ ndr_print_string(ndr, "account_ou", r->in.account_ou);
+ ndr_print_string(ndr, "admin_account", r->in.admin_account);
+ ndr_print_string(ndr, "admin_password", r->in.admin_password);
+ ndr_print_string(ndr, "machine_password", r->in.machine_password);
+ ndr_print_wkssvc_joinflags(ndr, "join_flags", r->in.join_flags);
+ ndr_print_string(ndr, "os_version", r->in.os_version);
+ ndr_print_string(ndr, "os_name", r->in.os_name);
+ ndr_print_uint8(ndr, "create_upn", r->in.create_upn);
+ ndr_print_string(ndr, "upn", r->in.upn);
+ ndr_print_uint8(ndr, "modify_config", r->in.modify_config);
+ ndr_print_ptr(ndr, "ads", r->in.ads);
+ ndr->depth++;
+ ndr_print_ads_struct(ndr, "ads", r->in.ads);
+ ndr->depth--;
+ ndr_print_uint8(ndr, "debug", r->in.debug);
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ ndr_print_struct(ndr, "out", "libnet_JoinCtx");
+ ndr->depth++;
+ ndr_print_string(ndr, "account_name", r->out.account_name);
+ ndr_print_string(ndr, "netbios_domain_name", r->out.netbios_domain_name);
+ ndr_print_string(ndr, "dns_domain_name", r->out.dns_domain_name);
+ ndr_print_string(ndr, "dn", r->out.dn);
+ ndr_print_ptr(ndr, "domain_sid", r->out.domain_sid);
+ ndr->depth++;
+ ndr_print_dom_sid(ndr, "domain_sid", r->out.domain_sid);
+ ndr->depth--;
+ ndr_print_uint8(ndr, "modified_config", r->out.modified_config);
+ ndr_print_string(ndr, "error_string", r->out.error_string);
+ ndr_print_uint8(ndr, "domain_is_ad", r->out.domain_is_ad);
+ ndr_print_WERROR(ndr, "result", r->out.result);
+ ndr->depth--;
+ }
+ ndr->depth--;
+}
+
+_PUBLIC_ void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_UnjoinCtx *r)
+{
+ ndr_print_struct(ndr, name, "libnet_UnjoinCtx");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "libnet_UnjoinCtx");
+ ndr->depth++;
+ ndr_print_string(ndr, "dc_name", r->in.dc_name);
+ ndr_print_string(ndr, "machine_name", r->in.machine_name);
+ ndr_print_string(ndr, "domain_name", r->in.domain_name);
+ ndr_print_string(ndr, "account_ou", r->in.account_ou);
+ ndr_print_string(ndr, "admin_account", r->in.admin_account);
+ ndr_print_string(ndr, "admin_password", r->in.admin_password);
+ ndr_print_string(ndr, "machine_password", r->in.machine_password);
+ ndr_print_wkssvc_joinflags(ndr, "unjoin_flags", r->in.unjoin_flags);
+ ndr_print_uint8(ndr, "modify_config", r->in.modify_config);
+ ndr_print_ptr(ndr, "domain_sid", r->in.domain_sid);
+ ndr->depth++;
+ ndr_print_dom_sid(ndr, "domain_sid", r->in.domain_sid);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "ads", r->in.ads);
+ ndr->depth++;
+ ndr_print_ads_struct(ndr, "ads", r->in.ads);
+ ndr->depth--;
+ ndr_print_uint8(ndr, "debug", r->in.debug);
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ ndr_print_struct(ndr, "out", "libnet_UnjoinCtx");
+ ndr->depth++;
+ ndr_print_string(ndr, "netbios_domain_name", r->out.netbios_domain_name);
+ ndr_print_string(ndr, "dns_domain_name", r->out.dns_domain_name);
+ ndr_print_uint8(ndr, "modified_config", r->out.modified_config);
+ ndr_print_string(ndr, "error_string", r->out.error_string);
+ ndr_print_WERROR(ndr, "result", r->out.result);
+ ndr->depth--;
+ }
+ ndr->depth--;
+}
+
diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.h b/source3/librpc/gen_ndr/ndr_libnet_join.h
new file mode 100644
index 0000000000..4a5fdf0d50
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_libnet_join.h
@@ -0,0 +1,20 @@
+/* header auto-generated by pidl */
+
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/libnet_join.h"
+
+#ifndef _HEADER_NDR_libnetjoin
+#define _HEADER_NDR_libnetjoin
+
+#define NDR_LIBNET_JOINCTX (0x00)
+
+#define NDR_LIBNET_UNJOINCTX (0x01)
+
+#define NDR_LIBNETJOIN_CALL_COUNT (2)
+enum ndr_err_code ndr_push_libnet_JoinCtx(struct ndr_push *ndr, int flags, const struct libnet_JoinCtx *r);
+enum ndr_err_code ndr_pull_libnet_JoinCtx(struct ndr_pull *ndr, int flags, struct libnet_JoinCtx *r);
+void ndr_print_libnet_JoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_JoinCtx *r);
+enum ndr_err_code ndr_push_libnet_UnjoinCtx(struct ndr_push *ndr, int flags, const struct libnet_UnjoinCtx *r);
+enum ndr_err_code ndr_pull_libnet_UnjoinCtx(struct ndr_pull *ndr, int flags, struct libnet_UnjoinCtx *r);
+void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_UnjoinCtx *r);
+#endif /* _HEADER_NDR_libnetjoin */
diff --git a/source3/librpc/gen_ndr/ndr_lsa.c b/source3/librpc/gen_ndr/ndr_lsa.c
index eed2a8e0e3..25fa3d2129 100644
--- a/source3/librpc/gen_ndr/ndr_lsa.c
+++ b/source3/librpc/gen_ndr/ndr_lsa.c
@@ -690,6 +690,34 @@ _PUBLIC_ void ndr_print_lsa_AuditLogInfo(struct ndr_print *ndr, const char *name
ndr->depth--;
}
+static enum ndr_err_code ndr_push_lsa_PolicyAuditPolicy(struct ndr_push *ndr, int ndr_flags, enum lsa_PolicyAuditPolicy r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_PolicyAuditPolicy(struct ndr_pull *ndr, int ndr_flags, enum lsa_PolicyAuditPolicy *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_PolicyAuditPolicy(struct ndr_print *ndr, const char *name, enum lsa_PolicyAuditPolicy r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case LSA_AUDIT_POLICY_NONE: val = "LSA_AUDIT_POLICY_NONE"; break;
+ case LSA_AUDIT_POLICY_SUCCESS: val = "LSA_AUDIT_POLICY_SUCCESS"; break;
+ case LSA_AUDIT_POLICY_FAILURE: val = "LSA_AUDIT_POLICY_FAILURE"; break;
+ case LSA_AUDIT_POLICY_ALL: val = "LSA_AUDIT_POLICY_ALL"; break;
+ case LSA_AUDIT_POLICY_CLEAR: val = "LSA_AUDIT_POLICY_CLEAR"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
static enum ndr_err_code ndr_push_lsa_AuditEventsInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_AuditEventsInfo *r)
{
uint32_t cntr_settings_1;
@@ -703,7 +731,7 @@ static enum ndr_err_code ndr_push_lsa_AuditEventsInfo(struct ndr_push *ndr, int
if (r->settings) {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
for (cntr_settings_1 = 0; cntr_settings_1 < r->count; cntr_settings_1++) {
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->settings[cntr_settings_1]));
+ NDR_CHECK(ndr_push_lsa_PolicyAuditPolicy(ndr, NDR_SCALARS, r->settings[cntr_settings_1]));
}
}
}
@@ -736,7 +764,7 @@ static enum ndr_err_code ndr_pull_lsa_AuditEventsInfo(struct ndr_pull *ndr, int
_mem_save_settings_1 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->settings, 0);
for (cntr_settings_1 = 0; cntr_settings_1 < r->count; cntr_settings_1++) {
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->settings[cntr_settings_1]));
+ NDR_CHECK(ndr_pull_lsa_PolicyAuditPolicy(ndr, NDR_SCALARS, &r->settings[cntr_settings_1]));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_settings_1, 0);
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_settings_0, 0);
@@ -763,7 +791,7 @@ _PUBLIC_ void ndr_print_lsa_AuditEventsInfo(struct ndr_print *ndr, const char *n
char *idx_1=NULL;
asprintf(&idx_1, "[%d]", cntr_settings_1);
if (idx_1) {
- ndr_print_uint32(ndr, "settings", r->settings[cntr_settings_1]);
+ ndr_print_lsa_PolicyAuditPolicy(ndr, "settings", r->settings[cntr_settings_1]);
free(idx_1);
}
}
@@ -1939,6 +1967,35 @@ _PUBLIC_ void ndr_print_lsa_RefDomainList(struct ndr_print *ndr, const char *nam
ndr->depth--;
}
+static enum ndr_err_code ndr_push_lsa_LookupNamesLevel(struct ndr_push *ndr, int ndr_flags, enum lsa_LookupNamesLevel r)
+{
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_LookupNamesLevel(struct ndr_pull *ndr, int ndr_flags, enum lsa_LookupNamesLevel *r)
+{
+ uint16_t v;
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_LookupNamesLevel(struct ndr_print *ndr, const char *name, enum lsa_LookupNamesLevel r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case LSA_LOOKUP_NAMES_ALL: val = "LSA_LOOKUP_NAMES_ALL"; break;
+ case LSA_LOOKUP_NAMES_DOMAINS_ONLY: val = "LSA_LOOKUP_NAMES_DOMAINS_ONLY"; break;
+ case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: val = "LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY"; break;
+ case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: val = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY"; break;
+ case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: val = "LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY"; break;
+ case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: val = "LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
static enum ndr_err_code ndr_push_lsa_TranslatedName(struct ndr_push *ndr, int ndr_flags, const struct lsa_TranslatedName *r)
{
if (ndr_flags & NDR_SCALARS) {
@@ -4027,6 +4084,434 @@ _PUBLIC_ void ndr_print_lsa_TransSidArray3(struct ndr_print *ndr, const char *na
ndr->depth--;
}
+static enum ndr_err_code ndr_push_lsa_ForestTrustBinaryData(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustBinaryData *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->length));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->data));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->data) {
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->length));
+ NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->data, r->length));
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_ForestTrustBinaryData(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustBinaryData *r)
+{
+ uint32_t _ptr_data;
+ TALLOC_CTX *_mem_save_data_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length));
+ if (r->length < 0 || r->length > 131072) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data));
+ if (_ptr_data) {
+ NDR_PULL_ALLOC(ndr, r->data);
+ } else {
+ r->data = NULL;
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->data) {
+ _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->data, 0);
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->data));
+ NDR_PULL_ALLOC_N(ndr, r->data, ndr_get_array_size(ndr, &r->data));
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->data, ndr_get_array_size(ndr, &r->data)));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0);
+ }
+ if (r->data) {
+ NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->data, r->length));
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustBinaryData(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustBinaryData *r)
+{
+ ndr_print_struct(ndr, name, "lsa_ForestTrustBinaryData");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "length", r->length);
+ ndr_print_ptr(ndr, "data", r->data);
+ ndr->depth++;
+ if (r->data) {
+ ndr_print_array_uint8(ndr, "data", r->data, r->length);
+ }
+ ndr->depth--;
+ ndr->depth--;
+}
+
+static enum ndr_err_code ndr_push_lsa_ForestTrustDomainInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustDomainInfo *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->domain_sid));
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_SCALARS, &r->dns_domain_name));
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_SCALARS, &r->netbios_domain_name));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->domain_sid) {
+ NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->domain_sid));
+ }
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_BUFFERS, &r->dns_domain_name));
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_BUFFERS, &r->netbios_domain_name));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_ForestTrustDomainInfo(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustDomainInfo *r)
+{
+ uint32_t _ptr_domain_sid;
+ TALLOC_CTX *_mem_save_domain_sid_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domain_sid));
+ if (_ptr_domain_sid) {
+ NDR_PULL_ALLOC(ndr, r->domain_sid);
+ } else {
+ r->domain_sid = NULL;
+ }
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_SCALARS, &r->dns_domain_name));
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_SCALARS, &r->netbios_domain_name));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->domain_sid) {
+ _mem_save_domain_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->domain_sid, 0);
+ NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->domain_sid));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domain_sid_0, 0);
+ }
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_BUFFERS, &r->dns_domain_name));
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_BUFFERS, &r->netbios_domain_name));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustDomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustDomainInfo *r)
+{
+ ndr_print_struct(ndr, name, "lsa_ForestTrustDomainInfo");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "domain_sid", r->domain_sid);
+ ndr->depth++;
+ if (r->domain_sid) {
+ ndr_print_dom_sid2(ndr, "domain_sid", r->domain_sid);
+ }
+ ndr->depth--;
+ ndr_print_lsa_StringLarge(ndr, "dns_domain_name", &r->dns_domain_name);
+ ndr_print_lsa_StringLarge(ndr, "netbios_domain_name", &r->netbios_domain_name);
+ ndr->depth--;
+}
+
+static enum ndr_err_code ndr_push_lsa_ForestTrustData(struct ndr_push *ndr, int ndr_flags, const union lsa_ForestTrustData *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level));
+ switch (level) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->top_level_name));
+ break;
+
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_SCALARS, &r->top_level_name_ex));
+ break;
+
+ case LSA_FOREST_TRUST_DOMAIN_INFO:
+ NDR_CHECK(ndr_push_lsa_ForestTrustDomainInfo(ndr, NDR_SCALARS, &r->domain_info));
+ break;
+
+ default:
+ NDR_CHECK(ndr_push_lsa_ForestTrustBinaryData(ndr, NDR_SCALARS, &r->data));
+ break;
+
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ switch (level) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->top_level_name));
+ break;
+
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+ NDR_CHECK(ndr_push_lsa_StringLarge(ndr, NDR_BUFFERS, &r->top_level_name_ex));
+ break;
+
+ case LSA_FOREST_TRUST_DOMAIN_INFO:
+ NDR_CHECK(ndr_push_lsa_ForestTrustDomainInfo(ndr, NDR_BUFFERS, &r->domain_info));
+ break;
+
+ default:
+ NDR_CHECK(ndr_push_lsa_ForestTrustBinaryData(ndr, NDR_BUFFERS, &r->data));
+ break;
+
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_ForestTrustData(struct ndr_pull *ndr, int ndr_flags, union lsa_ForestTrustData *r)
+{
+ int level;
+ uint32_t _level;
+ level = ndr_pull_get_switch_value(ndr, r);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level));
+ if (_level != level) {
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level);
+ }
+ switch (level) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME: {
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->top_level_name));
+ break; }
+
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: {
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_SCALARS, &r->top_level_name_ex));
+ break; }
+
+ case LSA_FOREST_TRUST_DOMAIN_INFO: {
+ NDR_CHECK(ndr_pull_lsa_ForestTrustDomainInfo(ndr, NDR_SCALARS, &r->domain_info));
+ break; }
+
+ default: {
+ NDR_CHECK(ndr_pull_lsa_ForestTrustBinaryData(ndr, NDR_SCALARS, &r->data));
+ break; }
+
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ switch (level) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->top_level_name));
+ break;
+
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+ NDR_CHECK(ndr_pull_lsa_StringLarge(ndr, NDR_BUFFERS, &r->top_level_name_ex));
+ break;
+
+ case LSA_FOREST_TRUST_DOMAIN_INFO:
+ NDR_CHECK(ndr_pull_lsa_ForestTrustDomainInfo(ndr, NDR_BUFFERS, &r->domain_info));
+ break;
+
+ default:
+ NDR_CHECK(ndr_pull_lsa_ForestTrustBinaryData(ndr, NDR_BUFFERS, &r->data));
+ break;
+
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustData(struct ndr_print *ndr, const char *name, const union lsa_ForestTrustData *r)
+{
+ int level;
+ level = ndr_print_get_switch_value(ndr, r);
+ ndr_print_union(ndr, name, level, "lsa_ForestTrustData");
+ switch (level) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
+ ndr_print_lsa_String(ndr, "top_level_name", &r->top_level_name);
+ break;
+
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
+ ndr_print_lsa_StringLarge(ndr, "top_level_name_ex", &r->top_level_name_ex);
+ break;
+
+ case LSA_FOREST_TRUST_DOMAIN_INFO:
+ ndr_print_lsa_ForestTrustDomainInfo(ndr, "domain_info", &r->domain_info);
+ break;
+
+ default:
+ ndr_print_lsa_ForestTrustBinaryData(ndr, "data", &r->data);
+ break;
+
+ }
+}
+
+static enum ndr_err_code ndr_push_lsa_ForestTrustRecordType(struct ndr_push *ndr, int ndr_flags, enum lsa_ForestTrustRecordType r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_ForestTrustRecordType(struct ndr_pull *ndr, int ndr_flags, enum lsa_ForestTrustRecordType *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustRecordType(struct ndr_print *ndr, const char *name, enum lsa_ForestTrustRecordType r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME: val = "LSA_FOREST_TRUST_TOP_LEVEL_NAME"; break;
+ case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: val = "LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX"; break;
+ case LSA_FOREST_TRUST_DOMAIN_INFO: val = "LSA_FOREST_TRUST_DOMAIN_INFO"; break;
+ case LSA_FOREST_TRUST_RECORD_TYPE_LAST: val = "LSA_FOREST_TRUST_RECORD_TYPE_LAST"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
+static enum ndr_err_code ndr_push_lsa_ForestTrustRecord(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustRecord *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 8));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->flags));
+ NDR_CHECK(ndr_push_lsa_ForestTrustRecordType(ndr, NDR_SCALARS, r->level));
+ NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->unknown));
+ NDR_CHECK(ndr_push_set_switch_value(ndr, &r->forest_trust_data, r->level));
+ NDR_CHECK(ndr_push_lsa_ForestTrustData(ndr, NDR_SCALARS, &r->forest_trust_data));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_push_lsa_ForestTrustData(ndr, NDR_BUFFERS, &r->forest_trust_data));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_lsa_ForestTrustRecord(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustRecord *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 8));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->flags));
+ NDR_CHECK(ndr_pull_lsa_ForestTrustRecordType(ndr, NDR_SCALARS, &r->level));
+ NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->unknown));
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->forest_trust_data, r->level));
+ NDR_CHECK(ndr_pull_lsa_ForestTrustData(ndr, NDR_SCALARS, &r->forest_trust_data));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_lsa_ForestTrustData(ndr, NDR_BUFFERS, &r->forest_trust_data));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustRecord(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustRecord *r)
+{
+ ndr_print_struct(ndr, name, "lsa_ForestTrustRecord");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "flags", r->flags);
+ ndr_print_lsa_ForestTrustRecordType(ndr, "level", r->level);
+ ndr_print_hyper(ndr, "unknown", r->unknown);
+ ndr_print_set_switch_value(ndr, &r->forest_trust_data, r->level);
+ ndr_print_lsa_ForestTrustData(ndr, "forest_trust_data", &r->forest_trust_data);
+ ndr->depth--;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_ForestTrustInformation(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustInformation *r)
+{
+ uint32_t cntr_entries_1;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->entries));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->entries) {
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count));
+ for (cntr_entries_1 = 0; cntr_entries_1 < r->count; cntr_entries_1++) {
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->entries[cntr_entries_1]));
+ }
+ for (cntr_entries_1 = 0; cntr_entries_1 < r->count; cntr_entries_1++) {
+ if (r->entries[cntr_entries_1]) {
+ NDR_CHECK(ndr_push_lsa_ForestTrustRecord(ndr, NDR_SCALARS|NDR_BUFFERS, r->entries[cntr_entries_1]));
+ }
+ }
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_ForestTrustInformation(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustInformation *r)
+{
+ uint32_t _ptr_entries;
+ uint32_t cntr_entries_1;
+ TALLOC_CTX *_mem_save_entries_0;
+ TALLOC_CTX *_mem_save_entries_1;
+ TALLOC_CTX *_mem_save_entries_2;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count));
+ if (r->count < 0 || r->count > 4000) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_entries));
+ if (_ptr_entries) {
+ NDR_PULL_ALLOC(ndr, r->entries);
+ } else {
+ r->entries = NULL;
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->entries) {
+ _mem_save_entries_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->entries, 0);
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->entries));
+ NDR_PULL_ALLOC_N(ndr, r->entries, ndr_get_array_size(ndr, &r->entries));
+ _mem_save_entries_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->entries, 0);
+ for (cntr_entries_1 = 0; cntr_entries_1 < r->count; cntr_entries_1++) {
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_entries));
+ if (_ptr_entries) {
+ NDR_PULL_ALLOC(ndr, r->entries[cntr_entries_1]);
+ } else {
+ r->entries[cntr_entries_1] = NULL;
+ }
+ }
+ for (cntr_entries_1 = 0; cntr_entries_1 < r->count; cntr_entries_1++) {
+ if (r->entries[cntr_entries_1]) {
+ _mem_save_entries_2 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->entries[cntr_entries_1], 0);
+ NDR_CHECK(ndr_pull_lsa_ForestTrustRecord(ndr, NDR_SCALARS|NDR_BUFFERS, r->entries[cntr_entries_1]));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_entries_2, 0);
+ }
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_entries_1, 0);
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_entries_0, 0);
+ }
+ if (r->entries) {
+ NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->entries, r->count));
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_lsa_ForestTrustInformation(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustInformation *r)
+{
+ uint32_t cntr_entries_1;
+ ndr_print_struct(ndr, name, "lsa_ForestTrustInformation");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "count", r->count);
+ ndr_print_ptr(ndr, "entries", r->entries);
+ ndr->depth++;
+ if (r->entries) {
+ ndr->print(ndr, "%s: ARRAY(%d)", "entries", r->count);
+ ndr->depth++;
+ for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) {
+ char *idx_1=NULL;
+ asprintf(&idx_1, "[%d]", cntr_entries_1);
+ if (idx_1) {
+ ndr_print_ptr(ndr, "entries", r->entries[cntr_entries_1]);
+ ndr->depth++;
+ if (r->entries[cntr_entries_1]) {
+ ndr_print_lsa_ForestTrustRecord(ndr, "entries", r->entries[cntr_entries_1]);
+ }
+ ndr->depth--;
+ free(idx_1);
+ }
+ }
+ ndr->depth--;
+ }
+ ndr->depth--;
+ ndr->depth--;
+}
+
static enum ndr_err_code ndr_push_lsa_Close(struct ndr_push *ndr, int flags, const struct lsa_Close *r)
{
if (flags & NDR_IN) {
@@ -4103,7 +4588,7 @@ _PUBLIC_ void ndr_print_lsa_Close(struct ndr_print *ndr, const char *name, int f
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_Delete(struct ndr_push *ndr, int flags, const struct lsa_Delete *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_Delete(struct ndr_push *ndr, int flags, const struct lsa_Delete *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -4117,7 +4602,7 @@ static enum ndr_err_code ndr_push_lsa_Delete(struct ndr_push *ndr, int flags, co
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_Delete(struct ndr_pull *ndr, int flags, struct lsa_Delete *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_Delete(struct ndr_pull *ndr, int flags, struct lsa_Delete *r)
{
TALLOC_CTX *_mem_save_handle_0;
if (flags & NDR_IN) {
@@ -4160,7 +4645,7 @@ _PUBLIC_ void ndr_print_lsa_Delete(struct ndr_print *ndr, const char *name, int
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, int flags, const struct lsa_EnumPrivs *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, int flags, const struct lsa_EnumPrivs *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -4187,7 +4672,7 @@ static enum ndr_err_code ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, int flags,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_EnumPrivs(struct ndr_pull *ndr, int flags, struct lsa_EnumPrivs *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_EnumPrivs(struct ndr_pull *ndr, int flags, struct lsa_EnumPrivs *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_resume_handle_0;
@@ -4441,7 +4926,7 @@ _PUBLIC_ void ndr_print_lsa_ChangePassword(struct ndr_print *ndr, const char *na
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy *r)
{
if (flags & NDR_IN) {
NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.system_name));
@@ -4464,7 +4949,7 @@ static enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int flags
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy *r)
{
uint32_t _ptr_system_name;
TALLOC_CTX *_mem_save_system_name_0;
@@ -4754,7 +5239,7 @@ _PUBLIC_ void ndr_print_lsa_ClearAuditLog(struct ndr_print *ndr, const char *nam
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_CreateAccount(struct ndr_push *ndr, int flags, const struct lsa_CreateAccount *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_CreateAccount(struct ndr_push *ndr, int flags, const struct lsa_CreateAccount *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -4777,7 +5262,7 @@ static enum ndr_err_code ndr_push_lsa_CreateAccount(struct ndr_push *ndr, int fl
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_CreateAccount(struct ndr_pull *ndr, int flags, struct lsa_CreateAccount *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_CreateAccount(struct ndr_pull *ndr, int flags, struct lsa_CreateAccount *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_sid_0;
@@ -4850,7 +5335,7 @@ _PUBLIC_ void ndr_print_lsa_CreateAccount(struct ndr_print *ndr, const char *nam
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_EnumAccounts(struct ndr_push *ndr, int flags, const struct lsa_EnumAccounts *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_EnumAccounts(struct ndr_push *ndr, int flags, const struct lsa_EnumAccounts *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -4877,7 +5362,7 @@ static enum ndr_err_code ndr_push_lsa_EnumAccounts(struct ndr_push *ndr, int fla
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_EnumAccounts(struct ndr_pull *ndr, int flags, struct lsa_EnumAccounts *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_EnumAccounts(struct ndr_pull *ndr, int flags, struct lsa_EnumAccounts *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_resume_handle_0;
@@ -4966,7 +5451,7 @@ _PUBLIC_ void ndr_print_lsa_EnumAccounts(struct ndr_print *ndr, const char *name
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_CreateTrustedDomain(struct ndr_push *ndr, int flags, const struct lsa_CreateTrustedDomain *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_CreateTrustedDomain(struct ndr_push *ndr, int flags, const struct lsa_CreateTrustedDomain *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -4989,7 +5474,7 @@ static enum ndr_err_code ndr_push_lsa_CreateTrustedDomain(struct ndr_push *ndr,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_CreateTrustedDomain(struct ndr_pull *ndr, int flags, struct lsa_CreateTrustedDomain *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_CreateTrustedDomain(struct ndr_pull *ndr, int flags, struct lsa_CreateTrustedDomain *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_info_0;
@@ -5112,9 +5597,6 @@ static enum ndr_err_code ndr_pull_lsa_EnumTrustDom(struct ndr_pull *ndr, int fla
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.max_size));
- if (r->in.max_size < 0 || r->in.max_size > 1000) {
- return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
- }
NDR_PULL_ALLOC(ndr, r->out.resume_handle);
*r->out.resume_handle = *r->in.resume_handle;
NDR_PULL_ALLOC(ndr, r->out.domains);
@@ -5178,7 +5660,7 @@ _PUBLIC_ void ndr_print_lsa_EnumTrustDom(struct ndr_print *ndr, const char *name
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flags, const struct lsa_LookupNames *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flags, const struct lsa_LookupNames *r)
{
uint32_t cntr_names_0;
if (flags & NDR_IN) {
@@ -5198,7 +5680,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flag
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_lsa_TransSidArray(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level));
+ NDR_CHECK(ndr_push_lsa_LookupNamesLevel(ndr, NDR_SCALARS, r->in.level));
if (r->in.count == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -5222,7 +5704,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flag
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int flags, struct lsa_LookupNames *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int flags, struct lsa_LookupNames *r)
{
uint32_t cntr_names_0;
uint32_t _ptr_domains;
@@ -5263,7 +5745,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int flag
NDR_PULL_SET_MEM_CTX(ndr, r->in.sids, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_lsa_TransSidArray(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level));
+ NDR_CHECK(ndr_pull_lsa_LookupNamesLevel(ndr, NDR_SCALARS, &r->in.level));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->in.count);
}
@@ -5342,7 +5824,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name,
ndr->depth++;
ndr_print_lsa_TransSidArray(ndr, "sids", r->in.sids);
ndr->depth--;
- ndr_print_uint16(ndr, "level", r->in.level);
+ ndr_print_lsa_LookupNamesLevel(ndr, "level", r->in.level);
ndr_print_ptr(ndr, "count", r->in.count);
ndr->depth++;
ndr_print_uint32(ndr, "count", *r->in.count);
@@ -5372,7 +5854,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int flags, const struct lsa_LookupSids *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int flags, const struct lsa_LookupSids *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -5411,7 +5893,7 @@ static enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int flags
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int flags, struct lsa_LookupSids *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int flags, struct lsa_LookupSids *r)
{
uint32_t _ptr_domains;
TALLOC_CTX *_mem_save_handle_0;
@@ -5540,7 +6022,7 @@ _PUBLIC_ void ndr_print_lsa_LookupSids(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_CreateSecret(struct ndr_push *ndr, int flags, const struct lsa_CreateSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_CreateSecret(struct ndr_push *ndr, int flags, const struct lsa_CreateSecret *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -5560,7 +6042,7 @@ static enum ndr_err_code ndr_push_lsa_CreateSecret(struct ndr_push *ndr, int fla
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_CreateSecret(struct ndr_pull *ndr, int flags, struct lsa_CreateSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_CreateSecret(struct ndr_pull *ndr, int flags, struct lsa_CreateSecret *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_sec_handle_0;
@@ -6349,7 +6831,7 @@ _PUBLIC_ void ndr_print_lsa_SetInformationTrustedDomain(struct ndr_print *ndr, c
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_OpenSecret(struct ndr_push *ndr, int flags, const struct lsa_OpenSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_OpenSecret(struct ndr_push *ndr, int flags, const struct lsa_OpenSecret *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -6369,7 +6851,7 @@ static enum ndr_err_code ndr_push_lsa_OpenSecret(struct ndr_push *ndr, int flags
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_OpenSecret(struct ndr_pull *ndr, int flags, struct lsa_OpenSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_OpenSecret(struct ndr_pull *ndr, int flags, struct lsa_OpenSecret *r)
{
TALLOC_CTX *_mem_save_handle_0;
TALLOC_CTX *_mem_save_sec_handle_0;
@@ -6432,7 +6914,7 @@ _PUBLIC_ void ndr_print_lsa_OpenSecret(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_SetSecret(struct ndr_push *ndr, int flags, const struct lsa_SetSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_SetSecret(struct ndr_push *ndr, int flags, const struct lsa_SetSecret *r)
{
if (flags & NDR_IN) {
if (r->in.sec_handle == NULL) {
@@ -6454,7 +6936,7 @@ static enum ndr_err_code ndr_push_lsa_SetSecret(struct ndr_push *ndr, int flags,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_SetSecret(struct ndr_pull *ndr, int flags, struct lsa_SetSecret *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_SetSecret(struct ndr_pull *ndr, int flags, struct lsa_SetSecret *r)
{
uint32_t _ptr_new_val;
uint32_t _ptr_old_val;
@@ -6537,7 +7019,7 @@ _PUBLIC_ void ndr_print_lsa_SetSecret(struct ndr_print *ndr, const char *name, i
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_QuerySecret(struct ndr_push *ndr, int flags, const struct lsa_QuerySecret *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_QuerySecret(struct ndr_push *ndr, int flags, const struct lsa_QuerySecret *r)
{
if (flags & NDR_IN) {
if (r->in.sec_handle == NULL) {
@@ -6583,7 +7065,7 @@ static enum ndr_err_code ndr_push_lsa_QuerySecret(struct ndr_push *ndr, int flag
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_QuerySecret(struct ndr_pull *ndr, int flags, struct lsa_QuerySecret *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_QuerySecret(struct ndr_pull *ndr, int flags, struct lsa_QuerySecret *r)
{
uint32_t _ptr_new_val;
uint32_t _ptr_new_mtime;
@@ -7824,7 +8306,7 @@ _PUBLIC_ void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const cha
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy2 *r)
{
if (flags & NDR_IN) {
NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.system_name));
@@ -7850,7 +8332,7 @@ static enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int flag
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy2 *r)
{
uint32_t _ptr_system_name;
TALLOC_CTX *_mem_save_system_name_0;
@@ -8985,7 +9467,7 @@ _PUBLIC_ void ndr_print_lsa_TestCall(struct ndr_print *ndr, const char *name, in
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int flags, const struct lsa_LookupSids2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int flags, const struct lsa_LookupSids2 *r)
{
if (flags & NDR_IN) {
if (r->in.handle == NULL) {
@@ -9026,7 +9508,7 @@ static enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int flag
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int flags, struct lsa_LookupSids2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int flags, struct lsa_LookupSids2 *r)
{
uint32_t _ptr_domains;
TALLOC_CTX *_mem_save_handle_0;
@@ -9159,7 +9641,7 @@ _PUBLIC_ void ndr_print_lsa_LookupSids2(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int flags, const struct lsa_LookupNames2 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int flags, const struct lsa_LookupNames2 *r)
{
uint32_t cntr_names_0;
if (flags & NDR_IN) {
@@ -9179,7 +9661,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int fla
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_lsa_TransSidArray2(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level));
+ NDR_CHECK(ndr_push_lsa_LookupNamesLevel(ndr, NDR_SCALARS, r->in.level));
if (r->in.count == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -9205,7 +9687,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int fla
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int flags, struct lsa_LookupNames2 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int flags, struct lsa_LookupNames2 *r)
{
uint32_t cntr_names_0;
uint32_t _ptr_domains;
@@ -9246,7 +9728,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int fla
NDR_PULL_SET_MEM_CTX(ndr, r->in.sids, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_lsa_TransSidArray2(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level));
+ NDR_CHECK(ndr_pull_lsa_LookupNamesLevel(ndr, NDR_SCALARS, &r->in.level));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->in.count);
}
@@ -9327,7 +9809,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames2(struct ndr_print *ndr, const char *name
ndr->depth++;
ndr_print_lsa_TransSidArray2(ndr, "sids", r->in.sids);
ndr->depth--;
- ndr_print_uint16(ndr, "level", r->in.level);
+ ndr_print_lsa_LookupNamesLevel(ndr, "level", r->in.level);
ndr_print_ptr(ndr, "count", r->in.count);
ndr->depth++;
ndr_print_uint32(ndr, "count", *r->in.count);
@@ -9728,7 +10210,7 @@ _PUBLIC_ void ndr_print_lsa_CREDRPROFILELOADED(struct ndr_print *ndr, const char
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int flags, const struct lsa_LookupNames3 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int flags, const struct lsa_LookupNames3 *r)
{
uint32_t cntr_names_0;
if (flags & NDR_IN) {
@@ -9748,7 +10230,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int fla
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_lsa_TransSidArray3(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level));
+ NDR_CHECK(ndr_push_lsa_LookupNamesLevel(ndr, NDR_SCALARS, r->in.level));
if (r->in.count == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -9774,7 +10256,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int fla
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int flags, struct lsa_LookupNames3 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int flags, struct lsa_LookupNames3 *r)
{
uint32_t cntr_names_0;
uint32_t _ptr_domains;
@@ -9815,7 +10297,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int fla
NDR_PULL_SET_MEM_CTX(ndr, r->in.sids, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_lsa_TransSidArray3(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level));
+ NDR_CHECK(ndr_pull_lsa_LookupNamesLevel(ndr, NDR_SCALARS, &r->in.level));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->in.count);
}
@@ -9896,7 +10378,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames3(struct ndr_print *ndr, const char *name
ndr->depth++;
ndr_print_lsa_TransSidArray3(ndr, "sids", r->in.sids);
ndr->depth--;
- ndr_print_uint16(ndr, "level", r->in.level);
+ ndr_print_lsa_LookupNamesLevel(ndr, "level", r->in.level);
ndr_print_ptr(ndr, "count", r->in.count);
ndr->depth++;
ndr_print_uint32(ndr, "count", *r->in.count);
@@ -10092,41 +10574,112 @@ _PUBLIC_ void ndr_print_lsa_LSARUNREGISTERAUDITEVENT(struct ndr_print *ndr, cons
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct ndr_push *ndr, int flags, const struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
+static enum ndr_err_code ndr_push_lsa_lsaRQueryForestTrustInformation(struct ndr_push *ndr, int flags, const struct lsa_lsaRQueryForestTrustInformation *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle));
+ if (r->in.trusted_domain_name == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.trusted_domain_name));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.unknown));
}
if (flags & NDR_OUT) {
+ if (r->out.forest_trust_info == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ if (*r->out.forest_trust_info == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_ref_ptr(ndr));
+ NDR_CHECK(ndr_push_lsa_ForestTrustInformation(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.forest_trust_info));
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct ndr_pull *ndr, int flags, struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
+static enum ndr_err_code ndr_pull_lsa_lsaRQueryForestTrustInformation(struct ndr_pull *ndr, int flags, struct lsa_lsaRQueryForestTrustInformation *r)
{
+ uint32_t _ptr_forest_trust_info;
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_trusted_domain_name_0;
+ TALLOC_CTX *_mem_save_forest_trust_info_0;
+ TALLOC_CTX *_mem_save_forest_trust_info_1;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.trusted_domain_name);
+ }
+ _mem_save_trusted_domain_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.trusted_domain_name, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.trusted_domain_name));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_trusted_domain_name_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.unknown));
+ NDR_PULL_ALLOC(ndr, r->out.forest_trust_info);
+ ZERO_STRUCTP(r->out.forest_trust_info);
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.forest_trust_info);
+ }
+ _mem_save_forest_trust_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.forest_trust_info, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_ref_ptr(ndr, &_ptr_forest_trust_info));
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, *r->out.forest_trust_info);
+ }
+ _mem_save_forest_trust_info_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->out.forest_trust_info, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_ForestTrustInformation(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.forest_trust_info));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_forest_trust_info_1, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_forest_trust_info_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ void ndr_print_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
+_PUBLIC_ void ndr_print_lsa_lsaRQueryForestTrustInformation(struct ndr_print *ndr, const char *name, int flags, const struct lsa_lsaRQueryForestTrustInformation *r)
{
- ndr_print_struct(ndr, name, "lsa_LSARQUERYFORESTTRUSTINFORMATION");
+ ndr_print_struct(ndr, name, "lsa_lsaRQueryForestTrustInformation");
ndr->depth++;
if (flags & NDR_SET_VALUES) {
ndr->flags |= LIBNDR_PRINT_SET_VALUES;
}
if (flags & NDR_IN) {
- ndr_print_struct(ndr, "in", "lsa_LSARQUERYFORESTTRUSTINFORMATION");
+ ndr_print_struct(ndr, "in", "lsa_lsaRQueryForestTrustInformation");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "trusted_domain_name", r->in.trusted_domain_name);
+ ndr->depth++;
+ ndr_print_lsa_String(ndr, "trusted_domain_name", r->in.trusted_domain_name);
+ ndr->depth--;
+ ndr_print_uint16(ndr, "unknown", r->in.unknown);
ndr->depth--;
}
if (flags & NDR_OUT) {
- ndr_print_struct(ndr, "out", "lsa_LSARQUERYFORESTTRUSTINFORMATION");
+ ndr_print_struct(ndr, "out", "lsa_lsaRQueryForestTrustInformation");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "forest_trust_info", r->out.forest_trust_info);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "forest_trust_info", *r->out.forest_trust_info);
ndr->depth++;
+ ndr_print_lsa_ForestTrustInformation(ndr, "forest_trust_info", *r->out.forest_trust_info);
+ ndr->depth--;
+ ndr->depth--;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
}
@@ -10215,7 +10768,7 @@ _PUBLIC_ void ndr_print_lsa_CREDRRENAME(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int flags, const struct lsa_LookupSids3 *r)
+_PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int flags, const struct lsa_LookupSids3 *r)
{
if (flags & NDR_IN) {
if (r->in.sids == NULL) {
@@ -10252,7 +10805,7 @@ static enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int flag
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int flags, struct lsa_LookupSids3 *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int flags, struct lsa_LookupSids3 *r)
{
uint32_t _ptr_domains;
TALLOC_CTX *_mem_save_sids_0;
@@ -10389,7 +10942,7 @@ static enum ndr_err_code ndr_push_lsa_LookupNames4(struct ndr_push *ndr, int fla
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_lsa_TransSidArray3(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level));
+ NDR_CHECK(ndr_push_lsa_LookupNamesLevel(ndr, NDR_SCALARS, r->in.level));
if (r->in.count == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -10448,7 +11001,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames4(struct ndr_pull *ndr, int fla
NDR_PULL_SET_MEM_CTX(ndr, r->in.sids, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_lsa_TransSidArray3(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sids));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sids_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level));
+ NDR_CHECK(ndr_pull_lsa_LookupNamesLevel(ndr, NDR_SCALARS, &r->in.level));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->in.count);
}
@@ -10525,7 +11078,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames4(struct ndr_print *ndr, const char *name
ndr->depth++;
ndr_print_lsa_TransSidArray3(ndr, "sids", r->in.sids);
ndr->depth--;
- ndr_print_uint16(ndr, "level", r->in.level);
+ ndr_print_lsa_LookupNamesLevel(ndr, "level", r->in.level);
ndr_print_ptr(ndr, "count", r->in.count);
ndr->depth++;
ndr_print_uint32(ndr, "count", *r->in.count);
@@ -11307,11 +11860,11 @@ static const struct ndr_interface_call lsarpc_calls[] = {
false,
},
{
- "lsa_LSARQUERYFORESTTRUSTINFORMATION",
- sizeof(struct lsa_LSARQUERYFORESTTRUSTINFORMATION),
- (ndr_push_flags_fn_t) ndr_push_lsa_LSARQUERYFORESTTRUSTINFORMATION,
- (ndr_pull_flags_fn_t) ndr_pull_lsa_LSARQUERYFORESTTRUSTINFORMATION,
- (ndr_print_function_t) ndr_print_lsa_LSARQUERYFORESTTRUSTINFORMATION,
+ "lsa_lsaRQueryForestTrustInformation",
+ sizeof(struct lsa_lsaRQueryForestTrustInformation),
+ (ndr_push_flags_fn_t) ndr_push_lsa_lsaRQueryForestTrustInformation,
+ (ndr_pull_flags_fn_t) ndr_pull_lsa_lsaRQueryForestTrustInformation,
+ (ndr_print_function_t) ndr_print_lsa_lsaRQueryForestTrustInformation,
false,
},
{
diff --git a/source3/librpc/gen_ndr/ndr_lsa.h b/source3/librpc/gen_ndr/ndr_lsa.h
index dc100297f5..ab4043f2a1 100644
--- a/source3/librpc/gen_ndr/ndr_lsa.h
+++ b/source3/librpc/gen_ndr/ndr_lsa.h
@@ -194,6 +194,7 @@ void ndr_print_lsa_PrivArray(struct ndr_print *ndr, const char *name, const stru
void ndr_print_lsa_QosInfo(struct ndr_print *ndr, const char *name, const struct lsa_QosInfo *r);
void ndr_print_lsa_ObjectAttribute(struct ndr_print *ndr, const char *name, const struct lsa_ObjectAttribute *r);
void ndr_print_lsa_AuditLogInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditLogInfo *r);
+void ndr_print_lsa_PolicyAuditPolicy(struct ndr_print *ndr, const char *name, enum lsa_PolicyAuditPolicy r);
void ndr_print_lsa_AuditEventsInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditEventsInfo *r);
void ndr_print_lsa_DomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_DomainInfo *r);
void ndr_print_lsa_PDAccountInfo(struct ndr_print *ndr, const char *name, const struct lsa_PDAccountInfo *r);
@@ -215,6 +216,7 @@ void ndr_print_lsa_SidType(struct ndr_print *ndr, const char *name, enum lsa_Sid
void ndr_print_lsa_TranslatedSid(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedSid *r);
void ndr_print_lsa_TransSidArray(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray *r);
void ndr_print_lsa_RefDomainList(struct ndr_print *ndr, const char *name, const struct lsa_RefDomainList *r);
+void ndr_print_lsa_LookupNamesLevel(struct ndr_print *ndr, const char *name, enum lsa_LookupNamesLevel r);
void ndr_print_lsa_TranslatedName(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedName *r);
void ndr_print_lsa_TransNameArray(struct ndr_print *ndr, const char *name, const struct lsa_TransNameArray *r);
void ndr_print_lsa_LUIDAttribute(struct ndr_print *ndr, const char *name, const struct lsa_LUIDAttribute *r);
@@ -246,22 +248,48 @@ void ndr_print_lsa_TranslatedSid2(struct ndr_print *ndr, const char *name, const
void ndr_print_lsa_TransSidArray2(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray2 *r);
void ndr_print_lsa_TranslatedSid3(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedSid3 *r);
void ndr_print_lsa_TransSidArray3(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray3 *r);
+void ndr_print_lsa_ForestTrustBinaryData(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustBinaryData *r);
+void ndr_print_lsa_ForestTrustDomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustDomainInfo *r);
+void ndr_print_lsa_ForestTrustData(struct ndr_print *ndr, const char *name, const union lsa_ForestTrustData *r);
+void ndr_print_lsa_ForestTrustRecordType(struct ndr_print *ndr, const char *name, enum lsa_ForestTrustRecordType r);
+void ndr_print_lsa_ForestTrustRecord(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustRecord *r);
+enum ndr_err_code ndr_push_lsa_ForestTrustInformation(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustInformation *r);
+enum ndr_err_code ndr_pull_lsa_ForestTrustInformation(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustInformation *r);
+void ndr_print_lsa_ForestTrustInformation(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustInformation *r);
void ndr_print_lsa_Close(struct ndr_print *ndr, const char *name, int flags, const struct lsa_Close *r);
+enum ndr_err_code ndr_push_lsa_Delete(struct ndr_push *ndr, int flags, const struct lsa_Delete *r);
+enum ndr_err_code ndr_pull_lsa_Delete(struct ndr_pull *ndr, int flags, struct lsa_Delete *r);
void ndr_print_lsa_Delete(struct ndr_print *ndr, const char *name, int flags, const struct lsa_Delete *r);
+enum ndr_err_code ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, int flags, const struct lsa_EnumPrivs *r);
+enum ndr_err_code ndr_pull_lsa_EnumPrivs(struct ndr_pull *ndr, int flags, struct lsa_EnumPrivs *r);
void ndr_print_lsa_EnumPrivs(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumPrivs *r);
void ndr_print_lsa_QuerySecurity(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QuerySecurity *r);
void ndr_print_lsa_SetSecObj(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetSecObj *r);
void ndr_print_lsa_ChangePassword(struct ndr_print *ndr, const char *name, int flags, const struct lsa_ChangePassword *r);
+enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy *r);
+enum ndr_err_code ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy *r);
void ndr_print_lsa_OpenPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenPolicy *r);
void ndr_print_lsa_QueryInfoPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryInfoPolicy *r);
void ndr_print_lsa_SetInfoPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetInfoPolicy *r);
void ndr_print_lsa_ClearAuditLog(struct ndr_print *ndr, const char *name, int flags, const struct lsa_ClearAuditLog *r);
+enum ndr_err_code ndr_push_lsa_CreateAccount(struct ndr_push *ndr, int flags, const struct lsa_CreateAccount *r);
+enum ndr_err_code ndr_pull_lsa_CreateAccount(struct ndr_pull *ndr, int flags, struct lsa_CreateAccount *r);
void ndr_print_lsa_CreateAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateAccount *r);
+enum ndr_err_code ndr_push_lsa_EnumAccounts(struct ndr_push *ndr, int flags, const struct lsa_EnumAccounts *r);
+enum ndr_err_code ndr_pull_lsa_EnumAccounts(struct ndr_pull *ndr, int flags, struct lsa_EnumAccounts *r);
void ndr_print_lsa_EnumAccounts(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumAccounts *r);
+enum ndr_err_code ndr_push_lsa_CreateTrustedDomain(struct ndr_push *ndr, int flags, const struct lsa_CreateTrustedDomain *r);
+enum ndr_err_code ndr_pull_lsa_CreateTrustedDomain(struct ndr_pull *ndr, int flags, struct lsa_CreateTrustedDomain *r);
void ndr_print_lsa_CreateTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateTrustedDomain *r);
void ndr_print_lsa_EnumTrustDom(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumTrustDom *r);
+enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flags, const struct lsa_LookupNames *r);
+enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int flags, struct lsa_LookupNames *r);
void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames *r);
+enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int flags, const struct lsa_LookupSids *r);
+enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int flags, struct lsa_LookupSids *r);
void ndr_print_lsa_LookupSids(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids *r);
+enum ndr_err_code ndr_push_lsa_CreateSecret(struct ndr_push *ndr, int flags, const struct lsa_CreateSecret *r);
+enum ndr_err_code ndr_pull_lsa_CreateSecret(struct ndr_pull *ndr, int flags, struct lsa_CreateSecret *r);
void ndr_print_lsa_CreateSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateSecret *r);
void ndr_print_lsa_OpenAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenAccount *r);
void ndr_print_lsa_EnumPrivsAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumPrivsAccount *r);
@@ -274,8 +302,14 @@ void ndr_print_lsa_SetSystemAccessAccount(struct ndr_print *ndr, const char *nam
void ndr_print_lsa_OpenTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenTrustedDomain *r);
void ndr_print_lsa_QueryTrustedDomainInfo(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryTrustedDomainInfo *r);
void ndr_print_lsa_SetInformationTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetInformationTrustedDomain *r);
+enum ndr_err_code ndr_push_lsa_OpenSecret(struct ndr_push *ndr, int flags, const struct lsa_OpenSecret *r);
+enum ndr_err_code ndr_pull_lsa_OpenSecret(struct ndr_pull *ndr, int flags, struct lsa_OpenSecret *r);
void ndr_print_lsa_OpenSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenSecret *r);
+enum ndr_err_code ndr_push_lsa_SetSecret(struct ndr_push *ndr, int flags, const struct lsa_SetSecret *r);
+enum ndr_err_code ndr_pull_lsa_SetSecret(struct ndr_pull *ndr, int flags, struct lsa_SetSecret *r);
void ndr_print_lsa_SetSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetSecret *r);
+enum ndr_err_code ndr_push_lsa_QuerySecret(struct ndr_push *ndr, int flags, const struct lsa_QuerySecret *r);
+enum ndr_err_code ndr_pull_lsa_QuerySecret(struct ndr_pull *ndr, int flags, struct lsa_QuerySecret *r);
void ndr_print_lsa_QuerySecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QuerySecret *r);
void ndr_print_lsa_LookupPrivValue(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupPrivValue *r);
void ndr_print_lsa_LookupPrivName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupPrivName *r);
@@ -290,6 +324,8 @@ void ndr_print_lsa_SetTrustedDomainInfo(struct ndr_print *ndr, const char *name,
void ndr_print_lsa_DeleteTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_DeleteTrustedDomain *r);
void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *name, int flags, const struct lsa_StorePrivateData *r);
void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const char *name, int flags, const struct lsa_RetrievePrivateData *r);
+enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy2 *r);
+enum ndr_err_code ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy2 *r);
void ndr_print_lsa_OpenPolicy2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenPolicy2 *r);
void ndr_print_lsa_GetUserName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_GetUserName *r);
void ndr_print_lsa_QueryInfoPolicy2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryInfoPolicy2 *r);
@@ -303,7 +339,11 @@ void ndr_print_lsa_QueryDomainInformationPolicy(struct ndr_print *ndr, const cha
void ndr_print_lsa_SetDomainInformationPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetDomainInformationPolicy *r);
void ndr_print_lsa_OpenTrustedDomainByName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenTrustedDomainByName *r);
void ndr_print_lsa_TestCall(struct ndr_print *ndr, const char *name, int flags, const struct lsa_TestCall *r);
+enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int flags, const struct lsa_LookupSids2 *r);
+enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int flags, struct lsa_LookupSids2 *r);
void ndr_print_lsa_LookupSids2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids2 *r);
+enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int flags, const struct lsa_LookupNames2 *r);
+enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int flags, struct lsa_LookupNames2 *r);
void ndr_print_lsa_LookupNames2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames2 *r);
void ndr_print_lsa_CreateTrustedDomainEx2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateTrustedDomainEx2 *r);
void ndr_print_lsa_CREDRWRITE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRWRITE *r);
@@ -314,14 +354,18 @@ void ndr_print_lsa_CREDRREADDOMAINCREDENTIALS(struct ndr_print *ndr, const char
void ndr_print_lsa_CREDRDELETE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRDELETE *r);
void ndr_print_lsa_CREDRGETTARGETINFO(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRGETTARGETINFO *r);
void ndr_print_lsa_CREDRPROFILELOADED(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRPROFILELOADED *r);
+enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int flags, const struct lsa_LookupNames3 *r);
+enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int flags, struct lsa_LookupNames3 *r);
void ndr_print_lsa_LookupNames3(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames3 *r);
void ndr_print_lsa_CREDRGETSESSIONTYPES(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRGETSESSIONTYPES *r);
void ndr_print_lsa_LSARREGISTERAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARREGISTERAUDITEVENT *r);
void ndr_print_lsa_LSARGENAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARGENAUDITEVENT *r);
void ndr_print_lsa_LSARUNREGISTERAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARUNREGISTERAUDITEVENT *r);
-void ndr_print_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r);
+void ndr_print_lsa_lsaRQueryForestTrustInformation(struct ndr_print *ndr, const char *name, int flags, const struct lsa_lsaRQueryForestTrustInformation *r);
void ndr_print_lsa_LSARSETFORESTTRUSTINFORMATION(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARSETFORESTTRUSTINFORMATION *r);
void ndr_print_lsa_CREDRRENAME(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRRENAME *r);
+enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int flags, const struct lsa_LookupSids3 *r);
+enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int flags, struct lsa_LookupSids3 *r);
void ndr_print_lsa_LookupSids3(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids3 *r);
void ndr_print_lsa_LookupNames4(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames4 *r);
void ndr_print_lsa_LSAROPENPOLICYSCE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSAROPENPOLICYSCE *r);
diff --git a/source3/librpc/gen_ndr/ndr_xattr.c b/source3/librpc/gen_ndr/ndr_xattr.c
new file mode 100644
index 0000000000..29a31a12b2
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_xattr.c
@@ -0,0 +1,102 @@
+/* parser auto-generated by pidl */
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name));
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->value));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->name));
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->value));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r)
+{
+ ndr_print_struct(ndr, name, "tdb_xattr");
+ ndr->depth++;
+ ndr_print_string(ndr, "name", r->name);
+ ndr_print_DATA_BLOB(ndr, "value", r->value);
+ ndr->depth--;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r)
+{
+ uint32_t cntr_xattrs_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_xattrs));
+ for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) {
+ NDR_CHECK(ndr_push_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0]));
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r)
+{
+ uint32_t cntr_xattrs_0;
+ TALLOC_CTX *_mem_save_xattrs_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_xattrs));
+ NDR_PULL_ALLOC_N(ndr, r->xattrs, r->num_xattrs);
+ _mem_save_xattrs_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->xattrs, 0);
+ for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) {
+ NDR_CHECK(ndr_pull_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0]));
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_xattrs_0, 0);
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r)
+{
+ uint32_t cntr_xattrs_0;
+ ndr_print_struct(ndr, name, "tdb_xattrs");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "num_xattrs", r->num_xattrs);
+ ndr->print(ndr, "%s: ARRAY(%d)", "xattrs", r->num_xattrs);
+ ndr->depth++;
+ for (cntr_xattrs_0=0;cntr_xattrs_0<r->num_xattrs;cntr_xattrs_0++) {
+ char *idx_0=NULL;
+ asprintf(&idx_0, "[%d]", cntr_xattrs_0);
+ if (idx_0) {
+ ndr_print_tdb_xattr(ndr, "xattrs", &r->xattrs[cntr_xattrs_0]);
+ free(idx_0);
+ }
+ }
+ ndr->depth--;
+ ndr->depth--;
+}
diff --git a/source3/librpc/gen_ndr/ndr_xattr.h b/source3/librpc/gen_ndr/ndr_xattr.h
new file mode 100644
index 0000000000..a18477f347
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_xattr.h
@@ -0,0 +1,16 @@
+/* header auto-generated by pidl */
+
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/xattr.h"
+
+#ifndef _HEADER_NDR_xattr
+#define _HEADER_NDR_xattr
+
+#define NDR_XATTR_CALL_COUNT (0)
+enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r);
+enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r);
+void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r);
+enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r);
+enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r);
+void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r);
+#endif /* _HEADER_NDR_xattr */
diff --git a/source3/librpc/gen_ndr/srv_lsa.c b/source3/librpc/gen_ndr/srv_lsa.c
index 68dc32cef5..8f8f985650 100644
--- a/source3/librpc/gen_ndr/srv_lsa.c
+++ b/source3/librpc/gen_ndr/srv_lsa.c
@@ -5579,18 +5579,18 @@ static bool api_lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p)
return true;
}
-static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
+static bool api_lsa_lsaRQueryForestTrustInformation(pipes_struct *p)
{
const struct ndr_interface_call *call;
struct ndr_pull *pull;
struct ndr_push *push;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
- struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r;
+ struct lsa_lsaRQueryForestTrustInformation *r;
call = &ndr_table_lsarpc.calls[NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION];
- r = talloc(NULL, struct lsa_LSARQUERYFORESTTRUSTINFORMATION);
+ r = talloc(NULL, struct lsa_lsaRQueryForestTrustInformation);
if (r == NULL) {
return false;
}
@@ -5614,10 +5614,17 @@ static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
}
if (DEBUGLEVEL >= 10) {
- NDR_PRINT_IN_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, r);
+ NDR_PRINT_IN_DEBUG(lsa_lsaRQueryForestTrustInformation, r);
}
- r->out.result = _lsa_LSARQUERYFORESTTRUSTINFORMATION(p, r);
+ ZERO_STRUCT(r->out);
+ r->out.forest_trust_info = talloc_zero(r, struct lsa_ForestTrustInformation *);
+ if (r->out.forest_trust_info == NULL) {
+ talloc_free(r);
+ return false;
+ }
+
+ r->out.result = _lsa_lsaRQueryForestTrustInformation(p, r);
if (p->rng_fault_state) {
talloc_free(r);
@@ -5626,7 +5633,7 @@ static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
}
if (DEBUGLEVEL >= 10) {
- NDR_PRINT_OUT_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, r);
+ NDR_PRINT_OUT_DEBUG(lsa_lsaRQueryForestTrustInformation, r);
}
push = ndr_push_init_ctx(r);
@@ -6331,7 +6338,7 @@ static struct api_struct api_lsarpc_cmds[] =
{"LSA_LSARREGISTERAUDITEVENT", NDR_LSA_LSARREGISTERAUDITEVENT, api_lsa_LSARREGISTERAUDITEVENT},
{"LSA_LSARGENAUDITEVENT", NDR_LSA_LSARGENAUDITEVENT, api_lsa_LSARGENAUDITEVENT},
{"LSA_LSARUNREGISTERAUDITEVENT", NDR_LSA_LSARUNREGISTERAUDITEVENT, api_lsa_LSARUNREGISTERAUDITEVENT},
- {"LSA_LSARQUERYFORESTTRUSTINFORMATION", NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION, api_lsa_LSARQUERYFORESTTRUSTINFORMATION},
+ {"LSA_LSARQUERYFORESTTRUSTINFORMATION", NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION, api_lsa_lsaRQueryForestTrustInformation},
{"LSA_LSARSETFORESTTRUSTINFORMATION", NDR_LSA_LSARSETFORESTTRUSTINFORMATION, api_lsa_LSARSETFORESTTRUSTINFORMATION},
{"LSA_CREDRRENAME", NDR_LSA_CREDRRENAME, api_lsa_CREDRRENAME},
{"LSA_LOOKUPSIDS3", NDR_LSA_LOOKUPSIDS3, api_lsa_LookupSids3},
diff --git a/source3/librpc/gen_ndr/srv_lsa.h b/source3/librpc/gen_ndr/srv_lsa.h
index e3decb2862..223ee5e970 100644
--- a/source3/librpc/gen_ndr/srv_lsa.h
+++ b/source3/librpc/gen_ndr/srv_lsa.h
@@ -74,7 +74,7 @@ NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTY
NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r);
NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r);
NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r);
-NTSTATUS _lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r);
+NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r);
NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r);
NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r);
NTSTATUS _lsa_LookupSids3(pipes_struct *p, struct lsa_LookupSids3 *r);
diff --git a/source3/librpc/gen_ndr/xattr.h b/source3/librpc/gen_ndr/xattr.h
new file mode 100644
index 0000000000..ee30376be8
--- /dev/null
+++ b/source3/librpc/gen_ndr/xattr.h
@@ -0,0 +1,18 @@
+/* header auto-generated by pidl */
+
+#include <stdint.h>
+
+#ifndef _HEADER_xattr
+#define _HEADER_xattr
+
+struct tdb_xattr {
+ const char * name;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */
+ DATA_BLOB value;
+}/* [public] */;
+
+struct tdb_xattrs {
+ uint32_t num_xattrs;
+ struct tdb_xattr *xattrs;
+}/* [public] */;
+
+#endif /* _HEADER_xattr */
diff --git a/source3/librpc/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl
new file mode 100644
index 0000000000..2741b7bd7b
--- /dev/null
+++ b/source3/librpc/idl/libnet_join.idl
@@ -0,0 +1,60 @@
+#include "idl_types.h"
+
+import "wkssvc.idl", "security.idl";
+
+/*
+ libnetjoin interface definition
+*/
+
+[
+ pointer_default(unique)
+]
+interface libnetjoin
+{
+ typedef bitmap wkssvc_joinflags wkssvc_joinflags;
+
+ [nopush,nopull] WERROR libnet_JoinCtx(
+ [in] string dc_name,
+ [in] string machine_name,
+ [in,ref] string *domain_name,
+ [in] string account_ou,
+ [in] string admin_account,
+ [in] string admin_password,
+ [in] string machine_password,
+ [in] wkssvc_joinflags join_flags,
+ [in] string os_version,
+ [in] string os_name,
+ [in] boolean8 create_upn,
+ [in] string upn,
+ [in] boolean8 modify_config,
+ [in] ads_struct *ads,
+ [in] boolean8 debug,
+ [out] string account_name,
+ [out] string netbios_domain_name,
+ [out] string dns_domain_name,
+ [out] string dn,
+ [out] dom_sid *domain_sid,
+ [out] boolean8 modified_config,
+ [out] string error_string,
+ [out] boolean8 domain_is_ad
+ );
+
+ [nopush,nopull] WERROR libnet_UnjoinCtx(
+ [in] string dc_name,
+ [in] string machine_name,
+ [in] string domain_name,
+ [in] string account_ou,
+ [in] string admin_account,
+ [in] string admin_password,
+ [in] string machine_password,
+ [in] wkssvc_joinflags unjoin_flags,
+ [in] boolean8 modify_config,
+ [in] dom_sid *domain_sid,
+ [in] ads_struct *ads,
+ [in] boolean8 debug,
+ [out] string netbios_domain_name,
+ [out] string dns_domain_name,
+ [out] boolean8 modified_config,
+ [out] string error_string
+ );
+}
diff --git a/source3/librpc/idl/lsa.idl b/source3/librpc/idl/lsa.idl
index 7daf648a63..8d26ec0aad 100644
--- a/source3/librpc/idl/lsa.idl
+++ b/source3/librpc/idl/lsa.idl
@@ -47,7 +47,7 @@ import "security.idl";
/******************/
/* Function: 0x01 */
- NTSTATUS lsa_Delete (
+ [public] NTSTATUS lsa_Delete (
[in] policy_handle *handle
);
@@ -69,7 +69,7 @@ import "security.idl";
[size_is(count)] lsa_PrivEntry *privs;
} lsa_PrivArray;
- NTSTATUS lsa_EnumPrivs (
+ [public] NTSTATUS lsa_EnumPrivs (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
[in] uint32 max_count,
@@ -116,7 +116,7 @@ import "security.idl";
/* notice the screwup with the system_name - thats why MS created
OpenPolicy2 */
- NTSTATUS lsa_OpenPolicy (
+ [public] NTSTATUS lsa_OpenPolicy (
[in,unique] uint16 *system_name,
[in] lsa_ObjectAttribute *attr,
[in] uint32 access_mask,
@@ -138,9 +138,29 @@ import "security.idl";
uint32 unknown;
} lsa_AuditLogInfo;
+ typedef [v1_enum] enum {
+ LSA_AUDIT_POLICY_NONE=0,
+ LSA_AUDIT_POLICY_SUCCESS=1,
+ LSA_AUDIT_POLICY_FAILURE=2,
+ LSA_AUDIT_POLICY_ALL=(LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE),
+ LSA_AUDIT_POLICY_CLEAR=4
+ } lsa_PolicyAuditPolicy;
+
+ typedef enum {
+ LSA_AUDIT_CATEGORY_SYSTEM = 0,
+ LSA_AUDIT_CATEGORY_LOGON = 1,
+ LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS = 2,
+ LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS = 3,
+ LSA_AUDIT_CATEGORY_PROCCESS_TRACKING = 4,
+ LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES = 5,
+ LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT = 6,
+ LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS = 7, /* only in win2k/2k3 */
+ LSA_AUDIT_CATEGORY_ACCOUNT_LOGON = 8 /* only in win2k/2k3 */
+ } lsa_PolicyAuditEventType;
+
typedef struct {
uint32 auditing_mode;
- [size_is(count)] uint32 *settings;
+ [size_is(count)] lsa_PolicyAuditPolicy *settings;
uint32 count;
} lsa_AuditEventsInfo;
@@ -251,7 +271,7 @@ import "security.idl";
/******************/
/* Function: 0x0a */
- NTSTATUS lsa_CreateAccount (
+ [public] NTSTATUS lsa_CreateAccount (
[in] policy_handle *handle,
[in] dom_sid2 *sid,
[in] uint32 access_mask,
@@ -272,7 +292,7 @@ import "security.idl";
[size_is(num_sids)] lsa_SidPtr *sids;
} lsa_SidArray;
- NTSTATUS lsa_EnumAccounts (
+ [public] NTSTATUS lsa_EnumAccounts (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
[in,range(0,8192)] uint32 num_entries,
@@ -283,7 +303,7 @@ import "security.idl";
/*************************************************/
/* Function: 0x0c */
- NTSTATUS lsa_CreateTrustedDomain(
+ [public] NTSTATUS lsa_CreateTrustedDomain(
[in] policy_handle *handle,
[in] lsa_DomainInfo *info,
[in] uint32 access_mask,
@@ -305,7 +325,7 @@ import "security.idl";
NTSTATUS lsa_EnumTrustDom (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
- [in,range(0,1000)] uint32 max_size,
+ [in] uint32 max_size,
[out] lsa_DomainList *domains
);
@@ -343,13 +363,30 @@ import "security.idl";
uint32 max_size;
} lsa_RefDomainList;
- NTSTATUS lsa_LookupNames (
+ /* Level 1: Ask everywhere
+ * Level 2: Ask domain and trusted domains, no builtin and wkn
+ * Level 3: Only ask domain
+ * Level 4: W2k3ad: Only ask AD trusts
+ * Level 5: Only ask transitive forest trusts
+ * Level 6: Like 4
+ */
+
+ typedef enum {
+ LSA_LOOKUP_NAMES_ALL = 1,
+ LSA_LOOKUP_NAMES_DOMAINS_ONLY = 2,
+ LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY = 3,
+ LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY = 4,
+ LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY = 5,
+ LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = 6
+ } lsa_LookupNamesLevel;
+
+ [public] NTSTATUS lsa_LookupNames (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray *sids,
- [in] uint16 level,
+ [in] lsa_LookupNamesLevel level,
[in,out] uint32 *count
);
@@ -368,7 +405,7 @@ import "security.idl";
[size_is(count)] lsa_TranslatedName *names;
} lsa_TransNameArray;
- NTSTATUS lsa_LookupSids (
+ [public] NTSTATUS lsa_LookupSids (
[in] policy_handle *handle,
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
@@ -379,7 +416,7 @@ import "security.idl";
/* Function: 0x10 */
- NTSTATUS lsa_CreateSecret(
+ [public] NTSTATUS lsa_CreateSecret(
[in] policy_handle *handle,
[in] lsa_String name,
[in] uint32 access_mask,
@@ -559,7 +596,7 @@ import "security.idl";
NTSTATUS lsa_SetInformationTrustedDomain();
/* Function: 0x1c */
- NTSTATUS lsa_OpenSecret(
+ [public] NTSTATUS lsa_OpenSecret(
[in] policy_handle *handle,
[in] lsa_String name,
[in] uint32 access_mask,
@@ -568,7 +605,7 @@ import "security.idl";
/* Function: 0x1d */
- NTSTATUS lsa_SetSecret(
+ [public] NTSTATUS lsa_SetSecret(
[in] policy_handle *sec_handle,
[in,unique] lsa_DATA_BUF *new_val,
[in,unique] lsa_DATA_BUF *old_val
@@ -579,7 +616,7 @@ import "security.idl";
} lsa_DATA_BUF_PTR;
/* Function: 0x1e */
- NTSTATUS lsa_QuerySecret (
+ [public] NTSTATUS lsa_QuerySecret (
[in] policy_handle *sec_handle,
[in,out,unique] lsa_DATA_BUF_PTR *new_val,
[in,out,unique] NTTIME_hyper *new_mtime,
@@ -685,7 +722,7 @@ import "security.idl";
/**********************/
/* Function: 0x2c */
- NTSTATUS lsa_OpenPolicy2 (
+ [public] NTSTATUS lsa_OpenPolicy2 (
[in,unique] [string,charset(UTF16)] uint16 *system_name,
[in] lsa_ObjectAttribute *attr,
[in] uint32 access_mask,
@@ -832,7 +869,7 @@ import "security.idl";
[size_is(count)] lsa_TranslatedName2 *names;
} lsa_TransNameArray2;
- NTSTATUS lsa_LookupSids2(
+ [public] NTSTATUS lsa_LookupSids2(
[in] policy_handle *handle,
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
@@ -858,13 +895,13 @@ import "security.idl";
[size_is(count)] lsa_TranslatedSid2 *sids;
} lsa_TransSidArray2;
- NTSTATUS lsa_LookupNames2 (
+ [public] NTSTATUS lsa_LookupNames2 (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray2 *sids,
- [in] uint16 level,
+ [in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2
@@ -911,13 +948,13 @@ import "security.idl";
[size_is(count)] lsa_TranslatedSid3 *sids;
} lsa_TransSidArray3;
- NTSTATUS lsa_LookupNames3 (
+ [public] NTSTATUS lsa_LookupNames3 (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray3 *sids,
- [in] uint16 level,
+ [in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2
@@ -936,7 +973,49 @@ import "security.idl";
NTSTATUS lsa_LSARUNREGISTERAUDITEVENT();
/* Function 0x49 */
- NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION();
+ typedef struct {
+ [range(0,131072)] uint32 length;
+ [size_is(length)] uint8 *data;
+ } lsa_ForestTrustBinaryData;
+
+ typedef struct {
+ dom_sid2 *domain_sid;
+ lsa_StringLarge dns_domain_name;
+ lsa_StringLarge netbios_domain_name;
+ } lsa_ForestTrustDomainInfo;
+
+ typedef [switch_type(uint32)] union {
+ [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME)] lsa_String top_level_name;
+ [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX)] lsa_StringLarge top_level_name_ex;
+ [case(LSA_FOREST_TRUST_DOMAIN_INFO)] lsa_ForestTrustDomainInfo domain_info;
+ [default] lsa_ForestTrustBinaryData data;
+ } lsa_ForestTrustData;
+
+ typedef [v1_enum] enum {
+ LSA_FOREST_TRUST_TOP_LEVEL_NAME = 0,
+ LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX = 1,
+ LSA_FOREST_TRUST_DOMAIN_INFO = 2,
+ LSA_FOREST_TRUST_RECORD_TYPE_LAST = 3
+ } lsa_ForestTrustRecordType;
+
+ typedef struct {
+ uint32 flags;
+ lsa_ForestTrustRecordType level;
+ hyper unknown;
+ [switch_is(level)] lsa_ForestTrustData forest_trust_data;
+ } lsa_ForestTrustRecord;
+
+ typedef [public] struct {
+ [range(0,4000)] uint32 count;
+ [size_is(count)] lsa_ForestTrustRecord **entries;
+ } lsa_ForestTrustInformation;
+
+ NTSTATUS lsa_lsaRQueryForestTrustInformation(
+ [in] policy_handle *handle,
+ [in,ref] lsa_String *trusted_domain_name,
+ [in] uint16 unknown, /* level ? */
+ [out,ref] lsa_ForestTrustInformation **forest_trust_info
+ );
/* Function 0x4a */
NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION();
@@ -947,7 +1026,7 @@ import "security.idl";
/*****************/
/* Function 0x4c */
- NTSTATUS lsa_LookupSids3(
+ [public] NTSTATUS lsa_LookupSids3(
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransNameArray2 *names,
@@ -963,7 +1042,7 @@ import "security.idl";
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray3 *sids,
- [in] uint16 level,
+ [in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2
diff --git a/source3/librpc/idl/xattr.idl b/source3/librpc/idl/xattr.idl
new file mode 100644
index 0000000000..ec230a4efb
--- /dev/null
+++ b/source3/librpc/idl/xattr.idl
@@ -0,0 +1,23 @@
+#include "idl_types.h"
+
+/*
+ IDL structures for xattrs
+*/
+
+[
+ pointer_default(unique)
+]
+interface xattr
+{
+ /* xattrs for file systems that don't have any */
+
+ typedef [public] struct {
+ utf8string name;
+ DATA_BLOB value;
+ } tdb_xattr;
+
+ typedef [public] struct {
+ uint32 num_xattrs;
+ tdb_xattr xattrs[num_xattrs];
+ } tdb_xattrs;
+}
diff --git a/source3/librpc/ndr/libndr.h b/source3/librpc/ndr/libndr.h
index 6341e20b65..d0c2c74db9 100644
--- a/source3/librpc/ndr/libndr.h
+++ b/source3/librpc/ndr/libndr.h
@@ -149,7 +149,7 @@ struct ndr_print {
/* set to avoid recursion in ndr_size_*() calculation */
#define LIBNDR_FLAG_NO_NDR_SIZE (1<<31)
-/* useful macro for debugging */
+/* useful macro for debugging with DEBUG */
#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
#define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
#define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
@@ -157,6 +157,14 @@ struct ndr_print {
#define NDR_PRINT_OUT_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_OUT, p)
#define NDR_PRINT_IN_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_IN | NDR_SET_VALUES, p)
+/* useful macro for debugging in strings */
+#define NDR_PRINT_STRUCT_STRING(ctx, type, p) ndr_print_struct_string(ctx, (ndr_print_fn_t)ndr_print_ ##type, #p, p)
+#define NDR_PRINT_UNION_STRING(ctx, type, level, p) ndr_print_union_string(ctx, (ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
+#define NDR_PRINT_FUNCTION_STRING(ctx, type, flags, p) ndr_print_function_string(ctx, (ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
+#define NDR_PRINT_BOTH_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_BOTH, p)
+#define NDR_PRINT_OUT_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_OUT, p)
+#define NDR_PRINT_IN_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_IN | NDR_SET_VALUES, p)
+
#define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
enum ndr_err_code {
diff --git a/source3/librpc/ndr/ndr_basic.c b/source3/librpc/ndr/ndr_basic.c
index 0ef78a2a54..54397c9469 100644
--- a/source3/librpc/ndr/ndr_basic.c
+++ b/source3/librpc/ndr/ndr_basic.c
@@ -847,3 +847,14 @@ _PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
if (!data) return ret;
return ret + data->length;
}
+
+_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b)
+{
+ ndr->print(ndr, "%-25s: %s", name, b?"true":"false");
+}
+
+_PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name, const struct sockaddr_storage *ss)
+{
+ char addr[INET6_ADDRSTRLEN];
+ ndr->print(ndr, "%-25s: %s", name, print_sockaddr(addr, sizeof(addr), ss));
+}
diff --git a/source3/librpc/ndr/ndr_misc.c b/source3/librpc/ndr/ndr_misc.c
index 2ca0cf08e8..245ba45215 100644
--- a/source3/librpc/ndr/ndr_misc.c
+++ b/source3/librpc/ndr/ndr_misc.c
@@ -153,3 +153,84 @@ void ndr_print_server_id(struct ndr_print *ndr, const char *name, const struct s
#endif
ndr->depth--;
}
+
+void ndr_print_ads_struct(struct ndr_print *ndr, const char *name, const struct ads_struct *r)
+{
+ if (!r) { return; }
+
+ ndr_print_struct(ndr, name, "ads_struct");
+ ndr->depth++;
+ ndr_print_bool(ndr, "is_mine", r->is_mine);
+ ndr_print_struct(ndr, name, "server");
+ ndr->depth++;
+ ndr_print_string(ndr, "realm", r->server.realm);
+ ndr_print_string(ndr, "workgroup", r->server.workgroup);
+ ndr_print_string(ndr, "ldap_server", r->server.ldap_server);
+ ndr_print_bool(ndr, "foreign", r->server.foreign);
+ ndr->depth--;
+ ndr_print_struct(ndr, name, "auth");
+ ndr->depth++;
+ ndr_print_string(ndr, "realm", r->auth.realm);
+#ifdef DEBUG_PASSWORD
+ ndr_print_string(ndr, "password", r->auth.password);
+#else
+ ndr_print_string(ndr, "password", "(PASSWORD ommited)");
+#endif
+ ndr_print_string(ndr, "user_name", r->auth.user_name);
+ ndr_print_string(ndr, "kdc_server", r->auth.kdc_server);
+ ndr_print_uint32(ndr, "flags", r->auth.flags);
+ ndr_print_uint32(ndr, "time_offset", r->auth.time_offset);
+ ndr_print_time_t(ndr, "tgt_expire", r->auth.tgt_expire);
+ ndr_print_time_t(ndr, "tgs_expire", r->auth.tgs_expire);
+ ndr_print_time_t(ndr, "renewable", r->auth.renewable);
+ ndr->depth--;
+ ndr_print_struct(ndr, name, "config");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "flags", r->config.flags);
+ ndr_print_string(ndr, "realm", r->config.realm);
+ ndr_print_string(ndr, "bind_path", r->config.bind_path);
+ ndr_print_string(ndr, "ldap_server_name", r->config.ldap_server_name);
+ ndr_print_string(ndr, "server_site_name", r->config.server_site_name);
+ ndr_print_string(ndr, "client_site_name", r->config.client_site_name);
+ ndr_print_time_t(ndr, "current_time", r->config.current_time);
+ ndr_print_bool(ndr, "tried_closest_dc", r->config.tried_closest_dc);
+ ndr_print_string(ndr, "schema_path", r->config.schema_path);
+ ndr_print_string(ndr, "config_path", r->config.config_path);
+ ndr->depth--;
+#ifdef HAVE_LDAP
+ ndr_print_struct(ndr, name, "ldap");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "ld", r->ldap.ld);
+ ndr_print_sockaddr_storage(ndr, "ss", &r->ldap.ss);
+ ndr_print_time_t(ndr, "last_attempt", r->ldap.last_attempt);
+ ndr_print_uint32(ndr, "port", r->ldap.port);
+ ndr_print_uint16(ndr, "wrap_type", r->ldap.wrap_type);
+#ifdef HAVE_LDAP_SASL_WRAPPING
+ ndr_print_ptr(ndr, "sbiod", r->ldap.sbiod);
+#endif /* HAVE_LDAP_SASL_WRAPPING */
+ ndr_print_ptr(ndr, "mem_ctx", r->ldap.mem_ctx);
+ ndr_print_ptr(ndr, "wrap_ops", r->ldap.wrap_ops);
+ ndr_print_ptr(ndr, "wrap_private_data", r->ldap.wrap_private_data);
+ ndr_print_struct(ndr, name, "in");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "ofs", r->ldap.in.ofs);
+ ndr_print_uint32(ndr, "needed", r->ldap.in.needed);
+ ndr_print_uint32(ndr, "left", r->ldap.in.left);
+ ndr_print_uint32(ndr, "max_wrapped", r->ldap.in.max_wrapped);
+ ndr_print_uint32(ndr, "min_wrapped", r->ldap.in.min_wrapped);
+ ndr_print_uint32(ndr, "size", r->ldap.in.size);
+ ndr_print_array_uint8(ndr, "buf", r->ldap.in.buf, r->ldap.in.size);
+ ndr->depth--;
+ ndr_print_struct(ndr, name, "out");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "ofs", r->ldap.out.ofs);
+ ndr_print_uint32(ndr, "left", r->ldap.out.left);
+ ndr_print_uint32(ndr, "max_unwrapped", r->ldap.out.max_unwrapped);
+ ndr_print_uint32(ndr, "sig_size", r->ldap.out.sig_size);
+ ndr_print_uint32(ndr, "size", r->ldap.out.size);
+ ndr_print_array_uint8(ndr, "buf", r->ldap.out.buf, r->ldap.out.size);
+ ndr->depth--;
+ ndr->depth--;
+#endif /* HAVE_LDAP */
+ ndr->depth--;
+}
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 0b33e43563..6b39a885f0 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -404,6 +404,9 @@ ssize_t cli_write(struct cli_state *cli,
mpx = 1;
}
+ /* Default (small) writesize. */
+ writesize = (cli->max_xmit - (smb_size+32)) & ~1023;
+
if (write_mode == 0 &&
!client_is_signing_on(cli) &&
!cli_encryption_on(cli) &&
@@ -415,11 +418,11 @@ ssize_t cli_write(struct cli_state *cli,
} else if (cli->capabilities & CAP_LARGE_WRITEX) {
if (cli->is_samba) {
writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE;
- } else {
+ } else if (!client_is_signing_on(cli)) {
+ /* Windows restricts signed writes to max_xmit.
+ * Found by Volker. */
writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
}
- } else {
- writesize = (cli->max_xmit - (smb_size+32)) & ~1023;
}
blocks = (size + (writesize-1)) / writesize;
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index da8f1e332b..fb04d143a5 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -592,13 +592,58 @@ smbc_remove_unused_server(SMBCCTX * context,
return 0;
}
+/****************************************************************
+ * Call the auth_fn with fixed size (fstring) buffers.
+ ***************************************************************/
+
+static void call_auth_fn(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
+{
+ fstring workgroup;
+ fstring username;
+ fstring password;
+
+ strlcpy(workgroup, *pp_workgroup, sizeof(workgroup));
+ strlcpy(username, *pp_username, sizeof(username));
+ strlcpy(password, *pp_password, sizeof(password));
+
+ if (context->internal->_auth_fn_with_context != NULL) {
+ (context->internal->_auth_fn_with_context)(
+ context,
+ server, share,
+ workgroup, sizeof(workgroup),
+ username, sizeof(username),
+ password, sizeof(password));
+ } else {
+ (context->callbacks.auth_fn)(
+ server, share,
+ workgroup, sizeof(workgroup),
+ username, sizeof(username),
+ password, sizeof(password));
+ }
+
+ TALLOC_FREE(*pp_workgroup);
+ TALLOC_FREE(*pp_username);
+ TALLOC_FREE(*pp_password);
+
+ *pp_workgroup = talloc_strdup(ctx, workgroup);
+ *pp_username = talloc_strdup(ctx, username);
+ *pp_password = talloc_strdup(ctx, password);
+}
+
static SMBCSRV *
-find_server(SMBCCTX *context,
+find_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
const char *server,
const char *share,
- char *workgroup,
- char *username,
- char *password)
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
{
SMBCSRV *srv;
int auth_called = 0;
@@ -606,22 +651,15 @@ find_server(SMBCCTX *context,
check_server_cache:
srv = (context->callbacks.get_cached_srv_fn)(context, server, share,
- workgroup, username);
-
- if (!auth_called && !srv && (!username[0] || !password[0])) {
- if (context->internal->_auth_fn_with_context != NULL) {
- (context->internal->_auth_fn_with_context)(
- context,
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
- } else {
- (context->callbacks.auth_fn)(
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
+ *pp_workgroup, *pp_username);
+
+ if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] ||
+ !*pp_password || !(*pp_password)[0])) {
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+
+ if (!pp_workgroup || !pp_username || !pp_password) {
+ return NULL;
}
/*
@@ -652,12 +690,12 @@ find_server(SMBCCTX *context,
(context->callbacks.remove_cached_srv_fn)(context,
srv);
}
-
+
/*
* Maybe there are more cached connections to this
* server
*/
- goto check_server_cache;
+ goto check_server_cache;
}
return srv;
@@ -678,13 +716,14 @@ find_server(SMBCCTX *context,
*/
static SMBCSRV *
-smbc_server(SMBCCTX *context,
+smbc_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
bool connect_if_not_found,
const char *server,
const char *share,
- char *workgroup,
- char *username,
- char *password)
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password)
{
SMBCSRV *srv=NULL;
struct cli_state *c;
@@ -706,8 +745,8 @@ smbc_server(SMBCCTX *context,
}
/* Look for a cached connection */
- srv = find_server(context, server, share,
- workgroup, username, password);
+ srv = find_server(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
/*
* If we found a connection and we're only allowed one share per
@@ -725,20 +764,17 @@ smbc_server(SMBCCTX *context,
*/
if (srv->cli->cnum == (uint16) -1) {
/* Ensure we have accurate auth info */
- if (context->internal->_auth_fn_with_context != NULL) {
- (context->internal->_auth_fn_with_context)(
- context,
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
- } else {
- (context->callbacks.auth_fn)(
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
- }
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ cli_shutdown(srv->cli);
+ srv->cli = NULL;
+ (context->callbacks.remove_cached_srv_fn)(context,
+ srv);
+ return NULL;
+ }
/*
* We don't need to renegotiate encryption
@@ -746,8 +782,9 @@ smbc_server(SMBCCTX *context,
* tid.
*/
- if (! cli_send_tconX(srv->cli, share, "?????",
- password, strlen(password)+1)) {
+ if (!cli_send_tconX(srv->cli, share, "?????",
+ *pp_password,
+ strlen(*pp_password)+1)) {
errno = smbc_errno(context, srv->cli);
cli_shutdown(srv->cli);
@@ -781,6 +818,11 @@ smbc_server(SMBCCTX *context,
return NULL;
}
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
make_nmb_name(&calling, context->netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
@@ -877,21 +919,21 @@ smbc_server(SMBCCTX *context,
return NULL;
}
- username_used = username;
+ username_used = *pp_username;
if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
- password, strlen(password),
- password, strlen(password),
- workgroup))) {
+ *pp_password, strlen(*pp_password),
+ *pp_password, strlen(*pp_password),
+ *pp_workgroup))) {
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = "";
if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
- password, 1,
- password, 0,
- workgroup))) {
+ *pp_password, 1,
+ *pp_password, 0,
+ *pp_workgroup))) {
cli_shutdown(c);
errno = EPERM;
@@ -902,7 +944,7 @@ smbc_server(SMBCCTX *context,
DEBUG(4,(" session setup ok\n"));
if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
+ *pp_password, strlen(*pp_password)+1)) {
errno = smbc_errno(context, c);
cli_shutdown(c);
return NULL;
@@ -914,8 +956,8 @@ smbc_server(SMBCCTX *context,
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(c,
username_used,
- password,
- workgroup))) {
+ *pp_password,
+ *pp_workgroup))) {
/*
* context->internal->_smb_encryption_level == 1
@@ -956,8 +998,9 @@ smbc_server(SMBCCTX *context,
/* Let the cache function set errno if it wants to */
errno = 0;
if ((context->callbacks.add_cached_srv_fn)(context, srv,
- server, share,
- workgroup, username)) {
+ server, share,
+ *pp_workgroup,
+ *pp_username)) {
int saved_errno = errno;
DEBUG(3, (" Failed to add server to cache\n"));
errno = saved_errno;
@@ -988,13 +1031,14 @@ smbc_server(SMBCCTX *context,
* connection. This works similarly to smbc_server().
*/
static SMBCSRV *
-smbc_attr_server(SMBCCTX *context,
- const char *server,
- const char *share,
- char *workgroup,
- char *username,
- char *password,
- POLICY_HND *pol)
+smbc_attr_server(TALLOC_CTX *ctx,
+ SMBCCTX *context,
+ const char *server,
+ const char *share,
+ char **pp_workgroup,
+ char **pp_username,
+ char **pp_password,
+ POLICY_HND *pol)
{
int flags;
struct sockaddr_storage ss;
@@ -1008,27 +1052,19 @@ smbc_attr_server(SMBCCTX *context,
* our "special" share name '*IPC$', which is an impossible real share
* name due to the leading asterisk.
*/
- ipc_srv = find_server(context, server, "*IPC$",
- workgroup, username, password);
+ ipc_srv = find_server(ctx, context, server, "*IPC$",
+ pp_workgroup, pp_username, pp_password);
if (!ipc_srv) {
/* We didn't find a cached connection. Get the password */
- if (*password == '\0') {
+ if (!*pp_password || (*pp_password)[0] == '\0') {
/* ... then retrieve it now. */
- if (context->internal->_auth_fn_with_context != NULL) {
- (context->internal->_auth_fn_with_context)(
- context,
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
- } else {
- (context->callbacks.auth_fn)(
- server, share,
- workgroup, strlen(workgroup)+1,
- username, strlen(username)+1,
- password, strlen(password)+1);
- }
+ call_auth_fn(ctx, context, server, share,
+ pp_workgroup, pp_username, pp_password);
+ if (!*pp_workgroup || !*pp_username || !*pp_password) {
+ errno = ENOMEM;
+ return NULL;
+ }
}
flags = 0;
@@ -1038,11 +1074,13 @@ smbc_attr_server(SMBCCTX *context,
zero_addr(&ss);
nt_status = cli_full_connection(&ipc_cli,
- global_myname(), server,
- &ss, 0, "IPC$", "?????",
- username, workgroup,
- password, flags,
- Undefined, NULL);
+ global_myname(), server,
+ &ss, 0, "IPC$", "?????",
+ *pp_username,
+ *pp_workgroup,
+ *pp_password,
+ flags,
+ Undefined, NULL);
if (! NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("cli_full_connection failed! (%s)\n",
nt_errstr(nt_status)));
@@ -1053,9 +1091,9 @@ smbc_attr_server(SMBCCTX *context,
if (context->internal->_smb_encryption_level) {
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
- username,
- password,
- workgroup))) {
+ *pp_username,
+ *pp_password,
+ *pp_workgroup))) {
/*
* context->internal->_smb_encryption_level == 1
@@ -1101,14 +1139,14 @@ smbc_attr_server(SMBCCTX *context,
* SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000
* so we might as well do it too.
*/
-
+
nt_status = rpccli_lsa_open_policy(
pipe_hnd,
talloc_tos(),
- True,
+ True,
GENERIC_EXECUTE_ACCESS,
pol);
-
+
if (!NT_STATUS_IS_OK(nt_status)) {
errno = smbc_errno(context, ipc_srv->cli);
cli_shutdown(ipc_srv->cli);
@@ -1120,10 +1158,10 @@ smbc_attr_server(SMBCCTX *context,
errno = 0; /* let cache function set errno if it likes */
if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv,
- server,
- "*IPC$",
- workgroup,
- username)) {
+ server,
+ "*IPC$",
+ *pp_workgroup,
+ *pp_username)) {
DEBUG(3, (" Failed to add server to cache\n"));
if (errno == 0) {
errno = ENOMEM;
@@ -1149,10 +1187,10 @@ smbc_open_ctx(SMBCCTX *context,
int flags,
mode_t mode)
{
- char *server, *share, *user, *password, *workgroup;
- char *path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
+ char *path = NULL;
char *targetpath = NULL;
- struct cli_state *targetcli;
+ struct cli_state *targetcli = NULL;
SMBCSRV *srv = NULL;
SMBCFILE *file = NULL;
int fd;
@@ -1199,8 +1237,8 @@ smbc_open_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
if (errno == EPERM) errno = EACCES;
@@ -1343,10 +1381,10 @@ smbc_read_ctx(SMBCCTX *context,
size_t count)
{
int ret;
- char *server, *share, *user, *password;
- char *path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
char *targetpath = NULL;
- struct cli_state *targetcli;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
/*
@@ -1444,10 +1482,10 @@ smbc_write_ctx(SMBCCTX *context,
{
int ret;
off_t offset;
- char *server, *share, *user, *password;
- char *path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
char *targetpath = NULL;
- struct cli_state *targetcli;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
/* First check all pointers before dereferencing them */
@@ -1526,10 +1564,10 @@ smbc_close_ctx(SMBCCTX *context,
SMBCFILE *file)
{
SMBCSRV *srv;
- char *server, *share, *user, *password;
- char *path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
char *targetpath = NULL;
- struct cli_state *targetcli;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -1618,9 +1656,9 @@ smbc_getatr(SMBCCTX * context,
struct timespec *change_time_ts,
SMB_INO_T *ino)
{
- char *fixedpath;
+ char *fixedpath = NULL;
char *targetpath = NULL;
- struct cli_state *targetcli;
+ struct cli_state *targetcli = NULL;
time_t write_time;
TALLOC_CTX *frame = talloc_stackframe();
@@ -1689,11 +1727,11 @@ smbc_getatr(SMBCCTX * context,
if (create_time_ts != NULL) {
*create_time_ts = w_time_ts;
}
-
+
if (access_time_ts != NULL) {
*access_time_ts = w_time_ts;
}
-
+
if (change_time_ts != NULL) {
*change_time_ts = w_time_ts;
}
@@ -1804,10 +1842,10 @@ static int
smbc_unlink_ctx(SMBCCTX *context,
const char *fname)
{
- char *server, *share, *user, *password, *workgroup;
- char *path;
- char *targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
SMBCSRV *srv = NULL;
TALLOC_CTX *frame = talloc_stackframe();
@@ -1850,8 +1888,8 @@ smbc_unlink_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
@@ -1926,21 +1964,21 @@ smbc_rename_ctx(SMBCCTX *ocontext,
SMBCCTX *ncontext,
const char *nname)
{
- char *server1;
- char *share1;
- char *server2;
- char *share2;
- char *user1;
- char *user2;
- char *password1;
- char *password2;
- char *workgroup;
- char *path1;
- char *path2;
- char *targetpath1;
- char *targetpath2;
- struct cli_state *targetcli1;
- struct cli_state *targetcli2;
+ char *server1 = NULL;
+ char *share1 = NULL;
+ char *server2 = NULL;
+ char *share2 = NULL;
+ char *user1 = NULL;
+ char *user2 = NULL;
+ char *password1 = NULL;
+ char *password2 = NULL;
+ char *workgroup = NULL;
+ char *path1 = NULL;
+ char *path2 = NULL;
+ char *targetpath1 = NULL;
+ char *targetpath2 = NULL;
+ struct cli_state *targetcli1 = NULL;
+ struct cli_state *targetcli2 = NULL;
SMBCSRV *srv = NULL;
TALLOC_CTX *frame = talloc_stackframe();
@@ -2017,8 +2055,8 @@ smbc_rename_ctx(SMBCCTX *ocontext,
return -1;
}
- srv = smbc_server(ocontext, True,
- server1, share1, workgroup, user1, password1);
+ srv = smbc_server(frame, ocontext, True,
+ server1, share1, &workgroup, &user1, &password1);
if (!srv) {
TALLOC_FREE(frame);
return -1;
@@ -2080,10 +2118,10 @@ smbc_lseek_ctx(SMBCCTX *context,
int whence)
{
SMB_OFF_T size;
- char *server, *share, *user, *password;
- char *path;
- char *targetpath;
- struct cli_state *targetcli;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -2253,13 +2291,13 @@ smbc_stat_ctx(SMBCCTX *context,
const char *fname,
struct stat *st)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
struct timespec write_time_ts;
struct timespec access_time_ts;
struct timespec change_time_ts;
@@ -2308,8 +2346,8 @@ smbc_stat_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
@@ -2355,13 +2393,13 @@ smbc_fstat_ctx(SMBCCTX *context,
struct timespec write_time_ts;
SMB_OFF_T size;
uint16 mode;
- char *server;
- char *share;
- char *user;
- char *password;
- char *path;
- char *targetpath;
- struct cli_state *targetcli;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
SMB_INO_T ino = 0;
TALLOC_CTX *frame = talloc_stackframe();
@@ -2743,14 +2781,14 @@ smbc_opendir_ctx(SMBCCTX *context,
const char *fname)
{
int saved_errno;
- char *server, *share, *user, *password, *options;
- char *workgroup;
- char *path;
+ char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
uint16 mode;
- char *p;
+ char *p = NULL;
SMBCSRV *srv = NULL;
SMBCFILE *dir = NULL;
- struct _smbc_callbacks *cb;
+ struct _smbc_callbacks *cb = NULL;
struct sockaddr_storage rem_ss;
TALLOC_CTX *frame = talloc_stackframe();
@@ -2939,8 +2977,8 @@ smbc_opendir_ctx(SMBCCTX *context,
* workgroups/domains that it knows about.
*/
- srv = smbc_server(context, True, server, "IPC$",
- workgroup, user, password);
+ srv = smbc_server(frame, context, True, server, "IPC$",
+ &workgroup, &user, &password);
if (!srv) {
continue;
}
@@ -2993,8 +3031,8 @@ smbc_opendir_ctx(SMBCCTX *context,
* establish a connection if one does not already
* exist.
*/
- srv = smbc_server(context, False, server, "IPC$",
- workgroup, user, password);
+ srv = smbc_server(frame, context, False, server, "IPC$",
+ &workgroup, &user, &password);
/*
* If no existing server and not an IP addr, look for
@@ -3032,9 +3070,9 @@ smbc_opendir_ctx(SMBCCTX *context,
* Get a connection to IPC$ on the server if
* we do not already have one
*/
- srv = smbc_server(context, True,
+ srv = smbc_server(frame, context, True,
buserver, "IPC$",
- workgroup, user, password);
+ &workgroup, &user, &password);
if (!srv) {
DEBUG(0, ("got no contact to IPC$\n"));
if (dir) {
@@ -3065,10 +3103,10 @@ smbc_opendir_ctx(SMBCCTX *context,
/* If we hadn't found the server, get one now */
if (!srv) {
- srv = smbc_server(context, True,
+ srv = smbc_server(frame, context, True,
server, "IPC$",
- workgroup,
- user, password);
+ &workgroup,
+ &user, &password);
}
if (!srv) {
@@ -3127,8 +3165,8 @@ smbc_opendir_ctx(SMBCCTX *context,
/* We connect to the server and list the directory */
dir->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(context, True, server, share,
- workgroup, user, password);
+ srv = smbc_server(frame, context, True, server, share,
+ &workgroup, &user, &password);
if (!srv) {
if (dir) {
@@ -3495,15 +3533,15 @@ smbc_mkdir_ctx(SMBCCTX *context,
const char *fname,
mode_t mode)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
- char *targetpath;
- struct cli_state *targetcli;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -3545,8 +3583,8 @@ smbc_mkdir_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
@@ -3603,15 +3641,15 @@ static int
smbc_rmdir_ctx(SMBCCTX *context,
const char *fname)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
- char *targetpath;
- struct cli_state *targetcli;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -3653,8 +3691,8 @@ smbc_rmdir_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
@@ -3888,13 +3926,13 @@ smbc_chmod_ctx(SMBCCTX *context,
const char *fname,
mode_t newmode)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
@@ -3937,8 +3975,8 @@ smbc_chmod_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
@@ -3967,13 +4005,13 @@ smbc_utimes_ctx(SMBCCTX *context,
const char *fname,
struct timeval *tbuf)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
time_t access_time;
time_t write_time;
TALLOC_CTX *frame = talloc_stackframe();
@@ -4043,8 +4081,8 @@ smbc_utimes_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
@@ -5679,16 +5717,16 @@ smbc_setxattr_ctx(SMBCCTX *context,
{
int ret;
int ret2;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
- DOS_ATTR_DESC *dad;
+ DOS_ATTR_DESC *dad = NULL;
struct {
const char * create_time_attr;
const char * access_time_attr;
@@ -5737,16 +5775,16 @@ smbc_setxattr_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
if (! srv->no_nt_session) {
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
@@ -5977,14 +6015,14 @@ smbc_getxattr_ctx(SMBCCTX *context,
size_t size)
{
int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
struct {
const char * create_time_attr;
@@ -6033,16 +6071,16 @@ smbc_getxattr_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
if (! srv->no_nt_session) {
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
@@ -6119,14 +6157,14 @@ smbc_removexattr_ctx(SMBCCTX *context,
const char *name)
{
int ret;
- SMBCSRV *srv;
- SMBCSRV *ipc_srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ SMBCSRV *ipc_srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
POLICY_HND pol;
TALLOC_CTX *frame = talloc_stackframe();
@@ -6169,16 +6207,16 @@ smbc_removexattr_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
return -1; /* errno set by smbc_server */
}
if (! srv->no_nt_session) {
- ipc_srv = smbc_attr_server(context, server, share,
- workgroup, user, password,
+ ipc_srv = smbc_attr_server(frame, context, server, share,
+ &workgroup, &user, &password,
&pol);
if (! ipc_srv) {
srv->no_nt_session = True;
@@ -6241,6 +6279,7 @@ smbc_listxattr_ctx(SMBCCTX *context,
* the complete set of attribute names, always, rather than only those
* attribute names which actually exist for a file. Hmmm...
*/
+ size_t retsize;
const char supported_old[] =
"system.*\0"
"system.*+\0"
@@ -6284,22 +6323,24 @@ smbc_listxattr_ctx(SMBCCTX *context,
if (context->internal->_full_time_names) {
supported = supported_new;
+ retsize = sizeof(supported_new);
} else {
supported = supported_old;
+ retsize = sizeof(supported_old);
}
if (size == 0) {
- return sizeof(supported);
+ return retsize;
}
- if (sizeof(supported) > size) {
+ if (retsize > size) {
errno = ERANGE;
return -1;
}
/* this can't be strcpy() because there are embedded null characters */
- memcpy(list, supported, sizeof(supported));
- return sizeof(supported);
+ memcpy(list, supported, retsize);
+ return retsize;
}
@@ -6311,11 +6352,11 @@ static SMBCFILE *
smbc_open_print_job_ctx(SMBCCTX *context,
const char *fname)
{
- char *server;
- char *share;
- char *user;
- char *password;
- char *path;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *path = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -6454,13 +6495,13 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
const char *fname,
smbc_list_print_job_fn fn)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
TALLOC_CTX *frame = talloc_stackframe();
if (!context || !context->internal ||
@@ -6502,8 +6543,8 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
TALLOC_FREE(frame);
@@ -6531,13 +6572,13 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
const char *fname,
int id)
{
- SMBCSRV *srv;
- char *server;
- char *share;
- char *user;
- char *password;
- char *workgroup;
- char *path;
+ SMBCSRV *srv = NULL;
+ char *server = NULL;
+ char *share = NULL;
+ char *user = NULL;
+ char *password = NULL;
+ char *workgroup = NULL;
+ char *path = NULL;
int err;
TALLOC_CTX *frame = talloc_stackframe();
@@ -6580,8 +6621,8 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
}
}
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(frame, context, True,
+ server, share, &workgroup, &user, &password);
if (!srv) {
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index ad999b34b4..ad16452e3e 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1299,11 +1299,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
Resolve via "ADS" method.
*********************************************************/
-NTSTATUS resolve_ads(const char *name,
- int name_type,
- const char *sitename,
- struct ip_service **return_iplist,
- int *return_count)
+static NTSTATUS resolve_ads(const char *name,
+ int name_type,
+ const char *sitename,
+ struct ip_service **return_iplist,
+ int *return_count)
{
int i, j;
NTSTATUS status;
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index d7f6f604f7..c547a4a003 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -443,7 +443,7 @@ bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_
the username and domain.
This prevents username swapping during the auth exchange
*/
- if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
+ if (!ntv2_owf_gen(nt_hash, user, domain, False, ntlm_v2_hash)) {
return False;
}
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index eb42d081fe..4191871bb1 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -41,11 +41,11 @@ static struct db_context *brlock_db;
static void print_lock_struct(unsigned int i, struct lock_struct *pls)
{
- DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %s, ",
+ DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %u, ",
i,
(unsigned int)pls->context.smbpid,
(unsigned int)pls->context.tid,
- procid_str_static(&pls->context.pid) ));
+ (unsigned int)procid_to_pid(&pls->context.pid) ));
DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n",
(double)pls->start,
@@ -263,10 +263,9 @@ void brl_init(bool read_only)
if (brlock_db) {
return;
}
- brlock_db = db_open(NULL, lock_path("brlock.tdb"), 0,
- TDB_DEFAULT
- |TDB_VOLATILE
- |(read_only?0x0:TDB_CLEAR_IF_FIRST),
+ brlock_db = db_open(NULL, lock_path("brlock.tdb"),
+ lp_open_files_db_hash_size(),
+ TDB_DEFAULT | TDB_CLEAR_IF_FIRST,
read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 );
if (!brlock_db) {
DEBUG(0,("Failed to open byte range locking database %s\n",
@@ -1495,14 +1494,16 @@ static int traverse_fn(struct db_record *rec, void *state)
}
}
- for ( i=0; i<num_locks; i++) {
- cb->fn(*key,
- locks[i].context.pid,
- locks[i].lock_type,
- locks[i].lock_flav,
- locks[i].start,
- locks[i].size,
- cb->private_data);
+ if (cb->fn) {
+ for ( i=0; i<num_locks; i++) {
+ cb->fn(*key,
+ locks[i].context.pid,
+ locks[i].lock_type,
+ locks[i].lock_flav,
+ locks[i].start,
+ locks[i].size,
+ cb->private_data);
+ }
}
SAFE_FREE(locks);
diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c
index 300e90fa69..590dbac26f 100644
--- a/source3/modules/gpfs.c
+++ b/source3/modules/gpfs.c
@@ -22,9 +22,11 @@
#ifdef HAVE_GPFS
#include "gpfs_gpl.h"
+#include "vfs_gpfs.h"
static void *libgpfs_handle = NULL;
static bool gpfs_share_modes;
+static bool gpfs_leases;
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);
@@ -42,7 +44,7 @@ bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
if (!gpfs_share_modes) {
return True;
}
-
+
if (gpfs_set_share_fn == NULL) {
return False;
}
@@ -88,7 +90,7 @@ int set_gpfs_lease(int fd, int leasetype)
{
int gpfs_type = GPFS_LEASE_NONE;
- if (!gpfs_share_modes) {
+ if (!gpfs_leases) {
return True;
}
@@ -103,6 +105,13 @@ int set_gpfs_lease(int fd, int leasetype)
if (leasetype == F_WRLCK) {
gpfs_type = GPFS_LEASE_WRITE;
}
+
+ /* we unconditionally set CAP_LEASE, rather than looking for
+ -1/EACCES as there is a bug in some versions of
+ libgpfs_gpl.so which results in a leaked fd on /dev/ss0
+ each time we try this with the wrong capabilities set
+ */
+ linux_set_lease_capability();
return gpfs_set_lease_fn(fd, gpfs_type);
}
@@ -172,11 +181,8 @@ void init_gpfs(void)
goto failed;
}
- if (lp_parm_bool(-1, "gpfs", "sharemodes", True)) {
- gpfs_share_modes = True;
- } else {
- gpfs_share_modes = False;
- }
+ gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True);
+ gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True);
return;
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 52d3983fff..0c3d010dcd 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -20,6 +20,9 @@
#include "includes.h"
#include "nfs4_acls.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_ACLS
+
#define SMBACL4_PARAM_TYPE_NAME "nfs4"
#define SMB_ACE4_INT_MAGIC 0x76F8A967
@@ -352,6 +355,7 @@ typedef struct _smbacl4_vfs_params {
enum smbacl4_mode_enum mode;
bool do_chown;
enum smbacl4_acedup_enum acedup;
+ struct db_context *sid_mapping_table;
} smbacl4_vfs_params;
/*
@@ -451,8 +455,65 @@ static SMB_ACE4PROP_T *smbacl4_find_equal_special(
return NULL;
}
-static int smbacl4_fill_ace4(
+static bool nfs4_map_sid(smbacl4_vfs_params *params, const DOM_SID *src,
+ DOM_SID *dst)
+{
+ static struct db_context *mapping_db = NULL;
+ TDB_DATA data;
+
+ if (mapping_db == NULL) {
+ const char *dbname = lp_parm_const_string(
+ -1, SMBACL4_PARAM_TYPE_NAME, "sidmap", NULL);
+
+ if (dbname == NULL) {
+ DEBUG(10, ("%s:sidmap not defined\n",
+ SMBACL4_PARAM_TYPE_NAME));
+ return False;
+ }
+
+ become_root();
+ mapping_db = db_open(NULL, dbname, 0, TDB_DEFAULT,
+ O_RDONLY, 0600);
+ unbecome_root();
+
+ if (mapping_db == NULL) {
+ DEBUG(1, ("could not open sidmap: %s\n",
+ strerror(errno)));
+ return False;
+ }
+ }
+
+ if (mapping_db->fetch(mapping_db, NULL,
+ string_term_tdb_data(sid_string_tos(src)),
+ &data) == -1) {
+ DEBUG(10, ("could not find mapping for SID %s\n",
+ sid_string_dbg(src)));
+ return False;
+ }
+
+ if ((data.dptr == NULL) || (data.dsize <= 0)
+ || (data.dptr[data.dsize-1] != '\0')) {
+ DEBUG(5, ("invalid mapping for SID %s\n",
+ sid_string_dbg(src)));
+ TALLOC_FREE(data.dptr);
+ return False;
+ }
+
+ if (!string_to_sid(dst, (char *)data.dptr)) {
+ DEBUG(1, ("invalid mapping %s for SID %s\n",
+ (char *)data.dptr, sid_string_dbg(src)));
+ TALLOC_FREE(data.dptr);
+ return False;
+ }
+
+ TALLOC_FREE(data.dptr);
+
+ return True;
+}
+
+static bool smbacl4_fill_ace4(
TALLOC_CTX *mem_ctx,
+ const char *filename,
smbacl4_vfs_params *params,
uid_t ownerUID,
gid_t ownerGID,
@@ -460,11 +521,6 @@ static int smbacl4_fill_ace4(
SMB_ACE4PROP_T *ace_v4 /* output */
)
{
- const char *dom, *name;
- enum lsa_SidType type;
- uid_t uid;
- gid_t gid;
-
DEBUG(10, ("got ace for %s\n", sid_string_dbg(&ace_nt->trustee)));
memset(ace_v4, 0, sizeof(SMB_ACE4PROP_T));
@@ -485,18 +541,46 @@ static int smbacl4_fill_ace4(
ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
} else {
- if (!lookup_sid(mem_ctx, &ace_nt->trustee, &dom, &name, &type)) {
- DEBUG(8, ("Could not find %s' type\n",
- sid_string_dbg(&ace_nt->trustee)));
- errno = EINVAL;
- return -1;
+ const char *dom, *name;
+ enum lsa_SidType type;
+ uid_t uid;
+ gid_t gid;
+ DOM_SID sid;
+
+ sid_copy(&sid, &ace_nt->trustee);
+
+ if (!lookup_sid(mem_ctx, &sid, &dom, &name, &type)) {
+
+ DOM_SID mapped;
+
+ if (!nfs4_map_sid(params, &sid, &mapped)) {
+ DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
+ "unknown\n", filename, sid_string_dbg(&sid)));
+ errno = EINVAL;
+ return False;
+ }
+
+ DEBUG(2, ("nfs4_acls.c: file [%s]: mapped SID %s "
+ "to %s\n", filename, sid_string_dbg(&sid), sid_string_dbg(&mapped)));
+
+ if (!lookup_sid(mem_ctx, &mapped, &dom,
+ &name, &type)) {
+ DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
+ "mapped from %s is unknown\n",
+ filename, sid_string_dbg(&mapped), sid_string_dbg(&sid)));
+ errno = EINVAL;
+ return False;
+ }
+
+ sid_copy(&sid, &mapped);
}
-
+
if (type == SID_NAME_USER) {
- if (!sid_to_uid(&ace_nt->trustee, &uid)) {
- DEBUG(2, ("Could not convert %s to uid\n",
- sid_string_dbg(&ace_nt->trustee)));
- return -1;
+ if (!sid_to_uid(&sid, &uid)) {
+ DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
+ "convert %s to uid\n", filename,
+ sid_string_dbg(&sid)));
+ return False;
}
if (params->mode==e_special && uid==ownerUID) {
@@ -506,11 +590,13 @@ static int smbacl4_fill_ace4(
ace_v4->who.uid = uid;
}
} else { /* else group? - TODO check it... */
- if (!sid_to_gid(&ace_nt->trustee, &gid)) {
- DEBUG(2, ("Could not convert %s to gid\n",
- sid_string_dbg(&ace_nt->trustee)));
- return -1;
+ if (!sid_to_gid(&sid, &gid)) {
+ DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
+ "convert %s to gid\n", filename,
+ sid_string_dbg(&sid)));
+ return False;
}
+
ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
if (params->mode==e_special && gid==ownerGID) {
@@ -522,7 +608,7 @@ static int smbacl4_fill_ace4(
}
}
- return 0; /* OK */
+ return True; /* OK */
}
static int smbacl4_MergeIgnoreReject(
@@ -560,6 +646,7 @@ static int smbacl4_MergeIgnoreReject(
}
static SMB4ACL_T *smbacl4_win2nfs4(
+ const char *filename,
SEC_ACL *dacl,
smbacl4_vfs_params *pparams,
uid_t ownerUID,
@@ -580,9 +667,14 @@ static SMB4ACL_T *smbacl4_win2nfs4(
SMB_ACE4PROP_T ace_v4;
bool addNewACE = True;
- if (smbacl4_fill_ace4(mem_ctx, pparams, ownerUID, ownerGID,
- dacl->aces + i, &ace_v4))
- return NULL;
+ if (!smbacl4_fill_ace4(mem_ctx, filename, pparams,
+ ownerUID, ownerGID,
+ dacl->aces + i, &ace_v4)) {
+ DEBUG(3, ("Could not fill ace for file %s, SID %s\n",
+ filename,
+ sid_string_dbg(&((dacl->aces+i)->trustee))));
+ continue;
+ }
if (pparams->acedup!=e_dontcare) {
if (smbacl4_MergeIgnoreReject(pparams->acedup, acl,
@@ -607,6 +699,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
bool result;
SMB_STRUCT_STAT sbuf;
+ bool need_chown = False;
uid_t newUID = (uid_t)-1;
gid_t newGID = (gid_t)-1;
@@ -635,25 +728,33 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
return status;
}
if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
- ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
- if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
- DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) ));
- if (errno == EPERM) {
- return NT_STATUS_INVALID_OWNER;
+ ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
+ need_chown = True;
+ }
+ if (need_chown) {
+ if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) {
+ if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
+ DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
+ strerror(errno)));
+ return map_nt_error_from_unix(errno);
}
- return map_nt_error_from_unix(errno);
+
+ DEBUG(10,("chown %s, %u, %u succeeded.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
+ return map_nt_error_from_unix(errno);
+ need_chown = False;
+ } else { /* chown is needed, but _after_ changing acl */
+ sbuf.st_uid = newUID; /* OWNER@ in case of e_special */
+ sbuf.st_gid = newGID; /* GROUP@ in case of e_special */
}
- DEBUG(10,("chown %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
- if (smbacl4_fGetFileOwner(fsp, &sbuf))
- return map_nt_error_from_unix(errno);
}
}
if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL)
{
- acl = smbacl4_win2nfs4(psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
+ acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
if (!acl)
return map_nt_error_from_unix(errno);
@@ -668,6 +769,20 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
} else
DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
+ /* Any chown pending? */
+ if (need_chown) {
+ DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
+ DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
+ strerror(errno)));
+ return map_nt_error_from_unix(errno);
+ }
+ DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ }
+
DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));
return NT_STATUS_OK;
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index e21136ccee..3e78c69a5e 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1225,6 +1225,38 @@ static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_st
return sys_aio_suspend(aiocb, n, timeout);
}
+static int vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
+{
+ return False;
+}
+
+static int vfswrap_is_offline(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, bool *offline)
+{
+ if (ISDOT(path) || ISDOTDOT(path)) {
+ return 1;
+ }
+
+ if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) {
+ return -1;
+ }
+
+ *offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
+ return 0;
+}
+
+static int vfswrap_set_offline(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
+{
+ /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
+ return -1;
+}
+
+static bool vfswrap_is_remotestorage(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
+{
+ /* We don't know how to detect that volume is remote storage. VFS modules should redefine it. */
+ return False;
+}
+
+
static vfs_op_tuple vfs_default_ops[] = {
/* Disk operations */
@@ -1442,6 +1474,16 @@ static vfs_op_tuple vfs_default_ops[] = {
{SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
+ SMB_VFS_LAYER_OPAQUE},
+
+ {SMB_VFS_OP(vfswrap_is_offline),SMB_VFS_OP_IS_OFFLINE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OFFLINE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_is_remotestorage),SMB_VFS_OP_IS_REMOTESTORAGE,
+ SMB_VFS_LAYER_OPAQUE},
+
/* Finish VFS operations definition */
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index bcf61f3bc7..d10906dfb1 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -30,7 +30,7 @@
#include <gpfs_gpl.h>
#include "nfs4_acls.h"
-
+#include "vfs_gpfs.h"
static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
uint32 share_mode)
@@ -153,7 +153,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname));
/* First get the real acl length */
- gacl = gpfs_getacl_alloc(fname, GPFS_ACL_TYPE_NFS4);
+ gacl = gpfs_getacl_alloc(fname, 0);
if (gacl == NULL) {
DEBUG(9, ("gpfs_getacl failed for %s with %s\n",
fname, strerror(errno)));
@@ -208,10 +208,10 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) {
struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1];
if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE &&
- prev->aceFlags == gace->aceFlags &&
- prev->aceIFlags == gace->aceIFlags &&
- (gace->aceMask & prev->aceMask) == 0 &&
- gace->aceWho == prev->aceWho) {
+ prev->aceFlags == gace->aceFlags &&
+ prev->aceIFlags == gace->aceIFlags &&
+ (gace->aceMask & prev->aceMask) == 0 &&
+ gace->aceWho == prev->aceWho) {
/* its redundent - skip it */
continue;
}
@@ -256,7 +256,7 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
int result;
*ppdesc = NULL;
- result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl);
+ result = gpfs_get_nfs4_acl(name, &pacl);
if (result == 0)
return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl);
@@ -301,8 +301,31 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
gace->aceType = aceprop->aceType;
gace->aceFlags = aceprop->aceFlags;
gace->aceMask = aceprop->aceMask;
+
+ /*
+ * GPFS can't distinguish between WRITE and APPEND on
+ * files, so one being set without the other is an
+ * error. Sorry for the many ()'s :-)
+ */
+
+ if (!fsp->is_directory
+ &&
+ ((((gace->aceMask & ACE4_MASK_WRITE) == 0)
+ && ((gace->aceMask & ACE4_MASK_APPEND) != 0))
+ ||
+ (((gace->aceMask & ACE4_MASK_WRITE) != 0)
+ && ((gace->aceMask & ACE4_MASK_APPEND) == 0)))
+ &&
+ lp_parm_bool(fsp->conn->params->service, "gpfs",
+ "merge_writeappend", True)) {
+ DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
+ "WRITE^APPEND, setting WRITE|APPEND\n",
+ fsp->fsp_name));
+ gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
+ }
+
gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0;
-
+
if (aceprop->flags&SMB_ACE4_ID_SPECIAL)
{
switch(aceprop->who.special_id)
@@ -347,7 +370,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i
struct gpfs_acl *acl;
NTSTATUS result = NT_STATUS_ACCESS_DENIED;
- acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
+ acl = gpfs_getacl_alloc(fsp->fsp_name, 0);
if (acl == NULL)
return result;
@@ -628,75 +651,225 @@ int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
return -1;
}
+/*
+ * Assumed: mode bits are shiftable and standard
+ * Output: the new aceMask field for an smb nfs4 ace
+ */
+static uint32 gpfsacl_mask_filter(uint32 aceType, uint32 aceMask, uint32 rwx)
+{
+ const uint32 posix_nfs4map[3] = {
+ SMB_ACE4_EXECUTE, /* execute */
+ SMB_ACE4_WRITE_DATA | SMB_ACE4_APPEND_DATA, /* write; GPFS specific */
+ SMB_ACE4_READ_DATA /* read */
+ };
+ int i;
+ uint32_t posix_mask = 0x01;
+ uint32_t posix_bit;
+ uint32_t nfs4_bits;
+
+ for(i=0; i<3; i++) {
+ nfs4_bits = posix_nfs4map[i];
+ posix_bit = rwx & posix_mask;
+
+ if (aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) {
+ if (posix_bit)
+ aceMask |= nfs4_bits;
+ else
+ aceMask &= ~nfs4_bits;
+ } else {
+ /* add deny bits when suitable */
+ if (!posix_bit)
+ aceMask |= nfs4_bits;
+ else
+ aceMask &= ~nfs4_bits;
+ } /* other ace types are unexpected */
+
+ posix_mask <<= 1;
+ }
+
+ return aceMask;
+}
+
+static int gpfsacl_emu_chmod(const char *path, mode_t mode)
+{
+ SMB4ACL_T *pacl = NULL;
+ int result;
+ bool haveAllowEntry[SMB_ACE4_WHO_EVERYONE + 1] = {False, False, False, False};
+ int i;
+ files_struct fake_fsp; /* TODO: rationalize parametrization */
+ SMB4ACE_T *smbace;
+
+ DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode));
+
+ result = gpfs_get_nfs4_acl(path, &pacl);
+ if (result)
+ return result;
+
+ if (mode & ~(S_IRWXU | S_IRWXG | S_IRWXO)) {
+ DEBUG(2, ("WARNING: cutting extra mode bits %o on %s\n", mode, path));
+ }
+
+ for (smbace=smb_first_ace4(pacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) {
+ SMB_ACE4PROP_T *ace = smb_get_ace4(smbace);
+ uint32_t specid = ace->who.special_id;
+
+ if (ace->flags&SMB_ACE4_ID_SPECIAL &&
+ ace->aceType<=SMB_ACE4_ACCESS_DENIED_ACE_TYPE &&
+ specid <= SMB_ACE4_WHO_EVERYONE) {
+
+ uint32_t newMask;
+
+ if (ace->aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE)
+ haveAllowEntry[specid] = True;
+
+ /* mode >> 6 for @owner, mode >> 3 for @group,
+ * mode >> 0 for @everyone */
+ newMask = gpfsacl_mask_filter(ace->aceType, ace->aceMask,
+ mode >> ((SMB_ACE4_WHO_EVERYONE - specid) * 3));
+ if (ace->aceMask!=newMask) {
+ DEBUG(10, ("ace changed for %s (%o -> %o) id=%d\n",
+ path, ace->aceMask, newMask, specid));
+ }
+ ace->aceMask = newMask;
+ }
+ }
+
+ /* make sure we have at least ALLOW entries
+ * for all the 3 special ids (@EVERYONE, @OWNER, @GROUP)
+ * - if necessary
+ */
+ for(i = SMB_ACE4_WHO_OWNER; i<=SMB_ACE4_WHO_EVERYONE; i++) {
+ SMB_ACE4PROP_T ace;
+
+ if (haveAllowEntry[i]==True)
+ continue;
+
+ memset(&ace, 0, sizeof(SMB_ACE4PROP_T));
+ ace.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE;
+ ace.flags |= SMB_ACE4_ID_SPECIAL;
+ ace.who.special_id = i;
+
+ if (i==SMB_ACE4_WHO_GROUP) /* not sure it's necessary... */
+ ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
+
+ ace.aceMask = gpfsacl_mask_filter(ace.aceType, ace.aceMask,
+ mode >> ((SMB_ACE4_WHO_EVERYONE - i) * 3));
+
+ /* don't add unnecessary aces */
+ if (!ace.aceMask)
+ continue;
+
+ /* we add it to the END - as windows expects allow aces */
+ smb_add_ace4(pacl, &ace);
+ DEBUG(10, ("Added ALLOW ace for %s, mode=%o, id=%d, aceMask=%x\n",
+ path, mode, i, ace.aceMask));
+ }
+
+ /* don't add complementary DENY ACEs here */
+ memset(&fake_fsp, 0, sizeof(struct files_struct));
+ fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */
+
+ /* put the acl */
+ if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False)
+ return -1;
+ return 0; /* ok for [f]chmod */
+}
+
static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
{
SMB_STRUCT_STAT st;
+ int rc;
+
if (SMB_VFS_NEXT_STAT(handle, path, &st) != 0) {
- return -1;
+ return -1;
}
+
/* avoid chmod() if possible, to preserve acls */
if ((st.st_mode & ~S_IFMT) == mode) {
- return 0;
+ return 0;
}
- return SMB_VFS_NEXT_CHMOD(handle, path, mode);
+
+ rc = gpfsacl_emu_chmod(path, mode);
+ if (rc == 1)
+ return SMB_VFS_NEXT_CHMOD(handle, path, mode);
+ return rc;
}
static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
{
SMB_STRUCT_STAT st;
+ int rc;
+
if (SMB_VFS_NEXT_FSTAT(handle, fsp, &st) != 0) {
- return -1;
+ return -1;
}
+
/* avoid chmod() if possible, to preserve acls */
if ((st.st_mode & ~S_IFMT) == mode) {
- return 0;
+ return 0;
}
- return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
+
+ rc = gpfsacl_emu_chmod(fsp->fsp_name, mode);
+ if (rc == 1)
+ return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
+ return rc;
}
/* VFS operations structure */
static vfs_op_tuple gpfs_op_tuples[] = {
-
- { SMB_VFS_OP(vfs_gpfs_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK,
- SMB_VFS_LAYER_OPAQUE },
-
- { SMB_VFS_OP(vfs_gpfs_setlease), SMB_VFS_OP_LINUX_SETLEASE,
- SMB_VFS_LAYER_OPAQUE },
-
- { SMB_VFS_OP(gpfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_set_nt_acl), SMB_VFS_OP_SET_NT_ACL,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(gpfsacl_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD,
- SMB_VFS_LAYER_TRANSPARENT },
-
+
+ { SMB_VFS_OP(vfs_gpfs_kernel_flock),
+ SMB_VFS_OP_KERNEL_FLOCK,
+ SMB_VFS_LAYER_OPAQUE },
+
+ { SMB_VFS_OP(vfs_gpfs_setlease),
+ SMB_VFS_OP_LINUX_SETLEASE,
+ SMB_VFS_LAYER_OPAQUE },
+
+ { SMB_VFS_OP(gpfsacl_fget_nt_acl),
+ SMB_VFS_OP_FGET_NT_ACL,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_get_nt_acl),
+ SMB_VFS_OP_GET_NT_ACL,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_fset_nt_acl),
+ SMB_VFS_OP_FSET_NT_ACL,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_set_nt_acl),
+ SMB_VFS_OP_SET_NT_ACL,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_sys_acl_get_file),
+ SMB_VFS_OP_SYS_ACL_GET_FILE,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_sys_acl_get_fd),
+ SMB_VFS_OP_SYS_ACL_GET_FD,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_sys_acl_set_file),
+ SMB_VFS_OP_SYS_ACL_SET_FILE,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(gpfsacl_sys_acl_set_fd),
+ SMB_VFS_OP_SYS_ACL_SET_FD,
+ SMB_VFS_LAYER_TRANSPARENT },
+
{ SMB_VFS_OP(gpfsacl_sys_acl_delete_def_file),
- SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(vfs_gpfs_chmod), SMB_VFS_OP_CHMOD,
- SMB_VFS_LAYER_TRANSPARENT },
-
- { SMB_VFS_OP(vfs_gpfs_fchmod), SMB_VFS_OP_FCHMOD,
- SMB_VFS_LAYER_TRANSPARENT },
+ SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(vfs_gpfs_chmod),
+ SMB_VFS_OP_CHMOD,
+ SMB_VFS_LAYER_TRANSPARENT },
+
+ { SMB_VFS_OP(vfs_gpfs_fchmod),
+ SMB_VFS_OP_FCHMOD,
+ SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP }
diff --git a/source3/modules/vfs_gpfs.h b/source3/modules/vfs_gpfs.h
new file mode 100644
index 0000000000..3c499b0850
--- /dev/null
+++ b/source3/modules/vfs_gpfs.h
@@ -0,0 +1,32 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap gpfs calls in vfs functions.
+
+ Copyright (C) Christian Ambach <cambach1@de.ibm.com> 2006
+
+ Major code contributions by Chetan Shringarpure <chetan.sh@in.ibm.com>
+ and Gomati Mohanan <gomati.mohanan@in.ibm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+*/
+
+bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
+ uint32 share_access);
+int set_gpfs_lease(int fd, int leasetype);
+int smbd_gpfs_getacl(char *pathname, int flags, void *acl);
+int smbd_gpfs_putacl(char *pathname, int flags, void *acl);
+void init_gpfs(void);
diff --git a/source3/modules/vfs_prealloc.c b/source3/modules/vfs_prealloc.c
index 2d64bc0184..cb3508dc30 100644
--- a/source3/modules/vfs_prealloc.c
+++ b/source3/modules/vfs_prealloc.c
@@ -47,11 +47,16 @@
#define lock_type struct flock64
#endif
+#ifdef HAVE_GPFS
+#include "gpfs_gpl.h"
+#endif
+
#define MODULE "prealloc"
static int module_debug;
static int preallocate_space(int fd, SMB_OFF_T size)
{
+#ifndef HAVE_GPFS
lock_type fl = {0};
int err;
@@ -78,6 +83,9 @@ static int preallocate_space(int fd, SMB_OFF_T size)
err = -1;
errno = ENOSYS;
#endif
+#else /* GPFS uses completely different interface */
+ err = gpfs_prealloc(fd, (gpfs_off64_t)0, (gpfs_off64_t)size);
+#endif
if (err) {
DEBUG(module_debug,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
new file mode 100644
index 0000000000..ddbc5aab18
--- /dev/null
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -0,0 +1,637 @@
+/*
+ * implementation of an Shadow Copy module - version 2
+ *
+ * Copyright (C) Andrew Tridgell 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/*
+
+ This is a 2nd implemetation of a shadow copy module for exposing
+ snapshots to windows clients as shadow copies. This version has the
+ following features:
+
+ 1) you don't need to populate your shares with symlinks to the
+ snapshots. This can be very important when you have thousands of
+ shares, or use [homes]
+
+ 2) the inode number of the files is altered so it is different
+ from the original. This allows the 'restore' button to work
+ without a sharing violation
+
+ Module options:
+
+ shadow:snapdir = <directory where snapshots are kept>
+
+ This is the directory containing the @GMT-* snapshot directories. If it is an absolute
+ path it is used as-is. If it is a relative path, then it is taken relative to the mount
+ point of the filesystem that the root of this share is on
+
+ shadow:basedir = <base directory that snapshots are from>
+
+ This is an optional parameter that specifies the directory that
+ the snapshots are relative to. It defaults to the filesystem
+ mount point
+
+ shadow:fixinodes = yes/no
+
+ If you enable shadow:fixinodes then this module will modify the
+ apparent inode number of files in the snapshot directories using
+ a hash of the files path. This is needed for snapshot systems
+ where the snapshots have the same device:inode number as the
+ original files (such as happens with GPFS snapshots). If you
+ don't set this option then the 'restore' button in the shadow
+ copy UI will fail with a sharing violation.
+
+ Note that the directory names in the snapshot directory must take the form
+ @GMT-YYYY.MM.DD-HH.MM.SS
+
+ The following command would generate a correctly formatted directory name:
+ date -u +@GMT-%Y.%m.%d-%H.%M.%S
+
+ */
+
+static int vfs_shadow_copy2_debug_level = DBGC_VFS;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS vfs_shadow_copy2_debug_level
+
+#define GMT_NAME_LEN 24 /* length of a @GMT- name */
+
+/*
+ make very sure it is one of our special names
+ */
+static inline bool shadow_copy2_match_name(const char *name)
+{
+ unsigned year, month, day, hr, min, sec;
+ if (name[0] != '@') return False;
+ if (strncmp(name, "@GMT-", 5) != 0) return False;
+ if (sscanf(name, "@GMT-%04u.%02u.%02u-%02u.%02u.%02u", &year, &month,
+ &day, &hr, &min, &sec) != 6) {
+ return False;
+ }
+ if (name[24] != 0 && name[24] != '/') {
+ return False;
+ }
+ return True;
+}
+
+/*
+ convert a name to the shadow directory
+ */
+
+#define _SHADOW2_NEXT(op, args, rtype, eret, extra) do { \
+ const char *name = fname; \
+ if (shadow_copy2_match_name(fname)) { \
+ char *name2; \
+ rtype ret; \
+ name2 = convert_shadow2_name(handle, fname); \
+ if (name2 == NULL) { \
+ errno = EINVAL; \
+ return eret; \
+ } \
+ name = name2; \
+ ret = SMB_VFS_NEXT_ ## op args; \
+ talloc_free(name2); \
+ if (ret != eret) extra; \
+ return ret; \
+ } else { \
+ return SMB_VFS_NEXT_ ## op args; \
+ } \
+} while (0)
+
+/*
+ convert a name to the shadow directory: NTSTATUS-specific handling
+ */
+
+#define _SHADOW2_NTSTATUS_NEXT(op, args, eret, extra) do { \
+ const char *name = fname; \
+ if (shadow_copy2_match_name(fname)) { \
+ char *name2; \
+ NTSTATUS ret; \
+ name2 = convert_shadow2_name(handle, fname); \
+ if (name2 == NULL) { \
+ errno = EINVAL; \
+ return eret; \
+ } \
+ name = name2; \
+ ret = SMB_VFS_NEXT_ ## op args; \
+ talloc_free(name2); \
+ if (!NT_STATUS_EQUAL(ret, eret)) extra; \
+ return ret; \
+ } else { \
+ return SMB_VFS_NEXT_ ## op args; \
+ } \
+} while (0)
+
+#define SHADOW2_NTSTATUS_NEXT(op, args, eret) _SHADOW2_NTSTATUS_NEXT(op, args, eret, )
+
+#define SHADOW2_NEXT(op, args, rtype, eret) _SHADOW2_NEXT(op, args, rtype, eret, )
+
+#define SHADOW2_NEXT2(op, args) do { \
+ if (shadow_copy2_match_name(oldname) || shadow_copy2_match_name(newname)) { \
+ errno = EROFS; \
+ return -1; \
+ } else { \
+ return SMB_VFS_NEXT_ ## op args; \
+ } \
+} while (0)
+
+
+/*
+ find the mount point of a filesystem
+ */
+static char *find_mount_point(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
+{
+ char *path = talloc_strdup(mem_ctx, handle->conn->connectpath);
+ dev_t dev;
+ struct stat st;
+ char *p;
+
+ if (stat(path, &st) != 0) {
+ talloc_free(path);
+ return NULL;
+ }
+
+ dev = st.st_dev;
+
+ while ((p = strrchr(path, '/')) && p > path) {
+ *p = 0;
+ if (stat(path, &st) != 0) {
+ talloc_free(path);
+ return NULL;
+ }
+ if (st.st_dev != dev) {
+ *p = '/';
+ break;
+ }
+ }
+
+ return path;
+}
+
+/*
+ work out the location of the snapshot for this share
+ */
+static const char *shadow_copy2_find_snapdir(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
+{
+ const char *snapdir;
+ char *mount_point;
+ const char *ret;
+
+ snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir", NULL);
+ if (snapdir == NULL) {
+ return NULL;
+ }
+ /* if its an absolute path, we're done */
+ if (*snapdir == '/') {
+ return snapdir;
+ }
+
+ /* other its relative to the filesystem mount point */
+ mount_point = find_mount_point(mem_ctx, handle);
+ if (mount_point == NULL) {
+ return NULL;
+ }
+
+ ret = talloc_asprintf(mem_ctx, "%s/%s", mount_point, snapdir);
+ talloc_free(mount_point);
+ return ret;
+}
+
+/*
+ work out the location of the base directory for snapshots of this share
+ */
+static const char *shadow_copy2_find_basedir(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
+{
+ const char *basedir = lp_parm_const_string(SNUM(handle->conn), "shadow", "basedir", NULL);
+
+ /* other its the filesystem mount point */
+ if (basedir == NULL) {
+ basedir = find_mount_point(mem_ctx, handle);
+ }
+
+ return basedir;
+}
+
+/*
+ convert a filename from a share relative path, to a path in the
+ snapshot directory
+ */
+static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
+ const char *snapdir, *relpath, *baseoffset, *basedir;
+ size_t baselen;
+ char *ret;
+
+ snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
+ if (snapdir == NULL) {
+ DEBUG(2,("no snapdir found for share at %s\n", handle->conn->connectpath));
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+
+ basedir = shadow_copy2_find_basedir(tmp_ctx, handle);
+ if (basedir == NULL) {
+ DEBUG(2,("no basedir found for share at %s\n", handle->conn->connectpath));
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+
+ relpath = fname + GMT_NAME_LEN;
+ baselen = strlen(basedir);
+ baseoffset = handle->conn->connectpath + baselen;
+
+ /* some sanity checks */
+ if (strncmp(basedir, handle->conn->connectpath, baselen) != 0 ||
+ (handle->conn->connectpath[baselen] != 0 && handle->conn->connectpath[baselen] != '/')) {
+ DEBUG(0,("convert_shadow2_name: basedir %s is not a parent of %s\n",
+ basedir, handle->conn->connectpath));
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+
+ if (*relpath == '/') relpath++;
+ if (*baseoffset == '/') baseoffset++;
+
+ ret = talloc_asprintf(handle->data, "%s/%.*s/%s/%s",
+ snapdir,
+ GMT_NAME_LEN, fname,
+ baseoffset,
+ relpath);
+ DEBUG(6,("convert_shadow2_name: '%s' -> '%s'\n", fname, ret));
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
+/*
+ simple string hash
+ */
+static uint32 string_hash(const char *s)
+{
+ uint32 n = 0;
+ while (*s) {
+ n = ((n << 5) + n) ^ (uint32)(*s++);
+ }
+ return n;
+}
+
+/*
+ modify a sbuf return to ensure that inodes in the shadow directory
+ are different from those in the main directory
+ */
+static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ if (lp_parm_bool(SNUM(handle->conn), "shadow", "fixinodes", False)) {
+ /* some snapshot systems, like GPFS, return the name
+ device:inode for the snapshot files as the current
+ files. That breaks the 'restore' button in the shadow copy
+ GUI, as the client gets a sharing violation.
+
+ This is a crude way of allowing both files to be
+ open at once. It has a slight chance of inode
+ number collision, but I can't see a better approach
+ without significant VFS changes
+ */
+ uint32_t shash = string_hash(fname) & 0xFF000000;
+ if (shash == 0) {
+ shash = 1;
+ }
+ sbuf->st_ino ^= shash;
+ }
+}
+
+static int shadow_copy2_rename(vfs_handle_struct *handle,
+ const char *oldname, const char *newname)
+{
+ SHADOW2_NEXT2(RENAME, (handle, oldname, newname));
+}
+
+static int shadow_copy2_symlink(vfs_handle_struct *handle,
+ const char *oldname, const char *newname)
+{
+ SHADOW2_NEXT2(SYMLINK, (handle, oldname, newname));
+}
+
+static int shadow_copy2_link(vfs_handle_struct *handle,
+ const char *oldname, const char *newname)
+{
+ SHADOW2_NEXT2(LINK, (handle, oldname, newname));
+}
+
+static int shadow_copy2_open(vfs_handle_struct *handle,
+ const char *fname, files_struct *fsp, int flags, mode_t mode)
+{
+ SHADOW2_NEXT(OPEN, (handle, name, fsp, flags, mode), int, -1);
+}
+
+static SMB_STRUCT_DIR *shadow_copy2_opendir(vfs_handle_struct *handle,
+ const char *fname, const char *mask, uint32 attr)
+{
+ SHADOW2_NEXT(OPENDIR, (handle, name, mask, attr), SMB_STRUCT_DIR *, NULL);
+}
+
+static int shadow_copy2_stat(vfs_handle_struct *handle,
+ const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ _SHADOW2_NEXT(STAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
+}
+
+static int shadow_copy2_lstat(vfs_handle_struct *handle,
+ const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ _SHADOW2_NEXT(LSTAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
+}
+
+static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
+{
+ int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+ if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
+ convert_sbuf(handle, fsp->fsp_name, sbuf);
+ }
+ return ret;
+}
+
+static int shadow_copy2_unlink(vfs_handle_struct *handle, const char *fname)
+{
+ SHADOW2_NEXT(UNLINK, (handle, name), int, -1);
+}
+
+static int shadow_copy2_chmod(vfs_handle_struct *handle,
+ const char *fname, mode_t mode)
+{
+ SHADOW2_NEXT(CHMOD, (handle, name, mode), int, -1);
+}
+
+static int shadow_copy2_chown(vfs_handle_struct *handle,
+ const char *fname, uid_t uid, gid_t gid)
+{
+ SHADOW2_NEXT(CHOWN, (handle, name, uid, gid), int, -1);
+}
+
+static int shadow_copy2_chdir(vfs_handle_struct *handle,
+ const char *fname)
+{
+ SHADOW2_NEXT(CHDIR, (handle, name), int, -1);
+}
+
+static int shadow_copy2_ntimes(vfs_handle_struct *handle,
+ const char *fname, const struct timespec ts[2])
+{
+ SHADOW2_NEXT(NTIMES, (handle, name, ts), int, -1);
+}
+
+static int shadow_copy2_readlink(vfs_handle_struct *handle,
+ const char *fname, char *buf, size_t bufsiz)
+{
+ SHADOW2_NEXT(READLINK, (handle, name, buf, bufsiz), int, -1);
+}
+
+static int shadow_copy2_mknod(vfs_handle_struct *handle,
+ const char *fname, mode_t mode, SMB_DEV_T dev)
+{
+ SHADOW2_NEXT(MKNOD, (handle, name, mode, dev), int, -1);
+}
+
+static char *shadow_copy2_realpath(vfs_handle_struct *handle,
+ const char *fname, char *resolved_path)
+{
+ SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, NULL);
+}
+
+static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
+ const char *fname, uint32 security_info,
+ struct security_descriptor **ppdesc)
+{
+ SHADOW2_NTSTATUS_NEXT(GET_NT_ACL, (handle, name, security_info, ppdesc), NT_STATUS_ACCESS_DENIED);
+}
+
+static NTSTATUS shadow_copy2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ const char *fname, uint32 security_info_sent,
+ struct security_descriptor *psd)
+{
+ SHADOW2_NTSTATUS_NEXT(SET_NT_ACL, (handle, fsp, name, security_info_sent, psd), NT_STATUS_ACCESS_DENIED);
+}
+
+static int shadow_copy2_mkdir(vfs_handle_struct *handle, const char *fname, mode_t mode)
+{
+ SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1);
+}
+
+static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname)
+{
+ SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
+}
+
+static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags)
+{
+ SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
+}
+
+static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
+ const char *fname, const char *aname, void *value, size_t size)
+{
+ SHADOW2_NEXT(GETXATTR, (handle, name, aname, value, size), ssize_t, -1);
+}
+
+static ssize_t shadow_copy2_lgetxattr(vfs_handle_struct *handle,
+ const char *fname, const char *aname, void *value, size_t size)
+{
+ SHADOW2_NEXT(LGETXATTR, (handle, name, aname, value, size), ssize_t, -1);
+}
+
+static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle, const char *fname,
+ char *list, size_t size)
+{
+ SHADOW2_NEXT(LISTXATTR, (handle, name, list, size), ssize_t, -1);
+}
+
+static int shadow_copy2_removexattr(struct vfs_handle_struct *handle, const char *fname,
+ const char *aname)
+{
+ SHADOW2_NEXT(REMOVEXATTR, (handle, name, aname), int, -1);
+}
+
+static int shadow_copy2_lremovexattr(struct vfs_handle_struct *handle, const char *fname,
+ const char *aname)
+{
+ SHADOW2_NEXT(LREMOVEXATTR, (handle, name, aname), int, -1);
+}
+
+static int shadow_copy2_setxattr(struct vfs_handle_struct *handle, const char *fname,
+ const char *aname, const void *value, size_t size, int flags)
+{
+ SHADOW2_NEXT(SETXATTR, (handle, name, aname, value, size, flags), int, -1);
+}
+
+static int shadow_copy2_lsetxattr(struct vfs_handle_struct *handle, const char *fname,
+ const char *aname, const void *value, size_t size, int flags)
+{
+ SHADOW2_NEXT(LSETXATTR, (handle, name, aname, value, size, flags), int, -1);
+}
+
+static int shadow_copy2_chmod_acl(vfs_handle_struct *handle,
+ const char *fname, mode_t mode)
+{
+ /* If the underlying VFS doesn't have ACL support... */
+ if (!handle->vfs_next.ops.chmod_acl) {
+ errno = ENOSYS;
+ return -1;
+ }
+ SHADOW2_NEXT(CHMOD_ACL, (handle, name, mode), int, -1);
+}
+
+static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SHADOW_COPY_DATA *shadow_copy2_data,
+ bool labels)
+{
+ SMB_STRUCT_DIR *p;
+ const char *snapdir;
+ SMB_STRUCT_DIRENT *d;
+ TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
+
+ snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
+ if (snapdir == NULL) {
+ DEBUG(0,("shadow:snapdir not found for %s in get_shadow_copy_data\n",
+ handle->conn->connectpath));
+ errno = EINVAL;
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+
+ p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0);
+
+ if (!p) {
+ DEBUG(0,("shadow_copy2: SMB_VFS_NEXT_OPENDIR() failed for '%s' - %s\n",
+ snapdir, strerror(errno)));
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+
+ talloc_free(tmp_ctx);
+
+ shadow_copy2_data->num_volumes = 0;
+ shadow_copy2_data->labels = NULL;
+
+ while ((d = SMB_VFS_NEXT_READDIR(handle, p))) {
+ SHADOW_COPY_LABEL *tlabels;
+
+ /* ignore names not of the right form in the snapshot directory */
+ if (!shadow_copy2_match_name(d->d_name)) {
+ continue;
+ }
+
+ if (!labels) {
+ /* the caller doesn't want the labels */
+ shadow_copy2_data->num_volumes++;
+ continue;
+ }
+
+ tlabels = talloc_realloc(shadow_copy2_data->mem_ctx,
+ shadow_copy2_data->labels,
+ SHADOW_COPY_LABEL, shadow_copy2_data->num_volumes+1);
+ if (tlabels == NULL) {
+ DEBUG(0,("shadow_copy2: out of memory\n"));
+ SMB_VFS_NEXT_CLOSEDIR(handle, p);
+ return -1;
+ }
+
+ strlcpy(tlabels[shadow_copy2_data->num_volumes], d->d_name, sizeof(*tlabels));
+ shadow_copy2_data->num_volumes++;
+ shadow_copy2_data->labels = tlabels;
+ }
+
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
+ return 0;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple shadow_copy2_ops[] = {
+ {SMB_VFS_OP(shadow_copy2_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* directory operations */
+ {SMB_VFS_OP(shadow_copy2_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* xattr and flags operations */
+ {SMB_VFS_OP(shadow_copy2_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_lremovexattr),SMB_VFS_OP_LREMOVEXATTR,SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* File operations */
+ {SMB_VFS_OP(shadow_copy2_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* NT File ACL operations */
+ {SMB_VFS_OP(shadow_copy2_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(shadow_copy2_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* POSIX ACL operations */
+ {SMB_VFS_OP(shadow_copy2_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* special shadown copy op */
+ {SMB_VFS_OP(shadow_copy2_get_shadow_copy2_data),
+ SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_shadow_copy2_init(void);
+NTSTATUS vfs_shadow_copy2_init(void)
+{
+ NTSTATUS ret;
+
+ ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy2", shadow_copy2_ops);
+
+ if (!NT_STATUS_IS_OK(ret))
+ return ret;
+
+ vfs_shadow_copy2_debug_level = debug_add_class("shadow_copy2");
+ if (vfs_shadow_copy2_debug_level == -1) {
+ vfs_shadow_copy2_debug_level = DBGC_VFS;
+ DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
+ "vfs_shadow_copy2_init"));
+ } else {
+ DEBUG(10, ("%s: Debug class number of '%s': %d\n",
+ "vfs_shadow_copy2_init","shadow_copy2",vfs_shadow_copy2_debug_level));
+ }
+
+ return ret;
+}
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
new file mode 100644
index 0000000000..fe791b24bf
--- /dev/null
+++ b/source3/modules/vfs_tsmsm.c
@@ -0,0 +1,338 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba VFS module for handling offline files
+ with Tivoli Storage Manager Space Management
+
+ (c) Alexander Bokovoy, 2007
+ (c) Andrew Tridgell, 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ This VFS module accepts following options:
+ tsmsm: hsm script = <path to hsm script> (/bin/true by default, i.e. does nothing)
+ hsm script should point to a shell script which accepts two arguments:
+ <operation> <filepath>
+ where <operation> is currently 'offline' to set offline status of the <filepath>
+
+ tsmsm: online ratio = ratio to check reported size against actual file size (0.5 by default)
+
+ The TSMSM VFS module tries to avoid calling expensive DMAPI calls with some heuristics
+ based on the fact that number of blocks reported of a file multiplied by 512 will be
+ bigger than 'online ratio' of actual size for online (non-migrated) files.
+
+ If checks fail, we call DMAPI and ask for specific IBM attribute which present for
+ offline (migrated) files. If this attribute presents, we consider file offline.
+ */
+
+#include "includes.h"
+
+#ifndef USE_DMAPI
+#error "This module requires DMAPI support!"
+#endif
+
+#ifdef HAVE_XFS_DMAPI_H
+#include <xfs/dmapi.h>
+#elif defined(HAVE_SYS_DMI_H)
+#include <sys/dmi.h>
+#elif defined(HAVE_SYS_JFSDMAPI_H)
+#include <sys/jfsdmapi.h>
+#elif defined(HAVE_SYS_DMAPI_H)
+#include <sys/dmapi.h>
+#elif defined(HAVE_DMAPI_H)
+#include <dmapi.h>
+#endif
+
+#ifndef _ISOC99_SOURCE
+#define _ISOC99_SOURCE
+#endif
+
+#include <math.h>
+
+/* optimisation tunables - used to avoid the DMAPI slow path */
+#define FILE_IS_ONLINE_RATIO 0.5
+#define DM_ATTRIB_OBJECT "IBMObj"
+#define DM_ATTRIB_MIGRATED "IBMMig"
+
+struct tsmsm_struct {
+ dm_sessid_t sid;
+ float online_ratio;
+ char *hsmscript;
+};
+
+#define TSM_STRINGIFY(a) #a
+#define TSM_TOSTRING(a) TSM_STRINGIFY(a)
+
+static void tsmsm_free_data(void **pptr) {
+ struct tsmsm_struct **tsmd = (struct tsmsm_struct **)pptr;
+ if(!tsmd) return;
+ TALLOC_FREE(*tsmd);
+}
+
+static int tsmsm_connect(struct vfs_handle_struct *handle,
+ const char *service,
+ const char *user) {
+ struct tsmsm_struct *tsmd = TALLOC_ZERO_P(handle, struct tsmsm_struct);
+ const char *hsmscript, *tsmname;
+ const char *fres;
+
+ if (!tsmd) {
+ DEBUG(0,("tsmsm_connect: out of memory!\n"));
+ return -1;
+ }
+
+ tsmd->sid = *(dm_sessid_t*) dmapi_get_current_session();
+
+ if (tsmd->sid == DM_NO_SESSION) {
+ DEBUG(0,("tsmsm_connect: no DMAPI session for Samba is available!\n"));
+ TALLOC_FREE(tsmd);
+ return -1;
+ }
+
+ tsmname = (handle->param ? handle->param : "tsmsm");
+ hsmscript = lp_parm_const_string(SNUM(handle->conn), tsmname,
+ "hsm script", NULL);
+ if (hsmscript) {
+ tsmd->hsmscript = talloc_strdup(tsmd, hsmscript);
+ if(!tsmd->hsmscript) {
+ DEBUG(1, ("tsmsm_connect: can't allocate memory for hsm script path"));
+ TALLOC_FREE(tsmd);
+ return -1;
+ }
+ } else {
+ DEBUG(1, ("tsmsm_connect: can't call hsm script because it "
+ "is not set to anything in the smb.conf\n"
+ "Use %s: 'hsm script = path' to set it\n",
+ tsmname));
+ TALLOC_FREE(tsmd);
+ return -1;
+ }
+
+ fres = lp_parm_const_string(SNUM(handle->conn), tsmname,
+ "online ratio", TSM_TOSTRING(FILE_IS_ONLINE_RATIO));
+ tsmd->online_ratio = strtof(fres, NULL);
+ if((tsmd->online_ratio == (float)0) || ((errno == ERANGE) &&
+ ((tsmd->online_ratio == HUGE_VALF) ||
+ (tsmd->online_ratio == HUGE_VALL)))) {
+ DEBUG(1, ("tsmsm_connect: error while getting online ratio from smb.conf."
+ "Default to %s.\n", TSM_TOSTRING(FILE_IS_ONLINE_RATIO)));
+ tsmd->online_ratio = FILE_IS_ONLINE_RATIO;
+ }
+
+ /* Store the private data. */
+ SMB_VFS_HANDLE_SET_DATA(handle, tsmd, tsmsm_free_data,
+ struct tsmsm_struct, return -1);
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
+
+static int tsmsm_is_offline(struct vfs_handle_struct *handle,
+ struct connection_struct *conn,
+ const char *path,
+ SMB_STRUCT_STAT *stbuf,
+ bool *offline) {
+ struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
+ void *dmhandle = NULL;
+ size_t dmhandle_len = 0;
+ size_t rlen;
+ dm_attrname_t dmname;
+ int ret;
+
+ /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
+ then assume it is not offline (it may not be 100%, as it could be sparse) */
+ if (512 * (off_t)stbuf->st_blocks >= stbuf->st_size * tsmd->online_ratio) {
+ *offline = false;
+ DEBUG(10,("%s not offline: st_blocks=%ld st_size=%ld online_ratio=%.2f\n",
+ path, stbuf->st_blocks, stbuf->st_size, tsmd->online_ratio));
+ return 0;
+ }
+
+ /* using POSIX capabilities does not work here. It's a slow path, so
+ * become_root() is just as good anyway (tridge)
+ */
+
+ /* Also, AIX has DMAPI but no POSIX capablities support. In this case,
+ * we need to be root to do DMAPI manipulations.
+ */
+ become_root();
+
+ /* go the slow DMAPI route */
+ if (dm_path_to_handle((char*)path, &dmhandle, &dmhandle_len) != 0) {
+ ret = -1;
+ DEBUG(2,("dm_path_to_handle failed - assuming offline (%s) - %s\n",
+ path, strerror(errno)));
+ *offline = True;
+ goto done;
+ }
+
+ memset(&dmname, 0, sizeof(dmname));
+ strlcpy((char *)&dmname.an_chars[0], DM_ATTRIB_OBJECT, sizeof(dmname.an_chars));
+
+ ret = dm_get_dmattr(tsmd->sid, dmhandle, dmhandle_len,
+ DM_NO_TOKEN, &dmname, 0, NULL, &rlen);
+
+ /* its offline if the IBMObj attribute exists */
+ *offline = (ret == 0 || (ret == -1 && errno == E2BIG));
+
+ DEBUG(10,("dm_get_dmattr %s ret=%d (%s)\n", path, ret, strerror(errno)));
+
+ ret = 0;
+
+ dm_handle_free(dmhandle, dmhandle_len);
+
+done:
+ unbecome_root();
+ return ret;
+}
+
+
+static bool tsmsm_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
+ /* see if the file might be offline. This is called before each IO
+ to ensure we use AIO if the file is offline. We don't do the full dmapi
+ call as that would be too slow, instead we err on the side of using AIO
+ if the file might be offline
+ */
+ if(SMB_VFS_FSTAT(fsp, &sbuf) == 0) {
+ DEBUG(10,("tsmsm_aio_force st_blocks=%ld st_size=%ld online_ratio=%.2f\n",
+ sbuf.st_blocks, sbuf.st_size, tsmd->online_ratio));
+ return !(512 * (off_t)sbuf.st_blocks >= sbuf.st_size * tsmd->online_ratio);
+ }
+ return False;
+}
+
+static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp,
+ SMB_STRUCT_AIOCB *aiocb)
+{
+ ssize_t result;
+
+ result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb);
+ if(result >= 0) {
+ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ fsp->fsp_name);
+ }
+
+ return result;
+}
+
+static ssize_t tsmsm_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, const DATA_BLOB *hdr,
+ SMB_OFF_T offset, size_t n)
+{
+ bool file_online = tsmsm_aio_force(handle, fsp);
+
+ if(!file_online)
+ return ENOSYS;
+
+ return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, hdr, offset, n);
+}
+
+/* We do overload pread to allow notification when file becomes online after offline status */
+/* We don't intercept SMB_VFS_READ here because all file I/O now goes through SMB_VFS_PREAD instead */
+static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct *fsp,
+ void *data, size_t n, SMB_OFF_T offset) {
+ ssize_t result;
+ bool notify_online = tsmsm_aio_force(handle, fsp);
+
+ result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+ if((result != -1) && notify_online) {
+ /* We can't actually force AIO at this point (came here not from reply_read_and_X)
+ what we can do is to send notification that file became online
+ */
+ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ fsp->fsp_name);
+ }
+
+ return result;
+}
+
+static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struct *fsp,
+ void *data, size_t n, SMB_OFF_T offset) {
+ ssize_t result;
+ bool notify_online = tsmsm_aio_force(handle, fsp);
+
+ result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+ if((result != -1) && notify_online) {
+ /* We can't actually force AIO at this point (came here not from reply_read_and_X)
+ what we can do is to send notification that file became online
+ */
+ notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ fsp->fsp_name);
+ }
+
+ return result;
+}
+
+static int tsmsm_set_offline(struct vfs_handle_struct *handle, struct connection_struct *conn,
+ const char *path) {
+ struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
+ int result = 0;
+ char *command;
+
+ /* Now, call the script */
+ command = talloc_asprintf(tsmd, "%s offline \"%s\"", tsmd->hsmscript, path);
+ if(!command) {
+ DEBUG(1, ("tsmsm_set_offline: can't allocate memory to run hsm script"));
+ return -1;
+ }
+ DEBUG(10, ("tsmsm_set_offline: Running [%s]\n", command));
+ if((result = smbrun(command, NULL)) != 0) {
+ DEBUG(1,("tsmsm_set_offline: Running [%s] returned %d\n", command, result));
+ }
+ TALLOC_FREE(command);
+ return result;
+}
+
+static bool tsmsm_is_remotestorage(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) {
+ return True;
+}
+
+static vfs_op_tuple vfs_tsmsm_ops[] = {
+
+ /* Disk operations */
+
+ {SMB_VFS_OP(tsmsm_connect), SMB_VFS_OP_CONNECT,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_aio_force), SMB_VFS_OP_AIO_FORCE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_aio_return), SMB_VFS_OP_AIO_RETURN,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_pread), SMB_VFS_OP_PREAD,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_pwrite), SMB_VFS_OP_PWRITE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_sendfile), SMB_VFS_OP_SENDFILE,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(tsmsm_is_offline),SMB_VFS_OP_IS_OFFLINE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(tsmsm_set_offline),SMB_VFS_OP_SET_OFFLINE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(tsmsm_is_remotestorage),SMB_VFS_OP_IS_REMOTESTORAGE,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* Finish VFS operations definition */
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,
+ SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_tsmsm_init(void);
+NTSTATUS vfs_tsmsm_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+ "tsmsm", vfs_tsmsm_ops);
+}
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
new file mode 100644
index 0000000000..29864a8f94
--- /dev/null
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -0,0 +1,737 @@
+/*
+ * Store posix-level xattrs in a tdb
+ *
+ * Copyright (C) Volker Lendecke, 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "librpc/gen_ndr/xattr.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+/*
+ * unmarshall tdb_xattrs
+ */
+
+static NTSTATUS xattr_tdb_pull_attrs(TALLOC_CTX *mem_ctx,
+ const TDB_DATA *data,
+ struct tdb_xattrs **presult)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct tdb_xattrs *result;
+
+ if (!(result = TALLOC_ZERO_P(mem_ctx, struct tdb_xattrs))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (data->dsize == 0) {
+ *presult = result;
+ return NT_STATUS_OK;
+ }
+
+ blob = data_blob_const(data->dptr, data->dsize);
+
+ ndr_err = ndr_pull_struct_blob(
+ &blob, result, result,
+ (ndr_pull_flags_fn_t)ndr_pull_tdb_xattrs);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_pull_tdb_xattrs failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(result);
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *presult = result;
+ return NT_STATUS_OK;
+}
+
+/*
+ * marshall tdb_xattrs
+ */
+
+static NTSTATUS xattr_tdb_push_attrs(TALLOC_CTX *mem_ctx,
+ const struct tdb_xattrs *attribs,
+ TDB_DATA *data)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(
+ &blob, mem_ctx, attribs,
+ (ndr_push_flags_fn_t)ndr_push_tdb_xattrs);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_push_tdb_xattrs failed: %s\n",
+ ndr_errstr(ndr_err)));
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *data = make_tdb_data(blob.data, blob.length);
+ return NT_STATUS_OK;
+}
+
+/*
+ * Load tdb_xattrs for a file from the tdb
+ */
+
+static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx,
+ struct db_context *db_ctx,
+ const struct file_id *id,
+ struct tdb_xattrs **presult)
+{
+ uint8 id_buf[16];
+ NTSTATUS status;
+ TDB_DATA data;
+
+ push_file_id_16((char *)id_buf, id);
+
+ if (db_ctx->fetch(db_ctx, mem_ctx,
+ make_tdb_data(id_buf, sizeof(id_buf)),
+ &data) == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ status = xattr_tdb_pull_attrs(mem_ctx, &data, presult);
+ TALLOC_FREE(data.dptr);
+ return NT_STATUS_OK;
+}
+
+/*
+ * fetch_lock the tdb_ea record for a file
+ */
+
+static struct db_record *xattr_tdb_lock_attrs(TALLOC_CTX *mem_ctx,
+ struct db_context *db_ctx,
+ const struct file_id *id)
+{
+ uint8 id_buf[16];
+ push_file_id_16((char *)id_buf, id);
+ return db_ctx->fetch_locked(db_ctx, mem_ctx,
+ make_tdb_data(id_buf, sizeof(id_buf)));
+}
+
+/*
+ * Save tdb_xattrs to a previously fetch_locked record
+ */
+
+static NTSTATUS xattr_tdb_save_attrs(struct db_record *rec,
+ const struct tdb_xattrs *attribs)
+{
+ TDB_DATA data = tdb_null;
+ NTSTATUS status;
+
+ status = xattr_tdb_push_attrs(talloc_tos(), attribs, &data);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("xattr_tdb_push_attrs failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ status = rec->store(rec, data, 0);
+
+ TALLOC_FREE(data.dptr);
+
+ return status;
+}
+
+/*
+ * Worker routine for getxattr and fgetxattr
+ */
+
+static ssize_t xattr_tdb_getattr(struct db_context *db_ctx,
+ const struct file_id *id,
+ const char *name, void *value, size_t size)
+{
+ struct tdb_xattrs *attribs;
+ uint32_t i;
+ ssize_t result = -1;
+ NTSTATUS status;
+
+ status = xattr_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("xattr_tdb_fetch_attrs failed: %s\n",
+ nt_errstr(status)));
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (i=0; i<attribs->num_xattrs; i++) {
+ if (strcmp(attribs->xattrs[i].name, name) == 0) {
+ break;
+ }
+ }
+
+ if (i == attribs->num_xattrs) {
+ errno = ENOATTR;
+ goto fail;
+ }
+
+ if (attribs->xattrs[i].value.length > size) {
+ errno = ERANGE;
+ goto fail;
+ }
+
+ memcpy(value, attribs->xattrs[i].value.data,
+ attribs->xattrs[i].value.length);
+ result = attribs->xattrs[i].value.length;
+
+ fail:
+ TALLOC_FREE(attribs);
+ return result;
+}
+
+static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle,
+ const char *path, const char *name,
+ void *value, size_t size)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_getattr(db, &id, name, value, size);
+}
+
+static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *name, void *value, size_t size)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_getattr(db, &id, name, value, size);
+}
+
+/*
+ * Worker routine for setxattr and fsetxattr
+ */
+
+static int xattr_tdb_setattr(struct db_context *db_ctx,
+ const struct file_id *id, const char *name,
+ const void *value, size_t size, int flags)
+{
+ NTSTATUS status;
+ struct db_record *rec;
+ struct tdb_xattrs *attribs;
+ uint32_t i;
+
+ rec = xattr_tdb_lock_attrs(talloc_tos(), db_ctx, id);
+
+ if (rec == NULL) {
+ DEBUG(0, ("xattr_tdb_lock_attrs failed\n"));
+ errno = EINVAL;
+ return -1;
+ }
+
+ status = xattr_tdb_pull_attrs(rec, &rec->value, &attribs);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("xattr_tdb_fetch_attrs failed: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(rec);
+ return -1;
+ }
+
+ for (i=0; i<attribs->num_xattrs; i++) {
+ if (strcmp(attribs->xattrs[i].name, name) == 0) {
+ break;
+ }
+ }
+
+ if (i == attribs->num_xattrs) {
+ struct tdb_xattr *tmp;
+
+ tmp = TALLOC_REALLOC_ARRAY(
+ attribs, attribs->xattrs, struct tdb_xattr,
+ attribs->num_xattrs + 1);
+
+ if (tmp == NULL) {
+ DEBUG(0, ("TALLOC_REALLOC_ARRAY failed\n"));
+ TALLOC_FREE(rec);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ attribs->xattrs = tmp;
+ attribs->num_xattrs += 1;
+ }
+
+ attribs->xattrs[i].name = name;
+ attribs->xattrs[i].value.data = CONST_DISCARD(uint8 *, value);
+ attribs->xattrs[i].value.length = size;
+
+ status = xattr_tdb_save_attrs(rec, attribs);
+
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("save failed: %s\n", nt_errstr(status)));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int xattr_tdb_setxattr(struct vfs_handle_struct *handle,
+ const char *path, const char *name,
+ const void *value, size_t size, int flags)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_setattr(db, &id, name, value, size, flags);
+}
+
+static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *name, const void *value,
+ size_t size, int flags)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_setattr(db, &id, name, value, size, flags);
+}
+
+/*
+ * Worker routine for listxattr and flistxattr
+ */
+
+static ssize_t xattr_tdb_listattr(struct db_context *db_ctx,
+ const struct file_id *id, char *list,
+ size_t size)
+{
+ NTSTATUS status;
+ struct tdb_xattrs *attribs;
+ uint32_t i;
+ size_t len = 0;
+
+ status = xattr_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("xattr_tdb_fetch_attrs failed: %s\n",
+ nt_errstr(status)));
+ errno = EINVAL;
+ return -1;
+ }
+
+ DEBUG(10, ("xattr_tdb_listattr: Found %d xattrs\n",
+ attribs->num_xattrs));
+
+ for (i=0; i<attribs->num_xattrs; i++) {
+ size_t tmp;
+
+ DEBUG(10, ("xattr_tdb_listattr: xattrs[i].name: %s\n",
+ attribs->xattrs[i].name));
+
+ tmp = strlen(attribs->xattrs[i].name);
+
+ /*
+ * Try to protect against overflow
+ */
+
+ if (len + (tmp+1) < len) {
+ TALLOC_FREE(attribs);
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Take care of the terminating NULL
+ */
+ len += (tmp + 1);
+ }
+
+ if (len > size) {
+ TALLOC_FREE(attribs);
+ errno = ERANGE;
+ return -1;
+ }
+
+ len = 0;
+
+ for (i=0; i<attribs->num_xattrs; i++) {
+ strlcpy(list+len, attribs->xattrs[i].name,
+ size-len);
+ len += (strlen(attribs->xattrs[i].name) + 1);
+ }
+
+ TALLOC_FREE(attribs);
+ return len;
+}
+
+static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle,
+ const char *path, char *list, size_t size)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_listattr(db, &id, list, size);
+}
+
+static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp, char *list,
+ size_t size)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_listattr(db, &id, list, size);
+}
+
+/*
+ * Worker routine for removexattr and fremovexattr
+ */
+
+static int xattr_tdb_removeattr(struct db_context *db_ctx,
+ const struct file_id *id, const char *name)
+{
+ NTSTATUS status;
+ struct db_record *rec;
+ struct tdb_xattrs *attribs;
+ uint32_t i;
+
+ rec = xattr_tdb_lock_attrs(talloc_tos(), db_ctx, id);
+
+ if (rec == NULL) {
+ DEBUG(0, ("xattr_tdb_lock_attrs failed\n"));
+ errno = EINVAL;
+ return -1;
+ }
+
+ status = xattr_tdb_pull_attrs(rec, &rec->value, &attribs);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("xattr_tdb_fetch_attrs failed: %s\n",
+ nt_errstr(status)));
+ TALLOC_FREE(rec);
+ return -1;
+ }
+
+ for (i=0; i<attribs->num_xattrs; i++) {
+ if (strcmp(attribs->xattrs[i].name, name) == 0) {
+ break;
+ }
+ }
+
+ if (i == attribs->num_xattrs) {
+ TALLOC_FREE(rec);
+ errno = ENOATTR;
+ return -1;
+ }
+
+ attribs->xattrs[i] =
+ attribs->xattrs[attribs->num_xattrs-1];
+ attribs->num_xattrs -= 1;
+
+ if (attribs->num_xattrs == 0) {
+ rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+ return 0;
+ }
+
+ status = xattr_tdb_save_attrs(rec, attribs);
+
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("save failed: %s\n", nt_errstr(status)));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int xattr_tdb_removexattr(struct vfs_handle_struct *handle,
+ const char *path, const char *name)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_removeattr(db, &id, name);
+}
+
+static int xattr_tdb_fremovexattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp, const char *name)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ return xattr_tdb_removeattr(db, &id, name);
+}
+
+/*
+ * Open the tdb file upon VFS_CONNECT
+ */
+
+static bool xattr_tdb_init(int snum, struct db_context **p_db)
+{
+ struct db_context *db;
+ const char *dbname;
+
+ dbname = lp_parm_const_string(snum, "ea", "tdb", lock_path("eas.tdb"));
+
+ if (dbname == NULL) {
+ errno = ENOTSUP;
+ return false;
+ }
+
+ become_root();
+ db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ unbecome_root();
+
+ if (db == NULL) {
+ errno = ENOTSUP;
+ return false;
+ }
+
+ *p_db = db;
+ return true;
+}
+
+/*
+ * On unlink we need to delete the tdb record
+ */
+static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+ struct db_record *rec;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, path);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
+
+ /*
+ * If rec == NULL there's not much we can do about it
+ */
+
+ if (rec != NULL) {
+ rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+ }
+
+ return 0;
+}
+
+/*
+ * On rmdir we need to delete the tdb record
+ */
+static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct file_id id;
+ struct db_context *db;
+ struct db_record *rec;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_RMDIR(handle, path);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+ rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
+
+ /*
+ * If rec == NULL there's not much we can do about it
+ */
+
+ if (rec != NULL) {
+ rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+ }
+
+ return 0;
+}
+
+/*
+ * Destructor for the VFS private data
+ */
+
+static void close_ea_db(void **data)
+{
+ struct db_context **p_db = (struct db_context **)data;
+ TALLOC_FREE(*p_db);
+}
+
+static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service,
+ const char *user)
+{
+ fstring sname;
+ int res, snum;
+ struct db_context *db;
+
+ res = SMB_VFS_NEXT_CONNECT(handle, service, user);
+ if (res < 0) {
+ return res;
+ }
+
+ fstrcpy(sname, service);
+ snum = find_service(sname);
+ if (snum == -1) {
+ /*
+ * Should not happen, but we should not fail just *here*.
+ */
+ return 0;
+ }
+
+ if (!xattr_tdb_init(snum, &db)) {
+ DEBUG(5, ("Could not init ea tdb\n"));
+ lp_do_parameter(snum, "ea support", "False");
+ return 0;
+ }
+
+ lp_do_parameter(snum, "ea support", "True");
+
+ SMB_VFS_HANDLE_SET_DATA(handle, db, close_ea_db,
+ struct db_context, return -1);
+
+ return 0;
+}
+
+/* VFS operations structure */
+
+static const vfs_op_tuple xattr_tdb_ops[] = {
+ {SMB_VFS_OP(xattr_tdb_getxattr), SMB_VFS_OP_GETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_fgetxattr), SMB_VFS_OP_FGETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_setxattr), SMB_VFS_OP_SETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_fsetxattr), SMB_VFS_OP_FSETXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_listxattr), SMB_VFS_OP_LISTXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_flistxattr), SMB_VFS_OP_FLISTXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_removexattr), SMB_VFS_OP_REMOVEXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_fremovexattr), SMB_VFS_OP_FREMOVEXATTR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_unlink), SMB_VFS_OP_UNLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_rmdir), SMB_VFS_OP_RMDIR,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(xattr_tdb_connect), SMB_VFS_OP_CONNECT,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_xattr_tdb_init(void);
+NTSTATUS vfs_xattr_tdb_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "xattr_tdb",
+ xattr_tdb_ops);
+}
diff --git a/source3/nsswitch/libwbclient/wbc_err.h b/source3/nsswitch/libwbclient/wbc_err.h
deleted file mode 100644
index 069f68f189..0000000000
--- a/source3/nsswitch/libwbclient/wbc_err.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind client API
-
- Copyright (C) Gerald (Jerry) Carter 2007
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _WBC_ERR_H
-#define _WBC_ERR_H
-
-
-/* Define error types */
-
-/**
- * @brief Status codes returned from wbc functions
- **/
-
-enum _wbcErrType {
- WBC_ERR_SUCCESS = 0, /**< Successful completion **/
- WBC_ERR_NOT_IMPLEMENTED,/**< Function not implemented **/
- WBC_ERR_UNKNOWN_FAILURE,/**< General failure **/
- WBC_ERR_NO_MEMORY, /**< Memory allocation error **/
- WBC_ERR_INVALID_SID, /**< Invalid SID format **/
- WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/
- WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
- WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
- WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
- WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/
-};
-
-typedef enum _wbcErrType wbcErr;
-
-#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS)
-
-char *wbcErrorString(wbcErr error);
-
-#endif /* _WBC_ERR_H */
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index 6b85d7e8b3..0b256d343f 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -23,7 +23,32 @@
#define _WBCLIENT_H
#include <pwd.h>
-#include <nsswitch/libwbclient/wbc_err.h>
+#include <grp.h>
+
+/* Define error types */
+
+/**
+ * @brief Status codes returned from wbc functions
+ **/
+
+enum _wbcErrType {
+ WBC_ERR_SUCCESS = 0, /**< Successful completion **/
+ WBC_ERR_NOT_IMPLEMENTED,/**< Function not implemented **/
+ WBC_ERR_UNKNOWN_FAILURE,/**< General failure **/
+ WBC_ERR_NO_MEMORY, /**< Memory allocation error **/
+ WBC_ERR_INVALID_SID, /**< Invalid SID format **/
+ WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/
+ WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
+ WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
+ WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
+ WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/
+};
+
+typedef enum _wbcErrType wbcErr;
+
+#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS)
+
+char *wbcErrorString(wbcErr error);
/*
* Data types used by the Winbind Client API
diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h
index 7f0e4b92e0..64d52af771 100644
--- a/source3/nsswitch/winbind_nss_config.h
+++ b/source3/nsswitch/winbind_nss_config.h
@@ -27,6 +27,14 @@
#undef SIZEOF_LONG
#endif
+/*
+ * we don't need socket wrapper
+ * nor nss wrapper here and we don't
+ * want to depend on swrap_close()
+ * so we better disable both
+ */
+#define SOCKET_WRAPPER_NOT_REPLACE
+#define NSS_WRAPPER_NOT_REPLACE
/* Include header files from data in config.h file */
diff --git a/source3/pam_smbpass/pam_smb_acct.c b/source3/pam_smbpass/pam_smb_acct.c
index 59ed4eee8b..b9bcb31091 100644
--- a/source3/pam_smbpass/pam_smb_acct.c
+++ b/source3/pam_smbpass/pam_smb_acct.c
@@ -78,7 +78,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
}
if (geteuid() != 0) {
- _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
return PAM_AUTHINFO_UNAVAIL;
}
diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c
index de5310761f..326a0b59e7 100644
--- a/source3/pam_smbpass/pam_smb_passwd.c
+++ b/source3/pam_smbpass/pam_smb_passwd.c
@@ -130,7 +130,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
if (geteuid() != 0) {
- _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
return PAM_AUTHINFO_UNAVAIL;
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index eaf19b746a..0d3fbbf77c 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -9,6 +9,7 @@
Copyright (C) Alexander Bokovoy 2002
Copyright (C) Stefan (metze) Metzmacher 2002
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Michael Adam 2008
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,16 +71,12 @@ extern userdom_struct current_user_info;
#define HOMES_NAME "homes"
#endif
-/* the special value for the include parameter
- * to be interpreted not as a file name but to
- * trigger loading of the global smb.conf options
- * from registry. */
-#ifndef INCLUDE_REGISTRY_NAME
-#define INCLUDE_REGISTRY_NAME "registry"
-#endif
-
static int regdb_last_seqnum = 0;
-static bool include_registry_globals = False;
+
+#define CONFIG_BACKEND_FILE 0
+#define CONFIG_BACKEND_REGISTRY 1
+
+static int config_backend = CONFIG_BACKEND_FILE;
/* some helpful bits */
#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
@@ -104,6 +101,7 @@ struct _param_opt_struct {
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct {
+ int ConfigBackend;
char *smb_ports;
char *dos_charset;
char *unix_charset;
@@ -842,6 +840,14 @@ static const struct enum_list enum_map_to_guest[] = {
{-1, NULL}
};
+/* Config backend options */
+
+static const struct enum_list enum_config_backend[] = {
+ {CONFIG_BACKEND_FILE, "file"},
+ {CONFIG_BACKEND_REGISTRY, "registry"},
+ {-1, NULL}
+};
+
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
* The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
@@ -880,6 +886,8 @@ static struct parm_struct parm_table[] = {
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+ {"config backend", P_ENUM, P_GLOBAL, &Globals.ConfigBackend, NULL, enum_config_backend, FLAG_ADVANCED},
+
{N_("Security Options"), P_SEP, P_SEPARATOR},
{"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
@@ -1215,14 +1223,14 @@ static struct parm_struct parm_table[] = {
{"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
+ {N_("EventLog Options"), P_SEP, P_SEPARATOR},
+ {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+
{N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
{"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
{"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
- {N_("EventLog Options"), P_SEP, P_SEPARATOR},
- {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
-
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
@@ -1294,6 +1302,8 @@ static struct parm_struct parm_table[] = {
{"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
+ {N_("MSDFS options"), P_SEP, P_SEPARATOR},
+
{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
@@ -1527,6 +1537,8 @@ static void init_globals(bool first_time_only)
Globals.bLoadPrinters = True;
Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
+ Globals.ConfigBackend = config_backend;
+
/* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
@@ -2046,6 +2058,7 @@ FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
+FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
FN_LOCAL_STRING(lp_preexec, szPreExec)
FN_LOCAL_STRING(lp_postexec, szPostExec)
@@ -3422,8 +3435,6 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
char * valstr;
struct registry_value *value = NULL;
- include_registry_globals = True;
-
ZERO_STRUCT(data);
reg_tdb = lp_regdb_open();
@@ -3536,8 +3547,6 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
smb_panic("Failed to create talloc context!");
}
- include_registry_globals = True;
-
if (!registry_init_regdb()) {
DEBUG(1, ("Error initializing the registry.\n"));
goto done;
@@ -3637,9 +3646,12 @@ static void add_to_file_list(const char *fname, const char *subfname)
}
}
-bool lp_include_registry_globals(void)
+/**
+ * Utility function for outsiders to check if we're running on registry.
+ */
+bool lp_config_backend_is_registry(void)
{
- return include_registry_globals;
+ return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
}
/*******************************************************************
@@ -3653,7 +3665,7 @@ bool lp_file_list_changed(void)
DEBUG(6, ("lp_file_list_changed()\n"));
- if (include_registry_globals) {
+ if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
reg_tdb = lp_regdb_open();
if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
{
@@ -3661,6 +3673,15 @@ bool lp_file_list_changed(void)
regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
TALLOC_FREE(reg_tdb);
return true;
+ } else {
+ /*
+ * Don't check files when config_backend is registry.
+ * Remove this to obtain checking of files even with
+ * registry config backend. That would enable switching
+ * off registry configuration by changing smb.conf even
+ * without restarting smbd.
+ */
+ return false;
}
}
@@ -3696,6 +3717,7 @@ bool lp_file_list_changed(void)
return (False);
}
+
/***************************************************************************
Run standard_sub_basic on netbios name... needed because global_myname
is not accessed through any lp_ macro.
@@ -3765,17 +3787,6 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
{
char *fname;
- if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
- if (bInGlobalSection) {
- return process_registry_globals(do_parameter);
- }
- else {
- DEBUG(1, ("\"include = registry\" only effective "
- "in %s section\n", GLOBAL_NAME));
- return false;
- }
- }
-
fname = alloc_sub_basic(get_current_username(),
current_user_info.domain,
pszParmValue);
@@ -5654,15 +5665,6 @@ bool lp_load(const char *pszFname,
bool bRetval;
param_opt_struct *data, *pdata;
- n2 = alloc_sub_basic(get_current_username(),
- current_user_info.domain,
- pszFname);
- if (!n2) {
- smb_panic("lp_load: out of memory");
- }
-
- add_to_file_list(pszFname, n2);
-
bRetval = False;
DEBUG(3, ("lp_load: refreshing parameters\n"));
@@ -5691,17 +5693,47 @@ bool lp_load(const char *pszFname,
Globals.param_opt = NULL;
}
- /* We get sections first, so have to start 'behind' to make up */
- iServiceIndex = -1;
- bRetval = pm_process(n2, do_section, do_parameter);
- SAFE_FREE(n2);
+ if (lp_config_backend() == CONFIG_BACKEND_FILE) {
+ n2 = alloc_sub_basic(get_current_username(),
+ current_user_info.domain,
+ pszFname);
+ if (!n2) {
+ smb_panic("lp_load: out of memory");
+ }
+
+ add_to_file_list(pszFname, n2);
- /* finish up the last section */
- DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
- if (bRetval) {
- if (iServiceIndex >= 0) {
- bRetval = service_ok(iServiceIndex);
+ /* We get sections first, so have to start 'behind' to make up */
+ iServiceIndex = -1;
+ bRetval = pm_process(n2, do_section, do_parameter);
+ SAFE_FREE(n2);
+
+ /* finish up the last section */
+ DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
+ if (bRetval) {
+ if (iServiceIndex >= 0) {
+ bRetval = service_ok(iServiceIndex);
+ }
+ }
+
+ if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
+ /*
+ * We need to use this extra global variable here to
+ * survive restart: init_globals usese this as a default
+ * for ConfigBackend. Otherwise, init_globals would
+ * send us into an endless loop here.
+ */
+ config_backend = CONFIG_BACKEND_REGISTRY;
+ /* start over */
+ return lp_load(pszFname, global_only, save_defaults,
+ add_ipc, initialize_globals);
}
+ } else if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
+ bRetval = process_registry_globals(do_parameter);
+ } else {
+ DEBUG(0, ("Illegal config backend given: %d\n",
+ lp_config_backend()));
+ bRetval = false;
}
lp_add_auto_services(lp_auto_services());
diff --git a/source3/pkgconfig/wbclient.pc.in b/source3/pkgconfig/wbclient.pc.in
new file mode 100644
index 0000000000..158fa923d6
--- /dev/null
+++ b/source3/pkgconfig/wbclient.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Samba libwbclient
+Description: A library to access winbindd
+Version: 0
+URL: http://www.samba.org/
+#Libs: -L@libdir@ -lwbclient
+Libs: -lwbclient
+Libs.private: -lwbclient
+Cflags: -I@includedir@
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index bba55c0e4a..d5803b711b 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -3315,8 +3315,13 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
/* publish it */
ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
- if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+ if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
+ int i;
+ for (i=0; mods[i] != 0; i++)
+ ;
+ mods[i] = (LDAPMod *)-1;
ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+ }
if (!ADS_ERR_OK(ads_rc))
DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 8bbdb6abd3..d1657c8cf6 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -1,4 +1,4 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Volker Lendecke 2006
@@ -7,12 +7,12 @@
* 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/>.
*/
@@ -140,7 +140,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
result = WERR_BADFILE;
goto done;
}
-
+
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
@@ -153,7 +153,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
result = WERR_BADFILE;
goto done;
}
-
+
TALLOC_FREE( subkeys );
if ( !regkey_access_check( key, access_desired, &key->access_granted,
@@ -302,7 +302,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
SAFE_FREE(val);
return WERR_NOMEM;
}
-
+
*pval = val;
return WERR_OK;
}
@@ -494,7 +494,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
TALLOC_FREE(mem_ctx);
return err;
}
-
WERROR reg_deletekey(struct registry_key *parent, const char *path)
{
@@ -712,8 +711,8 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
}
/*
- * Utility function to delete a registry key with all its subkeys.
- * Note that reg_deletekey returns ACCESS_DENIED when called on a
+ * Utility function to delete a registry key with all its subkeys.
+ * Note that reg_deletekey returns ACCESS_DENIED when called on a
* key that has subkeys.
*/
WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
@@ -739,11 +738,11 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
}
while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0,
- &subkey_name, NULL)))
+ &subkey_name, NULL)))
{
werr = reg_deletekey_recursive_internal(mem_ctx, key,
subkey_name,
- True);
+ true);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -771,12 +770,12 @@ 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_internal(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_internal(ctx, parent, path, false);
}
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 77ade5cba1..286cc210e2 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -542,7 +542,8 @@ NTSTATUS rpccli_lsa_query_info_policy2_new(struct rpc_pipe_client *cli, TALLOC_C
NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint16 info_class,
- char **domain_name, DOM_SID **domain_sid)
+ const char **domain_name,
+ DOM_SID **domain_sid)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_INFO q;
@@ -632,8 +633,9 @@ NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint16 info_class,
- char **domain_name, char **dns_name,
- char **forest_name,
+ const char **domain_name,
+ const char **dns_name,
+ const char **forest_name,
struct GUID **domain_guid,
DOM_SID **domain_sid)
{
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 1b78772a79..20cafbd0af 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -2583,7 +2583,7 @@ NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTE
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
+NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;
diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c
index 849ec9c4eb..de2e33732d 100644
--- a/source3/rpc_server/srv_wkssvc_nt.c
+++ b/source3/rpc_server/srv_wkssvc_nt.c
@@ -287,7 +287,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r
{
#if 0
struct libnet_JoinCtx *j = NULL;
- char *pwd = NULL;
+ char *cleartext_pwd = NULL;
char *admin_domain = NULL;
char *admin_account = NULL;
WERROR werr;
@@ -308,12 +308,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r
werr = decode_wkssvc_join_password_buffer(p->mem_ctx,
r->in.encrypted_password,
&p->session_key,
- &pwd);
- if (!W_ERROR_IS_OK(werr)) {
- return werr;
- }
-
- werr = libnet_init_JoinCtx(p->mem_ctx, &j);
+ &cleartext_pwd);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@@ -323,7 +318,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r
&admin_domain,
&admin_account);
- status = DsGetDcName(p->mem_ctx,
+ status = dsgetdcname(p->mem_ctx,
NULL,
r->in.domain_name,
NULL,
@@ -336,14 +331,18 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r
return ntstatus_to_werror(status);
}
- j->in.server_name = info->domain_controller_name;
+ werr = libnet_init_JoinCtx(p->mem_ctx, &j);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ j->in.dc_name = info->domain_controller_name;
j->in.domain_name = r->in.domain_name;
j->in.account_ou = r->in.account_ou;
j->in.join_flags = r->in.join_flags;
-
- j->in.admin_account = admin_account;
- j->in.password = pwd;
- j->in.modify_config = true;
+ j->in.admin_account = admin_account;
+ j->in.admin_password = cleartext_pwd;
+ j->in.modify_config = true;
become_root();
werr = libnet_Join(p->mem_ctx, j);
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index 7743269ce0..05269d7711 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -916,7 +916,8 @@ static void display_trust_dom_info_4(struct lsa_TrustDomainInfoPassword *p, cons
data_blob_free(&data_old);
}
-static void display_trust_dom_info(union lsa_TrustedDomainInfo *info,
+static void display_trust_dom_info(TALLOC_CTX *mem_ctx,
+ union lsa_TrustedDomainInfo *info,
enum lsa_TrustDomInfoEnum info_class,
const char *pass)
{
@@ -924,12 +925,17 @@ static void display_trust_dom_info(union lsa_TrustedDomainInfo *info,
case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
display_trust_dom_info_4(&info->password, pass);
break;
- default:
- NDR_PRINT_UNION_DEBUG(lsa_TrustedDomainInfo,
- info_class, info);
+ default: {
+ const char *str = NULL;
+ str = NDR_PRINT_UNION_STRING(mem_ctx,
+ lsa_TrustedDomainInfo,
+ info_class, info);
+ if (str) {
+ d_printf("%s\n", str);
+ }
break;
+ }
}
-
}
static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli,
@@ -967,7 +973,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- display_trust_dom_info(&info, info_class, cli->pwd.password);
+ display_trust_dom_info(mem_ctx, &info, info_class, cli->pwd.password);
done:
if (&pol)
@@ -1015,7 +1021,7 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- display_trust_dom_info(&info, info_class, cli->pwd.password);
+ display_trust_dom_info(mem_ctx, &info, info_class, cli->pwd.password);
done:
if (&pol)
@@ -1069,7 +1075,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- display_trust_dom_info(&info, info_class, cli->pwd.password);
+ display_trust_dom_info(mem_ctx, &info, info_class, cli->pwd.password);
done:
if (&pol)
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index dd8b911bb8..081e0fb15e 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -134,7 +134,7 @@ static void fetch_machine_sid(struct cli_state *cli)
POLICY_HND pol;
NTSTATUS result = NT_STATUS_OK;
uint32 info_class = 5;
- char *domain_name = NULL;
+ const char *domain_name = NULL;
static bool got_domain_sid;
TALLOC_CTX *mem_ctx;
DOM_SID *dom_sid = NULL;
diff --git a/source3/script/fix_bool.pl b/source3/script/fix_bool.pl
new file mode 100755
index 0000000000..c09645de7c
--- /dev/null
+++ b/source3/script/fix_bool.pl
@@ -0,0 +1,19 @@
+#!/usr/bin/perl -w
+
+open(INFILE, "$ARGV[0]") || die $@;
+open(OUTFILE, ">$ARGV[0].new") || die $@;
+
+while (<INFILE>) {
+ $_ =~ s/True/true/;
+ $_ =~ s/False/false/;
+ print OUTFILE "$_";
+}
+
+close(INFILE);
+close(OUTFILE);
+
+rename("$ARGV[0].new", "$ARGV[0]") || die @_;
+
+exit(0);
+
+
diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh
index 86abb15ed1..5a170b2117 100755
--- a/source3/script/tests/selftest.sh
+++ b/source3/script/tests/selftest.sh
@@ -186,6 +186,7 @@ cat >$SERVERCONFFILE<<EOF
map hidden = yes
map system = yes
create mask = 755
+ vfs objects = $BINDIR/xattr_tdb.so
[hideunread]
copy = tmp
hide unreadable = yes
diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh
index 9f672897ac..0b4a52d4b5 100755
--- a/source3/script/tests/test_posix_s3.sh
+++ b/source3/script/tests/test_posix_s3.sh
@@ -47,7 +47,7 @@ unix="UNIX-INFO2"
tests="$base $raw $rpc $unix"
skipped="BASE-CHARSET BASE-DELAYWRITE BASE-TCONDEV"
-skipped="$skipped RAW-ACLS RAW-COMPOSITE RAW-CONTEXT RAW-EAS"
+skipped="$skipped RAW-ACLS RAW-COMPOSITE RAW-CONTEXT"
skipped="$skipped RAW-IOCTL"
skipped="$skipped RAW-QFILEINFO RAW-QFSINFO RAW-SEARCH"
skipped="$skipped RAW-SFILEINFO RAW-STREAMS"
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 016c8adb1b..d7063c9989 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -118,6 +118,15 @@ int count_current_connections( const char *sharename, bool clear )
}
/****************************************************************************
+ Count the number of connections open across all shares.
+****************************************************************************/
+
+int count_all_current_connections(void)
+{
+ return count_current_connections(NULL, True /* clear stale entries */);
+}
+
+/****************************************************************************
Claim an entry in the connections database.
****************************************************************************/
diff --git a/source3/smbd/dmapi.c b/source3/smbd/dmapi.c
index 05e9138ea9..620baf199e 100644
--- a/source3/smbd/dmapi.c
+++ b/source3/smbd/dmapi.c
@@ -46,7 +46,7 @@ bool dmapi_have_session(void) { return False; }
#define DMAPI_SESSION_NAME "samba"
#define DMAPI_TRACE 10
-static dm_sessid_t dmapi_session = DM_NO_SESSION;
+static dm_sessid_t samba_dmapi_session = DM_NO_SESSION;
/* Initialise the DMAPI interface. Make sure that we only end up initialising
* once per process to avoid resource leaks across different DMAPI
@@ -75,7 +75,7 @@ static int init_dmapi_service(void)
bool dmapi_have_session(void)
{
- return dmapi_session != DM_NO_SESSION;
+ return samba_dmapi_session != DM_NO_SESSION;
}
static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
@@ -110,7 +110,7 @@ int dmapi_init_session(void)
*/
SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
- dmapi_session = DM_NO_SESSION;
+ samba_dmapi_session = DM_NO_SESSION;
if (init_dmapi_service() < 0) {
return -1;
}
@@ -139,7 +139,7 @@ retry:
err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
buf[sizeof(buf) - 1] = '\0';
if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
- dmapi_session = sessions[i];
+ samba_dmapi_session = sessions[i];
DEBUGADD(DMAPI_TRACE,
("attached to existing DMAPI session "
"named '%s'\n", buf));
@@ -150,16 +150,15 @@ retry:
TALLOC_FREE(sessions);
/* No session already defined. */
- if (dmapi_session == DM_NO_SESSION) {
- err = dm_create_session(DM_NO_SESSION,
- CONST_DISCARD(char *,
- DMAPI_SESSION_NAME),
- &dmapi_session);
+ if (samba_dmapi_session == DM_NO_SESSION) {
+ err = dm_create_session(DM_NO_SESSION,
+ CONST_DISCARD(char *, DMAPI_SESSION_NAME),
+ &samba_dmapi_session);
if (err < 0) {
DEBUGADD(DMAPI_TRACE,
("failed to create new DMAPI session: %s\n",
strerror(errno)));
- dmapi_session = DM_NO_SESSION;
+ samba_dmapi_session = DM_NO_SESSION;
return -1;
}
@@ -185,22 +184,22 @@ static int reattach_dmapi_session(void)
char buf[DM_SESSION_INFO_LEN];
size_t buflen;
- if (dmapi_session != DM_NO_SESSION ) {
+ if (samba_dmapi_session != DM_NO_SESSION ) {
become_root();
/* NOTE: On Linux, this call opens /dev/dmapi, costing us a
* file descriptor. Ideally, we would close this when we fork.
*/
if (init_dmapi_service() < 0) {
- dmapi_session = DM_NO_SESSION;
+ samba_dmapi_session = DM_NO_SESSION;
unbecome_root();
return -1;
}
- if (dm_query_session(dmapi_session, sizeof(buf),
+ if (dm_query_session(samba_dmapi_session, sizeof(buf),
buf, &buflen) < 0) {
/* Session is stale. Disable DMAPI. */
- dmapi_session = DM_NO_SESSION;
+ samba_dmapi_session = DM_NO_SESSION;
unbecome_root();
return -1;
}
@@ -214,33 +213,42 @@ static int reattach_dmapi_session(void)
return 0;
}
-uint32 dmapi_file_flags(const char * const path)
+/* If a DMAPI session has been initialised, then we need to make sure
+ * we are attached to it and have the correct privileges. This is
+ * necessary to be able to do DMAPI operations across a fork(2). If
+ * it fails, there is no likelihood of that failure being transient.
+ *
+ * Note that this use of the static attached flag relies on the fact
+ * that dmapi_file_flags() is never called prior to forking the
+ * per-client server process.
+ */
+const void * dmapi_get_current_session(void)
{
static int attached = 0;
+ if (dmapi_have_session() && !attached) {
+ attached++;
+ if (reattach_dmapi_session() < 0) {
+ return DM_NO_SESSION;
+ }
+ }
+ return &samba_dmapi_session;
+}
+uint32 dmapi_file_flags(const char * const path)
+{
+ dm_sessid_t dmapi_session;
int err;
dm_eventset_t events = {0};
uint nevents;
- void *dm_handle;
- size_t dm_handle_len;
+ void *dm_handle = NULL;
+ size_t dm_handle_len = 0;
uint32 flags = 0;
- /* If a DMAPI session has been initialised, then we need to make sure
- * we are attached to it and have the correct privileges. This is
- * necessary to be able to do DMAPI operations across a fork(2). If
- * it fails, there is no liklihood of that failure being transient.
- *
- * Note that this use of the static attached flag relies on the fact
- * that dmapi_file_flags() is never called prior to forking the
- * per-client server process.
- */
- if (dmapi_have_session() && !attached) {
- attached++;
- if (reattach_dmapi_session() < 0) {
- return 0;
- }
+ dmapi_session = *(dm_sessid_t*) dmapi_get_current_session();
+ if (dmapi_session == DM_NO_SESSION) {
+ return 0;
}
/* AIX has DMAPI but no POSIX capablities support. In this case,
@@ -313,4 +321,5 @@ done:
return flags;
}
+
#endif /* USE_DMAPI */
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index d3813f9b41..2021621dfa 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -31,23 +31,6 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
}
/****************************************************************************
- Work out whether this file is offline
-****************************************************************************/
-
-static uint32 set_offline_flag(connection_struct *conn, const char *const path)
-{
- if (ISDOT(path) || ISDOTDOT(path)) {
- return 0;
- }
-
- if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) {
- return 0;
- }
-
- return dmapi_file_flags(path);
-}
-
-/****************************************************************************
Change a dos mode to a unix mode.
Base permission for files:
if creating file and inheriting (i.e. parent_dir != NULL)
@@ -366,6 +349,8 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
{
uint32 result = 0;
+ bool offline;
+ int ret;
DEBUG(8,("dos_mode: %s\n", path));
@@ -395,8 +380,10 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
result |= dos_mode_from_sbuf(conn, path, sbuf);
}
- if (S_ISREG(sbuf->st_mode)) {
- result |= set_offline_flag(conn, path);
+
+ ret = SMB_VFS_IS_OFFLINE(conn, path, sbuf, &offline);
+ if (S_ISREG(sbuf->st_mode) && (ret == 0) && offline) {
+ result |= FILE_ATTRIBUTE_OFFLINE;
}
/* Optimization : Only call is_hidden_path if it's not already
@@ -432,7 +419,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
int mask=0;
mode_t tmp;
mode_t unixmode;
- int ret = -1;
+ int ret = -1, lret = -1;
/* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
dosmode &= SAMBA_ATTRIBUTES_MASK;
@@ -505,10 +492,21 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
- if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) {
- if (!newfile) {
+ if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
+ lret = SMB_VFS_SET_OFFLINE(conn, fname);
+ if (lret == -1) {
+ DEBUG(0, ("set_dos_mode: client has asked to set "
+ "FILE_ATTRIBUTE_OFFLINE to %s/%s but there was "
+ "an error while setting it or it is not supported.\n",
+ parent_dir, fname));
+ }
+ }
+
+ ret = SMB_VFS_CHMOD(conn, fname, unixmode);
+ if (ret == 0) {
+ if(!newfile || (lret != -1)) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
st->st_mode = unixmode;
return 0;
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 05021b6c74..fa7cb42bc6 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -93,17 +93,27 @@ static void set_capability(unsigned capability)
return;
}
- data.effective |= (1<<capability);
+ if (0 == (data.effective & (1<<capability))) {
+ data.effective |= (1<<capability);
- if (capset(&header, &data) == -1) {
- DEBUG(3,("Unable to set %d capability (%s)\n",
- capability, strerror(errno)));
+ if (capset(&header, &data) == -1) {
+ DEBUG(3,("Unable to set %d capability (%s)\n",
+ capability, strerror(errno)));
+ }
}
}
/*
- Call to set the kernel lease signal handler
-*/
+ * public function to get linux lease capability. Needed by some VFS modules (eg. gpfs.c)
+ */
+void linux_set_lease_capability(void)
+{
+ set_capability(CAP_LEASE);
+}
+
+/*
+ * Call to set the kernel lease signal handler
+ */
int linux_set_lease_sighandler(int fd)
{
if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 5f18615f66..6cec39f9c0 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3413,6 +3413,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
bool acl_perms = False;
mode_t orig_mode = (mode_t)0;
NTSTATUS status;
+ uid_t orig_uid;
+ gid_t orig_gid;
+ bool need_chown = False;
DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
@@ -3435,6 +3438,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
/* Save the original elements we check against. */
orig_mode = sbuf.st_mode;
+ orig_uid = sbuf.st_uid;
+ orig_gid = sbuf.st_gid;
/*
* Unpack the user/group/world id's.
@@ -3449,7 +3454,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* Do we need to chown ?
*/
- if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
+ if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) {
+ need_chown = True;
+ }
+
+ if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
@@ -3487,6 +3496,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
/* Save the original elements we check against. */
orig_mode = sbuf.st_mode;
+ orig_uid = sbuf.st_uid;
+ orig_gid = sbuf.st_gid;
+
+ /* We did chown already, drop the flag */
+ need_chown = False;
}
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
@@ -3630,6 +3644,21 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
free_canon_ace_list(dir_ace_list);
}
+ /* Any chown pending? */
+ if (need_chown) {
+ DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
+ fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
+
+ if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
+ DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
+ if (errno == EPERM) {
+ return NT_STATUS_INVALID_OWNER;
+ }
+ return map_nt_error_from_unix(errno);
+ }
+ }
+
return NT_STATUS_OK;
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index e2316ef120..381ddfe151 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3329,8 +3329,12 @@ void reply_read_and_X(struct smb_request *req)
return;
}
- if (!big_readX
- && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
+ /* It is possible for VFS modules to selectively decide whether Async I/O should be used
+ for the file or not.
+ */
+ if ((SMB_VFS_AIO_FORCE(fsp)) &&
+ !big_readX &&
+ schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
END_PROFILE(SMBreadX);
return;
}
@@ -4001,13 +4005,16 @@ void reply_write_and_X(struct smb_request *req)
nwritten = 0;
} else {
- if (req->unread_bytes == 0 &&
- schedule_aio_write_and_X(conn, req, fsp, data,
- startpos, numtowrite)) {
+ /* It is possible for VFS modules to selectively decide whether Async I/O
+ should be used for the file or not.
+ */
+ if ((SMB_VFS_AIO_FORCE(fsp)) && (req->unread_bytes == 0) &&
+ schedule_aio_write_and_X(conn, req, fsp, data, startpos,
+ numtowrite)) {
END_PROFILE(SMBwriteX);
return;
}
-
+
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8371d17f10..db241103ed 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -268,10 +268,20 @@ static void add_child_pid(pid_t pid)
num_children += 1;
}
-static void remove_child_pid(pid_t pid)
+static void remove_child_pid(pid_t pid, bool unclean_shutdown)
{
struct child_pid *child;
+ if (unclean_shutdown) {
+ /* a child terminated uncleanly so tickle all processes to see
+ if they can grab any of the pending locks
+ */
+ messaging_send_buf(smbd_messaging_context(), procid_self(),
+ MSG_SMB_BRL_VALIDATE, NULL, 0);
+ message_send_all(smbd_messaging_context(),
+ MSG_SMB_UNLOCK, NULL, 0, NULL);
+ }
+
if (lp_max_smbd_processes() == 0) {
/* Don't bother with the child list if we don't care anyway */
return;
@@ -560,10 +570,27 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
if (got_sig_cld) {
pid_t pid;
+ int status;
+
got_sig_cld = False;
- while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
- remove_child_pid(pid);
+ while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
+ bool unclean_shutdown = False;
+
+ /* If the child terminated normally, assume
+ it was an unclean shutdown unless the
+ status is 0
+ */
+ if (WIFEXITED(status)) {
+ unclean_shutdown = WEXITSTATUS(status);
+ }
+ /* If the child terminated due to a signal
+ we always assume it was unclean.
+ */
+ if (WIFSIGNALED(status)) {
+ unclean_shutdown = True;
+ }
+ remove_child_pid(pid, unclean_shutdown);
}
}
@@ -603,6 +630,15 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
continue;
}
+
+
+ /* If the idle timeout fired and we don't have any connected
+ * users, exit gracefully. We should be running under a process
+ * controller that will restart us if necessry.
+ */
+ if (num == 0 && count_all_current_connections() == 0) {
+ exit_server_cleanly("idle timeout");
+ }
/* process pending nDNS responses */
if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
@@ -906,6 +942,29 @@ void exit_server_fault(void)
exit_server("critical server fault");
}
+
+/****************************************************************************
+received when we should release a specific IP
+****************************************************************************/
+static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
+ uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
+{
+ const char *ip = (const char *)data->data;
+ char addr[INET6_ADDRSTRLEN];
+
+ if (strcmp(client_socket_addr(get_client_fd(),addr,sizeof(addr)), ip) == 0) {
+ /* we can't afford to do a clean exit - that involves
+ database writes, which would potentially mean we
+ are still running after the failover has finished -
+ we have to get rid of this process ID straight
+ away */
+ DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
+ ip));
+ _exit(0);
+ }
+}
+
+
/****************************************************************************
Initialise connect, service and file structs.
****************************************************************************/
@@ -1305,6 +1364,8 @@ extern void build_options(bool screen);
/* register our message handlers */
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_FORCE_TDIS, msg_force_tdis);
+ messaging_register(smbd_messaging_context(), NULL,
+ MSG_SMB_RELEASE_IP, msg_release_ip);
if ((lp_keepalive() != 0)
&& !(event_add_idle(smbd_event_context(), NULL,
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2588a66b8b..ed8061e2f7 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -219,44 +219,6 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
return(True);
}
-/****************************************************************************
- Add a home service. Returns the new service number or -1 if fail.
-****************************************************************************/
-
-int add_home_service(const char *service, const char *username, const char *homedir)
-{
- int iHomeService;
-
- if (!service || !homedir)
- return -1;
-
- if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0)
- return -1;
-
- /*
- * If this is a winbindd provided username, remove
- * the domain component before adding the service.
- * Log a warning if the "path=" parameter does not
- * include any macros.
- */
-
- {
- const char *p = strchr(service,*lp_winbind_separator());
-
- /* We only want the 'user' part of the string */
- if (p) {
- service = p + 1;
- }
- }
-
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
-
- return lp_servicenumber(service);
-
-}
-
static int load_registry_service(const char *servicename)
{
struct registry_key *key;
@@ -348,6 +310,47 @@ void load_registry_shares(void)
return;
}
+/****************************************************************************
+ Add a home service. Returns the new service number or -1 if fail.
+****************************************************************************/
+
+int add_home_service(const char *service, const char *username, const char *homedir)
+{
+ int iHomeService;
+
+ if (!service || !homedir)
+ return -1;
+
+ if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
+ if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
+ return -1;
+ }
+ }
+
+ /*
+ * If this is a winbindd provided username, remove
+ * the domain component before adding the service.
+ * Log a warning if the "path=" parameter does not
+ * include any macros.
+ */
+
+ {
+ const char *p = strchr(service,*lp_winbind_separator());
+
+ /* We only want the 'user' part of the string */
+ if (p) {
+ service = p + 1;
+ }
+ }
+
+ if (!lp_add_home(service, iHomeService, username, homedir)) {
+ return -1;
+ }
+
+ return lp_servicenumber(service);
+
+}
+
/**
* Find a service entry.
*
@@ -386,7 +389,10 @@ int find_service(fstring service)
if (iService < 0) {
int iPrinterService;
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
+ if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
+ iPrinterService = load_registry_service(PRINTERS_NAME);
+ }
+ if (iPrinterService) {
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
if (pcap_printername_ok(service)) {
DEBUG(3,("%s is a valid printer name\n", service));
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index bf6802f2a6..5729ab5349 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -2373,8 +2373,8 @@ static void call_trans2qfsinfo(connection_struct *conn,
const char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
- int quota_flag = 0;
-
+ uint32 additional_flags = 0;
+
if (total_params < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
@@ -2487,16 +2487,23 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
-
+ additional_flags = 0;
#if defined(HAVE_SYS_QUOTAS)
- quota_flag = FILE_VOLUME_QUOTAS;
+ additional_flags |= FILE_VOLUME_QUOTAS;
#endif
+ if(lp_nt_acl_support(SNUM(conn))) {
+ additional_flags |= FILE_PERSISTENT_ACLS;
+ }
+
+ if(SMB_VFS_IS_REMOTESTORAGE(conn, lp_pathname(SNUM(conn)))) {
+ additional_flags |= FILE_SUPPORTS_REMOTE_STORAGE;
+ additional_flags |= FILE_SUPPORTS_REPARSE_POINTS;
+ }
+
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
- FILE_SUPPORTS_OBJECT_IDS|
- FILE_UNICODE_ON_DISK|
- quota_flag); /* FS ATTRIBUTES */
+ FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
+ additional_flags); /* FS ATTRIBUTES */
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
diff --git a/source3/utils/net.h b/source3/utils/net.h
index 2ffa4d77b1..3a4b1da7b0 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -42,7 +42,7 @@ struct rpc_sh_ctx {
struct cli_state *cli;
DOM_SID *domain_sid;
- char *domain_name;
+ const char *domain_name;
const char *whoami;
const char *thiscmd;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 80f6ba9001..732ba8d8b6 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -817,7 +817,7 @@ static int net_ads_leave(int argc, const char **argv)
struct cli_state *cli = NULL;
TALLOC_CTX *ctx;
DOM_SID *dom_sid = NULL;
- char *short_domain_name = NULL;
+ const char *short_domain_name = NULL;
if (!secrets_init()) {
DEBUG(1,("Failed to initialise secrets database\n"));
@@ -961,7 +961,8 @@ static NTSTATUS check_ads_config( void )
********************************************************************/
static NTSTATUS net_join_domain(TALLOC_CTX *ctx, const char *servername,
- struct sockaddr_storage *pss, char **domain,
+ struct sockaddr_storage *pss,
+ const char **domain,
DOM_SID **dom_sid,
const char *password)
{
@@ -1294,14 +1295,13 @@ static bool net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads )
#if defined(WITH_DNS_UPDATES)
#include "dns.h"
DNS_ERROR DoDNSUpdate(char *pszServerName,
- const char *pszDomainName,
- const char *pszHostName,
- const struct in_addr *iplist, int num_addrs );
-
+ const char *pszDomainName, const char *pszHostName,
+ const struct sockaddr_storage *sslist,
+ size_t num_addrs );
static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads,
const char *machine_name,
- const struct in_addr *addrs,
+ const struct sockaddr_storage *addrs,
int num_addrs)
{
struct dns_rr_ns *nameservers = NULL;
@@ -1390,7 +1390,7 @@ done:
static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads)
{
int num_addrs;
- struct in_addr *iplist = NULL;
+ struct sockaddr_storage *iplist = NULL;
fstring machine_name;
NTSTATUS status;
@@ -1446,7 +1446,7 @@ int net_ads_join(int argc, const char **argv)
ADS_STRUCT *ads = NULL;
ADS_STATUS status;
NTSTATUS nt_status;
- char *short_domain_name = NULL;
+ const char *short_domain_name = NULL;
char *tmp_password, *password;
TALLOC_CTX *ctx = NULL;
DOM_SID *domain_sid = NULL;
diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c
index 44a0b46e4e..fb6644d6b2 100644
--- a/source3/utils/net_dns.c
+++ b/source3/utils/net_dns.c
@@ -32,7 +32,8 @@
DNS_ERROR DoDNSUpdate(char *pszServerName,
const char *pszDomainName, const char *pszHostName,
- const struct sockaddr_storage *sslist, size_t num_addrs );
+ const struct sockaddr_storage *sslist,
+ size_t num_addrs );
/*********************************************************************
*********************************************************************/
diff --git a/source3/utils/net_domain.c b/source3/utils/net_domain.c
index 3f1908e242..da5e61caf0 100644
--- a/source3/utils/net_domain.c
+++ b/source3/utils/net_domain.c
@@ -157,7 +157,7 @@ int netdom_store_machine_account( const char *domain, DOM_SID *sid, const char *
********************************************************************/
NTSTATUS netdom_get_domain_sid( TALLOC_CTX *mem_ctx, struct cli_state *cli,
- char **domain, DOM_SID **sid )
+ const char **domain, DOM_SID **sid )
{
struct rpc_pipe_client *pipe_hnd = NULL;
POLICY_HND lsa_pol;
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 2bd867fff3..677924649c 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -51,7 +51,8 @@ static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
**/
NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- DOM_SID **domain_sid, char **domain_name)
+ DOM_SID **domain_sid,
+ const char **domain_name)
{
struct rpc_pipe_client *lsa_pipe;
POLICY_HND pol;
@@ -112,7 +113,7 @@ int run_rpc_command(struct cli_state *cli_arg,
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
- char *domain_name;
+ const char *domain_name;
/* make use of cli_state handed over as an argument, if possible */
if (!cli_arg) {
@@ -5607,7 +5608,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
DOM_SID *domain_sid;
char* domain_name;
- char* domain_name_pol;
+ const char* domain_name_pol;
char* acct_name;
fstring pdc_name;
char *dc_name;
@@ -5917,7 +5918,7 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
DOM_SID *domain_sids;
char **trusted_dom_names;
fstring pdc_name;
- char *dummy;
+ const char *dummy;
/*
* Listing trusted domains (stored in secrets.tdb, if local)
@@ -6057,7 +6058,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
DOM_SID *domain_sids;
char **trusted_dom_names;
fstring pdc_name;
- char *dummy;
+ const char *dummy;
/* trusting domains listing variables */
POLICY_HND domain_hnd;
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 0c25a53365..6e37f3c84c 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -155,7 +155,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
NTSTATUS result;
int retval = 1;
- char *domain = NULL;
+ const char *domain = NULL;
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
char *acct_name;
@@ -413,7 +413,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Now store the secret in the secrets database */
- strupper_m(domain);
+ strupper_m(CONST_DISCARD(char *, domain));
if (!secrets_store_domain_sid(domain, domain_sid)) {
DEBUG(0, ("error storing domain sid for %s\n", domain));
diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c
new file mode 100644
index 0000000000..ab89e615f7
--- /dev/null
+++ b/source3/winbindd/idmap_tdb2.c
@@ -0,0 +1,1017 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ idmap TDB2 backend, used for clustered Samba setups.
+
+ This uses 2 tdb files. One is permanent, and is in shared storage
+ on the cluster (using "tdb:idmap2.tdb =" in smb.conf). The other is a
+ temporary cache tdb on local storage.
+
+ Copyright (C) Andrew Tridgell 2007
+
+ This is heavily based upon idmap_tdb.c, which is:
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Jeremy Allison 2006
+ Copyright (C) Simo Sorce 2003-2006
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+/* High water mark keys */
+#define HWM_GROUP "GROUP HWM"
+#define HWM_USER "USER HWM"
+
+static struct idmap_tdb2_state {
+ /* User and group id pool */
+ uid_t low_uid, high_uid; /* Range of uids to allocate */
+ gid_t low_gid, high_gid; /* Range of gids to allocate */
+ const char *idmap_script;
+} idmap_tdb2_state;
+
+
+
+/* tdb context for the local cache tdb */
+static TDB_CONTEXT *idmap_tdb2_tmp;
+
+/* handle to the permanent tdb */
+static struct db_context *idmap_tdb2_perm;
+
+/*
+ open the cache tdb
+ */
+static NTSTATUS idmap_tdb2_open_cache_db(void)
+{
+ const char *db_path;
+
+ if (idmap_tdb2_tmp) {
+ /* its already open */
+ return NT_STATUS_OK;
+ }
+
+ db_path = lock_path("idmap2_cache.tdb");
+
+ /* Open idmap repository */
+ if (!(idmap_tdb2_tmp = tdb_open_log(db_path, 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644))) {
+ DEBUG(0, ("Unable to open cache idmap database '%s'\n", db_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+static NTSTATUS idmap_tdb2_alloc_load(void);
+
+/*
+ open the permanent tdb
+ */
+static NTSTATUS idmap_tdb2_open_perm_db(void)
+{
+ char *db_path;
+
+ if (idmap_tdb2_perm) {
+ /* its already open */
+ return NT_STATUS_OK;
+ }
+
+ db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
+ if (db_path == NULL) {
+ /* fall back to the private directory, which, despite
+ its name, is usually on shared storage */
+ db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
+ }
+ NT_STATUS_HAVE_NO_MEMORY(db_path);
+
+ /* Open idmap repository */
+ idmap_tdb2_perm = db_open(NULL, db_path, 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0644);
+ TALLOC_FREE(db_path);
+
+ if (idmap_tdb2_perm == NULL) {
+ DEBUG(0, ("Unable to open permanent idmap database '%s'\n",
+ db_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* load the ranges and high/low water marks */
+ return idmap_tdb2_alloc_load();
+}
+
+
+/*
+ load the idmap allocation ranges and high/low water marks
+*/
+static NTSTATUS idmap_tdb2_alloc_load(void)
+{
+ const char *range;
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
+
+ /* load ranges */
+ idmap_tdb2_state.low_uid = 0;
+ idmap_tdb2_state.high_uid = 0;
+ idmap_tdb2_state.low_gid = 0;
+ idmap_tdb2_state.high_gid = 0;
+
+ /* see if a idmap script is configured */
+ idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
+
+ if (idmap_tdb2_state.idmap_script) {
+ DEBUG(1, ("using idmap script '%s'\n", idmap_tdb2_state.idmap_script));
+ }
+
+ range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
+ if (range && range[0]) {
+ unsigned low_id, high_id;
+ if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
+ if (low_id < high_id) {
+ idmap_tdb2_state.low_gid = idmap_tdb2_state.low_uid = low_id;
+ idmap_tdb2_state.high_gid = idmap_tdb2_state.high_uid = high_id;
+ } else {
+ DEBUG(1, ("ERROR: invalid idmap alloc range [%s]", range));
+ }
+ } else {
+ DEBUG(1, ("ERROR: invalid syntax for idmap alloc config:range [%s]", range));
+ }
+ }
+
+ /* Create high water marks for group and user id */
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ idmap_tdb2_state.low_uid = low_uid;
+ idmap_tdb2_state.high_uid = high_uid;
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ idmap_tdb2_state.low_gid = low_gid;
+ idmap_tdb2_state.high_gid = high_gid;
+ }
+
+ if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) {
+ DEBUG(1, ("idmap uid range missing or invalid\n"));
+ DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_USER)) == -1) ||
+ (low_id < idmap_tdb2_state.low_uid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_USER,
+ idmap_tdb2_state.low_uid) == -1) {
+ DEBUG(0, ("Unable to initialise user hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+ }
+ }
+
+ if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) {
+ DEBUG(1, ("idmap gid range missing or invalid\n"));
+ DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_GROUP)) == -1) ||
+ (low_id < idmap_tdb2_state.low_gid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_GROUP,
+ idmap_tdb2_state.low_gid) == -1) {
+ DEBUG(0, ("Unable to initialise group hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Initialise idmap alloc database.
+*/
+static NTSTATUS idmap_tdb2_alloc_init(const char *params)
+{
+ /* nothing to do - we want to avoid opening the permanent
+ database if possible. Instead we load the params when we
+ first need it. */
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Allocate a new id.
+*/
+static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
+{
+ bool ret;
+ const char *hwmkey;
+ const char *hwmtype;
+ uint32_t high_hwm;
+ uint32_t hwm;
+ NTSTATUS status;
+
+ status = idmap_tdb2_open_perm_db();
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ /* Get current high water mark */
+ switch (xid->type) {
+
+ case ID_TYPE_UID:
+ hwmkey = HWM_USER;
+ hwmtype = "UID";
+ high_hwm = idmap_tdb2_state.high_uid;
+ break;
+
+ case ID_TYPE_GID:
+ hwmkey = HWM_GROUP;
+ hwmtype = "GID";
+ high_hwm = idmap_tdb2_state.high_gid;
+ break;
+
+ default:
+ DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ /* check it is in the range */
+ if (hwm > high_hwm) {
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* fetch a new id and increment it */
+ ret = dbwrap_change_uint32_atomic(idmap_tdb2_perm, hwmkey, &hwm, 1);
+ if (ret == -1) {
+ DEBUG(1, ("Fatal error while fetching a new %s value\n!", hwmtype));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* recheck it is in the range */
+ if (hwm > high_hwm) {
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ xid->id = hwm;
+ DEBUG(10,("New %s = %d\n", hwmtype, hwm));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ Get current highest id.
+*/
+static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
+{
+ const char *hwmkey;
+ const char *hwmtype;
+ uint32_t hwm;
+ uint32_t high_hwm;
+
+ /* Get current high water mark */
+ switch (xid->type) {
+
+ case ID_TYPE_UID:
+ hwmkey = HWM_USER;
+ hwmtype = "UID";
+ high_hwm = idmap_tdb2_state.high_uid;
+ break;
+
+ case ID_TYPE_GID:
+ hwmkey = HWM_GROUP;
+ hwmtype = "GID";
+ high_hwm = idmap_tdb2_state.high_gid;
+ break;
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ xid->id = hwm;
+
+ /* Warn if it is out of range */
+ if (hwm >= high_hwm) {
+ DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ Set high id.
+*/
+static NTSTATUS idmap_tdb2_set_hwm(struct unixid *xid)
+{
+ /* not supported, or we would invalidate the cache tdb on
+ other nodes */
+ DEBUG(0,("idmap_tdb2_set_hwm not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+/*
+ Close the alloc tdb
+*/
+static NTSTATUS idmap_tdb2_alloc_close(void)
+{
+ /* don't actually close it */
+ return NT_STATUS_OK;
+}
+
+/*
+ IDMAP MAPPING TDB BACKEND
+*/
+struct idmap_tdb2_context {
+ uint32_t filter_low_id;
+ uint32_t filter_high_id;
+};
+
+/*
+ try fetching from the cache tdb, and if that fails then
+ fetch from the permanent tdb
+ */
+static TDB_DATA tdb2_fetch_bystring(TALLOC_CTX *mem_ctx, const char *keystr)
+{
+ TDB_DATA ret;
+ NTSTATUS status;
+
+ ret = tdb_fetch_bystring(idmap_tdb2_tmp, keystr);
+ if (ret.dptr != NULL) {
+ /* got it from cache */
+ unsigned char *tmp;
+
+ tmp = (unsigned char *)talloc_memdup(mem_ctx, ret.dptr,
+ ret.dsize);
+ SAFE_FREE(ret.dptr);
+ ret.dptr = tmp;
+
+ if (ret.dptr == NULL) {
+ return make_tdb_data(NULL, 0);
+ }
+ return ret;
+ }
+
+ status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return ret;
+ }
+
+ /* fetch from the permanent tdb */
+ return dbwrap_fetch_bystring(idmap_tdb2_perm, mem_ctx, keystr);
+}
+
+/*
+ store into both databases
+ */
+static NTSTATUS tdb2_store_bystring(const char *keystr, TDB_DATA data, int flags)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_store_bystring(idmap_tdb2_perm, keystr, data, flags);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_store_bystring(idmap_tdb2_tmp, keystr, data, flags) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
+ delete from both databases
+ */
+static NTSTATUS tdb2_delete_bystring(const char *keystr)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_delete_bystring(idmap_tdb2_perm, keystr);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_delete_bystring(idmap_tdb2_tmp, keystr) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
+ Initialise idmap database.
+*/
+static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
+{
+ NTSTATUS ret;
+ struct idmap_tdb2_context *ctx;
+ char *config_option = NULL;
+ const char *range;
+ NTSTATUS status;
+
+ status = idmap_tdb2_open_cache_db();
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ ctx = talloc(dom, struct idmap_tdb2_context);
+ if ( ! ctx) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (( ! range) ||
+ (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
+ (ctx->filter_low_id > ctx->filter_high_id)) {
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+
+ dom->private_data = ctx;
+ dom->initialized = True;
+
+ talloc_free(config_option);
+ return NT_STATUS_OK;
+
+failed:
+ talloc_free(ctx);
+ return ret;
+}
+
+
+/*
+ run a script to perform a mapping
+
+ The script should the following command lines:
+
+ SIDTOID S-1-xxxx
+ IDTOSID UID xxxx
+ IDTOSID GID xxxx
+
+ and should return one of the following as a single line of text
+ UID:xxxx
+ GID:xxxx
+ SID:xxxx
+ ERR:xxxx
+ */
+static NTSTATUS idmap_tdb2_script(struct idmap_tdb2_context *ctx, struct id_map *map,
+ const char *fmt, ...)
+{
+ va_list ap;
+ char *cmd;
+ FILE *p;
+ char line[64];
+ unsigned long v;
+
+ cmd = talloc_asprintf(ctx, "%s ", idmap_tdb2_state.idmap_script);
+ NT_STATUS_HAVE_NO_MEMORY(cmd);
+
+ va_start(ap, fmt);
+ cmd = talloc_vasprintf_append(cmd, fmt, ap);
+ va_end(ap);
+ NT_STATUS_HAVE_NO_MEMORY(cmd);
+
+ p = popen(cmd, "r");
+ talloc_free(cmd);
+ if (p == NULL) {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ if (fgets(line, sizeof(line)-1, p) == NULL) {
+ pclose(p);
+ return NT_STATUS_NONE_MAPPED;
+ }
+ pclose(p);
+
+ DEBUG(10,("idmap script gave: %s\n", line));
+
+ if (sscanf(line, "UID:%lu", &v) == 1) {
+ map->xid.id = v;
+ map->xid.type = ID_TYPE_UID;
+ } else if (sscanf(line, "GID:%lu", &v) == 1) {
+ map->xid.id = v;
+ map->xid.type = ID_TYPE_GID;
+ } else if (strncmp(line, "SID:S-", 6) == 0) {
+ if (!string_to_sid(map->sid, &line[4])) {
+ DEBUG(0,("Bad SID in '%s' from idmap script %s\n",
+ line, idmap_tdb2_state.idmap_script));
+ return NT_STATUS_NONE_MAPPED;
+ }
+ } else {
+ DEBUG(0,("Bad reply '%s' from idmap script %s\n",
+ line, idmap_tdb2_state.idmap_script));
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+
+/*
+ Single id to sid lookup function.
+*/
+static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_map *map)
+{
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *keystr;
+
+ if (!ctx || !map) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* apply filters before checking */
+ if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
+ (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
+ DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
+ map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ switch (map->xid.type) {
+
+ case ID_TYPE_UID:
+ keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ break;
+
+ case ID_TYPE_GID:
+ keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ break;
+
+ default:
+ DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* final SAFE_FREE safe */
+ data.dptr = NULL;
+
+ if (keystr == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10,("Fetching record %s\n", keystr));
+
+ /* Check if the mapping exists */
+ data = tdb2_fetch_bystring(keystr, keystr);
+
+ if (!data.dptr) {
+ fstring sidstr;
+
+ DEBUG(10,("Record %s not found\n", keystr));
+ if (idmap_tdb2_state.idmap_script == NULL) {
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr);
+
+ /* store it on shared storage */
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto done;
+ }
+
+ if (sid_to_fstring(sidstr, map->sid)) {
+ /* both forward and reverse mappings */
+ tdb2_store_bystring(keystr,
+ string_term_tdb_data(sidstr),
+ TDB_REPLACE);
+ tdb2_store_bystring(sidstr,
+ string_term_tdb_data(keystr),
+ TDB_REPLACE);
+ }
+ goto done;
+ }
+
+ if (!string_to_sid(map->sid, (const char *)data.dptr)) {
+ DEBUG(10,("INVALID SID (%s) in record %s\n",
+ (const char *)data.dptr, keystr));
+ ret = NT_STATUS_INTERNAL_DB_ERROR;
+ goto done;
+ }
+
+ DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(keystr);
+ return ret;
+}
+
+
+/*
+ Single sid to id lookup function.
+*/
+static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_map *map)
+{
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *keystr;
+ unsigned long rec_id = 0;
+
+ if ((keystr = sid_string_talloc(ctx, map->sid)) == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10,("Fetching record %s\n", keystr));
+
+ /* Check if sid is present in database */
+ data = tdb2_fetch_bystring(keystr, keystr);
+ if (!data.dptr) {
+ fstring idstr;
+
+ DEBUG(10,(__location__ " Record %s not found\n", keystr));
+
+ if (idmap_tdb2_state.idmap_script == NULL) {
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr);
+ /* store it on shared storage */
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto done;
+ }
+
+ snprintf(idstr, sizeof(idstr), "%cID %lu",
+ map->xid.type == ID_TYPE_UID?'U':'G',
+ (unsigned long)map->xid.id);
+ /* store both forward and reverse mappings */
+ tdb2_store_bystring(keystr, string_term_tdb_data(idstr),
+ TDB_REPLACE);
+ tdb2_store_bystring(idstr, string_term_tdb_data(keystr),
+ TDB_REPLACE);
+ goto done;
+ }
+
+ /* What type of record is this ? */
+ if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
+ map->xid.id = rec_id;
+ map->xid.type = ID_TYPE_UID;
+ DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr ));
+ ret = NT_STATUS_OK;
+
+ } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
+ map->xid.id = rec_id;
+ map->xid.type = ID_TYPE_GID;
+ DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr ));
+ ret = NT_STATUS_OK;
+
+ } else { /* Unknown record type ! */
+ DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
+ ret = NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ /* apply filters before returning result */
+ if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
+ (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
+ DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
+ map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
+ ret = NT_STATUS_NONE_MAPPED;
+ }
+
+done:
+ talloc_free(keystr);
+ return ret;
+}
+
+/*
+ lookup a set of unix ids.
+*/
+static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ int i;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ for (i = 0; ids[i]; i++) {
+ ret = idmap_tdb2_id_to_sid(ctx, ids[i]);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ /* if it is just a failed mapping continue */
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+
+ /* make sure it is marked as unmapped */
+ ids[i]->status = ID_UNMAPPED;
+ continue;
+ }
+
+ /* some fatal error occurred, return immediately */
+ goto done;
+ }
+
+ /* all ok, id is mapped */
+ ids[i]->status = ID_MAPPED;
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+/*
+ lookup a set of sids.
+*/
+static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ int i;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ for (i = 0; ids[i]; i++) {
+ ret = idmap_tdb2_sid_to_id(ctx, ids[i]);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ /* if it is just a failed mapping continue */
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+
+ /* make sure it is marked as unmapped */
+ ids[i]->status = ID_UNMAPPED;
+ continue;
+ }
+
+ /* some fatal error occurred, return immediately */
+ goto done;
+ }
+
+ /* all ok, id is mapped */
+ ids[i]->status = ID_MAPPED;
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+
+/*
+ set a mapping.
+*/
+static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *ksidstr, *kidstr;
+ struct db_record *update_lock = NULL;
+ struct db_record *rec = NULL;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ if (!map || !map->sid) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ksidstr = kidstr = NULL;
+ data.dptr = NULL;
+
+ /* TODO: should we filter a set_mapping using low/high filters ? */
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ switch (map->xid.type) {
+
+ case ID_TYPE_UID:
+ kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ break;
+
+ case ID_TYPE_GID:
+ kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ break;
+
+ default:
+ DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (kidstr == NULL) {
+ DEBUG(0, ("ERROR: Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if (!(ksidstr = sid_string_talloc(ctx, map->sid))) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr));
+
+ /*
+ * Get us the update lock. This is necessary to get the lock orders
+ * right, we need to deal with two records under a lock.
+ */
+
+ if (!(update_lock = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, ctx,
+ string_term_tdb_data("UPDATELOCK")))) {
+ DEBUG(10,("Failed to lock record %s\n", ksidstr));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /*
+ * *DELETE* previous mappings if any. *
+ */
+
+ /* First delete indexed on SID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(ksidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
+ }
+ TALLOC_FREE(rec);
+
+ /* Now delete indexed on unix ID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(kidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
+ }
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(ksidstr, string_term_tdb_data(kidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing SID -> ID\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(kidstr, string_term_tdb_data(ksidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing ID -> SID\n"));
+ /* try to remove the previous stored SID -> ID map */
+ tdb2_delete_bystring(ksidstr);
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr));
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(ksidstr);
+ talloc_free(kidstr);
+ SAFE_FREE(data.dptr);
+ TALLOC_FREE(update_lock);
+ return ret;
+}
+
+/*
+ remove a mapping.
+*/
+static NTSTATUS idmap_tdb2_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
+{
+ /* not supported as it would invalidate the cache tdb on other
+ nodes */
+ DEBUG(0,("idmap_tdb2_remove_mapping not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+/*
+ Close the idmap tdb instance
+*/
+static NTSTATUS idmap_tdb2_close(struct idmap_domain *dom)
+{
+ /* don't do anything */
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Dump all mappings out
+*/
+static NTSTATUS idmap_tdb2_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps)
+{
+ DEBUG(0,("idmap_tdb2_dump_data not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct idmap_methods db_methods = {
+ .init = idmap_tdb2_db_init,
+ .unixids_to_sids = idmap_tdb2_unixids_to_sids,
+ .sids_to_unixids = idmap_tdb2_sids_to_unixids,
+ .set_mapping = idmap_tdb2_set_mapping,
+ .remove_mapping = idmap_tdb2_remove_mapping,
+ .dump_data = idmap_tdb2_dump_data,
+ .close_fn = idmap_tdb2_close
+};
+
+static struct idmap_alloc_methods db_alloc_methods = {
+ .init = idmap_tdb2_alloc_init,
+ .allocate_id = idmap_tdb2_allocate_id,
+ .get_id_hwm = idmap_tdb2_get_hwm,
+ .set_id_hwm = idmap_tdb2_set_hwm,
+ .close_fn = idmap_tdb2_alloc_close
+};
+
+NTSTATUS idmap_tdb2_init(void)
+{
+ NTSTATUS ret;
+
+ /* register both backends */
+ ret = smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_alloc_methods);
+ if (! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("Unable to register idmap alloc tdb2 module: %s\n", get_friendly_nt_error_msg(ret)));
+ return ret;
+ }
+
+ return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods);
+}
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index a9155a5763..908228717e 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -1799,9 +1799,9 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
struct rpc_pipe_client *cli;
POLICY_HND pol;
- char *domain_name = NULL;
- char *dns_name = NULL;
- char *forest_name = NULL;
+ const char *domain_name = NULL;
+ const char *dns_name = NULL;
+ const char *forest_name = NULL;
DOM_SID *dom_sid = NULL;
ZERO_STRUCT( ctr );