Merge branch 'master' of ssh://jht@git.samba.org/data/git/samba
authorJohn H Terpstra <jht@samba.org>
Thu, 23 Jul 2009 14:33:06 +0000 (09:33 -0500)
committerJohn H Terpstra <jht@samba.org>
Thu, 23 Jul 2009 14:33:06 +0000 (09:33 -0500)
388 files changed:
Roadmap
WHATSNEW.txt
client/cifs.upcall.c
examples/LDAP/samba-schema-FDS.ldif
examples/VFS/config.guess
examples/VFS/config.sub
lib/replace/libreplace.m4
lib/replace/replace.h
lib/tdb/common/lock.c
lib/tdb/common/tdb_private.h
lib/tdb/common/traverse.c
lib/tevent/testsuite.c
lib/tevent/tevent_req.c
lib/torture/torture.c
lib/torture/torture.h
lib/tsocket/tsocket_bsd.c
lib/util/genrand.c
lib/util/tests/genrand.c
lib/util/util_file.c
libcli/security/secacl.c
libds/common/flag_mapping.c [moved from source4/dsdb/common/flag_mapping.c with 89% similarity]
libds/common/flags.h [moved from source4/dsdb/common/flags.h with 62% similarity]
librpc/gen_ndr/cli_lsa.c
librpc/gen_ndr/cli_lsa.h
librpc/gen_ndr/cli_spoolss.c
librpc/gen_ndr/cli_spoolss.h
librpc/gen_ndr/lsa.h
librpc/gen_ndr/ndr_lsa.c
librpc/gen_ndr/ndr_samr.c
librpc/gen_ndr/ndr_spoolss.c
librpc/gen_ndr/samr.h
librpc/gen_ndr/spoolss.h
librpc/gen_ndr/srv_lsa.c
librpc/gen_ndr/srv_spoolss.c
librpc/idl/frsapi.idl
librpc/idl/frsrpc.idl
librpc/idl/frstrans.idl [new file with mode: 0644]
librpc/idl/lsa.idl
librpc/idl/samr.idl
librpc/idl/spoolss.idl
librpc/ndr/ndr_frsrpc.c [new file with mode: 0644]
librpc/ndr/ndr_frsrpc.h [new file with mode: 0644]
librpc/ndr_standard.pc.in [new file with mode: 0644]
nsswitch/pam_winbind.c
pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
pidl/lib/Parse/Pidl/Samba4/Python.pm
pidl/lib/Parse/Pidl/Typelist.pm
source3/Makefile.in
source3/auth/auth.c
source3/auth/auth_sam.c
source3/client/client.c
source3/include/ads.h
source3/include/passdb.h
source3/include/proto.h
source3/include/smb.h
source3/include/smb_macros.h
source3/include/util_tdb.h
source3/lib/account_pol.c
source3/lib/ads_flags.c [deleted file]
source3/lib/charcnv.c
source3/lib/ctdbd_conn.c
source3/lib/dbwrap_tdb.c
source3/lib/dbwrap_util.c
source3/lib/errmap_unix.c
source3/lib/events.c
source3/lib/gencache.c
source3/lib/ldap_escape.c
source3/lib/netapi/netapi.c
source3/lib/netapi/user.c
source3/lib/smbldap_util.c
source3/lib/system.c
source3/lib/tldap.c
source3/lib/util_sock.c
source3/lib/util_str.c
source3/lib/util_tdb.c
source3/libads/dns.c
source3/libads/ldap_user.c
source3/libnet/libnet_samsync_passdb.c
source3/libsmb/clidgram.c
source3/libsmb/clifile.c
source3/libsmb/clikrb5.c
source3/libsmb/clispnego.c
source3/libsmb/dsgetdcname.c
source3/libsmb/libsmb_context.c
source3/libsmb/libsmb_thread_posix.c
source3/libsmb/namecache.c
source3/libsmb/namequery.c
source3/libsmb/spnego.c
source3/libsmb/trustdom_cache.c
source3/locking/brlock.c
source3/locking/locking.c
source3/locking/posix.c
source3/modules/nfs4_acls.c
source3/modules/onefs_acl.c
source3/modules/onefs_open.c
source3/modules/onefs_streams.c
source3/modules/vfs_acl_tdb.c
source3/modules/vfs_acl_xattr.c
source3/modules/vfs_afsacl.c
source3/modules/vfs_aixacl2.c
source3/modules/vfs_audit.c
source3/modules/vfs_cacheprime.c
source3/modules/vfs_cap.c
source3/modules/vfs_catia.c
source3/modules/vfs_default.c
source3/modules/vfs_dirsort.c
source3/modules/vfs_extd_audit.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_hpuxacl.c
source3/modules/vfs_hpuxacl.h
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_smb_traffic_analyzer.c
source3/modules/vfs_streams_xattr.c
source3/modules/vfs_tsmsm.c
source3/modules/vfs_zfsacl.c
source3/nmbd/nmbd.c
source3/param/loadparm.c
source3/passdb/passdb.c
source3/passdb/pdb_ads.c
source3/passdb/pdb_get_set.c
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_wbc_sam.c
source3/printing/printfsp.c
source3/registry/reg_backend_db.c
source3/registry/reg_backend_netlogon_params.c
source3/registry/reg_objects.c
source3/rpc_parse/parse_prs.c
source3/rpc_server/srv_lsa_nt.c
source3/rpc_server/srv_samr_nt.c
source3/rpc_server/srv_samr_util.c
source3/rpc_server/srv_spoolss_nt.c
source3/rpc_server/srv_srvsvc_nt.c
source3/rpcclient/cmd_lsarpc.c
source3/rpcclient/cmd_spoolss.c
source3/script/tests/test_smbtorture_s3.sh
source3/smbd/aio.c
source3/smbd/blocking.c
source3/smbd/chgpasswd.c
source3/smbd/close.c
source3/smbd/dosmode.c
source3/smbd/error.c
source3/smbd/fake_file.c
source3/smbd/file_access.c
source3/smbd/fileio.c
source3/smbd/filename.c
source3/smbd/filename_util.c [new file with mode: 0644]
source3/smbd/files.c
source3/smbd/globals.c
source3/smbd/globals.h
source3/smbd/ipc.c
source3/smbd/msdfs.c
source3/smbd/notify.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/oplock_irix.c
source3/smbd/oplock_linux.c
source3/smbd/oplock_onefs.c
source3/smbd/password.c
source3/smbd/pipes.c
source3/smbd/posix_acls.c
source3/smbd/process.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/service.c
source3/smbd/sesssetup.c
source3/smbd/smb2_close.c
source3/smbd/smb2_create.c
source3/smbd/smb2_flush.c
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_lock.c
source3/smbd/smb2_notify.c
source3/smbd/smb2_read.c
source3/smbd/smb2_server.c
source3/smbd/smb2_setinfo.c
source3/smbd/smb2_write.c
source3/smbd/statcache.c
source3/smbd/trans2.c
source3/smbd/vfs.c
source3/torture/cmd_vfs.c
source3/torture/locktest.c
source3/torture/locktest2.c
source3/torture/pdbtest.c
source3/torture/torture.c
source3/utils/net.c
source3/utils/net.h
source3/utils/net_ads.c
source3/utils/net_cache.c
source3/utils/net_dom.c
source3/utils/net_help.c
source3/utils/net_proto.h
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source3/utils/net_rpc_samsync.c
source3/utils/net_rpc_shell.c
source3/utils/net_sam.c
source3/utils/net_usershare.c
source3/utils/net_util.c
source3/utils/pdbedit.c
source3/winbindd/winbindd.c
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_passdb.c
source3/winbindd/winbindd_sid.c
source3/winbindd/winbindd_util.c
source4/auth/auth.h
source4/auth/gensec/gensec_krb5.c
source4/auth/sam.c
source4/cldap_server/netlogon.c
source4/configure.ac
source4/dsdb/common/sidmap.c
source4/dsdb/common/util.c
source4/dsdb/config.mk
source4/dsdb/samdb/ldb_modules/instancetype.c
source4/dsdb/samdb/ldb_modules/linked_attributes.c
source4/dsdb/samdb/ldb_modules/password_hash.c
source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/ldb_modules/rootdse.c
source4/dsdb/samdb/ldb_modules/samldb.c
source4/dsdb/samdb/samdb.c
source4/dsdb/samdb/samdb.h
source4/heimdal/kdc/kaserver.c
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/krb5tgs.c
source4/heimdal/lib/gssapi/gssapi/gssapi.h
source4/heimdal/lib/gssapi/krb5/8003.c
source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
source4/heimdal/lib/gssapi/krb5/acquire_cred.c
source4/heimdal/lib/gssapi/krb5/add_cred.c
source4/heimdal/lib/gssapi/krb5/aeap.c
source4/heimdal/lib/gssapi/krb5/arcfour.c
source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
source4/heimdal/lib/gssapi/krb5/cfx.c
source4/heimdal/lib/gssapi/krb5/compare_name.c
source4/heimdal/lib/gssapi/krb5/compat.c
source4/heimdal/lib/gssapi/krb5/context_time.c
source4/heimdal/lib/gssapi/krb5/copy_ccache.c
source4/heimdal/lib/gssapi/krb5/decapsulate.c
source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
source4/heimdal/lib/gssapi/krb5/display_name.c
source4/heimdal/lib/gssapi/krb5/display_status.c
source4/heimdal/lib/gssapi/krb5/duplicate_name.c
source4/heimdal/lib/gssapi/krb5/encapsulate.c
source4/heimdal/lib/gssapi/krb5/export_name.c
source4/heimdal/lib/gssapi/krb5/export_sec_context.c
source4/heimdal/lib/gssapi/krb5/external.c
source4/heimdal/lib/gssapi/krb5/get_mic.c
source4/heimdal/lib/gssapi/krb5/import_name.c
source4/heimdal/lib/gssapi/krb5/import_sec_context.c
source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
source4/heimdal/lib/gssapi/krb5/init.c
source4/heimdal/lib/gssapi/krb5/init_sec_context.c
source4/heimdal/lib/gssapi/krb5/inquire_context.c
source4/heimdal/lib/gssapi/krb5/inquire_cred.c
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
source4/heimdal/lib/gssapi/krb5/prf.c
source4/heimdal/lib/gssapi/krb5/process_context_token.c
source4/heimdal/lib/gssapi/krb5/release_buffer.c
source4/heimdal/lib/gssapi/krb5/release_cred.c
source4/heimdal/lib/gssapi/krb5/release_name.c
source4/heimdal/lib/gssapi/krb5/sequence.c
source4/heimdal/lib/gssapi/krb5/set_cred_option.c
source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
source4/heimdal/lib/gssapi/krb5/unwrap.c
source4/heimdal/lib/gssapi/krb5/verify_mic.c
source4/heimdal/lib/gssapi/krb5/wrap.c
source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
source4/heimdal/lib/gssapi/mech/gss_aeap.c
source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
source4/heimdal/lib/hcrypto/des.h
source4/heimdal/lib/hcrypto/evp.h
source4/heimdal/lib/hdb/db.c
source4/heimdal/lib/hdb/dbinfo.c
source4/heimdal/lib/hdb/ext.c
source4/heimdal/lib/hdb/hdb.asn1
source4/heimdal/lib/hdb/hdb.c
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hdb/keys.c
source4/heimdal/lib/hdb/keytab.c
source4/heimdal/lib/hdb/mkey.c
source4/heimdal/lib/hdb/ndbm.c
source4/heimdal/lib/hx509/crypto.c
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/get_addrs.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/krb5.h
source4/heimdal/lib/krb5/log.c
source4/heimdal/lib/krb5/store_emem.c
source4/heimdal_build/ifaddrs.hin [new file with mode: 0644]
source4/heimdal_build/internal.m4
source4/heimdal_build/replace.c
source4/heimdal_build/roken.h
source4/kdc/hdb-samba4.c
source4/kdc/pac-glue.c
source4/lib/ldb/common/ldb.c
source4/lib/ldb/common/ldb_debug.c
source4/lib/ldb/common/ldb_ldif.c
source4/lib/ldb/common/ldb_match.c
source4/lib/ldb/common/ldb_modules.c
source4/lib/ldb/ldb.mk
source4/lib/ldb/ldb.pc.in
source4/lib/ldb/ldb_ildap/ldb_ildap.c
source4/lib/ldb/ldb_ldap/ldb_ldap.c
source4/lib/ldb/ldb_map/ldb_map.c
source4/lib/ldb/ldb_map/ldb_map_inbound.c
source4/lib/ldb/ldb_map/ldb_map_outbound.c
source4/lib/ldb/ldb_tdb/ldb_cache.c
source4/lib/ldb/ldb_tdb/ldb_index.c
source4/lib/ldb/ldb_tdb/ldb_pack.c
source4/lib/ldb/ldb_tdb/ldb_tdb.c
source4/lib/ldb/modules/asq.c
source4/lib/ldb/modules/operational.c
source4/lib/ldb/modules/paged_results.c
source4/lib/ldb/modules/rdn_name.c
source4/lib/ldb/modules/sort.c
source4/lib/ldb/pyldb.c
source4/lib/ldb/pyldb.h
source4/lib/ldb/pyldb_util.c [deleted file]
source4/lib/ldb/python.mk
source4/lib/ldb/rules.mk
source4/lib/registry/patchfile.c
source4/lib/samba3/README
source4/lib/samba3/STATUS [deleted file]
source4/lib/samba3/samba3.h
source4/libcli/security/security_token.c
source4/libcli/smb2/request.c
source4/libcli/smb2/smb2.h
source4/libcli/smb2/transport.c
source4/libnet/libnet_become_dc.c
source4/libnet/libnet_group.c
source4/libnet/libnet_group.h
source4/libnet/libnet_samdump.c
source4/libnet/libnet_unbecome_dc.c
source4/libnet/libnet_user.c
source4/libnet/libnet_user.h
source4/librpc/config.mk
source4/ntptr/simple_ldb/ntptr_simple_ldb.c
source4/ntvfs/ipc/vfs_ipc.c
source4/ntvfs/posix/pvfs_resolve.c
source4/ntvfs/unixuid/vfs_unixuid.c
source4/rpc_server/config.mk
source4/rpc_server/lsa/dcesrv_lsa.c
source4/rpc_server/lsa/lsa_lookup.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/samr/dcesrv_samr.c
source4/rpc_server/samr/samr_password.c
source4/script/installmisc.sh
source4/scripting/python/pyglue.c
source4/scripting/python/samba/__init__.py
source4/scripting/python/samba/getopt.py
source4/scripting/python/samba/idmap.py
source4/scripting/python/samba/ms_schema.py
source4/scripting/python/samba/provision.py
source4/scripting/python/samba/samba3.py
source4/scripting/python/samba/samdb.py
source4/scripting/python/samba/tests/shares.py [new file with mode: 0644]
source4/scripting/python/samba/upgrade.py
source4/selftest/knownfail
source4/setup/provision
source4/setup/provision.ldif
source4/setup/provision_basedn_modify.ldif
source4/setup/provision_computers_modify.ldif
source4/setup/provision_configuration.ldif
source4/setup/provision_group_policy.ldif
source4/setup/provision_rootdse_add.ldif
source4/setup/provision_self_join.ldif
source4/setup/provision_users.ldif
source4/setup/provision_users_modify.ldif
source4/setup/schema_samba4.ldif
source4/torture/auth/pac.c
source4/torture/rpc/frsapi.c
source4/torture/rpc/lsa.c
source4/torture/rpc/object_uuid.c
source4/torture/rpc/rpc.c
source4/torture/rpc/spoolss.c
source4/torture/smb2/config.mk
source4/torture/smb2/connect.c
source4/torture/smb2/dir.c
source4/torture/smb2/getinfo.c
source4/torture/smb2/smb2.c
source4/winbind/wb_cmd_list_users.c

diff --git a/Roadmap b/Roadmap
index 1132f6391c7bccac2f6583133bf0100ce2411627..c5b8a4d115e361cae7077f11bcf8a6f8dc2f88f0 100644 (file)
--- a/Roadmap
+++ b/Roadmap
@@ -12,7 +12,7 @@ are in progress:
 Samba-3.0.x            This release turned into maintenance mode since we
                        released 3.2.
 
-Samba-3.2.x            This is the current stable Samba 3 release intended
+Samba-3.4.x            This is the current stable Samba 3 release intended
                        for all Samba production server.
 
 Samba-4                        Danger Will Robinson, a big code clean up with major
index fe8d541de82138c3fdc2ccc2ba199971743d144a..066f7189992c8ac01c054c3fe2205ab1180cfa45 100644 (file)
@@ -14,9 +14,6 @@ Authentication Changes:
 o Changed the way smbd handles untrusted domain names given during user
   authentication
 
-net Command Changes:
-o parameter syntax made more consistent
-
 Authentication Changes
 ======================
 
@@ -35,38 +32,6 @@ on smbd to always pass through bogus names to the DC for verification.  A new
 parameter "map untrusted to domain" can be enabled to revert to the legacy
 behavior.
 
-net Command Changes
-===================
-
-The net command now accepts the common command line parameters most other Samba
-command line utilities use, with a couple of remaining differences:
-
--l still gives long output for net commands supporting the --long flag. This was
-more useful than the common --log-base parameter.
-
--i still tells net to read data from stdin (like --stdin) instead of toggling
-the common --scope flag.
-
--S still tells net the server to connect to (like --server) instead of
-negotiating the common --signing flag. As -S is probably used by most scripts
-doing net rpc commands, this would have been a high-impact change for little
-gain.
-
-This change was mainly done to unify the authentification options. Here, one
-flag changed it's meaning and one useful flag was added.
-
--N used to be the short version of --ntname. It now matches the Samba default of
---no-pass. Use this to stop net from prompting for a password if you want
-anonymous authentication.
-
--A --authentication-file now takes an authentication file with the username and
-password you want net to use, avoiding a password prompt as with plain -U user
-or having to give a password on the command line as in -U user%pass.
-
-Last but not least net now always falls back to your local unix username if no
--U is specified and a username is needed. net rpc commands will now prompt for a
-password unless one is specified using either -U user%pass or -A auth_file.
-
 ######################################################################
 Reporting bugs & Development Discussion
 #######################################
index 4110de35fde43dacc0eaa6300bd08922fb90223a..82b9f7b91ba46fd36798bc91b4475d39177e0b02 100644 (file)
@@ -1,6 +1,7 @@
 /*
 * CIFS user-space helper.
 * Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
+* Copyright (C) Jeff Layton (jlayton@redhat.com) 2009
 *
 * Used by /sbin/request-key for handling
 * cifs upcall for kerberos authorization of access to share and
@@ -37,6 +38,54 @@ typedef enum _secType {
        MS_KRB5
 } secType_t;
 
+/*
+ * given a process ID, get the value of the KRB5CCNAME environment variable
+ * in the context of that process. On error, just return NULL.
+ */
+static char *
+get_krb5_ccname(pid_t pid)
+{
+       int fd;
+       ssize_t len, left;
+
+       /*
+        * FIXME: sysconf for ARG_MAX instead? Kernel seems to be limited to a
+        * page however, so it may not matter.
+        */
+       char buf[4096];
+       char *p, *value = NULL;
+       
+       buf[4095] = '\0';
+       snprintf(buf, 4095, "/proc/%d/environ", pid);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+
+       /* FIXME: don't assume that we get it all in the first read? */
+       len = read(fd, buf, 4096);
+       close(fd);
+       if (len < 0)
+               return NULL;
+
+       left = len;
+       p = buf;
+
+       /* can't have valid KRB5CCNAME if there are < 13 bytes left */
+       while (left > 12) {
+               if (strncmp("KRB5CCNAME=", p, 11)) {
+                       p += strnlen(p, left);
+                       ++p;
+                       left = buf + len - p;
+                       continue;
+               }
+               p += 11;
+               left -= 11;
+               value = SMB_STRNDUP(p, left);
+               break;
+       }
+       return value;
+}
+
 /*
  * Prepares AP-REQ data for mechToken and gets session key
  * Uses credentials from cache. It will not ask for password
@@ -58,15 +107,15 @@ typedef enum _secType {
  * ret: 0 - success, others - failure
 */
 static int
-handle_krb5_mech(const char *oid, const char *principal,
-                    DATA_BLOB * secblob, DATA_BLOB * sess_key)
+handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob,
+                DATA_BLOB *sess_key, const char *ccname)
 {
        int retval;
        DATA_BLOB tkt, tkt_wrapped;
 
        /* get a kerberos ticket for the service and extract the session key */
-       retval = cli_krb5_get_ticket(principal, 0,
-                                    &tkt, sess_key, 0, NULL, NULL);
+       retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname,
+                                    NULL);
 
        if (retval)
                return retval;
@@ -88,11 +137,12 @@ handle_krb5_mech(const char *oid, const char *principal,
 #define DKD_HAVE_IPV4          8
 #define DKD_HAVE_IPV6          16
 #define DKD_HAVE_UID           32
+#define DKD_HAVE_PID           64
 #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
 
 static int
-decode_key_description(const char *desc, int *ver, secType_t * sec,
-                          char **hostname, uid_t * uid)
+decode_key_description(const char *desc, int *ver, secType_t *sec,
+                          char **hostname, uid_t *uid, pid_t *pid)
 {
        int retval = 0;
        char *pos;
@@ -117,6 +167,16 @@ decode_key_description(const char *desc, int *ver, secType_t * sec,
                        /* BB: do we need it if we have hostname already? */
                } else if (strncmp(tkn, "ipv6=", 5) == 0) {
                        /* BB: do we need it if we have hostname already? */
+               } else if (strncmp(tkn, "pid=", 4) == 0) {
+                       errno = 0;
+                       *pid = strtol(tkn + 4, NULL, 0);
+                       if (errno != 0) {
+                               syslog(LOG_WARNING, "Invalid pid format: %s",
+                                      strerror(errno));
+                               return 1;
+                       } else {
+                               retval |= DKD_HAVE_PID;
+                       }
                } else if (strncmp(tkn, "sec=", 4) == 0) {
                        if (strncmp(tkn + 4, "krb5", 4) == 0) {
                                retval |= DKD_HAVE_SEC;
@@ -224,9 +284,10 @@ int main(const int argc, char *const argv[])
        size_t datalen;
        long rc = 1;
        uid_t uid = 0;
+       pid_t pid = 0;
        int kernel_upcall_version = 0;
        int c, use_cifs_service_prefix = 0;
-       char *buf, *hostname = NULL;
+       char *buf, *ccname = NULL, *hostname = NULL;
        const char *oid;
 
        openlog(prog, 0, LOG_DAEMON);
@@ -278,7 +339,7 @@ int main(const int argc, char *const argv[])
        }
 
        rc = decode_key_description(buf, &kernel_upcall_version, &sectype,
-                                   &hostname, &uid);
+                                   &hostname, &uid, &pid);
        if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
                syslog(LOG_WARNING,
                       "unable to get from description necessary params");
@@ -296,6 +357,9 @@ int main(const int argc, char *const argv[])
                goto out;
        }
 
+       if (rc & DKD_HAVE_PID)
+               ccname = get_krb5_ccname(pid);
+
        if (rc & DKD_HAVE_UID) {
                rc = setuid(uid);
                if (rc == -1) {
@@ -304,9 +368,6 @@ int main(const int argc, char *const argv[])
                }
        }
 
-       /* BB: someday upcall SPNEGO blob could be checked here to decide
-        * what mech to use */
-
        // do mech specific authorization
        switch (sectype) {
        case MS_KRB5:
@@ -333,7 +394,8 @@ int main(const int argc, char *const argv[])
                        else
                                oid = OID_KERBEROS5;
 
-                       rc = handle_krb5_mech(oid, princ, &secblob, &sess_key);
+                       rc = handle_krb5_mech(oid, princ, &secblob, &sess_key,
+                                             ccname);
                        SAFE_FREE(princ);
                        break;
                }
@@ -385,6 +447,7 @@ out:
                keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
        data_blob_free(&secblob);
        data_blob_free(&sess_key);
+       SAFE_FREE(ccname);
        SAFE_FREE(hostname);
        SAFE_FREE(keydata);
        return rc;
index e88559fc8aa3b0c2d63f37b453b0812f7306b94d..fb16486374468016ebe9325934d3d01f2d509a6a 100644 (file)
@@ -115,6 +115,10 @@ attributeTypes: ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Loc
 attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 # "refuse machine password change"
 attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPassword' DESC 'Clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTextPassword' DESC 'Previous clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
 ##
 #######################################################################
 ##              objectClasses: used by Samba 3.0 schema               ##
@@ -154,3 +158,7 @@ objectClasses: ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCT
 ##     DESC 'Samba Privilege'
 ##     MUST ( sambaSID )
 ##     MAY ( sambaPrivilegeList ) )
+##
+## Trusted Domain Relationships
+##
+objectClasses: ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassword' SUP top STRUCTURAL DESC 'Samba Trusted Domain Password' MUST ( sambaDomainName $ sambaSID $ sambaClearTextPassword $ sambaPwdLastSet ) MAY ( sambaPreviousClearTextPassword ) )
index 600580b1aadc5a023f3449a372e088151304eca3..da8331460888af3b367e2a9df88cb52022866c73 100755 (executable)
@@ -1,13 +1,14 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
 
-timestamp='2005-09-19'
+timestamp='2009-04-27'
 
 # This file 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
+# 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
@@ -16,7 +17,9 @@ timestamp='2005-09-19'
 # 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/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -53,8 +56,8 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -104,7 +107,7 @@ set_cc_for_build='
 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
 trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 : ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
  { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
  { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
  { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@@ -158,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
            arm*) machine=arm-unknown ;;
            sh3el) machine=shl-unknown ;;
            sh3eb) machine=sh-unknown ;;
+           sh5el) machine=sh5le-unknown ;;
            *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
        esac
        # The Operating System including object format, if it has switched
@@ -204,8 +208,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:ekkoBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
        exit ;;
+    *:SolidBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       exit ;;
     macppc:MirBSD:*:*)
-       echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
        exit ;;
     *:MirBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -317,14 +324,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        case `/usr/bin/uname -p` in
            sparc) echo sparc-icl-nx7; exit ;;
        esac ;;
+    s390x:SunOS:*:*)
+       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
     sun4H:SunOS:5.*:*)
        echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
        echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
-    i86pc:SunOS:5.*:*)
-       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+       eval $set_cc_for_build
+       SUN_ARCH="i386"
+       # If there is a compiler, see if it is configured for 64-bit objects.
+       # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+       # This test works for both compilers.
+       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+           if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+               grep IS_64BIT_ARCH >/dev/null
+           then
+               SUN_ARCH="x86_64"
+           fi
+       fi
+       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
        exit ;;
     sun4*:SunOS:6*:*)
        # According to config.sub, this is the proper way to canonicalize
@@ -525,7 +548,7 @@ EOF
                echo rs6000-ibm-aix3.2
        fi
        exit ;;
-    *:AIX:*:[45])
+    *:AIX:*:[456])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
        if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
                IBM_ARCH=rs6000
@@ -762,12 +785,19 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit ;;
     *:FreeBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       case ${UNAME_MACHINE} in
+           pc98)
+               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           amd64)
+               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           *)
+               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       esac
        exit ;;
     i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
        exit ;;
-    i*:MINGW*:*)
+    *:MINGW*:*)
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
     i*:windows32*:*)
@@ -777,9 +807,18 @@ EOF
     i*:PW*:*)
        echo ${UNAME_MACHINE}-pc-pw32
        exit ;;
-    x86:Interix*:[34]*)
-       echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
-       exit ;;
+    *:Interix*:[3456]*)
+       case ${UNAME_MACHINE} in
+           x86)
+               echo i586-pc-interix${UNAME_RELEASE}
+               exit ;;
+           EM64T | authenticamd | genuineintel)
+               echo x86_64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+           IA64)
+               echo ia64-unknown-interix${UNAME_RELEASE}
+               exit ;;
+       esac ;;
     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
        echo i${UNAME_MACHINE}-pc-mks
        exit ;;
@@ -813,6 +852,16 @@ EOF
        echo ${UNAME_MACHINE}-pc-minix
        exit ;;
     arm*:Linux:*:*)
+       eval $set_cc_for_build
+       if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+           | grep -q __ARM_EABI__
+       then
+           echo ${UNAME_MACHINE}-unknown-linux-gnu
+       else
+           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+       fi
+       exit ;;
+    avr32*:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
     cris:Linux:*:*)
@@ -849,7 +898,11 @@ EOF
        #endif
        #endif
 EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
        test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
        ;;
     mips64:Linux:*:*)
@@ -868,7 +921,11 @@ EOF
        #endif
        #endif
 EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
        test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
        ;;
     or32:Linux:*:*)
@@ -894,6 +951,9 @@ EOF
        if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
        echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
        exit ;;
+    padre:Linux:*:*)
+       echo sparc-unknown-linux-gnu
+       exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -917,9 +977,15 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit ;;
+    vax:Linux:*:*)
+       echo ${UNAME_MACHINE}-dec-linux-gnu
+       exit ;;
     x86_64:Linux:*:*)
        echo x86_64-unknown-linux-gnu
        exit ;;
+    xtensa*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
     i*86:Linux:*:*)
        # The BFD linker knows what the default object file format is, so
        # first see if it will tell us. cd to the root directory to prevent
@@ -938,9 +1004,6 @@ EOF
          a.out-i386-linux)
                echo "${UNAME_MACHINE}-pc-linux-gnuaout"
                exit ;;
-         coff-i386)
-               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-               exit ;;
          "")
                # Either a pre-BFD a.out linker (linux-gnuoldld) or
                # one that does not give us useful --help.
@@ -962,7 +1025,7 @@ EOF
        LIBC=gnulibc1
        # endif
        #else
-       #ifdef __INTEL_COMPILER
+       #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
        LIBC=gnu
        #else
        LIBC=gnuaout
@@ -972,7 +1035,11 @@ EOF
        LIBC=dietlibc
        #endif
 EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^LIBC/{
+               s: ::g
+               p
+           }'`"
        test x"${LIBC}" != x && {
                echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
                exit
@@ -1051,8 +1118,11 @@ EOF
     pc:*:*:*)
        # Left here for compatibility:
         # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-       echo i386-pc-msdosdjgpp
+        # the processor, so we play safe by assuming i586.
+       # Note: whatever this is, it MUST be the same as what config.sub
+       # prints for the "djgpp" host, or else GDB configury will decide that
+       # this is a cross-build.
+       echo i586-pc-msdosdjgpp
         exit ;;
     Intel:Mach:3*:*)
        echo i386-pc-mach3
@@ -1090,6 +1160,16 @@ EOF
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
           && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+       OS_REL='.3'
+       test -r /etc/.relid \
+           && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
        echo m68k-unknown-lynxos${UNAME_RELEASE}
        exit ;;
@@ -1165,6 +1245,9 @@ EOF
     BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
        echo i586-pc-beos
        exit ;;
+    BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
+       echo i586-pc-haiku
+       exit ;;
     SX-4:SUPER-UX:*:*)
        echo sx4-nec-superux${UNAME_RELEASE}
        exit ;;
@@ -1174,6 +1257,15 @@ EOF
     SX-6:SUPER-UX:*:*)
        echo sx6-nec-superux${UNAME_RELEASE}
        exit ;;
+    SX-7:SUPER-UX:*:*)
+       echo sx7-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8:SUPER-UX:*:*)
+       echo sx8-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-8R:SUPER-UX:*:*)
+       echo sx8r-nec-superux${UNAME_RELEASE}
+       exit ;;
     Power*:Rhapsody:*:*)
        echo powerpc-apple-rhapsody${UNAME_RELEASE}
        exit ;;
@@ -1261,6 +1353,12 @@ EOF
     i*86:skyos:*:*)
        echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
        exit ;;
+    i*86:rdos:*:*)
+       echo ${UNAME_MACHINE}-pc-rdos
+       exit ;;
+    i*86:AROS:*:*)
+       echo ${UNAME_MACHINE}-pc-aros
+       exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1421,9 +1519,9 @@ This script, last modified $timestamp, has failed to recognize
 the operating system you are using. It is advised that you
 download the most up to date version of the config scripts from
 
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 and
-  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 
 If the version you run ($0) is already up to date, please
 send the following data and any information you think might be
index 23cd6fd75c85db36a7d824b2cf8b857374edbdbc..a39437d0158ed7058a189617db490472252a70ae 100755 (executable)
@@ -1,9 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
 
-timestamp='2005-07-08'
+timestamp='2009-04-17'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -11,7 +12,7 @@ timestamp='2005-07-08'
 #
 # This file 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
+# 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,
@@ -20,7 +21,9 @@ timestamp='2005-07-08'
 # 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/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -69,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,8 +120,10 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
-  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
@@ -169,6 +174,10 @@ case $os in
        -hiux*)
                os=-hiuxwe2
                ;;
+       -sco6)
+               os=-sco5v6
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
        -sco5)
                os=-sco3.2v5
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -185,6 +194,10 @@ case $os in
                # Don't forget version if it is 3.2v4 or newer.
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
                ;;
+       -sco5v6*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
        -sco*)
                os=-sco3.2v2
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -229,20 +242,24 @@ case $basic_machine in
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
        | bfin \
        | c4x | clipper \
        | d10v | d30v | dlx | dsp16xx \
-       | fr30 | frv \
+       | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
-       | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+       | lm32 \
+       | m32c | m32r | m32rle | m68000 | m68k | m88k \
+       | maxq | mb | microblaze | mcore | mep | metag \
        | mips | mipsbe | mipseb | mipsel | mipsle \
        | mips16 \
        | mips64 | mips64el \
-       | mips64vr | mips64vrel \
+       | mips64octeon | mips64octeonel \
        | mips64orion | mips64orionel \
+       | mips64r5900 | mips64r5900el \
+       | mips64vr | mips64vrel \
        | mips64vr4100 | mips64vr4100el \
        | mips64vr4300 | mips64vr4300el \
        | mips64vr5000 | mips64vr5000el \
@@ -255,26 +272,26 @@ case $basic_machine in
        | mipsisa64sr71k | mipsisa64sr71kel \
        | mipstx39 | mipstx39el \
        | mn10200 | mn10300 \
-       | ms1 \
+       | moxie \
+       | mt \
        | msp430 \
+       | nios | nios2 \
        | ns16k | ns32k \
        | or32 \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
        | pyramid \
-       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | score \
+       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b \
-       | strongarm \
+       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+       | spu | strongarm \
        | tahoe | thumb | tic4x | tic80 | tron \
        | v850 | v850e \
        | we32k \
-       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
-       | z8k)
-               basic_machine=$basic_machine-unknown
-               ;;
-       m32c)
+       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | z8k | z80)
                basic_machine=$basic_machine-unknown
                ;;
        m6811 | m68hc11 | m6812 | m68hc12)
@@ -284,6 +301,9 @@ case $basic_machine in
                ;;
        m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
                ;;
+       ms1)
+               basic_machine=mt-unknown
+               ;;
 
        # We use `pc' rather than `unknown'
        # because (1) that's what they normally are, and
@@ -303,25 +323,28 @@ case $basic_machine in
        | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
        | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* \
+       | avr-* | avr32-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
        | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
-       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
-       | m32r-* | m32rle-* \
+       | lm32-* \
+       | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
        | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
        | mips16-* \
        | mips64-* | mips64el-* \
-       | mips64vr-* | mips64vrel-* \
+       | mips64octeon-* | mips64octeonel-* \
        | mips64orion-* | mips64orionel-* \
+       | mips64r5900-* | mips64r5900el-* \
+       | mips64vr-* | mips64vrel-* \
        | mips64vr4100-* | mips64vr4100el-* \
        | mips64vr4300-* | mips64vr4300el-* \
        | mips64vr5000-* | mips64vr5000el-* \
@@ -334,30 +357,33 @@ case $basic_machine in
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
        | mipstx39-* | mipstx39el-* \
        | mmix-* \
-       | ms1-* \
+       | mt-* \
        | msp430-* \
+       | nios-* | nios2-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
        | pyramid-* \
        | romp-* | rs6000-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
        | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
        | tron-* \
        | v850-* | v850e-* | vax-* \
        | we32k-* \
-       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
-       | xstormy16-* | xtensa-* \
+       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | xstormy16-* | xtensa*-* \
        | ymp-* \
-       | z8k-*)
+       | z8k-* | z80-*)
                ;;
-       m32c-*)
+       # Recognize the basic CPU types without company name, with glob match.
+       xtensa*)
+               basic_machine=$basic_machine-unknown
                ;;
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
@@ -421,6 +447,10 @@ case $basic_machine in
                basic_machine=m68k-apollo
                os=-bsd
                ;;
+       aros)
+               basic_machine=i386-pc
+               os=-aros
+               ;;
        aux)
                basic_machine=m68k-apple
                os=-aux
@@ -429,10 +459,22 @@ case $basic_machine in
                basic_machine=ns32k-sequent
                os=-dynix
                ;;
+       blackfin)
+               basic_machine=bfin-unknown
+               os=-linux
+               ;;
+       blackfin-*)
+               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
        c90)
                basic_machine=c90-cray
                os=-unicos
                ;;
+        cegcc)
+               basic_machine=arm-unknown
+               os=-cegcc
+               ;;
        convex-c1)
                basic_machine=c1-convex
                os=-bsd
@@ -461,8 +503,8 @@ case $basic_machine in
                basic_machine=craynv-cray
                os=-unicosmp
                ;;
-       cr16c)
-               basic_machine=cr16c-unknown
+       cr16)
+               basic_machine=cr16-unknown
                os=-elf
                ;;
        crds | unos)
@@ -500,6 +542,10 @@ case $basic_machine in
                basic_machine=m88k-motorola
                os=-sysv3
                ;;
+       dicos)
+               basic_machine=i686-pc
+               os=-dicos
+               ;;
        djgpp)
                basic_machine=i586-pc
                os=-msdosdjgpp
@@ -654,6 +700,14 @@ case $basic_machine in
                basic_machine=m68k-isi
                os=-sysv
                ;;
+       m68knommu)
+               basic_machine=m68k-unknown
+               os=-linux
+               ;;
+       m68knommu-*)
+               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
        m88k-omron*)
                basic_machine=m88k-omron
                ;;
@@ -669,6 +723,10 @@ case $basic_machine in
                basic_machine=i386-pc
                os=-mingw32
                ;;
+       mingw32ce)
+               basic_machine=arm-unknown
+               os=-mingw32ce
+               ;;
        miniframe)
                basic_machine=m68000-convergent
                ;;
@@ -694,6 +752,9 @@ case $basic_machine in
                basic_machine=i386-pc
                os=-msdos
                ;;
+       ms1-*)
+               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               ;;
        mvs)
                basic_machine=i370-ibm
                os=-mvs
@@ -792,6 +853,14 @@ case $basic_machine in
                basic_machine=i860-intel
                os=-osf
                ;;
+       parisc)
+               basic_machine=hppa-unknown
+               os=-linux
+               ;;
+       parisc-*)
+               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+               os=-linux
+               ;;
        pbd)
                basic_machine=sparc-tti
                ;;
@@ -801,6 +870,12 @@ case $basic_machine in
        pc532 | pc532-*)
                basic_machine=ns32k-pc532
                ;;
+       pc98)
+               basic_machine=i386-pc
+               ;;
+       pc98-*)
+               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        pentium | p5 | k5 | k6 | nexgen | viac3)
                basic_machine=i586-pc
                ;;
@@ -857,6 +932,10 @@ case $basic_machine in
                basic_machine=i586-unknown
                os=-pw32
                ;;
+       rdos)
+               basic_machine=i386-pc
+               os=-rdos
+               ;;
        rom68k)
                basic_machine=m68k-rom68k
                os=-coff
@@ -883,6 +962,10 @@ case $basic_machine in
        sb1el)
                basic_machine=mipsisa64sb1el-unknown
                ;;
+       sde)
+               basic_machine=mipsisa32-sde
+               os=-elf
+               ;;
        sei)
                basic_machine=mips-sei
                os=-seiux
@@ -894,6 +977,9 @@ case $basic_machine in
                basic_machine=sh-hitachi
                os=-hms
                ;;
+       sh5el)
+               basic_machine=sh5le-unknown
+               ;;
        sh64)
                basic_machine=sh64-unknown
                ;;
@@ -983,6 +1069,10 @@ case $basic_machine in
                basic_machine=tic6x-unknown
                os=-coff
                ;;
+       tile*)
+               basic_machine=tile-unknown
+               os=-linux-gnu
+               ;;
        tx39)
                basic_machine=mipstx39-unknown
                ;;
@@ -1058,6 +1148,10 @@ case $basic_machine in
                basic_machine=z8k-unknown
                os=-sim
                ;;
+       z80-*-coff)
+               basic_machine=z80-unknown
+               os=-sim
+               ;;
        none)
                basic_machine=none-none
                os=-none
@@ -1096,10 +1190,10 @@ case $basic_machine in
        we32k)
                basic_machine=we32k-att
                ;;
-       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
                basic_machine=sh-unknown
                ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b)
+       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
                basic_machine=sparc-sun
                ;;
        cydra)
@@ -1168,25 +1262,28 @@ case $os in
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -kopensolaris* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* \
+             | -aos* | -aros* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -openbsd* | -solidbsd* \
              | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* \
+             | -chorusos* | -chorusrdb* | -cegcc* \
              | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
              | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
@@ -1316,6 +1413,9 @@ case $os in
        -zvmoe)
                os=-zvmoe
                ;;
+       -dicos*)
+               os=-dicos
+               ;;
        -none)
                ;;
        *)
@@ -1338,6 +1438,12 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
+        score-*)
+               os=-elf
+               ;;
+        spu-*)
+               os=-elf
+               ;;
        *-acorn)
                os=-riscix1.2
                ;;
@@ -1347,9 +1453,9 @@ case $basic_machine in
        arm*-semi)
                os=-aout
                ;;
-    c4x-* | tic4x-*)
-        os=-coff
-        ;;
+        c4x-* | tic4x-*)
+               os=-coff
+               ;;
        # This must come before the *-dec entry.
        pdp10-*)
                os=-tops20
@@ -1375,6 +1481,9 @@ case $basic_machine in
        m68*-cisco)
                os=-aout
                ;;
+        mep-*)
+               os=-elf
+               ;;
        mips*-cisco)
                os=-elf
                ;;
index 2d90d9c7e859cce0294182eb21c6b549188c953e..a3a26ef43e48280ef4075b147649632bf7891e41 100644 (file)
@@ -103,6 +103,7 @@ AC_CHECK_HEADERS(sys/time.h time.h)
 AC_CHECK_HEADERS(stdarg.h vararg.h)
 AC_CHECK_HEADERS(sys/mount.h mntent.h)
 AC_CHECK_HEADERS(stropts.h)
+AC_CHECK_HEADERS(unix.h)
 
 AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
 AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
index fe1f732acb275434ffdbab15ae48d768ecda15f5..2db6aa1226cbe796666371151dc89d7656bac78e 100644 (file)
@@ -258,6 +258,10 @@ char *rep_realpath(const char *path, char *resolved_path);
 int rep_lchown(const char *fname,uid_t uid,gid_t gid);
 #endif
 
+#ifdef HAVE_UNIX_H
+#include <unix.h>
+#endif
+
 #ifndef HAVE_SETLINEBUF
 #define setlinebuf rep_setlinebuf
 void rep_setlinebuf(FILE *);
index f156c0fa7b2e548640d47db23df71c9427ec73ce..2c72ae1f0de1c5097afe8f54d27a04d7816e432a 100644 (file)
@@ -301,16 +301,21 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
  */
 int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
 {
-       if (tdb->have_transaction_lock || tdb->global_lock.count) {
+       if (tdb->global_lock.count) {
+               return 0;
+       }
+       if (tdb->transaction_lock_count > 0) {
+               tdb->transaction_lock_count++;
                return 0;
        }
+
        if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, 
                                     F_SETLKW, 0, 1) == -1) {
                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
                tdb->ecode = TDB_ERR_LOCK;
                return -1;
        }
-       tdb->have_transaction_lock = 1;
+       tdb->transaction_lock_count++;
        return 0;
 }
 
@@ -320,12 +325,16 @@ int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
 int tdb_transaction_unlock(struct tdb_context *tdb)
 {
        int ret;
-       if (!tdb->have_transaction_lock) {
+       if (tdb->global_lock.count) {
+               return 0;
+       }
+       if (tdb->transaction_lock_count > 1) {
+               tdb->transaction_lock_count--;
                return 0;
        }
        ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
        if (ret == 0) {
-               tdb->have_transaction_lock = 0;
+               tdb->transaction_lock_count = 0;
        }
        return ret;
 }
index ffac89ff0e315195b3defdebc35184ef7ab6a038..45b85f4c9334b91084e80141937ea029f443c037 100644 (file)
@@ -166,7 +166,7 @@ struct tdb_context {
        struct tdb_transaction *transaction;
        int page_size;
        int max_dead_records;
-       bool have_transaction_lock;
+       int transaction_lock_count;
        volatile sig_atomic_t *interrupt_sig_ptr;
 };
 
index 69c81e6e98fd27b7a4d8d86c7c6f620e64cd552a..07b0c238587eb85fe3945b61b71dbd9dd0729d58 100644 (file)
@@ -204,23 +204,18 @@ int tdb_traverse_read(struct tdb_context *tdb,
 {
        struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
        int ret;
-       bool in_transaction = (tdb->transaction != NULL);
 
        /* we need to get a read lock on the transaction lock here to
           cope with the lock ordering semantics of solaris10 */
-       if (!in_transaction) {
-               if (tdb_transaction_lock(tdb, F_RDLCK)) {
-                       return -1;
-               }
+       if (tdb_transaction_lock(tdb, F_RDLCK)) {
+               return -1;
        }
 
        tdb->traverse_read++;
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
        tdb->traverse_read--;
 
-       if (!in_transaction) {
-               tdb_transaction_unlock(tdb);
-       }
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }
@@ -237,25 +232,20 @@ int tdb_traverse(struct tdb_context *tdb,
 {
        struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
        int ret;
-       bool in_transaction = (tdb->transaction != NULL);
 
        if (tdb->read_only || tdb->traverse_read) {
                return tdb_traverse_read(tdb, fn, private_data);
        }
        
-       if (!in_transaction) {
-               if (tdb_transaction_lock(tdb, F_WRLCK)) {
-                       return -1;
-               }
+       if (tdb_transaction_lock(tdb, F_WRLCK)) {
+               return -1;
        }
 
        tdb->traverse_write++;
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
        tdb->traverse_write--;
 
-       if (!in_transaction) {
-               tdb_transaction_unlock(tdb);
-       }
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }
index d964fb33d390fa495ff98a429ba206e4c63d1626..f9aca91aa1c39f2b6e3edc37115fac141ef4cc7a 100644 (file)
@@ -66,7 +66,13 @@ static bool test_event_context(struct torture_context *test,
        const char *backend = (const char *)test_data;
        int alarm_count=0, info_count=0;
        struct tevent_fd *fde;
-       struct signal_event *se1, *se2, *se3;
+#ifdef SA_RESTART
+       struct tevent_signal *se1 = NULL;
+#endif
+       struct tevent_signal *se2 = NULL;
+#ifdef SA_SIGINFO
+       struct tevent_signal *se3 = NULL;
+#endif
        int finished=0;
        struct timeval t;
        char c = 0;
@@ -92,7 +98,9 @@ static bool test_event_context(struct torture_context *test,
        event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0), 
                        finished_handler, &finished);
 
+#ifdef SA_RESTART
        se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count);
+#endif
        se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count);
 #ifdef SA_SIGINFO
        se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count);
@@ -120,7 +128,9 @@ static bool test_event_context(struct torture_context *test,
 
        torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
 
+#ifdef SA_RESTART
        talloc_free(se1);
+#endif
 
        torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
 
index 541f93f99c3e36fe77d4f18823484edfc503656b..0feabb5f1f9d7bd2674fdf81cf4ad6146b8da520 100644 (file)
@@ -104,7 +104,7 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       data = talloc_size(req, data_size);
+       data = talloc_zero_size(req, data_size);
        if (data == NULL) {
                talloc_free(req);
                return NULL;
index 99447e7e5355bd93b62e8fc0e65bdcea6dcddf37..392cb0ad4c0ccebbdd12aa87c50c413a9890e241 100644 (file)
@@ -65,7 +65,6 @@ struct torture_context *torture_context_child(struct torture_context *parent)
        if (subtorture == NULL)
                return NULL;
 
-       subtorture->level = parent->level+1;
        subtorture->ev = talloc_reference(subtorture, parent->ev);
        subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx);
        subtorture->outputdir = talloc_reference(subtorture, parent->outputdir);
@@ -257,7 +256,6 @@ bool torture_run_suite(struct torture_context *context,
        struct torture_suite *tsuite;
        char *old_testname;
 
-       context->level++;
        if (context->results->ui_ops->suite_start)
                context->results->ui_ops->suite_start(context, suite);
 
@@ -282,8 +280,6 @@ bool torture_run_suite(struct torture_context *context,
        if (context->results->ui_ops->suite_finish)
                context->results->ui_ops->suite_finish(context, suite);
 
-       context->level--;
-       
        return ret;
 }
 
@@ -378,8 +374,6 @@ bool torture_run_tcase(struct torture_context *context,
        char *old_testname;
        struct torture_test *test;
 
-       context->level++;
-
        context->active_tcase = tcase;
        if (context->results->ui_ops->tcase_start) 
                context->results->ui_ops->tcase_start(context, tcase);
@@ -415,8 +409,6 @@ done:
        if (context->results->ui_ops->tcase_finish)
                context->results->ui_ops->tcase_finish(context, tcase);
 
-       context->level--;
-
        return ret;
 }
 
index bc6365351e3ab15f8568301d430b98d7fa7d4177..e28801e2692fc7528416cadc912d6f221c0af624 100644 (file)
@@ -86,9 +86,6 @@ struct torture_context
        /** Directory used for temporary test data */
        const char *outputdir;
        
-       /** Indentation level */
-       int level;
-
        /** Event context */
        struct tevent_context *ev;
 
index 78bca4b0b568d547785a6af55fa53adf34b6ba44..8f1ccbeb432251b048636494cc2e18e4a3ba9305 100644 (file)
@@ -203,7 +203,7 @@ struct tsocket_address_bsd {
 
 static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
                                              struct sockaddr *sa,
-                                             socklen_t sa_len,
+                                             socklen_t sa_socklen,
                                              struct tsocket_address **_addr,
                                              const char *location)
 {
@@ -212,20 +212,20 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
 
        switch (sa->sa_family) {
        case AF_UNIX:
-               if (sa_len < sizeof(struct sockaddr_un)) {
+               if (sa_socklen < sizeof(struct sockaddr_un)) {
                        errno = EINVAL;
                        return -1;
                }
                break;
        case AF_INET:
-               if (sa_len < sizeof(struct sockaddr_in)) {
+               if (sa_socklen < sizeof(struct sockaddr_in)) {
                        errno = EINVAL;
                        return -1;
                }
                break;
 #ifdef HAVE_IPV6
        case AF_INET6:
-               if (sa_len < sizeof(struct sockaddr_in6)) {
+               if (sa_socklen < sizeof(struct sockaddr_in6)) {
                        errno = EINVAL;
                        return -1;
                }
@@ -236,7 +236,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
                return -1;
        }
 
-       if (sa_len > sizeof(struct sockaddr_storage)) {
+       if (sa_socklen > sizeof(struct sockaddr_storage)) {
                errno = EINVAL;
                return -1;
        }
@@ -253,7 +253,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
 
        ZERO_STRUCTP(bsda);
 
-       memcpy(&bsda->u.ss, sa, sa_len);
+       memcpy(&bsda->u.ss, sa, sa_socklen);
 
        *_addr = addr;
        return 0;
@@ -773,7 +773,7 @@ static void tdgram_bsd_recvfrom_handler(void *private_data)
        struct tsocket_address_bsd *bsda;
        ssize_t ret;
        struct sockaddr *sa = NULL;
-       socklen_t sa_len = 0;
+       socklen_t sa_socklen = 0;
        int err;
        bool retry;
 
@@ -809,16 +809,16 @@ static void tdgram_bsd_recvfrom_handler(void *private_data)
        ZERO_STRUCTP(bsda);
 
        sa = &bsda->u.sa;
-       sa_len = sizeof(bsda->u.ss);
+       sa_socklen = sizeof(bsda->u.ss);
        /*
         * for unix sockets we can't use the size of sockaddr_storage
         * we would get EINVAL
         */
        if (bsda->u.sa.sa_family == AF_UNIX) {
-               sa_len = sizeof(bsda->u.un);
+               sa_socklen = sizeof(bsda->u.un);
        }
 
-       ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_len);
+       ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_socklen);
        err = tsocket_bsd_error_from_errno(ret, errno, &retry);
        if (retry) {
                /* retry later */
@@ -946,7 +946,7 @@ static void tdgram_bsd_sendto_handler(void *private_data)
        struct tdgram_context *dgram = state->dgram;
        struct tdgram_bsd *bsds = tdgram_context_data(dgram, struct tdgram_bsd);
        struct sockaddr *sa = NULL;
-       socklen_t sa_len = 0;
+       socklen_t sa_socklen = 0;
        ssize_t ret;
        int err;
        bool retry;
@@ -957,17 +957,17 @@ static void tdgram_bsd_sendto_handler(void *private_data)
                        struct tsocket_address_bsd);
 
                sa = &bsda->u.sa;
-               sa_len = sizeof(bsda->u.ss);
+               sa_socklen = sizeof(bsda->u.ss);
                /*
                 * for unix sockets we can't use the size of sockaddr_storage
                 * we would get EINVAL
                 */
                if (bsda->u.sa.sa_family == AF_UNIX) {
-                       sa_len = sizeof(bsda->u.un);
+                       sa_socklen = sizeof(bsda->u.un);
                }
        }
 
-       ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_len);
+       ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_socklen);
        err = tsocket_bsd_error_from_errno(ret, errno, &retry);
        if (retry) {
                /* retry later */
@@ -1087,7 +1087,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
        int ret;
        bool do_bind = false;
        bool do_reuseaddr = false;
-       socklen_t sa_len = sizeof(lbsda->u.ss);
+       socklen_t sa_socklen = sizeof(lbsda->u.ss);
 
        if (remote) {
                rbsda = talloc_get_type_abort(remote->private_data,
@@ -1108,7 +1108,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
                 * for unix sockets we can't use the size of sockaddr_storage
                 * we would get EINVAL
                 */
-               sa_len = sizeof(lbsda->u.un);
+               sa_socklen = sizeof(lbsda->u.un);
                break;
        case AF_INET:
                if (lbsda->u.in.sin_port != 0) {
@@ -1189,7 +1189,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
        }
 
        if (do_bind) {
-               ret = bind(fd, &lbsda->u.sa, sa_len);
+               ret = bind(fd, &lbsda->u.sa, sa_socklen);
                if (ret == -1) {
                        int saved_errno = errno;
                        talloc_free(dgram);
@@ -1199,7 +1199,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
        }
 
        if (rbsda) {
-               ret = connect(fd, &rbsda->u.sa, sa_len);
+               ret = connect(fd, &rbsda->u.sa, sa_socklen);
                if (ret == -1) {
                        int saved_errno = errno;
                        talloc_free(dgram);
@@ -1889,7 +1889,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
        bool retry;
        bool do_bind = false;
        bool do_reuseaddr = false;
-       socklen_t sa_len = sizeof(rbsda->u.ss);
+       socklen_t sa_socklen = sizeof(rbsda->u.ss);
 
        req = tevent_req_create(mem_ctx, &state,
                                struct tstream_bsd_connect_state);
@@ -1917,7 +1917,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
                 * for unix sockets we can't use the size of sockaddr_storage
                 * we would get EINVAL
                 */
-               sa_len = sizeof(rbsda->u.un);
+               sa_socklen = sizeof(rbsda->u.un);
                break;
        case AF_INET:
                if (lbsda->u.in.sin_port != 0) {
@@ -1977,7 +1977,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
                }
        }
 
-       ret = connect(state->fd, &rbsda->u.sa, sa_len);
+       ret = connect(state->fd, &rbsda->u.sa, sa_socklen);
        err = tsocket_bsd_error_from_errno(ret, errno, &retry);
        if (retry) {
                /* retry later */
index cd1823a9a07bcacc2063713b22c3d772398ddca6..5b8456547ac9fc5ca1f8615a69297be96240f9c7 100644 (file)
@@ -294,6 +294,7 @@ _PUBLIC_ uint32_t generate_random(void)
 _PUBLIC_ bool check_password_quality(const char *s)
 {
        int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0;
+       const char* reals = s;
        while (*s) {
                if (isdigit((unsigned char)*s)) {
                        has_digit |= 1;
@@ -310,7 +311,7 @@ _PUBLIC_ bool check_password_quality(const char *s)
        }
 
        return ((has_digit + has_lower + has_capital + has_special) >= 3
-               || (has_high > strlen(s)/2));
+               || (has_high > strlen(reals)/2));
 }
 
 /**
index 5fe229c089e3e8f23e05a3070fc8e8bfd03d6cfa..20a20ac7fa1f0a3225d39cfac0eedf0137b1b572 100644 (file)
@@ -40,6 +40,8 @@ static bool test_check_password_quality(struct torture_context *tctx)
        torture_assert(tctx, !check_password_quality("aaaaaaaaaaaa"), "same char password");
        torture_assert(tctx, !check_password_quality("BLA"), "multiple upcases password");
        torture_assert(tctx, !check_password_quality("123"), "digits only");
+       torture_assert(tctx, !check_password_quality("matthiéu"), "not enough high symbols");
+       torture_assert(tctx, check_password_quality("abcdééàçè"), "valid");
        torture_assert(tctx, check_password_quality("A2e"), "valid");
        torture_assert(tctx, check_password_quality("BA2eLi443"), "valid");
        return true;
index 0275e78c54fc89f3a69d2539c82874ea1ce10878..7466004e5ce07f175608202d797d23d94f2f2274 100644 (file)
@@ -380,6 +380,7 @@ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
                return false;
        }
        if (write(fd, packet, length) != (size_t)length) {
+               close(fd);
                return false;
        }
        close(fd);
index 9373ef581266877ee0253235e02500fa09afcfa7..29afe460b16485a17b7796f4c04b60ca4b6b3ddd 100644 (file)
@@ -51,7 +51,7 @@ struct security_acl *make_sec_acl(TALLOC_CTX *ctx,
           positive number. */
 
        if ((num_aces) && 
-            ((dst->aces = talloc_array(ctx, struct security_ace, num_aces)) 
+            ((dst->aces = talloc_array(dst, struct security_ace, num_aces))
              == NULL)) {
                return NULL;
        }
similarity index 89%
rename from source4/dsdb/common/flag_mapping.c
rename to libds/common/flag_mapping.c
index dceb41be672309420ea79f8d2db888ed74fcf587..dc7d80185a2b9662c7fda092416eab198ca2d129 100644 (file)
@@ -1,33 +1,31 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
-   helper mapping functions for the SAMDB server
-   
+   helper mapping functions for the UF and ACB flags
+
    Copyright (C) Stefan (metze) Metzmacher 2002
    Copyright (C) Andrew Tridgell 2004
-  
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "librpc/gen_ndr/samr.h"
-#include "dsdb/common/flags.h"
-#include "lib/ldb/include/ldb.h"
-#include "dsdb/common/proto.h"
+#include "../libds/common/flags.h"
 
-/* 
-translated the ACB_CTRL Flags to UserFlags (userAccountControl) 
-*/ 
+/*
+translated the ACB_CTRL Flags to UserFlags (userAccountControl)
+*/
 /* mapping between ADS userAccountControl and SAMR acct_flags */
 static const struct {
        uint32_t uf;
@@ -54,7 +52,7 @@ static const struct {
        { UF_NO_AUTH_DATA_REQUIRED, ACB_NO_AUTH_DATA_REQD }
 };
 
-uint32_t samdb_acb2uf(uint32_t acb)
+uint32_t ds_acb2uf(uint32_t acb)
 {
        uint32_t i, ret = 0;
        for (i=0;i<ARRAY_SIZE(acct_flags_map);i++) {
@@ -68,7 +66,7 @@ uint32_t samdb_acb2uf(uint32_t acb)
 /*
 translated the UserFlags (userAccountControl) to ACB_CTRL Flags
 */
-uint32_t samdb_uf2acb(uint32_t uf)
+uint32_t ds_uf2acb(uint32_t uf)
 {
        uint32_t i;
        uint32_t ret = 0;
@@ -80,13 +78,13 @@ uint32_t samdb_uf2acb(uint32_t uf)
        return ret;
 }
 
-/* 
+/*
 get the accountType from the UserFlags
 */
-uint32_t samdb_uf2atype(uint32_t uf)
+uint32_t ds_uf2atype(uint32_t uf)
 {
        uint32_t atype = 0x00000000;
-               
+
        if (uf & UF_NORMAL_ACCOUNT)                     atype = ATYPE_NORMAL_ACCOUNT;
        else if (uf & UF_TEMP_DUPLICATE_ACCOUNT)        atype = ATYPE_NORMAL_ACCOUNT;
        else if (uf & UF_SERVER_TRUST_ACCOUNT)          atype = ATYPE_WORKSTATION_TRUST;
@@ -94,15 +92,15 @@ uint32_t samdb_uf2atype(uint32_t uf)
        else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT)     atype = ATYPE_INTERDOMAIN_TRUST;
 
        return atype;
-} 
+}
 
-/* 
+/*
 get the accountType from the groupType
 */
-uint32_t samdb_gtype2atype(uint32_t gtype)
+uint32_t ds_gtype2atype(uint32_t gtype)
 {
        uint32_t atype = 0x00000000;
-       
+
        switch(gtype) {
                case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
                        atype = ATYPE_SECURITY_LOCAL_GROUP;
@@ -113,7 +111,7 @@ uint32_t samdb_gtype2atype(uint32_t gtype)
                case GTYPE_SECURITY_GLOBAL_GROUP:
                        atype = ATYPE_SECURITY_GLOBAL_GROUP;
                        break;
-       
+
                case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
                        atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
                        break;
@@ -129,7 +127,7 @@ uint32_t samdb_gtype2atype(uint32_t gtype)
 }
 
 /* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType samdb_atype_map(uint32_t atype)
+enum lsa_SidType ds_atype_map(uint32_t atype)
 {
        switch (atype & 0xF0000000) {
        case ATYPE_GLOBAL_GROUP:
similarity index 62%
rename from source4/dsdb/common/flags.h
rename to libds/common/flags.h
index dd8081732c11c4f2468cd95f53fba2d14ca97d9d..2b342af8d6a1e137ae2e9e5514888f11cb5b2d8d 100644 (file)
 /* UserFlags for userAccountControl */
 #define UF_SCRIPT                              0x00000001  /* NT or Lan Manager Login script must be executed */
 #define UF_ACCOUNTDISABLE                      0x00000002
-#define UF_00000004                            0x00000004
+#define UF_00000004                            0x00000004
 #define UF_HOMEDIR_REQUIRED                    0x00000008
 
-#define UF_LOCKOUT                             0x00000010
-#define UF_PASSWD_NOTREQD                      0x00000020
-#define UF_PASSWD_CANT_CHANGE                  0x00000040
+#define UF_LOCKOUT                             0x00000010
+#define UF_PASSWD_NOTREQD                      0x00000020
+#define UF_PASSWD_CANT_CHANGE                  0x00000040
 #define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED     0x00000080
 
-#define UF_TEMP_DUPLICATE_ACCOUNT              0x00000100 /* Local user account in usrmgr */
-#define UF_NORMAL_ACCOUNT                      0x00000200
-#define UF_00000400                            0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT           0x00000800
+#define UF_TEMP_DUPLICATE_ACCOUNT              0x00000100 /* Local user account in usrmgr */
+#define UF_NORMAL_ACCOUNT                      0x00000200
+#define UF_00000400                            0x00000400
+#define UF_INTERDOMAIN_TRUST_ACCOUNT           0x00000800
 
-#define UF_WORKSTATION_TRUST_ACCOUNT           0x00001000
-#define UF_SERVER_TRUST_ACCOUNT                0x00002000
-#define UF_00004000                            0x00004000
-#define UF_00008000                            0x00008000
+#define UF_WORKSTATION_TRUST_ACCOUNT           0x00001000
+#define UF_SERVER_TRUST_ACCOUNT                        0x00002000
+#define UF_00004000                            0x00004000
+#define UF_00008000                            0x00008000
 
 #define UF_DONT_EXPIRE_PASSWD                  0x00010000
 #define UF_MNS_LOGON_ACCOUNT                   0x00020000
 #define UF_PASSWORD_EXPIRED                    0x00800000
 
 #define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED                0x02000000
+#define UF_NO_AUTH_DATA_REQUIRED               0x02000000
+
+#define UF_MACHINE_ACCOUNT_MASK (\
+               UF_INTERDOMAIN_TRUST_ACCOUNT |\
+               UF_WORKSTATION_TRUST_ACCOUNT |\
+               UF_SERVER_TRUST_ACCOUNT \
+               )
+
+#define UF_ACCOUNT_TYPE_MASK (\
+               UF_TEMP_DUPLICATE_ACCOUNT |\
+               UF_NORMAL_ACCOUNT |\
+               UF_INTERDOMAIN_TRUST_ACCOUNT |\
+               UF_WORKSTATION_TRUST_ACCOUNT |\
+               UF_SERVER_TRUST_ACCOUNT \
+                )
+
+#define UF_SETTABLE_BITS (\
+               UF_SCRIPT |\
+               UF_ACCOUNTDISABLE |\
+               UF_HOMEDIR_REQUIRED  |\
+               UF_LOCKOUT |\
+               UF_PASSWD_NOTREQD |\
+               UF_PASSWD_CANT_CHANGE |\
+               UF_ACCOUNT_TYPE_MASK | \
+               UF_DONT_EXPIRE_PASSWD | \
+               UF_MNS_LOGON_ACCOUNT |\
+               UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
+               UF_SMARTCARD_REQUIRED |\
+               UF_TRUSTED_FOR_DELEGATION |\
+               UF_NOT_DELEGATED |\
+               UF_USE_DES_KEY_ONLY  |\
+               UF_DONT_REQUIRE_PREAUTH \
+               )
 
 /* sAMAccountType */
 #define ATYPE_NORMAL_ACCOUNT                   0x30000000 /* 805306368 */
 #define ATYPE_WORKSTATION_TRUST                        0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST                        0x30000002 /* 805306370 */ 
+#define ATYPE_INTERDOMAIN_TRUST                        0x30000002 /* 805306370 */
 #define ATYPE_SECURITY_GLOBAL_GROUP            0x10000000 /* 268435456 */
 #define ATYPE_DISTRIBUTION_GLOBAL_GROUP                0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP     ATYPE_DISTRIBUTION_GLOBAL_GROUP
+#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP     ATYPE_DISTRIBUTION_GLOBAL_GROUP
 #define ATYPE_SECURITY_LOCAL_GROUP             0x20000000 /* 536870912 */
 #define ATYPE_DISTRIBUTION_LOCAL_GROUP         0x20000001 /* 536870913 */
 
-#define ATYPE_ACCOUNT          ATYPE_NORMAL_ACCOUNT            /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP     ATYPE_SECURITY_GLOBAL_GROUP     /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP      ATYPE_SECURITY_LOCAL_GROUP      /* 0x20000000 536870912 */
+#define ATYPE_ACCOUNT          ATYPE_NORMAL_ACCOUNT            /* 0x30000000 805306368 */
+#define ATYPE_GLOBAL_GROUP     ATYPE_SECURITY_GLOBAL_GROUP     /* 0x10000000 268435456 */
+#define ATYPE_LOCAL_GROUP      ATYPE_SECURITY_LOCAL_GROUP      /* 0x20000000 536870912 */
 
 /* groupType */
 #define GROUP_TYPE_BUILTIN_LOCAL_GROUP         0x00000001
 #define SYSTEM_FLAG_CR_NTDS_DOMAIN             0x00000002
 #define SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED  0x00000004
 #define SYSTEM_FLAG_SCHEMA_BASE_OBJECT         0x00000010
-#define SYSTEM_FLAG_ATTR_IS_RDN                        0x00000020
+#define SYSTEM_FLAG_ATTR_IS_RDN                        0x00000020
 #define SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE    0x02000000
 #define SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE       0x04000000
 #define SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME     0x08000000
 #define SYSTEM_FLAG_CONFIG_ALLOW_RENAME                0x40000000
 #define SYSTEM_FLAG_DISALLOW_DELTE             0x80000000
 
-#define SEARCH_FLAG_ATTINDEX            0x0000001
-#define SEARCH_FLAG_PDNTATTINDEX        0x0000002
-#define SEARCH_FLAG_ANR                 0x0000004
-#define SEARCH_FLAG_PRESERVEONDELETE    0x0000008
-#define SEARCH_FLAG_COPY                0x0000010
-#define SEARCH_FLAG_TUPLEINDEX          0x0000020
-#define SEARCH_FLAG_SUBTREEATTRINDEX    0x0000040
-#define SEARCH_FLAG_CONFIDENTIAL        0x0000080
-#define SEARCH_FLAG_NEVERVALUEAUDIT     0x0000100
-#define SEARCH_FLAG_RODC_ATTRIBUTE      0x0000200
+#define SEARCH_FLAG_ATTINDEX           0x0000001
+#define SEARCH_FLAG_PDNTATTINDEX       0x0000002
+#define SEARCH_FLAG_ANR                        0x0000004
+#define SEARCH_FLAG_PRESERVEONDELETE   0x0000008
+#define SEARCH_FLAG_COPY               0x0000010
+#define SEARCH_FLAG_TUPLEINDEX         0x0000020
+#define SEARCH_FLAG_SUBTREEATTRINDEX   0x0000040
+#define SEARCH_FLAG_CONFIDENTIAL       0x0000080
+#define SEARCH_FLAG_NEVERVALUEAUDIT    0x0000100
+#define SEARCH_FLAG_RODC_ATTRIBUTE     0x0000200
 
 #define DS_BEHAVIOR_WIN2000            0
 #define DS_BEHAVIOR_WIN2003_INTERIM    1
 #define DS_BEHAVIOR_WIN2003            2
 #define DS_BEHAVIOR_WIN2008            3
+
+/* Settings for the domainFunctionality attribute in the rootDSE */
+
+#define DS_DOMAIN_FUNCTION_2000                0
+#define DS_DOMAIN_FUCNTION_2003_MIXED  1
+#define DS_DOMAIN_FUNCTION_2003                2
+#define DS_DOMAIN_FUNCTION_2008                3
+
index 93362537b47526ff89ddbed06051966050ddb971..04cf38aaf3811d1ec55d3aff3146ac4604ae4a03 100644 (file)
@@ -1796,12 +1796,18 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli,
 }
 
 NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
-                                    TALLOC_CTX *mem_ctx)
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *handle /* [in] [ref] */,
+                                    struct lsa_String *name /* [in] [ref] */,
+                                    struct lsa_DATA_BUF *val /* [in] [unique] */)
 {
        struct lsa_StorePrivateData r;
        NTSTATUS status;
 
        /* In parameters */
+       r.in.handle = handle;
+       r.in.name = name;
+       r.in.val = val;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(lsa_StorePrivateData, &r);
@@ -1832,12 +1838,18 @@ NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
 }
 
 NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
-                                       TALLOC_CTX *mem_ctx)
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle /* [in] [ref] */,
+                                       struct lsa_String *name /* [in] [ref] */,
+                                       struct lsa_DATA_BUF **val /* [in,out] [ref] */)
 {
        struct lsa_RetrievePrivateData r;
        NTSTATUS status;
 
        /* In parameters */
+       r.in.handle = handle;
+       r.in.name = name;
+       r.in.val = val;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, &r);
@@ -1862,6 +1874,7 @@ NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
+       *val = *r.out.val;
 
        /* Return result */
        return r.out.result;
index 8dbd7330b43daca38835937c5495570c3f4d1064..10c408528f8d7c5d934fc3ef0df1ff4a21b5c495 100644 (file)
@@ -214,9 +214,15 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli,
                                        struct policy_handle *handle /* [in] [ref] */,
                                        struct dom_sid2 *dom_sid /* [in] [ref] */);
 NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
-                                    TALLOC_CTX *mem_ctx);
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *handle /* [in] [ref] */,
+                                    struct lsa_String *name /* [in] [ref] */,
+                                    struct lsa_DATA_BUF *val /* [in] [unique] */);
 NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
-                                       TALLOC_CTX *mem_ctx);
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle /* [in] [ref] */,
+                                       struct lsa_String *name /* [in] [ref] */,
+                                       struct lsa_DATA_BUF **val /* [in,out] [ref] */);
 NTSTATUS rpccli_lsa_OpenPolicy2(struct rpc_pipe_client *cli,
                                TALLOC_CTX *mem_ctx,
                                const char *system_name /* [in] [unique,charset(UTF16)] */,
index 66083e6856740292a3a929666ed99b1e61f8ade5..38031b615de118b0435d11cb2d30551e986578ba 100644 (file)
@@ -2006,12 +2006,17 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli,
 
 NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle /* [in] [ref] */,
+                                       struct policy_handle *gdi_handle /* [out] [ref] */,
+                                       struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
                                        WERROR *werror)
 {
        struct spoolss_CreatePrinterIC r;
        NTSTATUS status;
 
        /* In parameters */
+       r.in.handle = handle;
+       r.in.devmode_ctr = devmode_ctr;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, &r);
@@ -2036,6 +2041,7 @@ NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
+       *gdi_handle = *r.out.gdi_handle;
 
        /* Return result */
        if (werror) {
@@ -2088,12 +2094,14 @@ NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli,
 
 NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *gdi_handle /* [in,out] [ref] */,
                                        WERROR *werror)
 {
        struct spoolss_DeletePrinterIC r;
        NTSTATUS status;
 
        /* In parameters */
+       r.in.gdi_handle = gdi_handle;
 
        if (DEBUGLEVEL >= 10) {
                NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, &r);
@@ -2118,6 +2126,7 @@ NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
        }
 
        /* Return variables */
+       *gdi_handle = *r.out.gdi_handle;
 
        /* Return result */
        if (werror) {
index baf5d61e2a8dc9015e36bc56a14794cdb1f9e27a..b171c69fbd8aa1c4745b5ef8615d3ac2a2059015 100644 (file)
@@ -294,12 +294,16 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli,
                                   WERROR *werror);
 NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle /* [in] [ref] */,
+                                       struct policy_handle *gdi_handle /* [out] [ref] */,
+                                       struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
                                        WERROR *werror);
 NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli,
                                                 TALLOC_CTX *mem_ctx,
                                                 WERROR *werror);
 NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
                                        TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *gdi_handle /* [in,out] [ref] */,
                                        WERROR *werror);
 NTSTATUS rpccli_spoolss_AddPrinterConnection(struct rpc_pipe_client *cli,
                                             TALLOC_CTX *mem_ctx,
index 3c9a5d80a61502623230a8543a6388416ac4bbd2..9ee5fab4c80dad1ee375fe0ef62842fcb4bd0c0d 100644 (file)
@@ -445,7 +445,7 @@ enum lsa_TrustDomInfoEnum
        LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL=10,
        LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL=11,
        LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL=12,
-       LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES=13
+       LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES=13
 }
 #else
  { __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF}
@@ -461,7 +461,7 @@ enum lsa_TrustDomInfoEnum
 #define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL ( 10 )
 #define LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL ( 11 )
 #define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL ( 12 )
-#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES ( 13 )
+#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES ( 13 )
 #endif
 ;
 
@@ -603,7 +603,7 @@ union lsa_TrustedDomainInfo {
        struct lsa_TrustDomainInfoFullInfoInternal full_info_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL)] */
        struct lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL)] */
        struct lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)] */
-       struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)] */
+       struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)] */
 }/* [switch_type(lsa_TrustDomInfoEnum)] */;
 
 struct lsa_DATA_BUF_PTR {
@@ -1332,6 +1332,12 @@ struct lsa_DeleteTrustedDomain {
 
 
 struct lsa_StorePrivateData {
+       struct {
+               struct policy_handle *handle;/* [ref] */
+               struct lsa_String *name;/* [ref] */
+               struct lsa_DATA_BUF *val;/* [unique] */
+       } in;
+
        struct {
                NTSTATUS result;
        } out;
@@ -1341,6 +1347,13 @@ struct lsa_StorePrivateData {
 
 struct lsa_RetrievePrivateData {
        struct {
+               struct policy_handle *handle;/* [ref] */
+               struct lsa_String *name;/* [ref] */
+               struct lsa_DATA_BUF **val;/* [ref] */
+       } in;
+
+       struct {
+               struct lsa_DATA_BUF **val;/* [ref] */
                NTSTATUS result;
        } out;
 
index 3ad9c41fd77498750d507709e3a8c60507ba69be..b8ba67937870a0769b31224acc4b206977e1fa28 100644 (file)
@@ -2735,7 +2735,7 @@ _PUBLIC_ void ndr_print_lsa_TrustDomInfoEnum(struct ndr_print *ndr, const char *
                case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL"; break;
                case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL"; break;
                case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL"; break;
-               case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES"; break;
+               case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES"; break;
        }
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
@@ -3662,7 +3662,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in
                                NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
                        break; }
 
-                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
                                NDR_CHECK(ndr_push_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
                        break; }
 
@@ -3720,7 +3720,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in
                                NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
                        break;
 
-                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
                        break;
 
                        default:
@@ -3789,7 +3789,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in
                                NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
                        break; }
 
-                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
                                NDR_CHECK(ndr_pull_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
                        break; }
 
@@ -3846,7 +3846,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in
                                NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
                        break;
 
-                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+                       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
                        break;
 
                        default:
@@ -3910,7 +3910,7 @@ _PUBLIC_ void ndr_print_lsa_TrustedDomainInfo(struct ndr_print *ndr, const char
                        ndr_print_lsa_TrustDomainInfoFullInfo2Internal(ndr, "full_info2_internal", &r->full_info2_internal);
                break;
 
-               case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+               case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
                        ndr_print_lsa_TrustDomainInfoSupportedEncTypes(ndr, "enc_types", &r->enc_types);
                break;
 
@@ -9225,6 +9225,18 @@ _PUBLIC_ void ndr_print_lsa_DeleteTrustedDomain(struct ndr_print *ndr, const cha
 static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int flags, const struct lsa_StorePrivateData *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, r->in.handle));
+               if (r->in.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.name));
+               NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.val));
+               if (r->in.val) {
+                       NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+               }
        }
        if (flags & NDR_OUT) {
                NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
@@ -9234,7 +9246,37 @@ static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int
 
 static enum ndr_err_code ndr_pull_lsa_StorePrivateData(struct ndr_pull *ndr, int flags, struct lsa_StorePrivateData *r)
 {
+       uint32_t _ptr_val;
+       TALLOC_CTX *_mem_save_handle_0;
+       TALLOC_CTX *_mem_save_name_0;
+       TALLOC_CTX *_mem_save_val_0;
        if (flags & NDR_IN) {
+               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, 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.name);
+               }
+               _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+               if (_ptr_val) {
+                       NDR_PULL_ALLOC(ndr, r->in.val);
+               } else {
+                       r->in.val = NULL;
+               }
+               if (r->in.val) {
+                       _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, r->in.val, 0);
+                       NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, 0);
+               }
        }
        if (flags & NDR_OUT) {
                NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
@@ -9252,6 +9294,20 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *
        if (flags & NDR_IN) {
                ndr_print_struct(ndr, "in", "lsa_StorePrivateData");
                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, "name", r->in.name);
+               ndr->depth++;
+               ndr_print_lsa_String(ndr, "name", r->in.name);
+               ndr->depth--;
+               ndr_print_ptr(ndr, "val", r->in.val);
+               ndr->depth++;
+               if (r->in.val) {
+                       ndr_print_lsa_DATA_BUF(ndr, "val", r->in.val);
+               }
+               ndr->depth--;
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
@@ -9266,8 +9322,30 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *
 static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr, int flags, const struct lsa_RetrievePrivateData *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, r->in.handle));
+               if (r->in.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.name));
+               if (r->in.val == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_unique_ptr(ndr, *r->in.val));
+               if (*r->in.val) {
+                       NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+               }
        }
        if (flags & NDR_OUT) {
+               if (r->out.val == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.val));
+               if (*r->out.val) {
+                       NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+               }
                NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -9275,9 +9353,68 @@ static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr,
 
 static enum ndr_err_code ndr_pull_lsa_RetrievePrivateData(struct ndr_pull *ndr, int flags, struct lsa_RetrievePrivateData *r)
 {
+       uint32_t _ptr_val;
+       TALLOC_CTX *_mem_save_handle_0;
+       TALLOC_CTX *_mem_save_name_0;
+       TALLOC_CTX *_mem_save_val_0;
+       TALLOC_CTX *_mem_save_val_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, 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.name);
+               }
+               _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->in.val);
+               }
+               _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->in.val, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+               if (_ptr_val) {
+                       NDR_PULL_ALLOC(ndr, *r->in.val);
+               } else {
+                       *r->in.val = NULL;
+               }
+               if (*r->in.val) {
+                       _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, *r->in.val, 0);
+                       NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+               }
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
+               NDR_PULL_ALLOC(ndr, r->out.val);
+               *r->out.val = *r->in.val;
        }
        if (flags & NDR_OUT) {
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.val);
+               }
+               _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.val, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+               if (_ptr_val) {
+                       NDR_PULL_ALLOC(ndr, *r->out.val);
+               } else {
+                       *r->out.val = NULL;
+               }
+               if (*r->out.val) {
+                       _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+                       NDR_PULL_SET_MEM_CTX(ndr, *r->out.val, 0);
+                       NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+               }
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -9293,11 +9430,37 @@ _PUBLIC_ void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const cha
        if (flags & NDR_IN) {
                ndr_print_struct(ndr, "in", "lsa_RetrievePrivateData");
                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, "name", r->in.name);
+               ndr->depth++;
+               ndr_print_lsa_String(ndr, "name", r->in.name);
+               ndr->depth--;
+               ndr_print_ptr(ndr, "val", r->in.val);
+               ndr->depth++;
+               ndr_print_ptr(ndr, "val", *r->in.val);
+               ndr->depth++;
+               if (*r->in.val) {
+                       ndr_print_lsa_DATA_BUF(ndr, "val", *r->in.val);
+               }
+               ndr->depth--;
+               ndr->depth--;
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
                ndr_print_struct(ndr, "out", "lsa_RetrievePrivateData");
                ndr->depth++;
+               ndr_print_ptr(ndr, "val", r->out.val);
+               ndr->depth++;
+               ndr_print_ptr(ndr, "val", *r->out.val);
+               ndr->depth++;
+               if (*r->out.val) {
+                       ndr_print_lsa_DATA_BUF(ndr, "val", *r->out.val);
+               }
+               ndr->depth--;
+               ndr->depth--;
                ndr_print_NTSTATUS(ndr, "result", r->out.result);
                ndr->depth--;
        }
index 58b7ae2413f4f1269d487bd23802304ee032bd97..258aba9bb6d623c0510d90cef5edd0eec70c0c63 100644 (file)
@@ -4831,12 +4831,14 @@ _PUBLIC_ void ndr_print_samr_ValidationStatus(struct ndr_print *ndr, const char
                case SAMR_VALIDATION_STATUS_SUCCESS: val = "SAMR_VALIDATION_STATUS_SUCCESS"; break;
                case SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE: val = "SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE"; break;
                case SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT: val = "SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT"; break;
+               case SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED: val = "SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED"; break;
                case SAMR_VALIDATION_STATUS_BAD_PASSWORD: val = "SAMR_VALIDATION_STATUS_BAD_PASSWORD"; break;
                case SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT: val = "SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT"; break;
                case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT: val = "SAMR_VALIDATION_STATUS_PWD_TOO_SHORT"; break;
                case SAMR_VALIDATION_STATUS_PWD_TOO_LONG: val = "SAMR_VALIDATION_STATUS_PWD_TOO_LONG"; break;
                case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH: val = "SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH"; break;
                case SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT: val = "SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT"; break;
+               case SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR: val = "SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR"; break;
        }
        ndr_print_enum(ndr, name, "ENUM", val, r);
 }
index a1be2fd92c594d2ace4e98a292c696601f2d4267..fedebb2d56149aeda1fbc3f419f1a44e9956d59c 100644 (file)
@@ -14464,7 +14464,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersion(struct ndr_pull *ndr, int
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
                {
                        uint32_t _flags_save_string = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14490,7 +14490,7 @@ _PUBLIC_ void ndr_print_spoolss_OSVersion(struct ndr_print *ndr, const char *nam
        ndr_print_uint32(ndr, "major", r->major);
        ndr_print_uint32(ndr, "minor", r->minor);
        ndr_print_uint32(ndr, "build", r->build);
-       ndr_print_uint32(ndr, "unknown", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown);
+       ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
        ndr_print_string(ndr, "extra_string", r->extra_string);
        ndr->depth--;
 }
@@ -14520,8 +14520,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_OSVersionEx(struct ndr_push *ndr, in
                        }
                        ndr->flags = _flags_save_string;
                }
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown2));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3));
+               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_major));
+               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_minor));
+               NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->suite_mask));
+               NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->product_type));
+               NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->reserved));
        }
        if (ndr_flags & NDR_BUFFERS) {
        }
@@ -14536,7 +14539,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
                {
                        uint32_t _flags_save_string = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14548,8 +14551,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in
                        }
                        ndr->flags = _flags_save_string;
                }
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3));
+               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_major));
+               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_minor));
+               NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->suite_mask));
+               NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->product_type));
+               NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->reserved));
        }
        if (ndr_flags & NDR_BUFFERS) {
        }
@@ -14564,10 +14570,13 @@ _PUBLIC_ void ndr_print_spoolss_OSVersionEx(struct ndr_print *ndr, const char *n
        ndr_print_uint32(ndr, "major", r->major);
        ndr_print_uint32(ndr, "minor", r->minor);
        ndr_print_uint32(ndr, "build", r->build);
-       ndr_print_uint32(ndr, "unknown1", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown1);
+       ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
        ndr_print_string(ndr, "extra_string", r->extra_string);
-       ndr_print_uint32(ndr, "unknown2", r->unknown2);
-       ndr_print_uint32(ndr, "unknown3", r->unknown3);
+       ndr_print_uint16(ndr, "service_pack_major", r->service_pack_major);
+       ndr_print_uint16(ndr, "service_pack_minor", r->service_pack_minor);
+       ndr_print_uint16(ndr, "suite_mask", r->suite_mask);
+       ndr_print_uint8(ndr, "product_type", r->product_type);
+       ndr_print_uint8(ndr, "reserved", r->reserved);
        ndr->depth--;
 }
 
@@ -23702,8 +23711,20 @@ _PUBLIC_ void ndr_print_spoolss_DeletePort(struct ndr_print *ndr, const char *na
 static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_CreatePrinterIC *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, r->in.handle));
+               if (r->in.devmode_ctr == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
        }
        if (flags & NDR_OUT) {
+               if (r->out.gdi_handle == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
                NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -23711,9 +23732,37 @@ static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr,
 
 static enum ndr_err_code ndr_pull_spoolss_CreatePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_CreatePrinterIC *r)
 {
+       TALLOC_CTX *_mem_save_handle_0;
+       TALLOC_CTX *_mem_save_gdi_handle_0;
+       TALLOC_CTX *_mem_save_devmode_ctr_0;
        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, 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.devmode_ctr);
+               }
+               _mem_save_devmode_ctr_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->in.devmode_ctr, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_ctr_0, LIBNDR_FLAG_REF_ALLOC);
+               NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+               ZERO_STRUCTP(r->out.gdi_handle);
        }
        if (flags & NDR_OUT) {
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+               }
+               _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -23729,11 +23778,23 @@ _PUBLIC_ void ndr_print_spoolss_CreatePrinterIC(struct ndr_print *ndr, const cha
        if (flags & NDR_IN) {
                ndr_print_struct(ndr, "in", "spoolss_CreatePrinterIC");
                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, "devmode_ctr", r->in.devmode_ctr);
+               ndr->depth++;
+               ndr_print_spoolss_DevmodeContainer(ndr, "devmode_ctr", r->in.devmode_ctr);
+               ndr->depth--;
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
                ndr_print_struct(ndr, "out", "spoolss_CreatePrinterIC");
                ndr->depth++;
+               ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+               ndr->depth++;
+               ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+               ndr->depth--;
                ndr_print_WERROR(ndr, "result", r->out.result);
                ndr->depth--;
        }
@@ -23784,8 +23845,16 @@ _PUBLIC_ void ndr_print_spoolss_PlayGDIScriptOnPrinterIC(struct ndr_print *ndr,
 static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_DeletePrinterIC *r)
 {
        if (flags & NDR_IN) {
+               if (r->in.gdi_handle == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
        }
        if (flags & NDR_OUT) {
+               if (r->out.gdi_handle == NULL) {
+                       return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+               }
+               NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
                NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -23793,9 +23862,28 @@ static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr,
 
 static enum ndr_err_code ndr_pull_spoolss_DeletePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_DeletePrinterIC *r)
 {
+       TALLOC_CTX *_mem_save_gdi_handle_0;
        if (flags & NDR_IN) {
+               ZERO_STRUCT(r->out);
+
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->in.gdi_handle);
+               }
+               _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->in.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
+               NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+               *r->out.gdi_handle = *r->in.gdi_handle;
        }
        if (flags & NDR_OUT) {
+               if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+                       NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+               }
+               _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+               NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+               NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+               NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
                NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
        }
        return NDR_ERR_SUCCESS;
@@ -23811,11 +23899,19 @@ _PUBLIC_ void ndr_print_spoolss_DeletePrinterIC(struct ndr_print *ndr, const cha
        if (flags & NDR_IN) {
                ndr_print_struct(ndr, "in", "spoolss_DeletePrinterIC");
                ndr->depth++;
+               ndr_print_ptr(ndr, "gdi_handle", r->in.gdi_handle);
+               ndr->depth++;
+               ndr_print_policy_handle(ndr, "gdi_handle", r->in.gdi_handle);
+               ndr->depth--;
                ndr->depth--;
        }
        if (flags & NDR_OUT) {
                ndr_print_struct(ndr, "out", "spoolss_DeletePrinterIC");
                ndr->depth++;
+               ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+               ndr->depth++;
+               ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+               ndr->depth--;
                ndr_print_WERROR(ndr, "result", r->out.result);
                ndr->depth--;
        }
index e44de1b037c69728bcfaad8c16757ab349da10ef..ce84b45a9e237bb0927c939521434da303379491 100644 (file)
@@ -834,24 +834,28 @@ enum samr_ValidationStatus
        SAMR_VALIDATION_STATUS_SUCCESS=0,
        SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE=1,
        SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT=2,
+       SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED=3,
        SAMR_VALIDATION_STATUS_BAD_PASSWORD=4,
        SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT=5,
        SAMR_VALIDATION_STATUS_PWD_TOO_SHORT=6,
        SAMR_VALIDATION_STATUS_PWD_TOO_LONG=7,
        SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH=8,
-       SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9
+       SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9,
+       SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR=10
 }
 #else
  { __donnot_use_enum_samr_ValidationStatus=0x7FFFFFFF}
 #define SAMR_VALIDATION_STATUS_SUCCESS ( 0 )
 #define SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE ( 1 )
 #define SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT ( 2 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED ( 3 )
 #define SAMR_VALIDATION_STATUS_BAD_PASSWORD ( 4 )
 #define SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT ( 5 )
 #define SAMR_VALIDATION_STATUS_PWD_TOO_SHORT ( 6 )
 #define SAMR_VALIDATION_STATUS_PWD_TOO_LONG ( 7 )
 #define SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH ( 8 )
 #define SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT ( 9 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR ( 10 )
 #endif
 ;
 
index 9446193863ada05caa378aa63029335c49c1eaa0..1a9d393e093b635e980d8cae2d870b8d20fbd5bb 100644 (file)
@@ -1058,7 +1058,7 @@ struct spoolss_OSVersion {
        uint32_t major;
        uint32_t minor;
        uint32_t build;
-       uint32_t unknown;/* [value(2)] */
+       uint32_t platform_id;/* [value(2)] */
        const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
 }/* [gensize,public] */;
 
@@ -1067,10 +1067,13 @@ struct spoolss_OSVersionEx {
        uint32_t major;
        uint32_t minor;
        uint32_t build;
-       uint32_t unknown1;/* [value(2)] */
+       uint32_t platform_id;/* [value(2)] */
        const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
-       uint32_t unknown2;
-       uint32_t unknown3;
+       uint16_t service_pack_major;
+       uint16_t service_pack_minor;
+       uint16_t suite_mask;
+       uint8_t product_type;
+       uint8_t reserved;
 }/* [gensize,public] */;
 
 union spoolss_PrinterData {
@@ -2516,6 +2519,12 @@ struct spoolss_DeletePort {
 
 struct spoolss_CreatePrinterIC {
        struct {
+               struct policy_handle *handle;/* [ref] */
+               struct spoolss_DevmodeContainer *devmode_ctr;/* [ref] */
+       } in;
+
+       struct {
+               struct policy_handle *gdi_handle;/* [ref] */
                WERROR result;
        } out;
 
@@ -2532,6 +2541,11 @@ struct spoolss_PlayGDIScriptOnPrinterIC {
 
 struct spoolss_DeletePrinterIC {
        struct {
+               struct policy_handle *gdi_handle;/* [ref] */
+       } in;
+
+       struct {
+               struct policy_handle *gdi_handle;/* [ref] */
                WERROR result;
        } out;
 
index c86d0857f845a59ba0c300d1b0bfd0a14ac55003..f1b4a06d0d403b80bc22c35c835e08dd2a683161 100644 (file)
@@ -3366,6 +3366,8 @@ static bool api_lsa_RetrievePrivateData(pipes_struct *p)
                NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, r);
        }
 
+       ZERO_STRUCT(r->out);
+       r->out.val = r->in.val;
        r->out.result = _lsa_RetrievePrivateData(p, r);
 
        if (p->rng_fault_state) {
@@ -6810,6 +6812,8 @@ NTSTATUS rpc_lsarpc_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, c
 
                case NDR_LSA_RETRIEVEPRIVATEDATA: {
                        struct lsa_RetrievePrivateData *r = (struct lsa_RetrievePrivateData *)_r;
+                       ZERO_STRUCT(r->out);
+                       r->out.val = r->in.val;
                        r->out.result = _lsa_RetrievePrivateData(cli->pipes_struct, r);
                        return NT_STATUS_OK;
                }
index 41a79b4a79d137f05ee89dfcccbe3f2ff47bb0a1..ae99f098a617349a80e05d6606076d724eb174cf 100644 (file)
@@ -3245,6 +3245,13 @@ static bool api_spoolss_CreatePrinterIC(pipes_struct *p)
                NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, r);
        }
 
+       ZERO_STRUCT(r->out);
+       r->out.gdi_handle = talloc_zero(r, struct policy_handle);
+       if (r->out.gdi_handle == NULL) {
+               talloc_free(r);
+               return false;
+       }
+
        r->out.result = _spoolss_CreatePrinterIC(p, r);
 
        if (p->rng_fault_state) {
@@ -3391,6 +3398,8 @@ static bool api_spoolss_DeletePrinterIC(pipes_struct *p)
                NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, r);
        }
 
+       ZERO_STRUCT(r->out);
+       r->out.gdi_handle = r->in.gdi_handle;
        r->out.result = _spoolss_DeletePrinterIC(p, r);
 
        if (p->rng_fault_state) {
@@ -8068,6 +8077,12 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
                case NDR_SPOOLSS_CREATEPRINTERIC: {
                        struct spoolss_CreatePrinterIC *r = (struct spoolss_CreatePrinterIC *)_r;
+                       ZERO_STRUCT(r->out);
+                       r->out.gdi_handle = talloc_zero(mem_ctx, struct policy_handle);
+                       if (r->out.gdi_handle == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+                       }
+
                        r->out.result = _spoolss_CreatePrinterIC(cli->pipes_struct, r);
                        return NT_STATUS_OK;
                }
@@ -8080,6 +8095,8 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
                case NDR_SPOOLSS_DELETEPRINTERIC: {
                        struct spoolss_DeletePrinterIC *r = (struct spoolss_DeletePrinterIC *)_r;
+                       ZERO_STRUCT(r->out);
+                       r->out.gdi_handle = r->in.gdi_handle;
                        r->out.result = _spoolss_DeletePrinterIC(cli->pipes_struct, r);
                        return NT_STATUS_OK;
                }
index 11593f479a6faf40ca1f5d12ff7582bd31cbcece..ea7880c9f8ab327eea5d43b8c35674fb67da033c 100644 (file)
@@ -98,24 +98,31 @@ interface frsapi
        WERROR frsapi_IsPathReplicated(
                [in,unique] [string,charset(UTF16)] uint16 *path,
                [in] frsapi_ReplicaSetType replica_set_type,
-               [out] uint32 *unknown1,
-               [out] uint32 *unknown2,
-               [out] uint32 *unknown3,
+               [out] uint32 *replicated,
+               [out] uint32 *primary,
+               [out] uint32 *root,
                [out] GUID *replica_set_guid
        );
 
        /****************/
        /* Function 0x09 */
-       [todo] void FRSAPI_WRITER_COMMAND();
+       typedef [v1_enum] enum {
+               FRSAPI_WRITER_COMMAND_FREEZE    = 0x00000001,
+               FRSAPI_WRITER_COMMAND_THAW      = 0x00000002
+       } frsapi_WriterCommandsValues;
+
+       WERROR frsapi_WriterCommand(
+               [in] frsapi_WriterCommandsValues command
+       );
 
        /****************/
        /* Function 0x0a */
        /* not supported before w2k3 sp2 */
        WERROR frsapi_ForceReplication(
-               [in,unique] GUID *guid1,
-               [in,unique] GUID *guid2,
-               [in,unique] [charset(UTF16),string] uint16 *replica_set,
-               [in,unique] [charset(UTF16),string] uint16 *partner_name
+               [in,unique] GUID *replica_set_guid,
+               [in,unique] GUID *connection_guid,
+               [in,unique] [charset(UTF16),string] uint16 *replica_set_name,
+               [in,unique] [charset(UTF16),string] uint16 *partner_dns_name
        );
 
 }
index 1019a25b28a9c2bc649b5b7f7e18234d2d16b062..cab155295d2d3f5adea34ecf8167f9d84306cf27 100644 (file)
@@ -7,6 +7,7 @@ import "misc.idl";
   version(1.1),
   endpoint("ncacn_ip_tcp:", "ncalrpc:"),
   helpstring("File Replication Service"),
+  helper("../librpc/ndr/ndr_frsrpc.h"),
   pointer_default(unique)
 ] 
 interface frsrpc
@@ -14,112 +15,337 @@ interface frsrpc
        /*****************/
        /* Function 0x00 */
 
-       /* TAG:3 this TLV contains a GUID and the name of the server sending
-        * the call
-        */
        typedef struct {
-               [subcontext(4)] GUID unknown1;
-               [subcontext(4)] nstring source_server;
-       } frsrpc_FrsSendCommPktChunkDataSSRV;
+               [subcontext(4)] GUID guid;
+               [subcontext(4)] nstring name;
+       } frsrpc_CommPktChunkGuidName;
 
-       /* TAG:4 this TLV contains a GUID and the name of the destination
-        * server the PDU is sent to
-        */
        typedef struct {
-               [subcontext(4)] GUID unknown1;
-               [subcontext(4)] nstring dest_server;
-       } frsrpc_FrsSendCommPktChunkDataDSRV;
+               hyper vsn;
+               GUID guid;
+       } frsrpc_CommPktGSVN;
+
+       typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+               FRSRPC_CO_FLAG_ABORT_CO = 0x00000001,
+               FRSRPC_CO_FLAG_VV_ACTIVATED     = 0x00000002,
+               FRSRPC_CO_FLAG_CONTENT_CMD      = 0x00000004,
+               FRSRPC_CO_FLAG_LOCATION_CMD     = 0x00000008,
+               FRSRPC_CO_FLAG_ONLIST           = 0x00000010,
+               FRSRPC_CO_FLAG_LOCALCO          = 0x00000020,
+               FRSRPC_CO_FLAG_RETRY            = 0x00000040,
+               FRSRPC_CO_FLAG_OUT_OF_ORDER     = 0x00000200,
+               FRSRPC_CO_FLAG_NEW_FILE         = 0x00000400,
+               FRSRPC_CO_FLAG_CONTROL          = 0x00001000,
+               FRSRPC_CO_FLAG_DIRECTED_CO      = 0x00002000,
+               FRSRPC_CO_FLAG_VVJOIN_TO_ORIG   = 0x00040000,
+               FRSRPC_CO_FLAG_SKIP_ORIG_REC_C  = 0x00100000,
+               FRSRPC_CO_FLAG_MOVEIN_GEN       = 0x00200000,
+               FRSRPC_CO_FLAG_MORPH_GEN_HEAD   = 0x00400000,
+               FRSRPC_CO_FLAG_JUST_OID_RESET   = 0x00800000,
+               FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+               FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+               FRSRPC_CO_FLAG_SKIP_VV_UPDATE   = 0x02000000
+       } frsrpc_CommPktCoCmdFlags;
+
+       const uint32 FRSRPC_CO_IFLAG_NONE = 0x0000000;
+
+       typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+               FRSRPC_CO_IFLAG_VVRETIRE_EXEC   = 0x00000001,
+               FRSRPC_CO_IFLAG_CO_ABORT        = 0x00000002,
+               FRSRPC_CO_IFLAG_DIR_ENUM_PENDING= 0x00000004
+       } frsrpc_CommPktCoCmdIFlags;
+
+       typedef [v1_enum,flag(NDR_PAHEX)] enum {
+               FRSRPC_CO_STATUS_CO_ENTERED_LOG                 = 0x00000000,
+               FRSRPC_CO_STATUS_ALLOC_STAGING_LOCAL_CO         = 0x00000001,
+               FRSRPC_CO_STATUS_LOCAL_CO_STAGING_STARTED       = 0x00000002,
+               FRSRPC_CO_STATUS_LOCAL_CO_STAGING_COMPLETED     = 0x00000003,
+               FRSRPC_CO_STATUS_WAIT_RETRY_LOCAL_CO_STAGING    = 0x00000004,
+               FRSRPC_CO_STATUS_ALLOC_STAGING_REMOTE_CO        = 0x00000005,
+               FRSRPC_CO_STATUS_REMOTE_CO_STAGING_STARTED      = 0x00000006,
+               FRSRPC_CO_STATUS_REMOTE_CO_STAGING_COMPLETED    = 0x00000007,
+               FRSRPC_CO_STATUS_WAIT_RETRY_REMOTE_CO_STAGING   = 0x00000008,
+               FRSRPC_CO_STATUS_FILE_INSTALL_REQUESTED         = 0x00000009,
+               FRSRPC_CO_STATUS_FILE_INSTALL_STARTED           = 0x0000000A,
+               FRSRPC_CO_STATUS_FILE_INSTALL_COMPLETED         = 0x0000000B,
+               FRSRPC_CO_STATUS_FILE_INSTALL_WAIT_RETRY        = 0x0000000C,
+               FRSRPC_CO_STATUS_FILE_INSTALL_RETRYING          = 0x0000000D,
+               FRSRPC_CO_STATUS_FILE_INSTALL_RENAME_RETRYING   = 0x0000000E,
+               FRSRPC_CO_STATUS_FILE_INSTALL_DELETE_RETRYING   = 0x0000000F,
+               FRSRPC_CO_STATUS_CO_RECYCLED_FOR_ENUM           = 0x00000013,
+               FRSRPC_CO_STATUS_REQUEST_OUTBOUND_PROPAGATION   = 0x00000014,
+               FRSRPC_CO_STATUS_REQUEST_ACCEPTED_OUTBOUND_LOG  = 0x00000015,
+               FRSRPC_CO_STATUS_DB_STATE_UPDATE_STARTED        = 0x00000016,
+               FRSRPC_CO_STATUS_DB_STATE_UPDATE_COMPLETED      = 0x00000017,
+               FRSRPC_CO_STATUS_CO_ABORTED                     = 0x00000018
+       } frsrpc_CommPktCoCmdStatus;
+
+       typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+               FRSRPC_CONTENT_REASON_DATA_OVERWRITE            = 0x00000001,
+               FRSRPC_CONTENT_REASON_DATA_EXTEND               = 0x00000002,
+               FRSRPC_CONTENT_REASON_DATA_TRUNCATION           = 0x00000004,
+               FRSRPC_CONTENT_REASON_NAMED_DATA_OVERWRITE      = 0x00000010,
+               FRSRPC_CONTENT_REASON_NAMED_DATA_EXTEND         = 0x00000020,
+               FRSRPC_CONTENT_REASON_NAMED_DATA_TRUNCATION     = 0x00000040,
+               FRSRPC_CONTENT_REASON_FILE_CREATE               = 0x00000100,
+               FRSRPC_CONTENT_REASON_FILE_DELETE               = 0x00000200,
+               FRSRPC_CONTENT_REASON_EA_CHANGE                 = 0x00000400,
+               FRSRPC_CONTENT_REASON_SECURITY_CHANGE           = 0x00000800,
+               FRSRPC_CONTENT_REASON_OLD_NAME                  = 0x00001000,
+               FRSRPC_CONTENT_REASON_NEW_NAME                  = 0x00002000,
+               FRSRPC_CONTENT_REASON_BASIC_INFO_CHANGE         = 0x00004000,
+               FRSRPC_CONTENT_REASON_COMPRESSION_CHANGE        = 0x00020000
+       } frsrpc_CommPktCoCmdContentCmd;
+
+       typedef [v1_enum,flag(NDR_PAHEX)] enum {
+               FRSRPC_CO_LOCATION_FILE_CREATE  = 0x00000000,
+               FRSRPC_CO_LOCATION_DIR_CREATE   = 0x00000000 | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_DELETE  = 0x00000002,
+               FRSRPC_CO_LOCATION_DIR_DELETE   = 0x00000002 | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_MOVEIN  = 0x00000004,
+               FRSRPC_CO_LOCATION_DIR_MOVEIN   = 0x00000004 | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_MOVEIN2 = 0x00000006,
+               FRSRPC_CO_LOCATION_DIR_MOVEIN2  = 0x00000006 | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_MOVEOUT = 0x00000008,
+               FRSRPC_CO_LOCATION_DIR_MOVEOUT  = 0x00000008 | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_MOVERS  = 0x0000000a,
+               FRSRPC_CO_LOCATION_DIR_MOVERS   = 0x0000000a | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_MOVEDIR = 0x0000000c,
+               FRSRPC_CO_LOCATION_DIR_MOVEDIR  = 0x0000000c | 0x00000001,
+               FRSRPC_CO_LOCATION_FILE_NO_CMD  = 0x0000000e,
+               FRSRPC_CO_LOCATION_DIR_NO_CMD   = 0x0000000e | 0x00000001
+       } frsrpc_CommPktCoCmdLocationCmd;
 
-       /* TAG:18 this TLV contains a  timestamp 
-       */
        typedef struct {
-               [subcontext(4)] NTTIME time;
-       } frsrpc_FrsSendCommPktChunkDataTS;
+               uint32 sequence_number;
+               frsrpc_CommPktCoCmdFlags flags;
+               frsrpc_CommPktCoCmdIFlags iflags;
+               frsrpc_CommPktCoCmdStatus status;
+               frsrpc_CommPktCoCmdContentCmd content_cmd;
+               frsrpc_CommPktCoCmdLocationCmd location_cmd;
+               uint32 file_attributes;
+               uint32 file_version_number;
+               uint32 partern_ack_sequence_number;
+               [value(0)] uint32 not_used;
+               hyper file_size;
+               hyper file_offset;
+               hyper frs_vsn;
+               hyper file_usn;
+               hyper jrnl_usn;
+               hyper jrnl_first_usn;
+               uint32 original_replica_num;
+               uint32 new_replica_num;
+               GUID change_order_guid;
+               GUID originator_guid;
+               GUID file_guid;
+               GUID old_parent_guid;
+               GUID new_parent_guid;
+               GUID connection_guid;
+               hyper ack_version;
+               [value(0)] hyper spare2ul1;
+               [value(0)] hyper spare1guid_p1;
+               [value(0)] hyper spare1guid_p2;
+               [value(0)] hyper spare2guid_p1;
+               [value(0)] hyper spare3guid_p2;
+               [value(0)] uint32 spare1wcs;
+               [value(0)] uint32 spare2wcs;
+               [value(0)] uint32 extension;
+               [value(0)] uint32 spare2bin;
+               NTTIME event_time;
+               [value(2*strlen_m(file_name))] uint16 file_name_length;
+#define FRSRPC_MAX_PATH 260
+               [charset(UTF16)] uint16 file_name[FRSRPC_MAX_PATH+1];
+               [value(0)] uint8 padding1;
+               [value(0)] uint8 padding2;
+               [value(0)] uint8 padding3;
+               [value(0)] uint8 padding4;
+       } frsrpc_CommPktChangeOrderCommand;
+
+       typedef [v1_enum,flag(NDR_PAHEX)] enum {
+               FRSRPC_DATA_EXTENSION_TERMINATOR        = 0x00000000,
+               FRSRPC_DATA_EXTENSION_MD5_CHECKSUM      = 0x00000001,
+               FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT     = 0x00000002
+       } frsrpc_CommPktDataExtensionType;
 
+       typedef [flag(NDR_PAHEX)] struct {
+               [value(0x00000018)] uint32 prefix_size;
+               [value(FRSRPC_DATA_EXTENSION_MD5_CHECKSUM)]
+                       frsrpc_CommPktDataExtensionType prefix_type;
+               uint8 data[16];
+       } frsrpc_CommPktDataExtensionChecksum;
 
        typedef struct {
-               uint32 unknown1;
-       } frsrpc_FrsSendCommPktChunkDataA;
+               [value(0x00000018)] uint32 prefix_size;
+               [value(FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT)]
+                       frsrpc_CommPktDataExtensionType prefix_type;
+               uint32 count;
+               [value(0)] uint32 not_used;
+               NTTIME first_try_time;
+       } frsrpc_CommPktDataExtensionRetryTimeout;
+
+       typedef [flag(NDR_PAHEX)] enum {
+               FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K        = 0x0000,
+               FRSRPC_CO_RECORD_EXTENSION_VERSION_1            = 0x0001
+       } frsrpc_CommPktCoRecordExtensionMajor;
 
        typedef struct {
-               uint32 unknown1;
-               GUID unknown2;
-               [subcontext(4)] nstring unknown3;
-       } frsrpc_FrsSendCommPktChunkDataB;
+               [value(0x00000028)] uint32 field_size;
+               [value(FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K)]
+                       frsrpc_CommPktCoRecordExtensionMajor major;
+               [value(0x0001)] uint16 offset_count;
+               [value(0x00000010)] uint32 offset;
+               [value(0)] uint32 offset_last;
+               frsrpc_CommPktDataExtensionChecksum data_checksum;
+       } frsrpc_CommPktCoRecordExtensionWin2k;
 
        typedef struct {
-               uint32 unknown1;
-               GUID unknown2;
-       } frsrpc_FrsSendCommPktChunkDataC;
+               [value(0x00000048)] uint32 field_size;
+               frsrpc_CommPktCoRecordExtensionMajor major;
+               [value(0x0002)] uint16 offset_count;
+               [value(0x00000018)] uint32 offset0;
+               [value(0x00000030)] uint32 offset1;/*TODO: is this correct??? */
+               [value(0)] uint32 offset_last;
+               [value(0)] uint32 not_used;
+               frsrpc_CommPktDataExtensionChecksum data_checksum;
+               frsrpc_CommPktDataExtensionRetryTimeout data_retry_timeout;
+       } frsrpc_CommPktChangeOrderRecordExtension;
+
+       typedef [v1_enum,flag(NDR_PAHEX)] enum {
+               FRSRPC_COMMAND_REMOTE_CO                = 0x00000218,
+               FRSRPC_COMMAND_RECEIVING_STATE          = 0x00000238,
+               FRSRPC_COMMAND_REMOTE_CO_DONE           = 0x00000250,
+               FRSRPC_COMMAND_ABORT_FETCH              = 0x00000246,
+               FRSRPC_COMMAND_RETRY_FETCH              = 0x00000244,
+               FRSRPC_COMMAND_NEED_JOIN                = 0x00000121,
+               FRSRPC_COMMAND_START_JOIN               = 0x00000122,
+               FRSRPC_COMMAND_JOINING                  = 0x00000130,
+               FRSRPC_COMMAND_JOINED                   = 0x00000128,
+               FRSRPC_COMMAND_UNJOIN_REMOTE            = 0x00000148,
+               FRSRPC_COMMAND_WJOIN_DONE               = 0x00000136,
+               FRSRPC_COMMAND_SEND_STAGE               = 0x00000228
+       } frsrpc_CommPktCommand;
+
+       typedef [flag(NDR_PAHEX)] enum {
+               FRSRPC_COMM_PKT_CHUNK_BOP                       = 0x0001,
+               FRSRPC_COMM_PKT_CHUNK_COMMAND                   = 0x0002,
+               FRSRPC_COMM_PKT_CHUNK_TO                        = 0x0003,
+               FRSRPC_COMM_PKT_CHUNK_FROM                      = 0x0004,
+               FRSRPC_COMM_PKT_CHUNK_REPLICA                   = 0x0005,
+               FRSRPC_COMM_PKT_CHUNK_CONNECTION                = 0x0008,
+               FRSRPC_COMM_PKT_CHUNK_JOIN_GUID                 = 0x0006,
+               FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME            = 0x0012,
+
+               FRSRPC_COMM_PKT_CHUNK_VVECTOR                   = 0x0007,
+               FRSRPC_COMM_PKT_CHUNK_JOIN_TIME                 = 0x0011,
+               FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID      = 0x0014,
+               FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID          = 0x0018,
+
+               FRSRPC_COMM_PKT_CHUNK_BLOCK                     = 0x0009,
+               FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE                = 0x000A,
+               FRSRPC_COMM_PKT_CHUNK_FILE_SIZE                 = 0x000B,
+               FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET               = 0x000C,
+               FRSRPC_COMM_PKT_CHUNK_GVSN                      = 0x000E,
+               FRSRPC_COMM_PKT_CHUNK_CO_GUID                   = 0x000F,
+               FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER        = 0x0010,
+
+               FRSRPC_COMM_PKT_CHUNK_REMOTE_CO                 = 0x000D,
+               FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K              = 0x0016,
+               FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2            = 0x0017,
+
+               FRSRPC_COMM_PKT_CHUNK_EOP                       = 0x0013
+       } frsrpc_CommPktChunkType;
 
        typedef [nodiscriminant] union {
                [default,flag(NDR_REMAINING)] DATA_BLOB blob;
-               [case(1)] frsrpc_FrsSendCommPktChunkDataA A;
-               [case(2)] frsrpc_FrsSendCommPktChunkDataA A;
-               [case(3)] frsrpc_FrsSendCommPktChunkDataSSRV SSRV;
-               [case(4)] frsrpc_FrsSendCommPktChunkDataDSRV DSRV;
-               [case(5)] frsrpc_FrsSendCommPktChunkDataB B;
-               [case(8)] frsrpc_FrsSendCommPktChunkDataB B;
-               [case(6)] frsrpc_FrsSendCommPktChunkDataC C;
-               [case(18)] frsrpc_FrsSendCommPktChunkDataTS TS;
-               [case(19)] frsrpc_FrsSendCommPktChunkDataA A;
-       } frsrpc_FrsSendCommPktChunkData;
+               [case(FRSRPC_COMM_PKT_CHUNK_BOP)]
+                       [value(0)] uint32 bop;
+               [case(FRSRPC_COMM_PKT_CHUNK_COMMAND)]
+                       frsrpc_CommPktCommand command;
+               [case(FRSRPC_COMM_PKT_CHUNK_TO)]
+                       frsrpc_CommPktChunkGuidName to;
+               [case(FRSRPC_COMM_PKT_CHUNK_FROM)]
+                       frsrpc_CommPktChunkGuidName from;
+               [case(FRSRPC_COMM_PKT_CHUNK_REPLICA)]
+                       frsrpc_CommPktChunkGuidName replica;
+               [case(FRSRPC_COMM_PKT_CHUNK_CONNECTION)]
+                       frsrpc_CommPktChunkGuidName connection;
+               [case(FRSRPC_COMM_PKT_CHUNK_JOIN_GUID)][subcontext(4)]
+                       GUID join_guid;
+               [case(FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME)]
+                       NTTIME last_join_time;
+               [case(FRSRPC_COMM_PKT_CHUNK_VVECTOR)][subcontext(4)]
+                       frsrpc_CommPktGSVN vvector;
+               [case(FRSRPC_COMM_PKT_CHUNK_JOIN_TIME)][subcontext(4)]
+                       NTTIME join_time;
+               [case(FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID)][subcontext(4)]
+                       GUID replica_version_guid;
+               [case(FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID)]
+                       GUID compression_guid;
+               [case(FRSRPC_COMM_PKT_CHUNK_BLOCK)]
+                       [flag(NDR_REMAINING)] DATA_BLOB block;
+               [case(FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE)]
+                       hyper block_size;
+               [case(FRSRPC_COMM_PKT_CHUNK_FILE_SIZE)]
+                       hyper file_size;
+               [case(FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET)]
+                       hyper file_offset;
+               [case(FRSRPC_COMM_PKT_CHUNK_GVSN)][subcontext(4)]
+                       frsrpc_CommPktGSVN gvsn;
+               [case(FRSRPC_COMM_PKT_CHUNK_CO_GUID)][subcontext(4)]
+                       GUID co_guid;
+               [case(FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER)]
+                       uint32 co_sequnence_number;
+               [case(FRSRPC_COMM_PKT_CHUNK_REMOTE_CO)][subcontext(4)]
+                       frsrpc_CommPktChangeOrderCommand remote_co;
+               [case(FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K)][subcontext(4)]
+                       frsrpc_CommPktCoRecordExtensionWin2k co_ext_win2k;
+               [case(FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2)][subcontext(4)]
+                       frsrpc_CommPktChangeOrderRecordExtension co_extension2;
+               [case(FRSRPC_COMM_PKT_CHUNK_EOP)]
+                       [value(0xFFFFFFFF)] uint32 bop;
+       } frsrpc_CommPktChunkData;
 
-       typedef struct {
-               uint16 type;
-               [subcontext(4),switch_is(type)] frsrpc_FrsSendCommPktChunkData data;
-       } frsrpc_FrsSendCommPktChunk;
-
-       typedef [flag(NDR_NOALIGN)] struct {
-               frsrpc_FrsSendCommPktChunk chunk1;
-               frsrpc_FrsSendCommPktChunk chunk2;
-               frsrpc_FrsSendCommPktChunk chunk3;
-               frsrpc_FrsSendCommPktChunk chunk4;
-               frsrpc_FrsSendCommPktChunk chunk5;
-               frsrpc_FrsSendCommPktChunk chunk6;
-               frsrpc_FrsSendCommPktChunk chunk7;
-               frsrpc_FrsSendCommPktChunk chunk8;
-               frsrpc_FrsSendCommPktChunk chunk9;
-       } frsrpc_FrsSendCommPktChunkCtr;
+       typedef [public,flag(NDR_NOALIGN)] struct {
+               frsrpc_CommPktChunkType type;
+               [subcontext(4),switch_is(type)] frsrpc_CommPktChunkData data;
+       } frsrpc_CommPktChunk;
+
+       typedef [nopull,nopush,flag(NDR_NOALIGN)] struct {
+               uint32 num_chunks; /* this doesn't appear on the wire */
+               frsrpc_CommPktChunk chunks[num_chunks];
+       } frsrpc_CommPktChunkCtr;
+
+       typedef [v1_enum] enum {
+               FRSRPC_COMM_PKT_MAJOR_0 = 0x00000000
+       } frsrpc_CommPktMajor;
+
+       typedef [v1_enum] enum {
+               FRSRPC_COMM_PKT_MINOR_0 = 0x00000000,
+               FRSRPC_COMM_PKT_MINOR_1 = 0x00000001,
+               FRSRPC_COMM_PKT_MINOR_2 = 0x00000002,
+               FRSRPC_COMM_PKT_MINOR_3 = 0x00000003,
+               FRSRPC_COMM_PKT_MINOR_4 = 0x00000004,
+               FRSRPC_COMM_PKT_MINOR_5 = 0x00000005,
+               FRSRPC_COMM_PKT_MINOR_6 = 0x00000006,
+               FRSRPC_COMM_PKT_MINOR_7 = 0x00000007,
+               FRSRPC_COMM_PKT_MINOR_8 = 0x00000008,
+               FRSRPC_COMM_PKT_MINOR_9 = 0x00000009
+       } frsrpc_CommPktMinor;
 
        typedef struct {
-               uint32 unknown1;
-               uint32 unknown2;
-               uint32 unknown3;
-               uint32 unknown4;
-               uint32 tlv_size;
-               uint32 unknown6;
-               uint32 unknown7; /* This may be a UNIQUE pointer? */
-               uint32 unknown8;
-               uint32 unknown9;
-               /*
-                * The format of this blob is this a concatenation
-                * of TLVs which are not really NDR encoded.
-                *
-                * The individual TLVs are encoded as :
-                * struct {
-                *      uint16 type;
-                *      [subcontext(4),switch_is(type)] chunk_data data;
-                * } chunk;
-                * 
-                * some of the chunk are like this:
-                *
-                * struct {
-                *      uint32 unknown; // 0x00000010
-                *      struct GUID guid;
-                *      lstring string;
-                * } ...;
-                *
-                *
-                * The tags are (might be) :
-                *  3: Source server sending the PDU
-                *  4: Destination server the PDU is sent to
-                * 18: Timestamp
-                *
-                */
-               [subcontext(4)/*,size_is(tlv_size)*/] frsrpc_FrsSendCommPktChunkCtr *chunks;
-               uint32 unknown10;
-               uint32 unknown11;
+               frsrpc_CommPktMajor major;
+               frsrpc_CommPktMinor minor;
+               [value(1)] uint32 cs_id;
+               [value(pkt_len+12)] uint32 memory_len;
+               [value(ndr_size_frsrpc_CommPktChunkCtr(r->ctr,
+                       ndr->iconv_convenience, ndr->flags))]
+               [range(0, 262144)]
+                       uint32 pkt_len;
+               [value(0)] uint32 upk_len;
+               [subcontext(4),subcontext_size(pkt_len)]
+                       frsrpc_CommPktChunkCtr *ctr;
+               [value(0)] uint32 data_name;
+               [value(0)] uint32 data_handle;
        } frsrpc_FrsSendCommPktReq;
 
        WERROR frsrpc_FrsSendCommPkt(
@@ -132,7 +358,28 @@ interface frsrpc
 
        /*****************/
        /* Function 0x02 */
-       [todo] void FRSRPC_START_PROMOTION_PARENT();
+       typedef [v1_enum,flag(NDR_PAHEX)] enum {
+               FRSRPC_PARENT_AUTH_LEVEL_ENCRYPTED_KERBEROS     = 0x00000000,
+               FRSRPC_PARENT_AUTH_LEVEL_NO_AUTHENTICATION      = 0x00000001
+       } frsrpc_PartnerAuthLevel;
+
+       WERROR frsrpc_FrsStartPromotionParent(
+               [in,unique,string,charset(UTF16)] uint16 *parent_account,
+               [in,unique,string,charset(UTF16)] uint16 *parent_password,
+               [in,unique,string,charset(UTF16)] uint16 *replica_set_name,
+               [in,unique,string,charset(UTF16)] uint16 *replica_set_type,
+               [in,unique,string,charset(UTF16)] uint16 *connection_name,
+               [in,unique,string,charset(UTF16)] uint16 *partner_name,
+               [in,unique,string,charset(UTF16)] uint16 *partner_princ_name,
+               [in] frsrpc_PartnerAuthLevel partner_auth_level,
+               [in,value(16),range(16,16)] uint32 __ndr_guid_size,
+               [in,unique,subcontext(4),subcontext_size(16)]
+                       GUID *connection_guid,
+               [in,unique,subcontext(4),subcontext_size(16)]
+                       GUID *partner_guid,
+               [in,out,unique,subcontext(4),subcontext_size(16)]
+                       GUID *parent_guid
+       );
 
        /*****************/
        /* Function 0x03 */
diff --git a/librpc/idl/frstrans.idl b/librpc/idl/frstrans.idl
new file mode 100644 (file)
index 0000000..c79aabf
--- /dev/null
@@ -0,0 +1,83 @@
+#include "idl_types.h"
+
+import "misc.idl";
+
+[
+  uuid("897e2e5f-93f3-4376-9c9c-fd2277495c27"),
+  version(1.0),
+  endpoint("ncacn_ip_tcp:", "ncalrpc:"),
+  helpstring("File Replication Service DFS-R"),
+  pointer_default(unique)
+]
+interface frstrans
+{
+       /*****************/
+       /* Function 0x00 */
+       [todo] void FRSTRANS_CHECK_CONNECTIVITY();
+
+       /*****************/
+       /* Function 0x01 */
+       [todo] void FRSTRANS_ESTABLISH_CONNECTION();
+
+       /*****************/
+       /* Function 0x02 */
+       [todo] void FRSTRANS_ESTABLISH_SESSION();
+
+       /*****************/
+       /* Function 0x03 */
+       [todo] void FRSTRANS_REQUEST_UPDATES();
+
+       /*****************/
+       /* Function 0x04 */
+       [todo] void FRSTRANS_REQUEST_VERSION_VECTOR();
+
+       /*****************/
+       /* Function 0x05 */
+       [todo] void FRSTRANS_ASYNC_POLL();
+
+       /*****************/
+       /* Function 0x06 */
+       [todo] void FRSTRANS_REQUEST_RECORDS();
+
+       /*****************/
+       /* Function 0x07 */
+       [todo] void FRSTRANS_UPDATE_CANCEL();
+
+       /*****************/
+       /* Function 0x08 */
+       [todo] void FRSTRANS_RAW_GET_FILE_DATA();
+
+       /*****************/
+       /* Function 0x09 */
+       [todo] void FRSTRANS_RDC_GET_SIGNATURES();
+
+       /*****************/
+       /* Function 0x0a */
+       [todo] void FRSTRANS_RDC_PUSH_SOURCE_NEEDS();
+
+       /*****************/
+       /* Function 0x0b */
+       [todo] void FRSTRANS_RDC_GET_FILE_DATA();
+
+       /*****************/
+       /* Function 0x0c */
+       [todo] void FRSTRANS_RDC_CLOSE();
+
+       /*****************/
+       /* Function 0x0d */
+       [todo] void FRSTRANS_INITIALIZE_FILE_TRANSFER_ASYNC();
+
+       /*****************/
+       /* Function 0x0e */
+       [todo] void FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE();
+
+       /* The following functions are new in Windows 2008 */
+
+       /*****************/
+       /* Function 0x0f */
+       [todo] void FRSTRANS_RAW_GET_FILE_DATA_ASYNC();
+
+       /*****************/
+       /* Function 0x10 */
+       [todo] void FRSTRANS_RDC_GET_FILE_DATA_ASYNC();
+}
index 9e3b7d604830c192055d5a4323422a495fe1d2d8..7f8ed4afe30d057907bab8638e47aa6737c90cfc 100644 (file)
@@ -651,7 +651,7 @@ import "misc.idl", "security.idl";
                LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL    = 10,
                LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL     = 11,
                LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL  = 12,
-               LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES = 13
+               LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES = 13
        } lsa_TrustDomInfoEnum;
 
        typedef [public,bitmap32bit] bitmap {
@@ -788,7 +788,7 @@ import "misc.idl", "security.idl";
                        lsa_TrustDomainInfoInfoEx2Internal   info_ex2_internal;
                [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)]
                        lsa_TrustDomainInfoFullInfo2Internal     full_info2_internal;
-               [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)]
+               [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)]
                        lsa_TrustDomainInfoSupportedEncTypes enc_types;
        } lsa_TrustedDomainInfo;
 
@@ -935,10 +935,18 @@ import "misc.idl", "security.idl";
        );
 
        /* Function:       0x2a */
-       [todo] NTSTATUS lsa_StorePrivateData();
-       /* Function:        0x2b */
-       [todo] NTSTATUS lsa_RetrievePrivateData();
+       NTSTATUS lsa_StorePrivateData(
+               [in]            policy_handle   *handle,
+               [in,ref]        lsa_String      *name,
+               [in,unique]     lsa_DATA_BUF    *val
+       );
 
+       /* Function:        0x2b */
+       NTSTATUS lsa_RetrievePrivateData(
+               [in]            policy_handle   *handle,
+               [in,ref]        lsa_String      *name,
+               [in,out,ref]    lsa_DATA_BUF    **val
+       );
 
        /**********************/
        /* Function:     0x2c */
index b7c151d413afaafdf7950c0c25f0f2d4a4f47cfa..8a5692fe17d48f36fec27ff0e29d7e8c84b5620b 100644 (file)
@@ -1544,12 +1544,14 @@ import "misc.idl", "lsa.idl", "security.idl";
                SAMR_VALIDATION_STATUS_SUCCESS = 0,
                SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
                SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
+               SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED = 3,
                SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
                SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
                SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
                SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
                SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
-               SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
+               SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9,
+               SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR = 10
        } samr_ValidationStatus;
 
        typedef struct {
index f37424634d08c90e9bb3ccf04916b07befdd9fa9..0c68dffcd19d28ef795187a242a0cc44621975a3 100644 (file)
@@ -1311,7 +1311,7 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 major;
                uint32 minor;
                uint32 build;
-               [value(2)] uint32 unknown;
+               [value(2)] uint32 platform_id;
                [subcontext(0),subcontext_size(256)] nstring extra_string;
        } spoolss_OSVersion;
 
@@ -1320,10 +1320,13 @@ import "misc.idl", "security.idl", "winreg.idl";
                uint32 major;
                uint32 minor;
                uint32 build;
-               [value(2)] uint32 unknown1;
+               [value(2)] uint32 platform_id;
                [subcontext(0),subcontext_size(256)] nstring extra_string;
-               uint32 unknown2;/* service pack number? I saw 0 from w2k3 and 1 from winxp sp1*/
-               uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */
+               uint16 service_pack_major;
+               uint16 service_pack_minor;
+               uint16 suite_mask;
+               uint8 product_type;
+               uint8 reserved;
        } spoolss_OSVersionEx;
 
        typedef [nodiscriminant,public,gensize] union {
@@ -1683,7 +1686,10 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        /******************/
        /* Function: 0x28 */
-       [todo] WERROR spoolss_CreatePrinterIC(
+       WERROR spoolss_CreatePrinterIC(
+               [in,ref] policy_handle *handle,
+               [out,ref] policy_handle *gdi_handle,
+               [in,ref] spoolss_DevmodeContainer *devmode_ctr
        );
 
        /******************/
@@ -1693,7 +1699,8 @@ import "misc.idl", "security.idl", "winreg.idl";
 
        /******************/
        /* Function: 0x2a */
-       [todo] WERROR spoolss_DeletePrinterIC(
+       WERROR spoolss_DeletePrinterIC(
+               [in,out,ref] policy_handle *gdi_handle
        );
 
        /******************/
diff --git a/librpc/ndr/ndr_frsrpc.c b/librpc/ndr/ndr_frsrpc.c
new file mode 100644 (file)
index 0000000..e0c7f1c
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   helper routines for FRSRPC marshalling
+
+   Copyright (C) Stefan (metze) Metzmacher 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_frsrpc.h"
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+                                       int ndr_flags,
+                                       const struct frsrpc_CommPktChunkCtr *r)
+{
+       uint32_t cntr_chunks_0;
+       {
+               uint32_t _flags_save_STRUCT = ndr->flags;
+               ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+               if (ndr_flags & NDR_SCALARS) {
+                       NDR_CHECK(ndr_push_align(ndr, 2));
+                       for (cntr_chunks_0 = 0; cntr_chunks_0 < r->num_chunks; cntr_chunks_0++) {
+                               NDR_CHECK(ndr_push_frsrpc_CommPktChunk(ndr, NDR_SCALARS, &r->chunks[cntr_chunks_0]));
+                       }
+               }
+               if (ndr_flags & NDR_BUFFERS) {
+               }
+               ndr->flags = _flags_save_STRUCT;
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+#define _TMP_PULL_REALLOC_N(ndr, s, t, n) do { \
+       _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\
+       (s) = talloc_realloc(ndr->current_mem_ctx, (s), t, n); \
+       if (!(s)) { \
+               return ndr_pull_error(ndr, NDR_ERR_ALLOC, \
+                                     "Alloc %u * %s failed: %s\n", \
+                                     (unsigned)n, # s, __location__); \
+       } \
+} while (0)
+
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+                                       int ndr_flags,
+                                       struct frsrpc_CommPktChunkCtr *r)
+{
+       uint32_t cntr_chunks_0;
+       {
+               uint32_t _flags_save_STRUCT = ndr->flags;
+               ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+               if (ndr_flags & NDR_SCALARS) {
+                       uint32_t remaining = ndr->data_size - ndr->offset;
+                       r->num_chunks = 0;
+                       r->chunks = NULL;
+                       for (cntr_chunks_0 = 0; remaining > 0; cntr_chunks_0++) {
+                               r->num_chunks += 1;
+                               _TMP_PULL_REALLOC_N(ndr, r->chunks,
+                                                   struct frsrpc_CommPktChunk,
+                                                   r->num_chunks);
+                               NDR_CHECK(ndr_pull_frsrpc_CommPktChunk(ndr,
+                                               NDR_SCALARS,
+                                               &r->chunks[cntr_chunks_0]));
+                               remaining = ndr->data_size - ndr->offset;
+                       }
+               }
+               if (ndr_flags & NDR_BUFFERS) {
+               }
+               ndr->flags = _flags_save_STRUCT;
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+                                      struct smb_iconv_convenience *ic,
+                                      int flags)
+{
+       flags |= LIBNDR_FLAG_NOALIGN;
+       return ndr_size_struct(r, flags,
+                       (ndr_push_flags_fn_t)ndr_push_frsrpc_CommPktChunkCtr,
+                       ic);
+}
diff --git a/librpc/ndr/ndr_frsrpc.h b/librpc/ndr/ndr_frsrpc.h
new file mode 100644 (file)
index 0000000..e8dc769
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   helper routines for FRSRPC marshalling
+
+   Copyright (C) Stefan (metze) Metzmacher 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBRPC_NDR_NDR_FRSRPC_H
+#define _LIBRPC_NDR_NDR_FRSRPC_H
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+                                       int ndr_flags,
+                                       const struct frsrpc_CommPktChunkCtr *r);
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+                                       int ndr_flags,
+                                       struct frsrpc_CommPktChunkCtr *r);
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+                                      struct smb_iconv_convenience *ic,
+                                      int flags);
+
+#endif /* _LIBRPC_NDR_NDR_FRSRPC_H */
diff --git a/librpc/ndr_standard.pc.in b/librpc/ndr_standard.pc.in
new file mode 100644 (file)
index 0000000..80eace1
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ndr-standard
+Description: NDR marshallers for the standard set of DCE/RPC interfaces
+Requires: ndr
+Version: 0.0.1
+Libs: -L${libdir} -lndr-standard
+Cflags: -I${includedir}  -DHAVE_IMMEDIATE_STRUCTURES=1 -D_GNU_SOURCE=1
index e90f1b75ad63973e1dcca996ef97b30cc78f5727..4e84574d258b3a9db57fc4efcf2b108265810e3d 100644 (file)
@@ -11,6 +11,8 @@
 */
 
 #include "pam_winbind.h"
+#define CONST_DISCARD(type,ptr) ((type)(void *)ptr)
+
 
 static int wbc_error_to_pam_error(wbcErr status)
 {
@@ -410,49 +412,51 @@ static int _pam_parse(const pam_handle_t *pamh,
                config_file = PAM_WINBIND_CONFIG_FILE;
        }
 
-       d = iniparser_load(config_file);
+       d = iniparser_load(CONST_DISCARD(char *, config_file));
        if (d == NULL) {
                goto config_from_pam;
        }
 
-       if (iniparser_getboolean(d, "global:debug", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug"), false)) {
                ctrl |= WINBIND_DEBUG_ARG;
        }
 
-       if (iniparser_getboolean(d, "global:debug_state", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug_state"), false)) {
                ctrl |= WINBIND_DEBUG_STATE;
        }
 
-       if (iniparser_getboolean(d, "global:cached_login", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:cached_login"), false)) {
                ctrl |= WINBIND_CACHED_LOGIN;
        }
 
-       if (iniparser_getboolean(d, "global:krb5_auth", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
                ctrl |= WINBIND_KRB5_AUTH;
        }
 
-       if (iniparser_getboolean(d, "global:silent", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:silent"), false)) {
                ctrl |= WINBIND_SILENT;
        }
 
-       if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) {
+       if (iniparser_getstr(d, CONST_DISCARD(char *, "global:krb5_ccache_type")) != NULL) {
                ctrl |= WINBIND_KRB5_CCACHE_TYPE;
        }
 
-       if ((iniparser_getstr(d, "global:require-membership-of") != NULL) ||
-           (iniparser_getstr(d, "global:require_membership_of") != NULL)) {
+       if ((iniparser_getstr(d, CONST_DISCARD(char *, "global:require-membership-of"))
+            != NULL) ||
+           (iniparser_getstr(d, CONST_DISCARD(char *, "global:require_membership_of"))
+            != NULL)) {
                ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
        }
 
-       if (iniparser_getboolean(d, "global:try_first_pass", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:try_first_pass"), false)) {
                ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
        }
 
-       if (iniparser_getint(d, "global:warn_pwd_expire", 0)) {
+       if (iniparser_getint(d, CONST_DISCARD(char *, "global:warn_pwd_expire"), 0)) {
                ctrl |= WINBIND_WARN_PWD_EXPIRE;
        }
 
-       if (iniparser_getboolean(d, "global:mkhomedir", false)) {
+       if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:mkhomedir"), false)) {
                ctrl |= WINBIND_MKHOMEDIR;
        }
 
@@ -2284,6 +2288,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
        enum wbcSidType type;
        char *domain;
        char *name;
+       char *p;
 
        /* This cannot work when the winbind separator = @ */
 
@@ -2292,9 +2297,18 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
                return NULL;
        }
 
+       name = talloc_strdup(ctx, upn);
+       if (!name) {
+               return NULL;
+       }
+       if ((p = strchr(name, '@')) != NULL) {
+               *p = 0;
+               domain = p + 1;
+       }
+
        /* Convert the UPN to a SID */
 
-       wbc_status = wbcLookupName("", upn, &sid, &type);
+       wbc_status = wbcLookupName(domain, name, &sid, &type);
        if (!WBC_ERROR_IS_OK(wbc_status)) {
                return NULL;
        }
index ed1b71a236f7767405900d99099af5ecf573ef13..a2a61d87d07319546e54ea1b6988304bea577282 100644 (file)
@@ -96,11 +96,17 @@ sub ParseOutputArgument($$$)
                # structure, the user should be able to know the size beforehand 
                # to allocate a structure of the right size.
                my $env = GenerateFunctionInEnv($fn, "r.");
-               my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL});
-               if (has_property($e, "charset")) {
-                   $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+               my $l = $e->{LEVELS}[$level];
+               unless (defined($l->{SIZE_IS})) {
+                       error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'");
+                       $self->pidl('#error No size known for [out] array `$e->{NAME}');
                } else {
-                   $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+                       my $size_is = ParseExpr($l->{SIZE_IS}, $env, $e->{ORIGINAL});
+                       if (has_property($e, "charset")) {
+                               $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+                       } else {
+                               $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+                       }
                }
        } else {
                $self->pidl("*$e->{NAME} = *r.out.$e->{NAME};");
index c9a8eea59fd146f17192da43a68e4b3b9440383d..5599de9d790904692ee2b215859f8957f603e584 100644 (file)
@@ -11,7 +11,7 @@ use Exporter;
 @EXPORT_OK = qw(DeclLevel);
 
 use strict;
-use Parse::Pidl qw(warning fatal);
+use Parse::Pidl qw(warning error fatal);
 use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
 use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
 use Parse::Pidl::NDR qw(GetNextLevel);
@@ -72,8 +72,13 @@ sub AllocOutVar($$$$$)
        }
 
        if ($l->{TYPE} eq "ARRAY") {
-               my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
-               pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+               unless(defined($l->{SIZE_IS})) {
+                       error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'");
+                       pidl "#error No size known for array `$e->{NAME}'";
+               } else {
+                       my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+                       pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+               }
        } else {
                pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
        }
index 81869b0da5c93d652c1bba734914557da95106b6..d27192d6ddb76e31399606ed3eec5c67c51604f3 100644 (file)
@@ -431,7 +431,7 @@ sub PythonFunctionUnpackOut($$$)
        } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") {
                $self->handle_werror("r->out.result", "NULL", undef);
        } elsif (defined($fn->{RETURN_TYPE})) {
-               my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result");
+               my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn);
                if ($result_size > 1) {
                        $self->pidl("PyTuple_SetItem(result, $i, $conv);");
                } else {
@@ -815,11 +815,11 @@ sub assign($$$)
        }
 }
 
-sub ConvertObjectFromPythonData($$$$$$)
+sub ConvertObjectFromPythonData($$$$$$;$)
 {
-       my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_;
+       my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location) = @_;
 
-       die("undef type for $cvar") unless(defined($ctype));
+       fatal($location, "undef type for $cvar") unless(defined($ctype));
 
        $ctype = resolveType($ctype);
 
@@ -839,7 +839,7 @@ sub ConvertObjectFromPythonData($$$$$$)
        if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
                my $ctype_name = $self->use_type_variable($ctype);
                unless (defined ($ctype_name)) {
-                       error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+                       error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
                        $self->assign($target, "NULL");
                        # FIXME:
                        return;
@@ -886,7 +886,7 @@ sub ConvertObjectFromPythonData($$$$$$)
                return;
        }
 
-       fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+       fatal($location, "unknown type `$actual_ctype->{TYPE}' for ".mapTypeName($ctype) . ": $cvar");
 
 }
 
@@ -946,7 +946,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
                if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
                        $var_name = get_pointer_to($var_name);
                }
-               $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail);
+               $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail, $e->{ORIGINAL});
        } elsif ($l->{TYPE} eq "SWITCH") {
                $var_name = get_pointer_to($var_name);
                my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
@@ -954,7 +954,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
        } elsif ($l->{TYPE} eq "SUBCONTEXT") {
                $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
        } else {
-               die("unknown level type $l->{TYPE}");
+               fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
        }
 }
 
@@ -1003,9 +1003,9 @@ sub ConvertScalarToPython($$$)
        die("Unknown scalar type $ctypename");
 }
 
-sub ConvertObjectToPythonData($$$$$)
+sub ConvertObjectToPythonData($$$$$;$)
 {
-       my ($self, $mem_ctx, $ctype, $cvar) = @_;
+       my ($self, $mem_ctx, $ctype, $cvar, $location) = @_;
 
        die("undef type for $cvar") unless(defined($ctype));
 
@@ -1027,13 +1027,13 @@ sub ConvertObjectToPythonData($$$$$)
        } elsif ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
                my $ctype_name = $self->use_type_variable($ctype);
                unless (defined($ctype_name)) {
-                       error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+                       error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
                        return "NULL"; # FIXME!
                }
                return "py_talloc_import_ex($ctype_name, $mem_ctx, $cvar)";
        }
 
-       fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+       fatal($location, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
 }
 
 sub fail_on_null($$$)
@@ -1113,12 +1113,12 @@ sub ConvertObjectToPythonLevel($$$$$$)
                if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
                        $var_name = get_pointer_to($var_name);
                }
-               my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name);
+               my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
                $self->pidl("$py_var = $conv;");
        } elsif ($l->{TYPE} eq "SUBCONTEXT") {
                $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail);
        } else {
-               die("Unknown level type $l->{TYPE} $var_name");
+               fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
        }
 }
 
@@ -1223,7 +1223,7 @@ sub Parse($$$$$)
                } elsif ($cvar =~ /^".*"$/) {
                        $py_obj = "PyString_FromString($cvar)";
                } else {
-                       $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar);
+                       $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
                }
 
                $self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);");
index e63b3c990f302271ccdcf78473243212d00f1207..12ffa92bf6ff795d61701455f7e75dd76baa47e6 100644 (file)
@@ -273,12 +273,15 @@ sub mapTypeName($)
        my $dt;
        $t = expandAlias($t);
 
-       unless ($dt or ($dt = getType($t))) {
+       if ($dt = getType($t)) {
+               return mapType($dt, $dt->{NAME});
+       } elsif (ref($t) eq "HASH" and defined($t->{NAME})) {
+               return mapType($t, $t->{NAME});
+       } else {
                # Best guess
                return "struct $t";
        }
 
-       return mapType($dt, $dt->{NAME});
 }
 
 sub LoadIdl($;$)
index 4c927e7346b87c2d934f6a70ac64bc3630761193..e6d0cf00ddd0069f6a60e2bba5961c8f3a42c54d 100644 (file)
@@ -381,7 +381,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
          lib/interface.o lib/pidfile.o \
          lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
          lib/username.o \
-         lib/ads_flags.o \
+         ../libds/common/flag_mapping.o \
          lib/util_pw.o lib/access.o lib/smbrun.o \
          lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
          lib/wins_srv.o \
@@ -667,6 +667,8 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \
 
 NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
 
+FNAME_UTIL_OBJ = smbd/filename_util.o
+
 VFS_DEFAULT_OBJ = modules/vfs_default.o
 VFS_AUDIT_OBJ = modules/vfs_audit.o
 VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
@@ -786,7 +788,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
                $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \
                $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
                $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
-               $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
+               $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
                $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \
                $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
                $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
@@ -828,16 +830,16 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
           $(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \
           $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
           $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \
-           $(PASSCHANGE_OBJ) $(LDB_OBJ)
+           $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ)
 
 STATUS_OBJ = utils/status.o utils/status_profile.o \
             $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
-            $(LIBSAMBA_OBJ)
+            $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ)
 
 SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
        $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
-       $(LIBSAMBA_OBJ) \
+       $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \
        $(PRINTBASE_OBJ)
 
 SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
@@ -1033,7 +1035,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIEN
 
 LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
                $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \
-               $(LIBNDR_GEN_OBJ0)
+               $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
 
 NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
                  $(LIB_NONSMBD_OBJ) \
@@ -1052,7 +1054,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o
 
 LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
                $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
-               $(LIBNDR_GEN_OBJ0)
+               $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
 
 SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
                $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
@@ -1476,10 +1478,10 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@
 
 bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
        @echo Linking $@
-       @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
+       @$(CC) -o $@ $(LDFLAGS) $(RPCCLIENT_OBJ) \
                $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
                $(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
-               $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS)
+               $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) $(PASSDB_LIBS)
 
 bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
        @echo Linking $@
@@ -1517,7 +1519,7 @@ bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ)
 bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
        @echo Linking $@
        @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
-               -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \
+               $(LIBSMBCLIENT_OBJ1) $(LIBS) -lkeyutils $(KRB5LIBS) \
                $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \
                $(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS)
 
index fd4c50375258875052c5046e792de58c2c500d51..ce8722a1b48d5cd0e88399d750ffcdbb11cdedcd 100644 (file)
@@ -82,7 +82,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
        DATA_BLOB challenge = data_blob_null;
        const char *challenge_set_by = NULL;
        auth_methods *auth_method;
-       TALLOC_CTX *mem_ctx;
 
        if (auth_context->challenge.length) {
                DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n", 
@@ -106,12 +105,8 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
                        continue;
                }
 
-               mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name);
-               if (!mem_ctx) {
-                       smb_panic("talloc_init() failed!");
-               }
-
-               challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
+               challenge = auth_method->get_chal(auth_context, &auth_method->private_data,
+                                       auth_context->mem_ctx);
                if (!challenge.length) {
                        DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", 
                                  auth_method->name));
@@ -121,7 +116,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
                        challenge_set_by = auth_method->name;
                        auth_context->challenge_set_method = auth_method;
                }
-               talloc_destroy(mem_ctx);
        }
 
        if (!challenge_set_by) {
index a2634feb6c02c4b3ddb014d2946e8672922da8eb..26b45e47e5664821828cc7bc376bb0acad14df1e 100644 (file)
@@ -226,10 +226,10 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
 
        if (*workstation_list) {
                bool invalid_ws = True;
-               char *tok;
+               char *tok = NULL;
                const char *s = workstation_list;
+               char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
 
-               const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
                if (machine_name == NULL)
                        return NT_STATUS_NO_MEMORY;
 
@@ -251,6 +251,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
                        TALLOC_FREE(tok);
                }
                TALLOC_FREE(tok);
+               TALLOC_FREE(machine_name);
 
                if (invalid_ws)
                        return NT_STATUS_INVALID_WORKSTATION;
index ed45f4e2caacd3823d55ea3ee40e37373805d204..6b273b47b0bdaf1668a6e4f765992209dd5ce6e8 100644 (file)
@@ -2605,7 +2605,7 @@ static int cmd_lock(void)
 
        len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
-       if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) {
+       if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) {
                d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
        }
 
@@ -2639,7 +2639,7 @@ static int cmd_unlock(void)
 
        len = (uint64_t)strtol(buf, (char **)NULL, 16);
 
-       if (!cli_posix_unlock(cli, fnum, start, len)) {
+       if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) {
                d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
        }
 
index afa4e1217556ec545c4957427a2f1fbcf43d26ae..9761d54086652f953260cd5298fbaa71d4bd4195 100644 (file)
@@ -6,6 +6,8 @@
   basically this is a wrapper around ldap
 */
 
+#include "../libds/common/flags.h"
+
 enum wb_posix_mapping {
        WB_POSIX_MAP_UNKNOWN    = -1,
        WB_POSIX_MAP_TEMPLATE   = 0, 
@@ -202,124 +204,6 @@ typedef void **ADS_MODLIST;
 #define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803"
 #define ADS_LDAP_MATCHING_RULE_BIT_OR  "1.2.840.113556.1.4.804"
 
-/* UserFlags for userAccountControl */
-#define UF_SCRIPT                              0x00000001
-#define UF_ACCOUNTDISABLE                      0x00000002
-#define UF_UNUSED_1                            0x00000004
-#define UF_HOMEDIR_REQUIRED                    0x00000008
-
-#define UF_LOCKOUT                             0x00000010
-#define UF_PASSWD_NOTREQD                      0x00000020
-#define UF_PASSWD_CANT_CHANGE                  0x00000040
-#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED     0x00000080
-
-#define UF_TEMP_DUPLICATE_ACCOUNT              0x00000100
-#define UF_NORMAL_ACCOUNT                      0x00000200
-#define UF_UNUSED_2                            0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT           0x00000800
-
-#define UF_WORKSTATION_TRUST_ACCOUNT           0x00001000
-#define UF_SERVER_TRUST_ACCOUNT                0x00002000
-#define UF_UNUSED_3                            0x00004000
-#define UF_UNUSED_4                            0x00008000
-
-#define UF_DONT_EXPIRE_PASSWD                  0x00010000
-#define UF_MNS_LOGON_ACCOUNT                   0x00020000
-#define UF_SMARTCARD_REQUIRED                  0x00040000
-#define UF_TRUSTED_FOR_DELEGATION              0x00080000
-
-#define UF_NOT_DELEGATED                       0x00100000
-#define UF_USE_DES_KEY_ONLY                    0x00200000
-#define UF_DONT_REQUIRE_PREAUTH                        0x00400000
-#define UF_PASSWORD_EXPIRED                    0x00800000
-
-#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED               0x02000000
-#define UF_UNUSED_8                            0x04000000
-#define UF_UNUSED_9                            0x08000000
-
-#define UF_UNUSED_10                           0x10000000
-#define UF_UNUSED_11                           0x20000000
-#define UF_UNUSED_12                           0x40000000
-#define UF_UNUSED_13                           0x80000000
-
-#define UF_MACHINE_ACCOUNT_MASK (\
-               UF_INTERDOMAIN_TRUST_ACCOUNT |\
-               UF_WORKSTATION_TRUST_ACCOUNT |\
-               UF_SERVER_TRUST_ACCOUNT \
-               )
-
-#define UF_ACCOUNT_TYPE_MASK (\
-               UF_TEMP_DUPLICATE_ACCOUNT |\
-               UF_NORMAL_ACCOUNT |\
-               UF_INTERDOMAIN_TRUST_ACCOUNT |\
-               UF_WORKSTATION_TRUST_ACCOUNT |\
-               UF_SERVER_TRUST_ACCOUNT \
-                )
-
-#define UF_SETTABLE_BITS (\
-               UF_SCRIPT |\
-               UF_ACCOUNTDISABLE |\
-               UF_HOMEDIR_REQUIRED  |\
-               UF_LOCKOUT |\
-               UF_PASSWD_NOTREQD |\
-               UF_PASSWD_CANT_CHANGE |\
-               UF_ACCOUNT_TYPE_MASK | \
-               UF_DONT_EXPIRE_PASSWD | \
-               UF_MNS_LOGON_ACCOUNT |\
-               UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
-               UF_SMARTCARD_REQUIRED |\
-               UF_TRUSTED_FOR_DELEGATION |\
-               UF_NOT_DELEGATED |\
-               UF_USE_DES_KEY_ONLY  |\
-               UF_DONT_REQUIRE_PREAUTH \
-               )
-
-/* sAMAccountType */
-#define ATYPE_NORMAL_ACCOUNT                   0x30000000 /* 805306368 */
-#define ATYPE_WORKSTATION_TRUST                        0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST                        0x30000002 /* 805306370 */ 
-#define ATYPE_SECURITY_GLOBAL_GROUP            0x10000000 /* 268435456 */
-#define ATYPE_DISTRIBUTION_GLOBAL_GROUP                0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP     ATYPE_DISTRIBUTION_GLOBAL_GROUP
-#define ATYPE_SECURITY_LOCAL_GROUP             0x20000000 /* 536870912 */
-#define ATYPE_DISTRIBUTION_LOCAL_GROUP         0x20000001 /* 536870913 */
-
-#define ATYPE_ACCOUNT          ATYPE_NORMAL_ACCOUNT            /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP     ATYPE_SECURITY_GLOBAL_GROUP     /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP      ATYPE_SECURITY_LOCAL_GROUP      /* 0x20000000 536870912 */
-
-/* groupType */
-#define GROUP_TYPE_BUILTIN_LOCAL_GROUP         0x00000001
-#define GROUP_TYPE_ACCOUNT_GROUP               0x00000002
-#define GROUP_TYPE_RESOURCE_GROUP              0x00000004
-#define GROUP_TYPE_UNIVERSAL_GROUP             0x00000008
-#define GROUP_TYPE_APP_BASIC_GROUP             0x00000010
-#define GROUP_TYPE_APP_QUERY_GROUP             0x00000020
-#define GROUP_TYPE_SECURITY_ENABLED            0x80000000
-
-#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP (   /* 0x80000005 -2147483643 */ \
-               GROUP_TYPE_BUILTIN_LOCAL_GROUP| \
-               GROUP_TYPE_RESOURCE_GROUP| \
-               GROUP_TYPE_SECURITY_ENABLED \
-               )
-#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP (    /* 0x80000004 -2147483644 */ \
-               GROUP_TYPE_RESOURCE_GROUP| \
-               GROUP_TYPE_SECURITY_ENABLED \
-               )
-#define GTYPE_SECURITY_GLOBAL_GROUP (          /* 0x80000002 -2147483646 */ \
-               GROUP_TYPE_ACCOUNT_GROUP| \
-               GROUP_TYPE_SECURITY_ENABLED \
-               )
-#define GTYPE_SECURITY_UNIVERSAL_GROUP (       /* 0x80000008 -2147483656 */ \
-               GROUP_TYPE_UNIVERSAL_GROUP| \
-               GROUP_TYPE_SECURITY_ENABLED \
-               )
-
-#define GTYPE_DISTRIBUTION_GLOBAL_GROUP                0x00000002      /* 2 */
-#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP  0x00000004      /* 4 */
-#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP     0x00000008      /* 8 */
-
 #define ADS_PINGS          0x0000FFFF  /* Ping response */
 #define ADS_DNS_CONTROLLER 0x20000000  /* DomainControllerName is a DNS name*/
 #define ADS_DNS_DOMAIN     0x40000000  /* DomainName is a DNS name */
@@ -411,11 +295,4 @@ typedef struct {
 
 #define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore"
 
-/* Settings for the domainFunctionality attribute in the rootDSE */
-
-#define DS_DOMAIN_FUNCTION_2000                0
-#define DS_DOMAIN_FUCNTION_2003_MIXED  1
-#define DS_DOMAIN_FUNCTION_2003                2
-#define DS_DOMAIN_FUNCTION_2008                3
-
 #endif /* _INCLUDE_ADS_H_ */
index 4e53311eba7169a35865074483283c016be7c048..2b4f9c2e4393716f23d7095514801459c2c3141c 100644 (file)
@@ -205,6 +205,22 @@ struct pdb_domain_info {
        struct GUID guid;
 };
 
+/*
+ * Types of account policy.
+ */
+enum pdb_policy_type {
+       PDB_POLICY_MIN_PASSWORD_LEN = 1,
+       PDB_POLICY_PASSWORD_HISTORY = 2,
+       PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS  = 3,
+       PDB_POLICY_MAX_PASSWORD_AGE = 4,
+       PDB_POLICY_MIN_PASSWORD_AGE = 5,
+       PDB_POLICY_LOCK_ACCOUNT_DURATION = 6,
+       PDB_POLICY_RESET_COUNT_TIME = 7,
+       PDB_POLICY_BAD_ATTEMPT_LOCKOUT = 8,
+       PDB_POLICY_TIME_TO_LOGOUT = 9,
+       PDB_POLICY_REFUSE_MACHINE_PW_CHANGE = 10
+};
+
 #define PDB_CAP_STORE_RIDS     0x0001
 #define PDB_CAP_ADS            0x0002
 
@@ -351,10 +367,12 @@ struct pdb_methods
                                 enum lsa_SidType *attrs);
 
        NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
-                                      int policy_index, uint32 *value);
+                                      enum pdb_policy_type type,
+                                      uint32_t *value);
 
        NTSTATUS (*set_account_policy)(struct pdb_methods *methods,
-                                      int policy_index, uint32 value);
+                                      enum pdb_policy_type type,
+                                      uint32_t value);
 
        NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num);
 
index f887b4e7967be4873288d0ee48a1e80892126a50..77283d9cf0a172af6aa38e61607920f938f6d608 100644 (file)
@@ -290,16 +290,16 @@ bool check_access(int sock, const char **allow_list, const char **deny_list);
 /* The following definitions come from lib/account_pol.c  */
 
 void account_policy_names_list(const char ***names, int *num_names);
-const char *decode_account_policy_name(int field);
-const char *get_account_policy_attr(int field);
-const char *account_policy_get_desc(int field);
-int account_policy_name_to_fieldnum(const char *name);
-bool account_policy_get_default(int account_policy, uint32 *val);
+const char *decode_account_policy_name(enum pdb_policy_type type);
+const char *get_account_policy_attr(enum pdb_policy_type type);
+const char *account_policy_get_desc(enum pdb_policy_type type);
+enum pdb_policy_type account_policy_name_to_typenum(const char *name);
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val);
 bool init_account_policy(void);
-bool account_policy_get(int field, uint32 *value);
-bool account_policy_set(int field, uint32 value);
-bool cache_account_policy_set(int field, uint32 value);
-bool cache_account_policy_get(int field, uint32 *value);
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value);
+bool account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value);
 struct db_context *get_account_pol_db( void );
 
 /* The following definitions come from lib/adt_tree.c  */
@@ -454,6 +454,14 @@ NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr,
 NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key,
                                     TDB_DATA data, int flags);
 NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key);
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+                        NTSTATUS (*action)(struct db_context *, void *),
+                        void *private_data);
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key);
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+                                    TDB_DATA data, int flags);
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+                                    const char *key);
 
 /* The following definitions come from lib/debug.c  */
 
@@ -515,17 +523,15 @@ void pull_file_id_24(char *buf, struct file_id *id);
 
 /* The following definitions come from lib/gencache.c  */
 
-bool gencache_init(void);
-bool gencache_shutdown(void);
 bool gencache_set(const char *keystr, const char *value, time_t timeout);
 bool gencache_del(const char *keystr);
 bool gencache_get(const char *keystr, char **valstr, time_t *timeout);
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired);
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+                           time_t *timeout);
+bool gencache_stabilize(void);
 bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout);
 void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
                       void* data, const char* keystr_pattern);
-int gencache_lock_entry( const char *key );
-void gencache_unlock_entry( const char *key );
 
 /* The following definitions come from lib/interface.c  */
 
@@ -554,7 +560,7 @@ void init_ldap_debugging(void);
 
 /* The following definitions come from lib/ldap_escape.c  */
 
-char *escape_ldap_string_alloc(const char *s);
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s);
 char *escape_rdn_val_string_alloc(const char *s);
 
 /* The following definitions come from lib/module.c  */
@@ -1678,13 +1684,6 @@ ADS_STRUCT *ads_init(const char *realm,
                     const char *ldap_server);
 void ads_destroy(ADS_STRUCT **ads);
 
-/* The following definitions come from libads/ads_utils.c  */
-
-uint32 ads_acb2uf(uint32 acb);
-uint32 ads_uf2acb(uint32 uf);
-uint32 ads_uf2atype(uint32 uf);
-uint32 ads_gtype2atype(uint32 gtype);
-enum lsa_SidType ads_atype_map(uint32 atype);
 const char *ads_get_ldap_server_name(ADS_STRUCT *ads);
 
 /* The following definitions come from libads/authdata.c  */
@@ -2271,13 +2270,6 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
 
 /* The following definitions come from libsmb/clidgram.c  */
 
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
-                      bool unique, const char *mailslot,
-                      uint16 priority,
-                      char *buf, int len,
-                      const char *srcname, int src_type,
-                      const char *dstname, int dest_type,
-                      const struct sockaddr_storage *dest_ss);
 bool send_getdc_request(TALLOC_CTX *mem_ctx,
                        struct messaging_context *msg_ctx,
                        struct sockaddr_storage *dc_ss,
@@ -2519,15 +2511,44 @@ NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum,
                      int timeout, unsigned char locktype);
 bool cli_lock(struct cli_state *cli, uint16_t fnum,
              uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+                                struct event_context *ev,
+                                struct cli_state *cli,
+                                uint16_t fnum,
+                                uint64_t offset,
+                                uint64_t len);
+NTSTATUS cli_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
 bool cli_lock64(struct cli_state *cli, uint16_t fnum,
                uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+                                struct event_context *ev,
+                                struct cli_state *cli,
+                                uint16_t fnum,
+                                uint64_t offset,
+                                uint64_t len);
+NTSTATUS cli_unlock64_recv(struct tevent_req *req);
+NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+                                        struct event_context *ev,
+                                        struct cli_state *cli,
+                                        uint16_t fnum,
+                                        uint64_t offset,
+                                        uint64_t len,
+                                        bool wait_lock,
+                                        enum brl_type lock_type);
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
                        uint64_t offset, uint64_t len,
                        bool wait_lock, enum brl_type lock_type);
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen);
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+                                        struct event_context *ev,
+                                        struct cli_state *cli,
+                                        uint16_t fnum,
+                                        uint64_t offset,
+                                        uint64_t len);
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
 struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx,
                                struct event_context *ev,
                                struct cli_state *cli,
@@ -4587,8 +4608,8 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
                          const char **names,
                          uint32 *rids,
                          enum lsa_SidType *attrs);
-bool pdb_get_account_policy(int policy_index, uint32 *value);
-bool pdb_set_account_policy(int policy_index, uint32 value);
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value);
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value);
 bool pdb_get_seq_num(time_t *seq_num);
 bool pdb_uid_to_rid(uid_t uid, uint32 *rid);
 bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid);
@@ -5083,6 +5104,7 @@ WERROR registry_init_smbconf(const char *keyname);
 /* The following definitions come from registry/reg_objects.c  */
 
 WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr);
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr);
 WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum);
 int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr);
 WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname );
@@ -5647,32 +5669,16 @@ void prs_switch_type(prs_struct *ps, bool io);
 void prs_force_dynamic(prs_struct *ps);
 void prs_set_session_key(prs_struct *ps, const char sess_key[16]);
 bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8);
-bool prs_pointer( const char *name, prs_struct *ps, int depth, 
-                 void *dta, size_t data_size,
-                 bool (*prs_fn)(const char*, prs_struct*, int, void*) );
 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);
 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);
 bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32);
 bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
 bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status);
 bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
 bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
 bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
 bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
 bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size);
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str);
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
-                               uint32 ptr_uint16, uint32 start_offset);
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
-                               uint32 ptr_uint32, uint32 data_size);
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps);
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx);
-bool prs_hash1(prs_struct *ps, uint32 offset, int len);
 void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
                   enum schannel_direction direction,
                   RPC_AUTH_SCHANNEL_CHK * verf,
@@ -5877,7 +5883,6 @@ void copy_id26_to_sam_passwd(struct samu *to,
 
 /* The following definitions come from rpc_server/srv_spoolss_nt.c  */
 
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename );
 void do_drv_upgrade_printer(struct messaging_context *msg,
                            void *private_data,
                            uint32_t msg_type,
@@ -5966,9 +5971,7 @@ void construct_info_data(struct spoolss_Notify *info_data,
                         int id);
 struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
                                              const char *servicename);
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
 
 /* The following definitions come from rpc_server/srv_srvsvc_nt.c  */
 
@@ -6260,16 +6263,14 @@ void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode,
 void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode,
                      NTSTATUS status, int line, const char *file);
 void reply_openerror(struct smb_request *req, NTSTATUS status);
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
-                       NTSTATUS defstatus, int line, const char *file);
 
 /* The following definitions come from smbd/fake_file.c  */
 
-enum FAKE_FILE_TYPE is_fake_file(const char *fname);
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname);
 NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
                                uint16_t current_vuid,
                                enum FAKE_FILE_TYPE fake_file_type,
-                               const char *fname,
+                               const struct smb_filename *smb_fname,
                                uint32 access_mask,
                                files_struct **result);
 NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp);
@@ -6306,6 +6307,23 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst);
 
 /* The following definitions come from smbd/filename.c  */
 
+NTSTATUS unix_convert(TALLOC_CTX *ctx,
+                     connection_struct *conn,
+                     const char *orig_path,
+                     struct smb_filename **smb_fname,
+                     uint32_t ucf_flags);
+NTSTATUS check_name(connection_struct *conn, const char *name);
+int get_real_filename(connection_struct *conn, const char *path,
+                     const char *name, TALLOC_CTX *mem_ctx,
+                     char **found_name);
+NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
+                       connection_struct *conn,
+                       bool dfs_path,
+                       const char *name_in,
+                       struct smb_filename **pp_smb_fname);
+
+/* The following definitions come from smbd/filename_utils.c */
+
 NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
                              char **full_name);
 NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
@@ -6316,29 +6334,13 @@ NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
                                          const char *fname,
                                          const SMB_STRUCT_STAT *psbuf,
                                          struct smb_filename **smb_fname_out);
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
-                      SMB_STRUCT_STAT *psbuf);
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
-                       SMB_STRUCT_STAT *psbuf);
 const char *smb_fname_str_dbg(const struct smb_filename *smb_fname);
+const char *fsp_str_dbg(const struct files_struct *fsp);
 NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
                           const struct smb_filename *smb_fname_in,
                           struct smb_filename **smb_fname_out);
-NTSTATUS unix_convert(TALLOC_CTX *ctx,
-                     connection_struct *conn,
-                     const char *orig_path,
-                     struct smb_filename **smb_fname,
-                     uint32_t ucf_flags);
-NTSTATUS check_name(connection_struct *conn, const char *name);
-int get_real_filename(connection_struct *conn, const char *path,
-                     const char *name, TALLOC_CTX *mem_ctx,
-                     char **found_name);
-NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
-                       connection_struct *conn,
-                       bool dfs_path,
-                       const char *name_in,
-                       struct smb_filename **pp_smb_fname,
-                       char **pp_name);
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
 
 /* The following definitions come from smbd/files.c  */
 
@@ -6364,9 +6366,11 @@ void file_sync_all(connection_struct *conn);
 void file_free(struct smb_request *req, files_struct *fsp);
 files_struct *file_fnum(uint16 fnum);
 files_struct *file_fsp(struct smb_request *req, uint16 fid);
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
                      uint32 access_mask, uint32 share_access,
                      uint32 create_options, files_struct *to);
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+                          const struct smb_filename *smb_fname_in);
 
 /* The following definitions come from smbd/ipc.c  */
 
@@ -6544,8 +6548,6 @@ void send_nt_replies(connection_struct *conn,
                        struct smb_request *req, NTSTATUS nt_error,
                     char *params, int paramsize,
                     char *pdata, int datasize);
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
 void reply_ntcreate_and_X(struct smb_request *req);
 void reply_ntcancel(struct smb_request *req);
 void reply_ntrename(struct smb_request *req);
@@ -6586,7 +6588,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
                         uint32 access_mask,
                         uint32 share_access,
                         uint32 create_options);
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+                                int deny_mode, int open_func,
                                 uint32 *paccess_mask,
                                 uint32 *pshare_mode,
                                 uint32 *pcreate_disposition,
@@ -7113,6 +7116,10 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf);
 int vfs_ChDir(connection_struct *conn, const char *path);
 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+                      SMB_STRUCT_STAT *psbuf);
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+                       SMB_STRUCT_STAT *psbuf);
 
 /* The following definitions come from torture/denytest.c  */
 
@@ -7262,6 +7269,16 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
                                SE_PRIV *rights, uint32 rights_mask,
                                uint32 des_access, uint32 *acc_granted,
                                const char *debug);
-void map_max_allowed_access(const NT_USER_TOKEN *token,
-                               uint32_t *pacc_requested);
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+                           const struct unix_user_token *unix_token,
+                           uint32_t *pacc_requested);
+
+/* The following definitions come from ../libds/common/flag_mapping.c  */
+
+uint32_t ds_acb2uf(uint32_t acb);
+uint32_t ds_uf2acb(uint32_t uf);
+uint32_t ds_uf2atype(uint32_t uf);
+uint32_t ds_gtype2atype(uint32_t gtype);
+enum lsa_SidType ds_atype_map(uint32_t atype);
+
 #endif /*  _PROTO_H_  */
index 9afeb67b00b475598b57469f1aedcb4948d3258f..94ed2186fbd561ac199a2ad06e035afc80b5b891 100644 (file)
@@ -452,7 +452,7 @@ typedef struct files_struct {
        bool lockdb_clean;
        bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
        bool posix_open;
-       char *fsp_name;
+       struct smb_filename *fsp_name;
 
        struct vfs_fsp_data *vfs_extension;
        struct fake_file_handle *fake_file_handle;
@@ -833,20 +833,6 @@ struct pipe_open_rec {
 #define PW_HISTORY_ENTRY_LEN (PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN)
 #define MAX_PW_HISTORY_LEN 24
 
-/*
- * Flags for account policy.
- */
-#define AP_MIN_PASSWORD_LEN            1
-#define AP_PASSWORD_HISTORY            2
-#define AP_USER_MUST_LOGON_TO_CHG_PASS 3
-#define AP_MAX_PASSWORD_AGE            4
-#define AP_MIN_PASSWORD_AGE            5
-#define AP_LOCK_ACCOUNT_DURATION       6
-#define AP_RESET_COUNT_TIME            7
-#define AP_BAD_ATTEMPT_LOCKOUT         8
-#define AP_TIME_TO_LOGOUT              9
-#define AP_REFUSE_MACHINE_PW_CHANGE    10
-
 /*
  * Flags for local user manipulation.
  */
index 7528883c2d9921ee4c9b53651bc298eb2609e25f..10ee78b3943fa980a159593144338299a302a24f 100644 (file)
 #define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__)
 #define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__)
 #define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__)
-#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
 
 #if 0
 /* defined in IDL */
index c79436434f3209b350992a686df59aa11d07de99..80b95921d7c1c7f509f06cc6513ae4ef26dc5f36 100644 (file)
@@ -59,4 +59,6 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
 
 NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
 
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2);
+
 #endif /* __TDBUTIL_H__ */
index 1e435ca53e8cb9c2253ed41745082bbf83be0b76..f4101e96bc59e920949331a865d834aba3c5d2ee 100644 (file)
@@ -1,20 +1,20 @@
-/* 
+/*
  *  Unix SMB/CIFS implementation.
  *  account policy storage
  *  Copyright (C) Jean François Micouleau      1998-2001.
  *  Copyright (C) Andrew Bartlett              2002
  *  Copyright (C) Guenther Deschner            2004-2005
- *  
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
@@ -31,7 +31,7 @@ static struct db_context *db;
 
 
 struct ap_table {
-       int field;
+       enum pdb_policy_type type;
        const char *string;
        uint32 default_val;
        const char *description;
@@ -39,51 +39,51 @@ struct ap_table {
 };
 
 static const struct ap_table account_policy_names[] = {
-       {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH, 
-               "Minimal password length (default: 5)", 
+       {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
+               "Minimal password length (default: 5)",
                "sambaMinPwdLength" },
 
-       {AP_PASSWORD_HISTORY, "password history", 0,
-               "Length of Password History Entries (default: 0 => off)", 
+       {PDB_POLICY_PASSWORD_HISTORY, "password history", 0,
+               "Length of Password History Entries (default: 0 => off)",
                "sambaPwdHistoryLength" },
-               
-       {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
+
+       {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
                "Force Users to logon for password change (default: 0 => off, 2 => on)",
                "sambaLogonToChgPwd" },
-       
-       {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
-               "Maximum password age, in seconds (default: -1 => never expire passwords)", 
+
+       {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
+               "Maximum password age, in seconds (default: -1 => never expire passwords)",
                "sambaMaxPwdAge" },
-               
-       {AP_MIN_PASSWORD_AGE,"minimum password age", 0,
-               "Minimal password age, in seconds (default: 0 => allow immediate password change)", 
+
+       {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0,
+               "Minimal password age, in seconds (default: 0 => allow immediate password change)",
                "sambaMinPwdAge" },
-               
-       {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
+
+       {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
                "Lockout duration in minutes (default: 30, -1 => forever)",
                "sambaLockoutDuration" },
-               
-       {AP_RESET_COUNT_TIME, "reset count minutes", 30,
-               "Reset time after lockout in minutes (default: 30)", 
+
+       {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30,
+               "Reset time after lockout in minutes (default: 30)",
                "sambaLockoutObservationWindow" },
-               
-       {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
-               "Lockout users after bad logon attempts (default: 0 => off)", 
+
+       {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
+               "Lockout users after bad logon attempts (default: 0 => off)",
                "sambaLockoutThreshold" },
-               
-       {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
-               "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", 
-               "sambaForceLogoff" }, 
-               
-       {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
+
+       {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
+               "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
+               "sambaForceLogoff" },
+
+       {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
                "Allow Machine Password changes (default: 0 => off)",
                "sambaRefuseMachinePwdChange" },
-               
+
        {0, NULL, 0, "", NULL}
 };
 
 void account_policy_names_list(const char ***names, int *num_names)
-{      
+{
        const char **nl;
        int i, count;
 
@@ -106,11 +106,11 @@ void account_policy_names_list(const char ***names, int *num_names)
 Get the account policy name as a string from its #define'ed number
 ****************************************************************************/
 
-const char *decode_account_policy_name(int field)
+const char *decode_account_policy_name(enum pdb_policy_type type)
 {
        int i;
        for (i=0; account_policy_names[i].string; i++) {
-               if (field == account_policy_names[i].field) {
+               if (type == account_policy_names[i].type) {
                        return account_policy_names[i].string;
                }
        }
@@ -121,11 +121,11 @@ const char *decode_account_policy_name(int field)
 Get the account policy LDAP attribute as a string from its #define'ed number
 ****************************************************************************/
 
-const char *get_account_policy_attr(int field)
+const char *get_account_policy_attr(enum pdb_policy_type type)
 {
        int i;
-       for (i=0; account_policy_names[i].field; i++) {
-               if (field == account_policy_names[i].field) {
+       for (i=0; account_policy_names[i].type; i++) {
+               if (type == account_policy_names[i].type) {
                        return account_policy_names[i].ldap_attr;
                }
        }
@@ -136,11 +136,11 @@ const char *get_account_policy_attr(int field)
 Get the account policy description as a string from its #define'ed number
 ****************************************************************************/
 
-const char *account_policy_get_desc(int field)
+const char *account_policy_get_desc(enum pdb_policy_type type)
 {
        int i;
        for (i=0; account_policy_names[i].string; i++) {
-               if (field == account_policy_names[i].field) {
+               if (type == account_policy_names[i].type) {
                        return account_policy_names[i].description;
                }
        }
@@ -151,12 +151,12 @@ const char *account_policy_get_desc(int field)
 Get the account policy name as a string from its #define'ed number
 ****************************************************************************/
 
-int account_policy_name_to_fieldnum(const char *name)
+enum pdb_policy_type account_policy_name_to_typenum(const char *name)
 {
        int i;
        for (i=0; account_policy_names[i].string; i++) {
                if (strcmp(name, account_policy_names[i].string) == 0) {
-                       return account_policy_names[i].field;
+                       return account_policy_names[i].type;
                }
        }
        return 0;
@@ -166,35 +166,35 @@ int account_policy_name_to_fieldnum(const char *name)
 Get default value for account policy
 *****************************************************************************/
 
-bool account_policy_get_default(int account_policy, uint32 *val)
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val)
 {
        int i;
-       for (i=0; account_policy_names[i].field; i++) {
-               if (account_policy_names[i].field == account_policy) {
+       for (i=0; account_policy_names[i].type; i++) {
+               if (account_policy_names[i].type == type) {
                        *val = account_policy_names[i].default_val;
                        return True;
                }
        }
-       DEBUG(0,("no default for account_policy index %d found. This should never happen\n", 
-               account_policy));
+       DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
+               type));
        return False;
 }
 
 /*****************************************************************************
- Set default for a field if it is empty
+ Set default for a type if it is empty
 *****************************************************************************/
 
-static bool account_policy_set_default_on_empty(int account_policy)
+static bool account_policy_set_default_on_empty(enum pdb_policy_type type)
 {
 
        uint32 value;
 
-       if (!account_policy_get(account_policy, &value) && 
-           !account_policy_get_default(account_policy, &value)) {
+       if (!account_policy_get(type, &value) &&
+           !account_policy_get_default(type, &value)) {
                return False;
        }
 
-       return account_policy_set(account_policy, value);
+       return account_policy_set(type, value);
 }
 
 /*****************************************************************************
@@ -255,9 +255,9 @@ bool init_account_policy(void)
                        goto cancel;
                }
 
-               for (i=0; account_policy_names[i].field; i++) {
+               for (i=0; account_policy_names[i].type; i++) {
 
-                       if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
+                       if (!account_policy_set_default_on_empty(account_policy_names[i].type)) {
                                DEBUG(0,("failed to set default value in account policy tdb\n"));
                                goto cancel;
                        }
@@ -299,10 +299,10 @@ bool init_account_policy(void)
 }
 
 /*****************************************************************************
-Get an account policy (from tdb) 
+Get an account policy (from tdb)
 *****************************************************************************/
 
-bool account_policy_get(int field, uint32 *value)
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value)
 {
        const char *name;
        uint32 regval;
@@ -315,17 +315,17 @@ bool account_policy_get(int field, uint32 *value)
                *value = 0;
        }
 
-       name = decode_account_policy_name(field);
+       name = decode_account_policy_name(type);
        if (name == NULL) {
-               DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type!  Cannot get, returning 0.\n", field));
+               DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type!  Cannot get, returning 0.\n", type));
                return False;
        }
-       
+
        if (!dbwrap_fetch_uint32(db, name, &regval)) {
-               DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
+               DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name));
                return False;
        }
-       
+
        if (value) {
                *value = regval;
        }
@@ -336,10 +336,10 @@ bool account_policy_get(int field, uint32 *value)
 
 
 /****************************************************************************
-Set an account policy (in tdb) 
+Set an account policy (in tdb)
 ****************************************************************************/
 
-bool account_policy_set(int field, uint32 value)
+bool account_policy_set(enum pdb_policy_type type, uint32_t value)
 {
        const char *name;
        NTSTATUS status;
@@ -348,36 +348,36 @@ bool account_policy_set(int field, uint32 value)
                return False;
        }
 
-       name = decode_account_policy_name(field);
+       name = decode_account_policy_name(type);
        if (name == NULL) {
-               DEBUG(1, ("Field %d is not a valid account policy type!  Cannot set.\n", field));
+               DEBUG(1, ("Field %d is not a valid account policy type!  Cannot set.\n", type));
                return False;
        }
 
        status = dbwrap_trans_store_uint32(db, name, value);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("store_uint32 failed for field %d (%s) on value "
-                         "%u: %s\n", field, name, value, nt_errstr(status)));
+               DEBUG(1, ("store_uint32 failed for type %d (%s) on value "
+                         "%u: %s\n", type, name, value, nt_errstr(status)));
                return False;
        }
 
        DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
-       
+
        return True;
 }
 
 /****************************************************************************
-Set an account policy in the cache 
+Set an account policy in the cache
 ****************************************************************************/
 
-bool cache_account_policy_set(int field, uint32 value)
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value)
 {
        const char *policy_name = NULL;
        char *cache_key = NULL;
        char *cache_value = NULL;
        bool ret = False;
 
-       policy_name = decode_account_policy_name(field);
+       policy_name = decode_account_policy_name(type);
        if (policy_name == NULL) {
                DEBUG(0,("cache_account_policy_set: no policy found\n"));
                return False;
@@ -404,17 +404,17 @@ bool cache_account_policy_set(int field, uint32 value)
 }
 
 /*****************************************************************************
-Get an account policy from the cache 
+Get an account policy from the cache
 *****************************************************************************/
 
-bool cache_account_policy_get(int field, uint32 *value)
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
 {
        const char *policy_name = NULL;
        char *cache_key = NULL;
        char *cache_value = NULL;
        bool ret = False;
 
-       policy_name = decode_account_policy_name(field);
+       policy_name = decode_account_policy_name(type);
        if (policy_name == NULL) {
                DEBUG(0,("cache_account_policy_set: no policy found\n"));
                return False;
diff --git a/source3/lib/ads_flags.c b/source3/lib/ads_flags.c
deleted file mode 100644 (file)
index a8fa062..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   ads (active directory) utility library
-
-   Copyright (C) Stefan (metze) Metzmacher 2002
-   Copyright (C) Andrew Tridgell 2001
-
-   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"
-
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
-uint32 ads_acb2uf(uint32 acb)
-{
-       uint32 uf = 0x00000000;
-
-       if (acb & ACB_DISABLED)                 uf |= UF_ACCOUNTDISABLE;
-       if (acb & ACB_HOMDIRREQ)                uf |= UF_HOMEDIR_REQUIRED;
-       if (acb & ACB_PWNOTREQ)                 uf |= UF_PASSWD_NOTREQD;
-       if (acb & ACB_TEMPDUP)                  uf |= UF_TEMP_DUPLICATE_ACCOUNT;
-       if (acb & ACB_NORMAL)                   uf |= UF_NORMAL_ACCOUNT;
-       if (acb & ACB_MNS)                      uf |= UF_MNS_LOGON_ACCOUNT;
-       if (acb & ACB_DOMTRUST)                 uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
-       if (acb & ACB_WSTRUST)                  uf |= UF_WORKSTATION_TRUST_ACCOUNT;
-       if (acb & ACB_SVRTRUST)                 uf |= UF_SERVER_TRUST_ACCOUNT;
-       if (acb & ACB_PWNOEXP)                  uf |= UF_DONT_EXPIRE_PASSWD;
-       if (acb & ACB_AUTOLOCK)                 uf |= UF_LOCKOUT;
-       if (acb & ACB_USE_DES_KEY_ONLY)         uf |= UF_USE_DES_KEY_ONLY;
-       if (acb & ACB_SMARTCARD_REQUIRED)       uf |= UF_SMARTCARD_REQUIRED;
-       if (acb & ACB_TRUSTED_FOR_DELEGATION)   uf |= UF_TRUSTED_FOR_DELEGATION;
-       if (acb & ACB_DONT_REQUIRE_PREAUTH)     uf |= UF_DONT_REQUIRE_PREAUTH;
-       if (acb & ACB_NO_AUTH_DATA_REQD)        uf |= UF_NO_AUTH_DATA_REQUIRED;
-       if (acb & ACB_NOT_DELEGATED)            uf |= UF_NOT_DELEGATED;
-       if (acb & ACB_ENC_TXT_PWD_ALLOWED)      uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
-
-       return uf;
-}
-
-/*
-translated the UserFlags (userAccountControl) to ACB_CTRL Flags
-*/
-uint32 ads_uf2acb(uint32 uf)
-{
-       uint32 acb = 0x00000000;
-
-       if (uf & UF_ACCOUNTDISABLE)             acb |= ACB_DISABLED;
-       if (uf & UF_HOMEDIR_REQUIRED)           acb |= ACB_HOMDIRREQ;
-       if (uf & UF_PASSWD_NOTREQD)             acb |= ACB_PWNOTREQ;
-       if (uf & UF_MNS_LOGON_ACCOUNT)          acb |= ACB_MNS;
-       if (uf & UF_DONT_EXPIRE_PASSWD)         acb |= ACB_PWNOEXP;
-       if (uf & UF_LOCKOUT)                    acb |= ACB_AUTOLOCK;
-       if (uf & UF_USE_DES_KEY_ONLY)           acb |= ACB_USE_DES_KEY_ONLY;
-       if (uf & UF_SMARTCARD_REQUIRED)         acb |= ACB_SMARTCARD_REQUIRED;
-       if (uf & UF_TRUSTED_FOR_DELEGATION)     acb |= ACB_TRUSTED_FOR_DELEGATION;
-       if (uf & UF_DONT_REQUIRE_PREAUTH)       acb |= ACB_DONT_REQUIRE_PREAUTH;
-       if (uf & UF_NO_AUTH_DATA_REQUIRED)      acb |= ACB_NO_AUTH_DATA_REQD;
-       if (uf & UF_NOT_DELEGATED)              acb |= ACB_NOT_DELEGATED;
-       if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED;
-
-       switch (uf & UF_ACCOUNT_TYPE_MASK)
-       {
-               case UF_TEMP_DUPLICATE_ACCOUNT:         acb |= ACB_TEMPDUP;break;
-               case UF_NORMAL_ACCOUNT:                 acb |= ACB_NORMAL;break;
-               case UF_INTERDOMAIN_TRUST_ACCOUNT:      acb |= ACB_DOMTRUST;break;
-               case UF_WORKSTATION_TRUST_ACCOUNT:      acb |= ACB_WSTRUST;break;
-               case UF_SERVER_TRUST_ACCOUNT:           acb |= ACB_SVRTRUST;break;
-               /*Fix Me: what should we do here? */
-               default:                                acb |= ACB_NORMAL;break;
-       }
-
-       return acb;
-}
-
-/*
-get the accountType from the UserFlags
-*/
-uint32 ads_uf2atype(uint32 uf)
-{
-       uint32 atype = 0x00000000;
-
-       if (uf & UF_NORMAL_ACCOUNT)                     atype = ATYPE_NORMAL_ACCOUNT;
-       else if (uf & UF_TEMP_DUPLICATE_ACCOUNT)        atype = ATYPE_NORMAL_ACCOUNT;
-       else if (uf & UF_SERVER_TRUST_ACCOUNT)          atype = ATYPE_WORKSTATION_TRUST;
-       else if (uf & UF_WORKSTATION_TRUST_ACCOUNT)     atype = ATYPE_WORKSTATION_TRUST;
-       else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT)     atype = ATYPE_INTERDOMAIN_TRUST;
-
-       return atype;
-}
-
-/*
-get the accountType from the groupType
-*/
-uint32 ads_gtype2atype(uint32 gtype)
-{
-       uint32 atype = 0x00000000;
-
-       switch(gtype) {
-               case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
-                       atype = ATYPE_SECURITY_LOCAL_GROUP;
-                       break;
-               case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
-                       atype = ATYPE_SECURITY_LOCAL_GROUP;
-                       break;
-               case GTYPE_SECURITY_GLOBAL_GROUP:
-                       atype = ATYPE_SECURITY_GLOBAL_GROUP;
-                       break;
-
-               case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
-                       atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
-                       break;
-               case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
-                       atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
-                       break;
-               case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
-                       atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
-                       break;
-       }
-
-       return atype;
-}
-
-/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType ads_atype_map(uint32 atype)
-{
-       switch (atype & 0xF0000000) {
-       case ATYPE_GLOBAL_GROUP:
-               return SID_NAME_DOM_GRP;
-       case ATYPE_SECURITY_LOCAL_GROUP:
-               return SID_NAME_ALIAS;
-       case ATYPE_ACCOUNT:
-               return SID_NAME_USER;
-       default:
-               DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
-       }
-       return SID_NAME_UNKNOWN;
-}
index a1663c1f38530a166f29b4db5e56fa701a313825..272f107138c25eb82f311e4f45b7105e634de5e4 100644 (file)
@@ -753,7 +753,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
        size_t size;
        smb_ucs2_t *buffer;
 
-       if (!push_ucs2_talloc(NULL, &buffer, src, &size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
                return (size_t)-1;
        }
 
@@ -837,7 +837,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
        size_t size;
        smb_ucs2_t *buffer = NULL;
 
-       if (!convert_string_talloc(NULL, CH_UNIX, CH_UTF16LE, src, srclen,
+       if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
                                   (void **)(void *)&buffer, &size,
                                   True))
        {
@@ -951,7 +951,7 @@ size_t push_ascii_nstring(void *dest, const char *src)
        smb_ucs2_t *buffer;
 
        conv_silent = True;
-       if (!push_ucs2_talloc(NULL, &buffer, src, &buffer_len)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
                smb_panic("failed to create UCS2 buffer");
        }
 
@@ -1268,7 +1268,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
        }
 
        if (flags & STR_UPPER) {
-               tmpbuf = strupper_talloc(NULL, src);
+               tmpbuf = strupper_talloc(talloc_tos(), src);
                if (!tmpbuf) {
                        return (size_t)-1;
                }
index dde377581b93ed601ab97b45c6a78642dc96fb79..449e049ffa26093cf254e0c5af639aa712967b99 100644 (file)
@@ -358,7 +358,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
                        goto next_pkt;
                }
 
-               if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) {
+               if (!(msg_state = TALLOC_P(talloc_autofree_context(), struct deferred_msg_state))) {
                        DEBUG(0, ("talloc failed\n"));
                        TALLOC_FREE(hdr);
                        goto next_pkt;
index c71e073b41e5110626ee942a12b7009c7d462951..297a351764ec0e344e1076b5761524389ac70416 100644 (file)
@@ -94,7 +94,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
 
        /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
        if(DEBUGLEVEL >= 10) {
-               char *keystr = hex_encode_talloc(NULL, (unsigned char*)key.dptr, key.dsize);
+               char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize);
                DEBUG(10, (DEBUGLEVEL > 10
                           ? "Locking key %s\n" : "Locking key %.20s\n",
                           keystr));
index 3be3a49e7defc623305e088d8fa0b086431b79fc..c3ab93c4df5e557e39bcaf139d3afef159a50212 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    Utility functions for the dbwrap API
    Copyright (C) Volker Lendecke 2007
+   Copyright (C) Michael Adam 2009
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -178,96 +179,77 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
        return 0;
 }
 
-NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
-                           int flag)
+struct dbwrap_store_context {
+       TDB_DATA *key;
+       TDB_DATA *dbuf;
+       int flag;
+};
+
+static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data)
 {
-       int res;
        struct db_record *rec = NULL;
        NTSTATUS status;
+       struct dbwrap_store_context *store_ctx;
 
-       res = db->transaction_start(db);
-       if (res != 0) {
-               DEBUG(5, ("transaction_start failed\n"));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
+       store_ctx = (struct dbwrap_store_context *)private_data;
 
-       rec = db->fetch_locked(db, talloc_tos(), key);
+       rec = db->fetch_locked(db, talloc_tos(), *(store_ctx->key));
        if (rec == NULL) {
                DEBUG(5, ("fetch_locked failed\n"));
-               status = NT_STATUS_NO_MEMORY;
-               goto cancel;
+               return NT_STATUS_NO_MEMORY;
        }
 
-       status = rec->store(rec, dbuf, flag);
+       status = rec->store(rec, *(store_ctx->dbuf), store_ctx->flag);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("store returned %s\n", nt_errstr(status)));
-               goto cancel;
        }
 
        TALLOC_FREE(rec);
+       return status;
+}
 
-       res = db->transaction_commit(db);
-       if (res != 0) {
-               DEBUG(5, ("tdb_transaction_commit failed\n"));
-               status = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               TALLOC_FREE(rec);
-               return status;
-       }
+NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
+                           int flag)
+{
+       NTSTATUS status;
+       struct dbwrap_store_context store_ctx;
 
-       return NT_STATUS_OK;
+       store_ctx.key = &key;
+       store_ctx.dbuf = &dbuf;
+       store_ctx.flag = flag;
 
- cancel:
-       TALLOC_FREE(rec);
+       status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx);
 
-       if (db->transaction_cancel(db) != 0) {
-               smb_panic("Cancelling transaction failed");
-       }
        return status;
 }
 
-NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+static NTSTATUS dbwrap_delete_action(struct db_context * db, void *private_data)
 {
-       int res;
-       struct db_record *rec = NULL;
        NTSTATUS status;
+       struct db_record *rec;
+       TDB_DATA *key = (TDB_DATA *)private_data;
 
-       res = db->transaction_start(db);
-       if (res != 0) {
-               DEBUG(5, ("transaction_start failed\n"));
-               return NT_STATUS_INTERNAL_DB_CORRUPTION;
-       }
-
-       rec = db->fetch_locked(db, talloc_tos(), key);
+       rec = db->fetch_locked(db, talloc_tos(), *key);
        if (rec == NULL) {
                DEBUG(5, ("fetch_locked failed\n"));
-               status = NT_STATUS_NO_MEMORY;
-               goto cancel;
+               return NT_STATUS_NO_MEMORY;
        }
 
        status = rec->delete_rec(rec);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status)));
-               goto cancel;
        }
 
-       TALLOC_FREE(rec);
-
-       res = db->transaction_commit(db);
-       if (res != 0) {
-               DEBUG(5, ("tdb_transaction_commit failed\n"));
-               status = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               TALLOC_FREE(rec);
-               return status;          
-       }
+       talloc_free(rec);
+       return  status;
+}
 
-       return NT_STATUS_OK;
+NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+{
+       NTSTATUS status;
 
- cancel:
-       TALLOC_FREE(rec);
+       status = dbwrap_trans_do(db, dbwrap_delete_action, &key);
 
-       if (db->transaction_cancel(db) != 0) {
-               smb_panic("Cancelling transaction failed");
-       }
        return status;
 }
 
@@ -307,3 +289,86 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key)
 {
        return dbwrap_trans_delete(db, string_term_tdb_data(key));
 }
+
+/**
+ * Wrap db action(s) into a transaction.
+ */
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+                        NTSTATUS (*action)(struct db_context *, void *),
+                        void *private_data)
+{
+       int res;
+       NTSTATUS status;
+
+       res = db->transaction_start(db);
+       if (res != 0) {
+               DEBUG(5, ("transaction_start failed\n"));
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
+       status = action(db, private_data);
+       if (!NT_STATUS_IS_OK(status)) {
+               if (db->transaction_cancel(db) != 0) {
+                       smb_panic("Cancelling transaction failed");
+               }
+               return status;
+       }
+
+       res = db->transaction_commit(db);
+       if (res == 0) {
+               return NT_STATUS_OK;
+       }
+
+       DEBUG(2, ("transaction_commit failed\n"));
+       return NT_STATUS_INTERNAL_DB_CORRUPTION;
+}
+
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key)
+{
+       char *key_upper;
+       NTSTATUS status;
+
+       key_upper = talloc_strdup_upper(talloc_tos(), key);
+       if (key_upper == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = dbwrap_delete_bystring(db, key_upper);
+
+       talloc_free(key_upper);
+       return status;
+}
+
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+                                    TDB_DATA data, int flags)
+{
+       char *key_upper;
+       NTSTATUS status;
+
+       key_upper = talloc_strdup_upper(talloc_tos(), key);
+       if (key_upper == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = dbwrap_store_bystring(db, key_upper, data, flags);
+
+       talloc_free(key_upper);
+       return status;
+}
+
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+                                    const char *key)
+{
+       char *key_upper;
+       TDB_DATA result;
+
+       key_upper = talloc_strdup_upper(talloc_tos(), key);
+       if (key_upper == NULL) {
+               return make_tdb_data(NULL, 0);
+       }
+
+       result = dbwrap_fetch_bystring(db, mem_ctx, key_upper);
+
+       talloc_free(key_upper);
+       return result;
+}
index 0c39a572ad1db1d280cc650430610426c201da7f..00c5475394036f562b501538831538bed1e08880 100644 (file)
@@ -40,6 +40,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
        { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY},
        { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS },
        { EINTR,  ERRHRD, ERRgeneral, NT_STATUS_RETRY },
+       { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED },
 #ifdef ELOOP
        { ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
 #endif
index 08debb42528aa9cc5e1cf551f89e193bfd27267f..7a06ad082990fe85c4900ab8d3c9a9be692b5f3b 100644 (file)
@@ -286,7 +286,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level,
                samba_level = 2;
                break;
        case TEVENT_DEBUG_TRACE:
-               samba_level = 10;
+               samba_level = 11;
                break;
 
        };
index 7f133f20b0fbd43db10925204f2120fe954c6fab..ee1f4b70b3fe89d8a9d55daf2e205adc6513dafb 100644 (file)
 #define DBGC_CLASS DBGC_TDB
 
 #define TIMEOUT_LEN 12
-#define CACHE_DATA_FMT "%12u/%s"
+#define CACHE_DATA_FMT "%12u/"
 #define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
 #define BLOB_TYPE "DATA_BLOB"
 #define BLOB_TYPE_LEN 9
 
-static TDB_CONTEXT *cache;
+static struct tdb_context *cache;
+static struct tdb_context *cache_notrans;
 
 /**
  * @file gencache.c
@@ -49,9 +50,10 @@ static TDB_CONTEXT *cache;
  *         false on failure
  **/
 
-bool gencache_init(void)
+static bool gencache_init(void)
 {
        char* cache_fname = NULL;
+       int open_flags = O_RDWR|O_CREAT;
 
        /* skip file open if it's already opened */
        if (cache) return True;
@@ -60,11 +62,12 @@ bool gencache_init(void)
 
        DEBUG(5, ("Opening cache file at %s\n", cache_fname));
 
-       cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
-                            O_RDWR|O_CREAT, 0644);
+       cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, 0644);
 
        if (!cache && (errno == EACCES)) {
-               cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644);
+               open_flags = O_RDONLY;
+               cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags,
+                                    0644);
                if (cache) {
                        DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
                }
@@ -74,65 +77,123 @@ bool gencache_init(void)
                DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
                return False;
        }
-       return True;
-}
 
+       cache_fname = lock_path("gencache_notrans.tdb");
 
-/**
- * Cache shutdown function. Closes opened cache tdb file.
- *
- * @return true on successful closing the cache or
- *         false on failure during cache shutdown
- **/
+       DEBUG(5, ("Opening cache file at %s\n", cache_fname));
 
-bool gencache_shutdown(void)
-{
-       int ret;
-       /* tdb_close routine returns -1 on error */
-       if (!cache) return False;
-       DEBUG(5, ("Closing cache file\n"));
-       ret = tdb_close(cache);
-       cache = NULL;
-       return ret != -1;
+       cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST,
+                                    open_flags, 0644);
+       if (cache_notrans == NULL) {
+               DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
+                         strerror(errno)));
+               tdb_close(cache);
+               return false;
+       }
+
+       return True;
 }
 
+static TDB_DATA last_stabilize_key(void)
+{
+       TDB_DATA result;
+       result.dptr = (uint8_t *)"@LAST_STABILIZED";
+       result.dsize = 17;
+       return result;
+}
 
 /**
  * Set an entry in the cache file. If there's no such
  * one, then add it.
  *
  * @param keystr string that represents a key of this entry
- * @param value text representation value being cached
+ * @param blob DATA_BLOB value being cached
  * @param timeout time when the value is expired
  *
  * @retval true when entry is successfuly stored
  * @retval false on failure
  **/
 
-bool gencache_set(const char *keystr, const char *value, time_t timeout)
+bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
+                           time_t timeout)
 {
        int ret;
        TDB_DATA databuf;
-       char* valstr = NULL;
+       char* val;
+       time_t last_stabilize;
+       static int writecount;
+
+       if (tdb_data_cmp(string_term_tdb_data(keystr),
+                        last_stabilize_key()) == 0) {
+               DEBUG(10, ("Can't store %s as a key\n", keystr));
+               return false;
+       }
 
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(keystr && value);
+       if ((keystr == NULL) || (blob == NULL)) {
+               return false;
+       }
 
        if (!gencache_init()) return False;
 
-       if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) {
+       val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout);
+       if (val == NULL) {
                return False;
        }
+       val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1);
+       if (val == NULL) {
+               return false;
+       }
+       val = (char *)talloc_append_blob(NULL, val, *blob);
+       if (val == NULL) {
+               return false;
+       }
 
-       databuf = string_term_tdb_data(valstr);
-       DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
-                  " %s (%d seconds %s)\n", keystr, value,ctime(&timeout),
+       DEBUG(10, ("Adding cache entry with key = %s and timeout ="
+                  " %s (%d seconds %s)\n", keystr, ctime(&timeout),
                   (int)(timeout - time(NULL)), 
                   timeout > time(NULL) ? "ahead" : "in the past"));
 
-       ret = tdb_store_bystring(cache, keystr, databuf, 0);
-       SAFE_FREE(valstr);
+       ret = tdb_store_bystring(
+               cache_notrans, keystr,
+               make_tdb_data((uint8_t *)val, talloc_array_length(val)),
+               0);
+       TALLOC_FREE(val);
 
+       if (ret != 0) {
+               return false;
+       }
+
+       /*
+        * Every 100 writes within a single process, stabilize the cache with
+        * a transaction. This is done to prevent a single transaction to
+        * become huge and chew lots of memory.
+        */
+       writecount += 1;
+       if (writecount > lp_parm_int(-1, "gencache", "stabilize_count", 100)) {
+               gencache_stabilize();
+               writecount = 0;
+               goto done;
+       }
+
+       /*
+        * Every 5 minutes, call gencache_stabilize() to not let grow
+        * gencache_notrans.tdb too large.
+        */
+
+       last_stabilize = 0;
+       databuf = tdb_fetch(cache_notrans, last_stabilize_key());
+       if ((databuf.dptr != NULL)
+           && (databuf.dptr[databuf.dsize-1] == '\0')) {
+               last_stabilize = atoi((char *)databuf.dptr);
+               SAFE_FREE(databuf.dptr);
+       }
+       if ((last_stabilize
+            + lp_parm_int(-1, "gencache", "stabilize_interval", 300))
+           < time(NULL)) {
+               gencache_stabilize();
+       }
+
+done:
        return ret == 0;
 }
 
@@ -147,26 +208,63 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout)
 
 bool gencache_del(const char *keystr)
 {
-       int ret;
+       bool exists;
+       bool ret = false;
+       char *value;
 
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(keystr);
+       if (keystr == NULL) {
+               return false;
+       }
 
        if (!gencache_init()) return False;     
 
        DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
-       ret = tdb_delete_bystring(cache, keystr);
 
-       return ret == 0;
+       if (tdb_lock_bystring(cache_notrans, keystr) == -1) {
+               DEBUG(5, ("Could not lock key for %s\n", keystr));
+               return false;
+       }
+
+       /*
+        * We delete an element by setting its timeout to 0. This way we don't
+        * have to do a transaction on gencache.tdb every time we delete an
+        * element.
+        */
+
+       exists = gencache_get(keystr, &value, NULL);
+       if (exists) {
+               SAFE_FREE(value);
+               ret = gencache_set(keystr, "", 0);
+       }
+       tdb_unlock_bystring(cache_notrans, keystr);
+       return ret;
 }
 
+static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr)
+{
+       time_t res;
+       char *endptr;
+
+       res = strtol(val, &endptr, 10);
+
+       if ((endptr == NULL) || (*endptr != '/')) {
+               DEBUG(2, ("Invalid gencache data format: %s\n", val));
+               return false;
+       }
+       if (pres != NULL) {
+               *pres = res;
+       }
+       if (pendptr != NULL) {
+               *pendptr = endptr;
+       }
+       return true;
+}
 
 /**
  * Get existing entry from the cache file.
  *
  * @param keystr string that represents a key of this entry
- * @param valstr buffer that is allocated and filled with the entry value
- *        buffer's disposing must be done outside
+ * @param blob DATA_BLOB that is filled with entry's blob
  * @param timeout pointer to a time_t that is filled with entry's
  *        timeout
  *
@@ -174,31 +272,40 @@ bool gencache_del(const char *keystr)
  * @retval False for failure
  **/
 
-bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+                           time_t *timeout)
 {
        TDB_DATA databuf;
        time_t t;
        char *endptr;
 
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(keystr);
+       if (keystr == NULL) {
+               return false;
+       }
+
+       if (tdb_data_cmp(string_term_tdb_data(keystr),
+                        last_stabilize_key()) == 0) {
+               DEBUG(10, ("Can't get %s as a key\n", keystr));
+               return false;
+       }
 
        if (!gencache_init()) {
                return False;
        }
 
-       databuf = tdb_fetch_bystring(cache, keystr);
+       databuf = tdb_fetch_bystring(cache_notrans, keystr);
 
        if (databuf.dptr == NULL) {
-               DEBUG(10, ("Cache entry with key = %s couldn't be found\n",
+               databuf = tdb_fetch_bystring(cache, keystr);
+       }
+
+       if (databuf.dptr == NULL) {
+               DEBUG(10, ("Cache entry with key = %s couldn't be found \n",
                           keystr));
                return False;
        }
 
-       t = strtol((const char *)databuf.dptr, &endptr, 10);
-
-       if ((endptr == NULL) || (*endptr != '/')) {
-               DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr));
+       if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) {
                SAFE_FREE(databuf.dptr);
                return False;
        }
@@ -207,20 +314,33 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
                   "timeout = %s", t > time(NULL) ? "valid" :
                   "expired", keystr, endptr+1, ctime(&t)));
 
+       if (t == 0) {
+               /* Deleted */
+               SAFE_FREE(databuf.dptr);
+               return False;
+       }
+
        if (t <= time(NULL)) {
 
-               /* We're expired, delete the entry */
-               tdb_delete_bystring(cache, keystr);
+               /*
+                * We're expired, delete the entry. We can't use gencache_del
+                * here, because that uses gencache_get_data_blob for checking
+                * the existence of a record. We know the thing exists and
+                * directly store an empty value with 0 timeout.
+                */
+               gencache_set(keystr, "", 0);
 
                SAFE_FREE(databuf.dptr);
                return False;
        }
 
-       if (valstr) {
-               *valstr = SMB_STRDUP(endptr+1);
-               if (*valstr == NULL) {
+       if (blob != NULL) {
+               *blob = data_blob(
+                       endptr+1,
+                       databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr));
+               if (blob->data == NULL) {
                        SAFE_FREE(databuf.dptr);
-                       DEBUG(0, ("strdup failed\n"));
+                       DEBUG(0, ("memdup failed\n"));
                        return False;
                }
        }
@@ -234,155 +354,192 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
        return True;
 } 
 
+struct stabilize_state {
+       bool written;
+       bool error;
+};
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+                       void *priv);
+
 /**
- * Get existing entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB that is filled with entry's blob
- * @param expired pointer to a bool that indicates whether the entry is expired
+ * Stabilize gencache
  *
- * @retval true when entry is successfuly fetched
- * @retval False for failure
- **/
+ * Migrate the clear-if-first gencache data to the stable,
+ * transaction-based gencache.tdb
+ */
 
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired)
+bool gencache_stabilize(void)
 {
-       TDB_DATA databuf;
-       time_t t;
-       char *blob_type;
-       unsigned char *buf = NULL;
-       bool ret = False;
-       fstring valstr;
-       int buflen = 0, len = 0, blob_len = 0;
-       unsigned char *blob_buf = NULL;
-
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(keystr);
+       struct stabilize_state state;
+       int res;
+       char *now;
 
        if (!gencache_init()) {
-               return False;
+               return false;
        }
 
-       databuf = tdb_fetch_bystring(cache, keystr);
-       if (!databuf.dptr) {
-               DEBUG(10,("Cache entry with key = %s couldn't be found\n",
-                         keystr));
-               return False;
+       res = tdb_transaction_start(cache);
+       if (res == -1) {
+               DEBUG(10, ("Could not start transaction on gencache.tdb: "
+                          "%s\n", tdb_errorstr(cache)));
+               return false;
+       }
+       res = tdb_transaction_start(cache_notrans);
+       if (res == -1) {
+               tdb_transaction_cancel(cache);
+               DEBUG(10, ("Could not start transaction on "
+                          "gencache_notrans.tdb: %s\n",
+                          tdb_errorstr(cache_notrans)));
+               return false;
        }
 
-       buf = (unsigned char *)databuf.dptr;
-       buflen = databuf.dsize;
+       state.error = false;
+       state.written = false;
 
-       len += tdb_unpack(buf+len, buflen-len, "fB",
-                         &valstr,
-                         &blob_len, &blob_buf);
-       if (len == -1) {
-               goto out;
+       res = tdb_traverse(cache_notrans, stabilize_fn, &state);
+       if ((res == -1) || state.error) {
+               if ((tdb_transaction_cancel(cache_notrans) == -1)
+                   || (tdb_transaction_cancel(cache) == -1)) {
+                       smb_panic("tdb_transaction_cancel failed\n");
+               }
+               return false;
        }
 
-       t = strtol(valstr, &blob_type, 10);
+       if (!state.written) {
+               if ((tdb_transaction_cancel(cache_notrans) == -1)
+                   || (tdb_transaction_cancel(cache) == -1)) {
+                       smb_panic("tdb_transaction_cancel failed\n");
+               }
+               return true;
+       }
 
-       if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
-               goto out;
+       res = tdb_transaction_commit(cache);
+       if (res == -1) {
+               DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+                          "%s\n", tdb_errorstr(cache)));
+               if (tdb_transaction_cancel(cache_notrans) == -1) {
+                       smb_panic("tdb_transaction_cancel failed\n");
+               }
+               return false;
        }
 
-       DEBUG(10,("Returning %s cache entry: key = %s, "
-                 "timeout = %s", t > time(NULL) ? "valid" :
-                 "expired", keystr, ctime(&t)));
+       res = tdb_transaction_commit(cache_notrans);
+       if (res == -1) {
+               DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+                          "%s\n", tdb_errorstr(cache)));
+               return false;
+       }
 
-       if (t <= time(NULL)) {
-               /* We're expired */
-               if (expired) {
-                       *expired = True;
-               }
+       now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL));
+       if (now != NULL) {
+               tdb_store(cache_notrans, last_stabilize_key(),
+                         string_term_tdb_data(now), 0);
+               TALLOC_FREE(now);
        }
 
-       if (blob) {
-               *blob = data_blob(blob_buf, blob_len);
-               if (!blob->data) {
-                       goto out;
+       return true;
+}
+
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+                       void *priv)
+{
+       struct stabilize_state *state = (struct stabilize_state *)priv;
+       int res;
+       time_t timeout;
+
+       if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+               return 0;
+       }
+
+       if (!gencache_pull_timeout((char *)val.dptr, &timeout, NULL)) {
+               DEBUG(10, ("Ignoring invalid entry\n"));
+               return 0;
+       }
+       if ((timeout < time(NULL)) || (val.dsize == 0)) {
+               res = tdb_delete(cache, key);
+               if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
+                       res = 0;
+               } else {
+                       state->written = true;
+               }
+       } else {
+               res = tdb_store(cache, key, val, 0);
+               if (res == 0) {
+                       state->written = true;
                }
        }
 
-       ret = True;
- out:
-       SAFE_FREE(blob_buf);
-       SAFE_FREE(databuf.dptr);
+       if (res == -1) {
+               DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
+                          tdb_errorstr(cache)));
+               state->error = true;
+               return -1;
+       }
 
-       return ret;
+       if (tdb_delete(cache_notrans, key) == -1) {
+               DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
+                          "%s\n", tdb_errorstr(cache_notrans)));
+               state->error = true;
+               return -1;
+       }
+       return 0;
 }
 
 /**
- * Set an entry in the cache file. If there's no such
- * one, then add it.
+ * Get existing entry from the cache file.
  *
  * @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB value being cached
- * @param timeout time when the value is expired
+ * @param valstr buffer that is allocated and filled with the entry value
+ *        buffer's disposing must be done outside
+ * @param timeout pointer to a time_t that is filled with entry's
+ *        timeout
  *
- * @retval true when entry is successfuly stored
- * @retval false on failure
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
  **/
 
-bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout)
+bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
 {
+       DATA_BLOB blob;
        bool ret = False;
-       int tdb_ret;
-       TDB_DATA databuf;
-       char *valstr = NULL;
-       unsigned char *buf = NULL;
-       int len = 0, buflen = 0;
 
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(keystr && blob);
-
-       if (!gencache_init()) {
-               return False;
+       ret = gencache_get_data_blob(keystr, &blob, ptimeout);
+       if (!ret) {
+               return false;
        }
-
-       if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) {
-               return False;
+       if ((blob.data == NULL) || (blob.length == 0)) {
+               SAFE_FREE(blob.data);
+               return false;
        }
-
- again:
-       len = 0;
-
-       len += tdb_pack(buf+len, buflen-len, "fB",
-                       valstr,
-                       blob->length, blob->data);
-
-       if (len == -1) {
-               goto out;
+       if (blob.data[blob.length-1] != '\0') {
+               /* Not NULL terminated, can't be a string */
+               SAFE_FREE(blob.data);
+               return false;
        }
-
-       if (buflen < len) {
-               SAFE_FREE(buf);
-               buf = SMB_MALLOC_ARRAY(unsigned char, len);
-               if (!buf) {
-                       goto out;
-               }
-               buflen = len;
-               goto again;
-       }
-
-       databuf = make_tdb_data(buf, len);
-
-       DEBUG(10,("Adding cache entry with key = %s; "
-                 "blob size = %d and timeout = %s"
-                 "(%d seconds %s)\n", keystr, (int)databuf.dsize,
-                 ctime(&timeout), (int)(timeout - time(NULL)),
-                 timeout > time(NULL) ? "ahead" : "in the past"));
-
-       tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
-       if (tdb_ret == 0) {
-               ret = True;
+       *value = SMB_STRDUP((char *)blob.data);
+       data_blob_free(&blob);
+       if (*value == NULL) {
+               return false;
        }
+       return true;
+}
 
- out:
-       SAFE_FREE(valstr);
-       SAFE_FREE(buf);
+/**
+ * Set an entry in the cache file. If there's no such
+ * one, then add it.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param value text representation value being cached
+ * @param timeout time when the value is expired
+ *
+ * @retval true when entry is successfuly stored
+ * @retval false on failure
+ **/
 
-       return ret;
+bool gencache_set(const char *keystr, const char *value, time_t timeout)
+{
+       DATA_BLOB blob = data_blob_const(value, strlen(value)+1);
+       return gencache_set_data_blob(keystr, &blob, timeout);
 }
 
 /**
@@ -401,6 +558,7 @@ struct gencache_iterate_state {
                   void *priv);
        const char *pattern;
        void *priv;
+       bool in_persistent;
 };
 
 static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
@@ -416,6 +574,14 @@ static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
        time_t timeout;
        char *timeout_endp;
 
+       if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+               return 0;
+       }
+
+       if (state->in_persistent && tdb_exists(cache_notrans, key)) {
+               return 0;
+       }
+
        if (key.dptr[key.dsize-1] == '\0') {
                keystr = (char *)key.dptr;
        } else {
@@ -465,8 +631,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
 {
        struct gencache_iterate_state state;
 
-       /* fail completely if get null pointers passed */
-       SMB_ASSERT(fn && keystr_pattern);
+       if ((fn == NULL) || (keystr_pattern == NULL)) {
+               return;
+       }
 
        if (!gencache_init()) return;
 
@@ -475,30 +642,10 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
        state.fn = fn;
        state.pattern = keystr_pattern;
        state.priv = data;
-       tdb_traverse(cache, gencache_iterate_fn, &state);
-}
 
-/********************************************************************
- lock a key
-********************************************************************/
+       state.in_persistent = false;
+       tdb_traverse(cache_notrans, gencache_iterate_fn, &state);
 
-int gencache_lock_entry( const char *key )
-{
-       if (!gencache_init())
-               return -1;
-
-       return tdb_lock_bystring(cache, key);
-}
-
-/********************************************************************
- unlock a key
-********************************************************************/
-
-void gencache_unlock_entry( const char *key )
-{
-       if (!gencache_init())
-               return;
-
-       tdb_unlock_bystring(cache, key);
-       return;
+       state.in_persistent = true;
+       tdb_traverse(cache, gencache_iterate_fn, &state);
 }
index d101bc5ecd5eecfbbfb41fdf1b97b746ede2b256..a731cb986421d440913282f53be01d1ece1a5209 100644 (file)
  * and to be free()ed by the caller.
  **/
 
-char *escape_ldap_string_alloc(const char *s)
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s)
 {
        size_t len = strlen(s)+1;
-       char *output = (char *)SMB_MALLOC(len);
+       char *output = talloc_array(mem_ctx, char, len);
        const char *sub;
        int i = 0;
        char *p = output;
@@ -43,7 +43,7 @@ char *escape_ldap_string_alloc(const char *s)
        if (output == NULL) {
                return NULL;
        }
-       
+
        while (*s)
        {
                switch (*s)
@@ -64,14 +64,17 @@ char *escape_ldap_string_alloc(const char *s)
                        sub = NULL;
                        break;
                }
-               
+
                if (sub) {
+                       char *tmp;
                        len = len + 3;
-                       output = (char *)SMB_REALLOC(output, len);
-                       if (!output) { 
+                       tmp = talloc_realloc(mem_ctx, output, char, len);
+                       if (tmp == NULL) {
+                               TALLOC_FREE(output);
                                return NULL;
                        }
-                       
+                       output = tmp;
+
                        p = &output[i];
                        strncpy (p, sub, 3);
                        p += 3;
@@ -84,7 +87,7 @@ char *escape_ldap_string_alloc(const char *s)
                }
                s++;
        }
-       
+
        *p = '\0';
        return output;
 }
@@ -101,7 +104,7 @@ char *escape_rdn_val_string_alloc(const char *s)
        }
 
        p = output;
-       
+
        while (*s)
        {
                switch (*s)
@@ -122,10 +125,10 @@ char *escape_rdn_val_string_alloc(const char *s)
                        *p = *s;
                        p++;
                }
-               
+
                s++;
        }
-       
+
        *p = '\0';
 
        /* resize the string to the actual final size */
index 2f8474b37fdd0598abd1cb2e46aa10a87f9194fe..e80879a1d26677094cea7607ac00ee55f953e5b6 100644 (file)
@@ -170,7 +170,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
        gfree_charcnv();
        gfree_interfaces();
 
-       gencache_shutdown();
        secrets_shutdown();
 
        TALLOC_FREE(ctx);
index 39472b20d7867d97b8fb47ad2f519788ea9a4849..9fa3ddd9a89a4230d3889a41d946b62bb2765f1c 100644 (file)
@@ -770,7 +770,7 @@ static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
 {
        uint32_t fl = UF_SCRIPT; /* god knows why */
 
-       fl |= ads_acb2uf(acb);
+       fl |= ds_acb2uf(acb);
 
        return fl;
 }
index 66aef6ba668f0dc3daa91e70b36908ab2f255b2f..478a3d24ca9bf2a458836bbc6fbf68a788cf28eb 100644 (file)
@@ -126,7 +126,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
        char *escape_domain_name;
 
        /* escape for filter */
-       escape_domain_name = escape_ldap_string_alloc(domain_name);
+       escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
        if (!escape_domain_name) {
                DEBUG(0, ("Out of memory!\n"));
                return NT_STATUS_NO_MEMORY;
@@ -135,11 +135,11 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
        if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))",
                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
                        escape_domain_name, LDAP_OBJ_DOMINFO) < 0) {
-               SAFE_FREE(escape_domain_name);
+               TALLOC_FREE(escape_domain_name);
                return NT_STATUS_NO_MEMORY;
        }
 
-       SAFE_FREE(escape_domain_name);
+       TALLOC_FREE(escape_domain_name);
 
        attr_list = get_attr_list(NULL, dominfo_attr_list );
        rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
@@ -258,7 +258,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
        int count;
        char *escape_domain_name;
 
-       escape_domain_name = escape_ldap_string_alloc(domain_name);
+       escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
        if (!escape_domain_name) {
                DEBUG(0, ("Out of memory!\n"));
                return NT_STATUS_NO_MEMORY;
@@ -268,11 +268,11 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
                LDAP_OBJ_DOMINFO,
                get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
                escape_domain_name) < 0) {
-               SAFE_FREE(escape_domain_name);
+               TALLOC_FREE(escape_domain_name);
                return NT_STATUS_NO_MEMORY;
        }
 
-       SAFE_FREE(escape_domain_name);
+       TALLOC_FREE(escape_domain_name);
 
        DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter));
 
index ffc236e93b9cc03ad0eef869beb51b5a013c91bb..6a4f5d54130658156bf366dc061c7b6c08583601 100644 (file)
@@ -458,8 +458,6 @@ static struct timespec calc_create_time_stat_ex(const struct stat_ex *st)
 
 static void get_create_timespec(const struct stat *pst, struct stat_ex *dst)
 {
-       struct timespec ret;
-
        if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
                dst->st_ex_btime.tv_sec = 315493200L;          /* 1/1/1980 */
                dst->st_ex_btime.tv_nsec = 0;
@@ -483,7 +481,7 @@ static void get_create_timespec(const struct stat *pst, struct stat_ex *dst)
        /* Deal with systems that don't initialize birthtime correctly.
         * Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
         */
-       if (null_timespec(ret)) {
+       if (null_timespec(dst->st_ex_btime)) {
                dst->st_ex_btime = calc_create_time_stat(pst);
                dst->st_ex_calculated_birthtime = true;
        }
index 451bc18d2e7eeb6593fda54565c03cc0002960ff..fa56763a3358d608b804502f9a49a04a233bf46f 100644 (file)
@@ -1618,7 +1618,7 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx,
 
 static void tldap_add_done(struct tevent_req *subreq)
 {
-       return tldap_simple_done(subreq, TLDAP_RES_ADD);
+       tldap_simple_done(subreq, TLDAP_RES_ADD);
 }
 
 int tldap_add_recv(struct tevent_req *req)
@@ -1718,7 +1718,7 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
 
 static void tldap_modify_done(struct tevent_req *subreq)
 {
-       return tldap_simple_done(subreq, TLDAP_RES_MODIFY);
+       tldap_simple_done(subreq, TLDAP_RES_MODIFY);
 }
 
 int tldap_modify_recv(struct tevent_req *req)
@@ -1795,7 +1795,7 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx,
 
 static void tldap_delete_done(struct tevent_req *subreq)
 {
-       return tldap_simple_done(subreq, TLDAP_RES_DELETE);
+       tldap_simple_done(subreq, TLDAP_RES_DELETE);
 }
 
 int tldap_delete_recv(struct tevent_req *req)
index 31261afd7299e4bd026a7fe549d24cd6a524e273..af64f370baf18e33e60a78a1956e642b13b2444d 100644 (file)
@@ -348,6 +348,9 @@ static const smb_socket_option socket_options[] = {
 #endif
 #ifdef TCP_FASTACK
   {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
+#endif
+#ifdef TCP_QUICKACK
+  {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
 #endif
   {NULL,0,0,0,0}};
 
index cdd7d0a300e118768653191e62ba3dff7cb3f1a9..c197fd751598d955d1c5d96f18beddd660615d7c 100644 (file)
@@ -96,14 +96,14 @@ int StrCaseCmp(const char *s, const char *t)
                        return +1;
        }
 
-       if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
                return strcmp(ps, pt);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive, and it's pretty
                   close */
        }
 
-       if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
                TALLOC_FREE(buffer_s);
                return strcmp(ps, pt);
                /* Not quite the right answer, but finding the right one
@@ -157,14 +157,14 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
                return 0;
        }
 
-       if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive,
                   and it's pretty close */
        }
 
-       if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
                TALLOC_FREE(buffer_s);
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
@@ -366,7 +366,7 @@ size_t str_charnum(const char *s)
 {
        size_t ret, converted_size;
        smb_ucs2_t *tmpbuf2 = NULL;
-       if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
                return 0;
        }
        ret = strlen_w(tmpbuf2);
@@ -384,7 +384,7 @@ size_t str_ascii_charnum(const char *s)
 {
        size_t ret, converted_size;
        char *tmpbuf2 = NULL;
-       if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+       if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
                return 0;
        }
        ret = strlen(tmpbuf2);
@@ -455,7 +455,7 @@ bool strhasupper(const char *s)
        bool ret;
        size_t converted_size;
 
-       if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
                return false;
        }
 
@@ -480,7 +480,7 @@ bool strhaslower(const char *s)
        bool ret;
        size_t converted_size;
 
-       if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
                return false;
        }
 
@@ -1177,7 +1177,7 @@ char *strchr_m(const char *src, char c)
        s = src;
 #endif
 
-       if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
        }
@@ -1187,7 +1187,7 @@ char *strchr_m(const char *src, char c)
                return NULL;
        }
        *p = 0;
-       if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
                SAFE_FREE(ws);
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
@@ -1248,7 +1248,7 @@ char *strrchr_m(const char *s, char c)
                char *ret;
                size_t converted_size;
 
-               if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+               if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
                }
@@ -1258,7 +1258,7 @@ char *strrchr_m(const char *s, char c)
                        return NULL;
                }
                *p = 0;
-               if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+               if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
                        TALLOC_FREE(ws);
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
@@ -1283,7 +1283,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
        char *ret;
        size_t converted_size;
 
-       if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                /* Too hard to try and get right. */
                return NULL;
        }
@@ -1293,7 +1293,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
                return NULL;
        }
        *p = 0;
-       if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
                TALLOC_FREE(ws);
                /* Too hard to try and get right. */
                return NULL;
@@ -1352,12 +1352,12 @@ char *strstr_m(const char *src, const char *findstr)
        s = src;
 #endif
 
-       if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
                DEBUG(0,("strstr_m: src malloc fail\n"));
                return NULL;
        }
 
-       if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) {
+       if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
                TALLOC_FREE(src_w);
                DEBUG(0,("strstr_m: find malloc fail\n"));
                return NULL;
@@ -1372,7 +1372,7 @@ char *strstr_m(const char *src, const char *findstr)
        }
 
        *p = 0;
-       if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) {
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
                TALLOC_FREE(src_w);
                TALLOC_FREE(find_w);
                DEBUG(0,("strstr_m: dest malloc fail\n"));
@@ -1932,7 +1932,7 @@ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
        result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
        SMB_ASSERT(result != NULL);
 
-       while (len-- && out_cnt < (data.length * 2) - 5) {
+       while (len--) {
                int c = (unsigned char) *(data.data++);
                bits += c;
                char_count++;
index 78fa7cd0a15e9503445835eb4733c56fa3dacc6c..5b3d94dabe3b640af76f5fa19ac89c04fa5b8f5b 100644 (file)
@@ -630,3 +630,22 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
 
        return NT_STATUS_INTERNAL_ERROR;
 }
+
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2)
+{
+       int ret;
+       if (t1.dptr == NULL && t2.dptr != NULL) {
+               return -1;
+       }
+       if (t1.dptr != NULL && t2.dptr == NULL) {
+               return 1;
+       }
+       if (t1.dptr == t2.dptr) {
+               return t1.dsize - t2.dsize;
+       }
+       ret = memcmp(t1.dptr, t2.dptr, MIN(t1.dsize, t2.dsize));
+       if (ret == 0) {
+               return t1.dsize - t2.dsize;
+       }
+       return ret;
+}
index 3a9e8496685b165e40b1166931f99c793e4f48e0..5cf768de67241decbfe4f3ac42c81f35b5ae11d6 100644 (file)
@@ -754,10 +754,6 @@ bool sitename_store(const char *realm, const char *sitename)
        bool ret = False;
        char *key;
 
-       if (!gencache_init()) {
-               return False;
-       }
-
        if (!realm || (strlen(realm) == 0)) {
                DEBUG(0,("sitename_store: no realm\n"));
                return False;
@@ -795,10 +791,6 @@ char *sitename_fetch(const char *realm)
        const char *query_realm;
        char *key;
 
-       if (!gencache_init()) {
-               return NULL;
-       }
-
        if (!realm || (strlen(realm) == 0)) {
                query_realm = lp_realm();
        } else {
index eecd9045e5782296b148a3562fd44012834ff22f..69dc05335e1633e61c5594a12be99903f6874618 100644 (file)
        ADS_STATUS status;
        char *ldap_exp;
        const char *attrs[] = {"*", NULL};
-       char *escaped_user = escape_ldap_string_alloc(user);
+       char *escaped_user = escape_ldap_string(talloc_tos(), user);
        if (!escaped_user) {
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
 
        if (asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user) == -1) {
-               SAFE_FREE(escaped_user);
+               TALLOC_FREE(escaped_user);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
        status = ads_search(ads, res, ldap_exp, attrs);
        SAFE_FREE(ldap_exp);
-       SAFE_FREE(escaped_user);
+       TALLOC_FREE(escaped_user);
        return status;
 }
 
index 27c7aac7e7806581e541fc5ec9d4d750f385189d..41a9b3d9f3c588c58cff1d2378c1333ab04c0547 100644 (file)
@@ -676,21 +676,24 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx,
        }
 
 
-       if (!pdb_set_account_policy(AP_PASSWORD_HISTORY,
+       if (!pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
                                    r->password_history_length))
                return nt_status;
 
-       if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+       if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
                                    r->min_password_length))
                return nt_status;
 
-       if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+       if (!pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE,
+                                   (uint32)u_max_age))
                return nt_status;
 
-       if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+       if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE,
+                                   (uint32)u_min_age))
                return nt_status;
 
-       if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+       if (!pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT,
+                                   (uint32)u_logout))
                return nt_status;
 
        if (lockstr) {
@@ -699,21 +702,23 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx,
                u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count);
                u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration);
 
-               if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+               if (!pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
                                            lockstr->bad_attempt_lockout))
                        return nt_status;
 
-               if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60))
+               if (!pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME,
+                                           (uint32_t)u_lockoutreset/60))
                        return nt_status;
 
                if (u_lockouttime != -1)
                        u_lockouttime /= 60;
 
-               if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime))
+               if (!pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION,
+                                           (uint32_t)u_lockouttime))
                        return nt_status;
        }
 
-       if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+       if (!pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                                    r->logon_to_chgpass))
                return nt_status;
 
index 349a8331b47c97e2091800d66245aeb28d4deb5d..f5dbd72f22103842c83ba66edba75974bf5bbc5a 100644 (file)
@@ -25,7 +25,7 @@
  * cli_send_mailslot, send a mailslot for client code ...
  */
 
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
+static bool cli_send_mailslot(struct messaging_context *msg_ctx,
                       bool unique, const char *mailslot,
                       uint16 priority,
                       char *buf, int len,
@@ -309,4 +309,3 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx,
 
        return True;
 }
-
index af67fcb7467496954a46744ab03fffdfbc8acdc8..5ea05798394e6500c3652db4c383d7dbee01574c 100644 (file)
@@ -1893,7 +1893,6 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
        SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
 
        /* Setup param array. */
-       memset(state->param, '\0', 6);
        SSVAL(state->param,0,fnum);
        SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO);
 
@@ -2010,6 +2009,7 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
+
        vwv = state->vwv;
 
        SCVAL(vwv+0, 0, 0xFF);
@@ -2367,6 +2367,7 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
+
        SSVAL(state->vwv+0, 0, fnum);
        SIVALS(state->vwv+1, 0, -1);
 
@@ -2708,42 +2709,114 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum,
  Unlock a file.
 ****************************************************************************/
 
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len)
+struct cli_unlock_state {
+       uint16_t vwv[8];
+       uint8_t data[10];
+};
+
+static void cli_unlock_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+                               struct event_context *ev,
+                               struct cli_state *cli,
+                               uint16_t fnum,
+                               uint64_t offset,
+                               uint64_t len)
+
 {
-       char *p;
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct cli_unlock_state *state = NULL;
+       uint8_t additional_flags = 0;
 
-       memset(cli->outbuf,'\0',smb_size);
-       memset(cli->inbuf,'\0',smb_size);
+       req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
-       cli_set_message(cli->outbuf,8,0,True);
+       SCVAL(state->vwv+0, 0, 0xFF);
+       SSVAL(state->vwv+2, 0, fnum);
+       SCVAL(state->vwv+3, 0, 0);
+       SIVALS(state->vwv+4, 0, 0);
+       SSVAL(state->vwv+6, 0, 1);
+       SSVAL(state->vwv+7, 0, 0);
 
-       SCVAL(cli->outbuf,smb_com,SMBlockingX);
-       SSVAL(cli->outbuf,smb_tid,cli->cnum);
-       cli_setup_packet(cli);
+       SSVAL(state->data, 0, cli->pid);
+       SIVAL(state->data, 2, offset);
+       SIVAL(state->data, 6, len);
 
-       SCVAL(cli->outbuf,smb_vwv0,0xFF);
-       SSVAL(cli->outbuf,smb_vwv2,fnum);
-       SCVAL(cli->outbuf,smb_vwv3,0);
-       SIVALS(cli->outbuf, smb_vwv4, 0);
-       SSVAL(cli->outbuf,smb_vwv6,1);
-       SSVAL(cli->outbuf,smb_vwv7,0);
+       subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+                               8, state->vwv, 10, state->data);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_unlock_done, req);
+       return req;
+}
 
-       p = smb_buf(cli->outbuf);
-       SSVAL(p, 0, cli->pid);
-       SIVAL(p, 2, offset);
-       SIVAL(p, 6, len);
-       p += 10;
-       cli_setup_bcc(cli, p);
-       cli_send_smb(cli);
-       if (!cli_receive_smb(cli)) {
-               return False;
+static void cli_unlock_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+                               subreq, struct tevent_req);
+       NTSTATUS status;
+
+       status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
        }
+       tevent_req_done(req);
+}
 
-       if (cli_is_error(cli)) {
-               return False;
+NTSTATUS cli_unlock_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock(struct cli_state *cli,
+                       uint16_t fnum,
+                       uint32_t offset,
+                       uint32_t len)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (cli_has_async_calls(cli)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
        }
 
-       return True;
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = cli_unlock_send(frame, ev, cli,
+                       fnum, offset, len);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
+       }
+
+       status = cli_unlock_recv(req);
+
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
 }
 
 /****************************************************************************
@@ -2811,149 +2884,378 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum,
  Unlock a file with 64 bit offsets.
 ****************************************************************************/
 
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct cli_unlock64_state {
+       uint16_t vwv[8];
+       uint8_t data[20];
+};
+
+static void cli_unlock64_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+                               struct event_context *ev,
+                               struct cli_state *cli,
+                               uint16_t fnum,
+                               uint64_t offset,
+                               uint64_t len)
+
 {
-       char *p;
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct cli_unlock64_state *state = NULL;
+       uint8_t additional_flags = 0;
 
-       if (! (cli->capabilities & CAP_LARGE_FILES)) {
-               return cli_unlock(cli, fnum, offset, len);
+       req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state);
+       if (req == NULL) {
+               return NULL;
        }
 
-       memset(cli->outbuf,'\0',smb_size);
-       memset(cli->inbuf,'\0',smb_size);
+        SCVAL(state->vwv+0, 0, 0xff);
+       SSVAL(state->vwv+2, 0, fnum);
+       SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES);
+       SIVALS(state->vwv+4, 0, 0);
+       SSVAL(state->vwv+6, 0, 1);
+       SSVAL(state->vwv+7, 0, 0);
 
-       cli_set_message(cli->outbuf,8,0,True);
+       SIVAL(state->data, 0, cli->pid);
+       SOFF_T_R(state->data, 4, offset);
+       SOFF_T_R(state->data, 12, len);
 
-       SCVAL(cli->outbuf,smb_com,SMBlockingX);
-       SSVAL(cli->outbuf,smb_tid,cli->cnum);
-       cli_setup_packet(cli);
+       subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+                               8, state->vwv, 20, state->data);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_unlock64_done, req);
+       return req;
+}
 
-       SCVAL(cli->outbuf,smb_vwv0,0xFF);
-       SSVAL(cli->outbuf,smb_vwv2,fnum);
-       SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES);
-       SIVALS(cli->outbuf, smb_vwv4, 0);
-       SSVAL(cli->outbuf,smb_vwv6,1);
-       SSVAL(cli->outbuf,smb_vwv7,0);
+static void cli_unlock64_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+                               subreq, struct tevent_req);
+       NTSTATUS status;
 
-       p = smb_buf(cli->outbuf);
-       SIVAL(p, 0, cli->pid);
-       SOFF_T_R(p, 4, offset);
-       SOFF_T_R(p, 12, len);
-       p += 20;
-       cli_setup_bcc(cli, p);
-       cli_send_smb(cli);
-       if (!cli_receive_smb(cli)) {
-               return False;
+       status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
        }
+       tevent_req_done(req);
+}
 
-       if (cli_is_error(cli)) {
-               return False;
+NTSTATUS cli_unlock64_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock64(struct cli_state *cli,
+                               uint16_t fnum,
+                               uint64_t offset,
+                               uint64_t len)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (! (cli->capabilities & CAP_LARGE_FILES)) {
+               return cli_unlock(cli, fnum, offset, len);
        }
 
-       return True;
+       if (cli_has_async_calls(cli)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = cli_unlock64_send(frame, ev, cli,
+                       fnum, offset, len);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
+       }
+
+       status = cli_unlock64_recv(req);
+
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
 }
 
 /****************************************************************************
  Get/unlock a POSIX lock on a file - internal function.
 ****************************************************************************/
 
-static bool cli_posix_lock_internal(struct cli_state *cli, uint16_t fnum,
-               uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type)
+struct posix_lock_state {
+        uint16_t setup;
+       uint8_t param[4];
+        uint8_t data[POSIX_LOCK_DATA_SIZE];
+};
+
+static void cli_posix_unlock_internal_done(struct tevent_req *subreq)
 {
-       unsigned int param_len = 4;
-       unsigned int data_len = POSIX_LOCK_DATA_SIZE;
-       uint16_t setup = TRANSACT2_SETFILEINFO;
-       char param[4];
-       unsigned char data[POSIX_LOCK_DATA_SIZE];
-       char *rparam=NULL, *rdata=NULL;
-       int saved_timeout = cli->timeout;
+       struct tevent_req *req = tevent_req_callback_data(
+                                       subreq, struct tevent_req);
+       struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state);
+       NTSTATUS status;
 
-       SSVAL(param,0,fnum);
-       SSVAL(param,2,SMB_SET_POSIX_LOCK);
+       status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
 
+static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx,
+                                       struct event_context *ev,
+                                       struct cli_state *cli,
+                                       uint16_t fnum,
+                                       uint64_t offset,
+                                       uint64_t len,
+                                       bool wait_lock,
+                                       enum brl_type lock_type)
+{
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct posix_lock_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state, struct posix_lock_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       /* Setup setup word. */
+       SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
+
+       /* Setup param array. */
+       SSVAL(&state->param, 0, fnum);
+       SSVAL(&state->param, 2, SMB_SET_POSIX_LOCK);
+
+       /* Setup data array. */
        switch (lock_type) {
                case READ_LOCK:
-                       SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ);
+                       SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+                               POSIX_LOCK_TYPE_READ);
                        break;
                case WRITE_LOCK:
-                       SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE);
+                       SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+                               POSIX_LOCK_TYPE_WRITE);
                        break;
                case UNLOCK_LOCK:
-                       SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
+                       SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+                               POSIX_LOCK_TYPE_UNLOCK);
                        break;
                default:
-                       return False;
+                       return NULL;
        }
 
        if (wait_lock) {
-               SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT);
-               cli->timeout = 0x7FFFFFFF;
+               SSVAL(&state->data, POSIX_LOCK_FLAGS_OFFSET,
+                               POSIX_LOCK_FLAG_WAIT);
        } else {
-               SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT);
-       }
-
-       SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid);
-       SOFF_T(data, POSIX_LOCK_START_OFFSET, offset);
-       SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len);
+               SSVAL(state->data, POSIX_LOCK_FLAGS_OFFSET,
+                               POSIX_LOCK_FLAG_NOWAIT);
+       }
+
+       SIVAL(&state->data, POSIX_LOCK_PID_OFFSET, cli->pid);
+       SOFF_T(&state->data, POSIX_LOCK_START_OFFSET, offset);
+       SOFF_T(&state->data, POSIX_LOCK_LEN_OFFSET, len);
+
+       subreq = cli_trans_send(state,                  /* mem ctx. */
+                               ev,                     /* event ctx. */
+                               cli,                    /* cli_state. */
+                               SMBtrans2,              /* cmd. */
+                               NULL,                   /* pipe name. */
+                               -1,                     /* fid. */
+                               0,                      /* function. */
+                               0,                      /* flags. */
+                               &state->setup,          /* setup. */
+                               1,                      /* num setup uint16_t words. */
+                               0,                      /* max returned setup. */
+                               state->param,           /* param. */
+                               4,                      /* num param. */
+                               2,                      /* max returned param. */
+                               state->data,            /* data. */
+                               POSIX_LOCK_DATA_SIZE,   /* num data. */
+                               0);                     /* max returned data. */
 
-       if (!cli_send_trans(cli, SMBtrans2,
-                       NULL,                        /* name */
-                       -1, 0,                          /* fid, flags */
-                       &setup, 1, 0,                   /* setup, length, max */
-                       param, param_len, 2,            /* param, length, max */
-                       (char *)&data,  data_len, cli->max_xmit /* data, length, max */
-                       )) {
-               cli->timeout = saved_timeout;
-               return False;
-       }
-
-       if (!cli_receive_trans(cli, SMBtrans2,
-                               &rparam, &param_len,
-                               &rdata, &data_len)) {
-               cli->timeout = saved_timeout;
-               SAFE_FREE(rdata);
-               SAFE_FREE(rparam);
-               return False;
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
        }
-
-       cli->timeout = saved_timeout;
-
-       SAFE_FREE(rdata);
-       SAFE_FREE(rparam);
-
-       return True;
+       tevent_req_set_callback(subreq, cli_posix_unlock_internal_done, req);
+       return req;
 }
 
 /****************************************************************************
  POSIX Lock a file.
 ****************************************************************************/
 
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+                                       struct event_context *ev,
+                                       struct cli_state *cli,
+                                       uint16_t fnum,
+                                       uint64_t offset,
+                                       uint64_t len,
+                                       bool wait_lock,
+                                       enum brl_type lock_type)
+{
+       return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+                                       wait_lock, lock_type);
+}
+
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req)
+{
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
                        uint64_t offset, uint64_t len,
                        bool wait_lock, enum brl_type lock_type)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev = NULL;
+       struct tevent_req *req = NULL;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (cli_has_async_calls(cli)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+
        if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) {
-               return False;
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = cli_posix_lock_send(frame,
+                               ev,
+                               cli,
+                               fnum,
+                               offset,
+                               len,
+                               wait_lock,
+                               lock_type);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
+       }
+
+       status = cli_posix_lock_recv(req);
+
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
        }
-       return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type);
+       return status;
 }
 
 /****************************************************************************
  POSIX Unlock a file.
 ****************************************************************************/
 
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+                                       struct event_context *ev,
+                                       struct cli_state *cli,
+                                       uint16_t fnum,
+                                       uint64_t offset,
+                                       uint64_t len)
 {
-       return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK);
+       return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+                                       false, UNLOCK_LOCK);
 }
 
-/****************************************************************************
- POSIX Get any lock covering a file.
-****************************************************************************/
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req)
+{
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       return NT_STATUS_OK;
+}
 
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen)
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
 {
-       return True;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev = NULL;
+       struct tevent_req *req = NULL;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (cli_has_async_calls(cli)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = cli_posix_unlock_send(frame,
+                               ev,
+                               cli,
+                               fnum,
+                               offset,
+                               len);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
+       }
+
+       status = cli_posix_unlock_recv(req);
+
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
 }
 
 /****************************************************************************
@@ -3264,7 +3566,7 @@ NTSTATUS cli_getatr(struct cli_state *cli,
 static void cli_setattrE_done(struct tevent_req *subreq);
 
 struct cli_setattrE_state {
-       int dummy;
+       uint16_t vwv[7];
 };
 
 struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
@@ -3278,21 +3580,19 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
        struct tevent_req *req = NULL, *subreq = NULL;
        struct cli_setattrE_state *state = NULL;
        uint8_t additional_flags = 0;
-       uint16_t vwv[7];
 
        req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state);
        if (req == NULL) {
                return NULL;
        }
 
-       memset(vwv, '\0', sizeof(vwv));
-       SSVAL(vwv+0, 0, fnum);
-       cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time);
-       cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time);
-       cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time);
+       SSVAL(state->vwv+0, 0, fnum);
+       cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time);
+       cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time);
+       cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time);
 
        subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
-                             7, vwv, 0, NULL);
+                             7, state->vwv, 0, NULL);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -3399,7 +3699,6 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
-       memset(state->vwv, '\0', sizeof(state->vwv));
        SSVAL(state->vwv+0, 0, attr);
        cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);
 
index 8a567dc751f03d8a2a373e941f251b5826ae01da..152c23bd150c39f679ef563c8a2fecde0b3ab2ae 100644 (file)
@@ -346,7 +346,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
        }
        
        asn1_start_tag(data, ASN1_CONTEXT(2));
-       asn1_read_OctetString(data, NULL, &edata_contents);
+       asn1_read_OctetString(data, talloc_autofree_context(), &edata_contents);
        asn1_end_tag(data);
        asn1_end_tag(data);
        asn1_end_tag(data);
@@ -389,7 +389,7 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_
        
        asn1_end_tag(data);
        asn1_start_tag(data, ASN1_CONTEXT(1));
-       asn1_read_OctetString(data, NULL, &pac_contents);
+       asn1_read_OctetString(data, talloc_autofree_context(), &pac_contents);
        asn1_end_tag(data);
        asn1_end_tag(data);
        asn1_end_tag(data);
index fb95d719259a5f2e54d68f11d43d2eb3ad636552..e586d976cf35643c800f5698cfb242d7a05204b4 100644 (file)
@@ -151,7 +151,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob,
        asn1_start_tag(data,ASN1_SEQUENCE(0));
        for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
                const char *oid_str = NULL;
-               asn1_read_OID(data,NULL,&oid_str);
+               asn1_read_OID(data,talloc_autofree_context(),&oid_str);
                OIDs[i] = CONST_DISCARD(char *, oid_str);
        }
        OIDs[i] = NULL;
@@ -163,7 +163,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob,
                asn1_start_tag(data, ASN1_CONTEXT(3));
                asn1_start_tag(data, ASN1_SEQUENCE(0));
                asn1_start_tag(data, ASN1_CONTEXT(0));
-               asn1_read_GeneralString(data,NULL,principal);
+               asn1_read_GeneralString(data,talloc_autofree_context(),principal);
                asn1_end_tag(data);
                asn1_end_tag(data);
                asn1_end_tag(data);
@@ -256,7 +256,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
        asn1_start_tag(data, ASN1_SEQUENCE(0));
        for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
                const char *oid_str = NULL;
-               asn1_read_OID(data,NULL,&oid_str);
+               asn1_read_OID(data,talloc_autofree_context(),&oid_str);
                OIDs[i] = CONST_DISCARD(char *, oid_str);
        }
        OIDs[i] = NULL;
@@ -276,7 +276,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
        }
 
        asn1_start_tag(data, ASN1_CONTEXT(2));
-       asn1_read_OctetString(data,NULL,secblob);
+       asn1_read_OctetString(data,talloc_autofree_context(),secblob);
        asn1_end_tag(data);
 
        asn1_end_tag(data);
@@ -436,13 +436,13 @@ bool spnego_parse_challenge(const DATA_BLOB blob,
        asn1_end_tag(data);
 
        asn1_start_tag(data,ASN1_CONTEXT(2));
-       asn1_read_OctetString(data, NULL, chal1);
+       asn1_read_OctetString(data, talloc_autofree_context(), chal1);
        asn1_end_tag(data);
 
        /* the second challenge is optional (XP doesn't send it) */
        if (asn1_tag_remaining(data)) {
                asn1_start_tag(data,ASN1_CONTEXT(3));
-               asn1_read_OctetString(data, NULL, chal2);
+               asn1_read_OctetString(data, talloc_autofree_context(), chal2);
                asn1_end_tag(data);
        }
 
@@ -505,7 +505,7 @@ bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
        asn1_start_tag(data, ASN1_CONTEXT(1));
        asn1_start_tag(data, ASN1_SEQUENCE(0));
        asn1_start_tag(data, ASN1_CONTEXT(2));
-       asn1_read_OctetString(data, NULL, auth);
+       asn1_read_OctetString(data, talloc_autofree_context(), auth);
        asn1_end_tag(data);
        asn1_end_tag(data);
        asn1_end_tag(data);
@@ -609,7 +609,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
 
                if (asn1_tag_remaining(data)) {
                        asn1_start_tag(data,ASN1_CONTEXT(2));
-                       asn1_read_OctetString(data, NULL, auth);
+                       asn1_read_OctetString(data, talloc_autofree_context(), auth);
                        asn1_end_tag(data);
                }
        } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) {
@@ -623,7 +623,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
        if (asn1_tag_remaining(data)) {
                DATA_BLOB mechList = data_blob_null;
                asn1_start_tag(data, ASN1_CONTEXT(3));
-               asn1_read_OctetString(data, NULL, &mechList);
+               asn1_read_OctetString(data, talloc_autofree_context(), &mechList);
                asn1_end_tag(data);
                data_blob_free(&mechList);
                DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
index fb87b4dc9a3c15b78513b7bbb0ac78587b0ed935..3e0f4977aa250e444edb149c916a546316feac10 100644 (file)
@@ -133,10 +133,6 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx,
 {
        char *key;
 
-       if (!gencache_init()) {
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-
        key = dsgetdcname_cache_key(mem_ctx, domain_name);
        if (!key) {
                return NT_STATUS_NO_MEMORY;
@@ -160,10 +156,6 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
        char *key;
        bool ret = false;
 
-       if (!gencache_init()) {
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-
        key = dsgetdcname_cache_key(mem_ctx, domain_name);
        if (!key) {
                return NT_STATUS_NO_MEMORY;
@@ -171,14 +163,8 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
 
        expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
 
-       if (gencache_lock_entry(key) != 0) {
-               return NT_STATUS_LOCK_NOT_GRANTED;
-       }
-
        ret = gencache_set_data_blob(key, blob, expire_time);
 
-       gencache_unlock_entry(key);
-
        return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
@@ -353,8 +339,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
                                        struct GUID *domain_guid,
                                        uint32_t flags,
                                        const char *site_name,
-                                       struct netr_DsRGetDCNameInfo **info_p,
-                                       bool *expired)
+                                       struct netr_DsRGetDCNameInfo **info_p)
 {
        char *key;
        DATA_BLOB blob;
@@ -363,17 +348,13 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
        struct NETLOGON_SAM_LOGON_RESPONSE_EX r;
        NTSTATUS status;
 
-       if (!gencache_init()) {
-               return NT_STATUS_INTERNAL_DB_ERROR;
-       }
-
        key = dsgetdcname_cache_key(mem_ctx, domain_name);
        if (!key) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!gencache_get_data_blob(key, &blob, expired)) {
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       if (!gencache_get_data_blob(key, &blob, NULL)) {
+               return NT_STATUS_NOT_FOUND;
        }
 
        info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo);
@@ -428,11 +409,11 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx,
                                   struct netr_DsRGetDCNameInfo **info)
 {
        NTSTATUS status;
-       bool expired = false;
 
        status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid,
-                                        flags, site_name, info, &expired);
-       if (!NT_STATUS_IS_OK(status)) {
+                                        flags, site_name, info);
+       if (!NT_STATUS_IS_OK(status)
+           && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
                DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n",
                        nt_errstr(status)));
                return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
@@ -442,7 +423,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx,
                return status;
        }
 
-       if (expired) {
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
                status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
                                                   domain_name,
                                                   domain_guid, flags,
index 98885876b3350939e1ab84a22eb5bfb81ef43502..8b22ee5023c121b0f8d81e6253b773439639cb8d 100644 (file)
@@ -123,7 +123,6 @@ SMBC_module_init(void * punused)
 static void
 SMBC_module_terminate(void)
 {
-    gencache_shutdown();
     secrets_shutdown();
     gfree_all();
     SMBC_initialized = false;
index 411ffbdfbbc269654514537f468b5fe046805f85..6519659c25cca16233bc5308693b2d7d785522d7 100644 (file)
@@ -17,8 +17,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <pthread.h>
 #include "includes.h"
+#include <pthread.h>
 #include "libsmbclient.h"
 #include "libsmb_internal.h"
 
index d3230cffefb43548d199267a791467bf70c52f8c..dcfc609dcd6dcc4c2e05d6255d304ce06008e5e3 100644 (file)
@@ -45,14 +45,6 @@ bool namecache_enable(void)
                return False;
        }
 
-       /* Init namecache by calling gencache initialisation */
-
-       if (!gencache_init()) {
-               DEBUG(2, ("namecache_enable: "
-                       "Couldn't initialise namecache on top of gencache.\n"));
-               return False;
-       }
-
        /* I leave it for now, though I don't think we really
         * need this (mimir, 27.09.2002) */
        DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
@@ -102,14 +94,6 @@ bool namecache_store(const char *name,
        int i;
        bool ret;
 
-       /*
-        * we use gecache call to avoid annoying debug messages about
-        * initialised namecache again and again...
-        */
-       if (!gencache_init()) {
-               return False;
-       }
-
        if (name_type > 255) {
                return False; /* Don't store non-real name types. */
        }
@@ -186,10 +170,6 @@ bool namecache_fetch(const char *name,
                return False;
        }
 
-       if (!gencache_init()) {
-               return False;
-       }
-
        if (name_type > 255) {
                return False; /* Don't fetch non-real name types. */
        }
@@ -233,9 +213,6 @@ bool namecache_delete(const char *name, int name_type)
        bool ret;
        char *key;
 
-       if (!gencache_init())
-               return False;
-
        if (name_type > 255) {
                return False; /* Don't fetch non-real name types. */
        }
@@ -274,10 +251,6 @@ static void flush_netbios_name(const char *key,
 
 void namecache_flush(void)
 {
-       if (!gencache_init()) {
-               return;
-       }
-
        /*
         * iterate through each NBT cache's entry and flush it
         * by flush_netbios_name function
@@ -312,10 +285,6 @@ bool namecache_status_store(const char *keyname, int keyname_type,
        time_t expiry;
        bool ret;
 
-       if (!gencache_init()) {
-               return False;
-       }
-
        key = namecache_status_record_key(keyname, keyname_type,
                        name_type, keyip);
        if (!key)
@@ -348,9 +317,6 @@ bool namecache_status_fetch(const char *keyname,
        char *value = NULL;
        time_t timeout;
 
-       if (!gencache_init())
-               return False;
-
        key = namecache_status_record_key(keyname, keyname_type,
                        name_type, keyip);
        if (!key)
index 50fb9f1620590aefde3144b26a9edc0154525328..05143270b9fd8ce2a9f9f8b35740092a1e6ca6d7 100644 (file)
@@ -76,9 +76,6 @@ bool saf_store( const char *domain, const char *servername )
                return False;
        }
 
-       if ( !gencache_init() )
-               return False;
-
        key = saf_key( domain );
        expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
 
@@ -108,9 +105,6 @@ bool saf_join_store( const char *domain, const char *servername )
                return False;
        }
 
-       if ( !gencache_init() )
-               return False;
-
        key = saf_join_key( domain );
        expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
 
@@ -134,9 +128,6 @@ bool saf_delete( const char *domain )
                return False;
        }
 
-       if ( !gencache_init() )
-               return False;
-
        key = saf_join_key(domain);
        ret = gencache_del(key);
        SAFE_FREE(key);
@@ -171,9 +162,6 @@ char *saf_fetch( const char *domain )
                return NULL;
        }
 
-       if ( !gencache_init() )
-               return False;
-
        key = saf_join_key( domain );
 
        ret = gencache_get( key, &server, &timeout );
index ee2c3c3d5a7ac646b8641a6a832f88004334feb8..528c7f400902dd3fc110cc88d945c200e7fe249d 100644 (file)
@@ -41,17 +41,18 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
                        asn1_start_tag(asn1, ASN1_CONTEXT(0));
                        asn1_start_tag(asn1, ASN1_SEQUENCE(0));
 
-                       token->mechTypes = TALLOC_P(NULL, const char *);
+                       token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *);
                        for (i = 0; !asn1->has_error &&
                                     0 < asn1_tag_remaining(asn1); i++) {
                                const char *p_oid = NULL;
                                token->mechTypes = 
-                                       TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2);
+                                       TALLOC_REALLOC_ARRAY(talloc_autofree_context(),
+                                               token->mechTypes, const char *, i + 2);
                                if (!token->mechTypes) {
                                        asn1->has_error = True;
                                        return False;
                                }
-                               asn1_read_OID(asn1, NULL, &p_oid);
+                               asn1_read_OID(asn1, talloc_autofree_context(), &p_oid);
                                token->mechTypes[i] = p_oid;
                        }
                        token->mechTypes[i] = NULL;
@@ -69,14 +70,15 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
                 /* Read mechToken */
                case ASN1_CONTEXT(2):
                        asn1_start_tag(asn1, ASN1_CONTEXT(2));
-                       asn1_read_OctetString(asn1, NULL, &token->mechToken);
+                       asn1_read_OctetString(asn1,
+                               talloc_autofree_context(), &token->mechToken);
                        asn1_end_tag(asn1);
                        break;
                /* Read mecListMIC */
                case ASN1_CONTEXT(3):
                        asn1_start_tag(asn1, ASN1_CONTEXT(3));
                        if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
-                               asn1_read_OctetString(asn1, NULL,
+                               asn1_read_OctetString(asn1, talloc_autofree_context(),
                                                      &token->mechListMIC);
                        } else {
                                /* RFC 2478 says we have an Octet String here,
@@ -84,7 +86,8 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
                                char *mechListMIC;
                                asn1_push_tag(asn1, ASN1_SEQUENCE(0));
                                asn1_push_tag(asn1, ASN1_CONTEXT(0));
-                               asn1_read_GeneralString(asn1, NULL, &mechListMIC);
+                               asn1_read_GeneralString(asn1,
+                                       talloc_autofree_context(), &mechListMIC);
                                asn1_pop_tag(asn1);
                                asn1_pop_tag(asn1);
 
@@ -188,19 +191,21 @@ static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
                case ASN1_CONTEXT(1): {
                        const char *mech = NULL;
                        asn1_start_tag(asn1, ASN1_CONTEXT(1));
-                       asn1_read_OID(asn1, NULL, &mech);
+                       asn1_read_OID(asn1, talloc_autofree_context(), &mech);
                        asn1_end_tag(asn1);
                        token->supportedMech = CONST_DISCARD(char *, mech);
                        }
                        break;
                case ASN1_CONTEXT(2):
                        asn1_start_tag(asn1, ASN1_CONTEXT(2));
-                       asn1_read_OctetString(asn1, NULL, &token->responseToken);
+                       asn1_read_OctetString(asn1,
+                               talloc_autofree_context(), &token->responseToken);
                        asn1_end_tag(asn1);
                        break;
                case ASN1_CONTEXT(3):
                        asn1_start_tag(asn1, ASN1_CONTEXT(3));
-                       asn1_read_OctetString(asn1, NULL, &token->mechListMIC);
+                       asn1_read_OctetString(asn1,
+                               talloc_autofree_context(), &token->mechListMIC);
                        asn1_end_tag(asn1);
                        break;
                default:
index 6755de3814bb05c7174ed2b0f2e0af6704d88b33..eb52b3588d58d1f4d6ca2d00164ccc64859b28d7 100644 (file)
@@ -4,17 +4,17 @@
    Trusted domain names cache on top of gencache.
 
    Copyright (C) Rafal Szczesniak      2002
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -38,7 +38,6 @@
  * list of trusted domains
  **/
 
 /**
  * Initialise trustdom name caching system. Call gencache
  * initialisation routine to perform necessary activities.
  * @return true upon successful cache initialisation or
  *         false if cache init failed
  **/
+
 bool trustdom_cache_enable(void)
 {
-       /* Init trustdom cache by calling gencache initialisation */
-       if (!gencache_init()) {
-               DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
-               return False;
-       }
-
        return True;
 }
 
@@ -66,15 +59,9 @@ bool trustdom_cache_enable(void)
  * @return true upon successful cache close or
  *         false if it failed
  **/
+
 bool trustdom_cache_shutdown(void)
 {
-       /* Close trustdom cache by calling gencache shutdown */
-       if (!gencache_shutdown()) {
-               DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
-               return False;
-       }
-       
        return True;
 }
 
@@ -91,7 +78,7 @@ static char* trustdom_cache_key(const char* name)
 {
        char* keystr = NULL;
        asprintf_strupper_m(&keystr, TDOMKEY_FMT, name);
-       
+
        return keystr;
 }
 
@@ -115,13 +102,6 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
        fstring sid_string;
        bool ret;
 
-       /*
-        * we use gecache call to avoid annoying debug messages
-        * about initialised trustdom 
-        */
-       if (!gencache_init())
-               return False;
-
        DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
                  sid_string_dbg(sid), name));
 
@@ -160,16 +140,12 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
  * @return true if entry is found or
  *         false if has expired/doesn't exist
  **/
+
 bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
 {
        char *key = NULL, *value = NULL;
        time_t timeout;
 
-       /* init the cache */
-       if (!gencache_init())
-               return False;
-       
        /* exit now if null pointers were passed as they're required further */
        if (!sid)
                return False;
@@ -178,7 +154,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
        key = trustdom_cache_key(name);
        if (!key)
                return False;
-       
+
        if (!gencache_get(key, &value, &timeout)) {
                DEBUG(5, ("no entry for trusted domain %s found.\n", name));
                SAFE_FREE(key);
@@ -194,7 +170,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
                SAFE_FREE(value);
                return False;
        }
-       
+
        SAFE_FREE(value);
        return True;
 }
@@ -210,10 +186,6 @@ uint32 trustdom_cache_fetch_timestamp( void )
        time_t timeout;
        uint32 timestamp;
 
-       /* init the cache */
-       if (!gencache_init()) 
-               return False;
-               
        if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
                DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
                SAFE_FREE(value);
@@ -221,7 +193,7 @@ uint32 trustdom_cache_fetch_timestamp( void )
        } 
 
        timestamp = atoi(value);
-               
+
        SAFE_FREE(value);
        return timestamp;
 }
@@ -234,12 +206,8 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout )
 {
        fstring value;
 
-       /* init the cache */
-       if (!gencache_init()) 
-               return False;
-               
        fstr_sprintf(value, "%d", t );
-               
+
        if (!gencache_set(TDOMTSKEY, value, timeout)) {
                DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
                return False;
@@ -268,9 +236,6 @@ static void flush_trustdom_name(const char* key, const char *value, time_t timeo
 
 void trustdom_cache_flush(void)
 {
-       if (!gencache_init())
-               return;
-
        /* 
         * iterate through each TDOM cache's entry and flush it
         * by flush_trustdom_name function
@@ -294,13 +259,13 @@ void update_trustdom_cache( void )
        TALLOC_CTX *mem_ctx = NULL;
        time_t now = time(NULL);
        int i;
-       
+
        /* get the timestamp.  We have to initialise it if the last timestamp == 0 */   
        if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) 
                trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
 
        time_diff = (int) (now - last_check);
-       
+
        if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
                DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
                return;
@@ -310,14 +275,14 @@ void update_trustdom_cache( void )
           smbd from blocking all other smbd daemons while we
           enumerate the trusted domains */
        trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL);
-               
+
        if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
                DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
                goto done;
        }
 
        /* get the domains and store them */
-       
+
        if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, 
                &num_domains, &dom_sids)) {
                for ( i=0; i<num_domains; i++ ) {
@@ -333,6 +298,6 @@ void update_trustdom_cache( void )
 
 done:  
        talloc_destroy( mem_ctx );
-       
+
        return;
 }
index be2948c53113fd51218595c0d9e80b3ff02c6f7e..e238ec959b6e01682b1fa83bf32a25c9c26bcb20 100644 (file)
@@ -1196,7 +1196,7 @@ bool brl_locktest(struct byte_range_lock *br_lck,
 
                DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
                        (double)start, (double)size, ret ? "locked" : "unlocked",
-                       fsp->fnum, fsp->fsp_name ));
+                       fsp->fnum, fsp_str_dbg(fsp)));
 
                /* We need to return the inverse of is_posix_locked. */
                ret = !ret;
@@ -1262,7 +1262,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
 
                DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
                        (double)*pstart, (double)*psize, ret ? "locked" : "unlocked",
-                       fsp->fnum, fsp->fsp_name ));
+                       fsp->fnum, fsp_str_dbg(fsp)));
 
                if (ret) {
                        /* Hmmm. No clue what to set smbpid to - use -1. */
index 91fe137fdcbf8847a9e27f58edb63980f4098a0c..fba871c704e0cb5417e82bdd462524fed165e754 100644 (file)
@@ -109,11 +109,11 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
 
        if (strict_locking == Auto) {
                if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
-                       DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
+                       DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
                        ret = True;
                } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
                           (plock->lock_type == READ_LOCK)) {
-                       DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
+                       DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
                        ret = True;
                } else {
                        struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
@@ -149,7 +149,7 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
                        lock_flav_name(plock->lock_flav),
                        (double)plock->start, (double)plock->size,
                        ret ? "unlocked" : "locked",
-                       plock->fnum, fsp->fsp_name ));
+                       plock->fnum, fsp_str_dbg(fsp)));
 
        return ret;
 }
@@ -259,7 +259,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
                "blocking_lock=%s requested for fnum %d file %s\n",
                lock_flav_name(lock_flav), lock_type_name(lock_type),
                (double)offset, (double)count, blocking_lock ? "true" :
-               "false", fsp->fnum, fsp->fsp_name));
+               "false", fsp->fnum, fsp_str_dbg(fsp)));
 
        br_lck = brl_get_locks(talloc_tos(), fsp);
        if (!br_lck) {
@@ -308,7 +308,8 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx,
        }
        
        DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
-                 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+                 (double)offset, (double)count, fsp->fnum,
+                 fsp_str_dbg(fsp)));
 
        br_lck = brl_get_locks(talloc_tos(), fsp);
        if (!br_lck) {
@@ -358,7 +359,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp,
        }
 
        DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
-                 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+                 (double)offset, (double)count, fsp->fnum,
+                 fsp_str_dbg(fsp)));
 
        br_lck = brl_get_locks(talloc_tos(), fsp);
        if (!br_lck) {
@@ -1311,7 +1313,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
            !lp_delete_readonly(SNUM(fsp->conn))) {
                DEBUG(10,("can_set_delete_on_close: file %s delete on close "
                          "flag set but file attribute is readonly.\n",
-                         fsp->fsp_name ));
+                         fsp_str_dbg(fsp)));
                return NT_STATUS_CANNOT_DELETE;
        }
 
@@ -1322,7 +1324,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
        if (!CAN_WRITE(fsp->conn)) {
                DEBUG(10,("can_set_delete_on_close: file %s delete on "
                          "close flag set but write access denied on share.\n",
-                         fsp->fsp_name ));
+                         fsp_str_dbg(fsp)));
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -1334,13 +1336,15 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
        if (!(fsp->access_mask & DELETE_ACCESS)) {
                DEBUG(10,("can_set_delete_on_close: file %s delete on "
                          "close flag set but delete access denied.\n",
-                         fsp->fsp_name ));
+                         fsp_str_dbg(fsp)));
                return NT_STATUS_ACCESS_DENIED;
        }
 
        /* Don't allow delete on close for non-empty directories. */
        if (fsp->is_directory) {
-               return can_delete_directory(fsp->conn, fsp->fsp_name);
+               SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+               return can_delete_directory(fsp->conn,
+                                           fsp->fsp_name->base_name);
        }
 
        return NT_STATUS_OK;
@@ -1422,7 +1426,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE
        DEBUG(10,("set_delete_on_close: %s delete on close flag for "
                  "fnum = %d, file %s\n",
                  delete_on_close ? "Adding" : "Removing", fsp->fnum,
-                 fsp->fsp_name ));
+                 fsp_str_dbg(fsp)));
 
        lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
                                  NULL);
@@ -1443,7 +1447,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE
        set_delete_on_close_lck(lck, delete_on_close, tok);
 
        if (fsp->is_directory) {
-               send_stat_cache_delete_message(fsp->fsp_name);
+               SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+               send_stat_cache_delete_message(fsp->fsp_name->base_name);
        }
 
        TALLOC_FREE(lck);
index 9b51c3aa6abca3c48d7023530aaa5d474208e87a..33ffaf95caf928629a71e669f3015b5f90e1435e 100644 (file)
@@ -280,8 +280,9 @@ bool is_posix_locked(files_struct *fsp,
        SMB_OFF_T count;
        int posix_lock_type = map_posix_lock_type(fsp,*plock_type);
 
-       DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
-               fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) ));
+       DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, "
+                 "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset,
+                 (double)*pu_count,  posix_lock_type_name(*plock_type)));
 
        /*
         * If the requested lock won't fit in the POSIX range, we will
@@ -424,7 +425,7 @@ static void increment_windows_lock_ref_count(files_struct *fsp)
        TALLOC_FREE(rec);
 
        DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
-                 fsp->fsp_name, lock_ref_count ));
+                 fsp_str_dbg(fsp), lock_ref_count));
 }
 
 /****************************************************************************
@@ -460,7 +461,7 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
        TALLOC_FREE(rec);
 
        DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
-                 fsp->fsp_name, lock_ref_count ));
+                 fsp_str_dbg(fsp), lock_ref_count));
 }
 
 static void decrement_windows_lock_ref_count(files_struct *fsp)
@@ -492,7 +493,7 @@ static int get_windows_lock_ref_count(files_struct *fsp)
        }
 
        DEBUG(10,("get_windows_lock_count for file %s = %d\n",
-                 fsp->fsp_name, lock_ref_count ));
+                 fsp_str_dbg(fsp), lock_ref_count));
 
        return lock_ref_count;
 }
@@ -518,7 +519,7 @@ static void delete_windows_lock_ref_count(files_struct *fsp)
        TALLOC_FREE(rec);
 
        DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
-                 fsp->fsp_name));
+                 fsp_str_dbg(fsp)));
 }
 
 /****************************************************************************
@@ -555,7 +556,7 @@ static void add_fd_to_close_entry(files_struct *fsp)
        TALLOC_FREE(rec);
 
        DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
-                 fsp->fh->fd, fsp->fsp_name ));
+                 fsp->fh->fd, fsp_str_dbg(fsp)));
 }
 
 /****************************************************************************
@@ -945,8 +946,10 @@ bool set_posix_lock_windows_flavour(files_struct *fsp,
        struct lock_list *llist = NULL;
        struct lock_list *ll = NULL;
 
-       DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
-                       fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+       DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, "
+                "count = %.0f, type = %s\n", fsp_str_dbg(fsp),
+                (double)u_offset, (double)u_count,
+                posix_lock_type_name(lock_type)));
 
        /*
         * If the requested lock won't fit in the POSIX range, we will
@@ -1079,8 +1082,9 @@ bool release_posix_lock_windows_flavour(files_struct *fsp,
        struct lock_list *ulist = NULL;
        struct lock_list *ul = NULL;
 
-       DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n",
-               fsp->fsp_name, (double)u_offset, (double)u_count ));
+       DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, "
+                "count = %.0f\n", fsp_str_dbg(fsp),
+                (double)u_offset, (double)u_count));
 
        /* Remember the number of Windows locks we have on this dev/ino pair. */
        decrement_windows_lock_ref_count(fsp);
@@ -1197,8 +1201,10 @@ bool set_posix_lock_posix_flavour(files_struct *fsp,
        SMB_OFF_T count;
        int posix_lock_type = map_posix_lock_type(fsp,lock_type);
 
-       DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
-                       fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+       DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count "
+                "= %.0f, type = %s\n", fsp_str_dbg(fsp),
+                (double)u_offset, (double)u_count,
+                posix_lock_type_name(lock_type)));
 
        /*
         * If the requested lock won't fit in the POSIX range, we will
@@ -1241,8 +1247,9 @@ bool release_posix_lock_posix_flavour(files_struct *fsp,
        struct lock_list *ulist = NULL;
        struct lock_list *ul = NULL;
 
-       DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n",
-               fsp->fsp_name, (double)u_offset, (double)u_count ));
+       DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, "
+                "count = %.0f\n", fsp_str_dbg(fsp),
+                (double)u_offset, (double)u_count));
 
        /*
         * If the requested lock won't fit in the POSIX range, we will
index 9b3c8725d5b9768c8d7fc40990c8078390568126..748f17d45765d1a1cfce937bcdbcc6c128542813 100644 (file)
@@ -183,7 +183,8 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
        memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
 
        if (fsp->is_directory || fsp->fh->fd == -1) {
-               return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf);
+               return smbacl4_GetFileOwner(fsp->conn,
+                                           fsp->fsp_name->base_name, psbuf);
        }
        if (SMB_VFS_FSTAT(fsp, psbuf) != 0)
        {
@@ -327,7 +328,7 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
 {
        SMB_STRUCT_STAT sbuf;
 
-       DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+       DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
 
        if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
                return map_nt_error_from_unix(errno);
@@ -717,7 +718,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
        gid_t newGID = (gid_t)-1;
        int saved_errno;
 
-       DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+       DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
 
        if ((security_info_sent & (DACL_SECURITY_INFORMATION |
                GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0)
@@ -743,26 +744,23 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
                }
                if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
                    ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
-                       struct smb_filename *smb_fname = NULL;
-                       NTSTATUS status;
 
-                       status = create_synthetic_smb_fname_split(talloc_tos(),
-                           fsp->fsp_name, NULL, &smb_fname);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               return status;
-                       }
-                       if(try_chown(fsp->conn, smb_fname, newUID, newGID)) {
-                               DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
-                                        fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, 
+                       if(try_chown(fsp->conn, fsp->fsp_name, newUID,
+                                    newGID)) {
+                               DEBUG(3,("chown %s, %u, %u failed. Error = "
+                                        "%s.\n", fsp_str_dbg(fsp),
+                                        (unsigned int)newUID,
+                                        (unsigned int)newGID,
                                         strerror(errno)));
-                               TALLOC_FREE(smb_fname);
                                return map_nt_error_from_unix(errno);
                        }
-                       TALLOC_FREE(smb_fname);
 
                        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))
+                                 fsp_str_dbg(fsp), (unsigned int)newUID,
+                                 (unsigned int)newGID));
+                       if (smbacl4_GetFileOwner(fsp->conn,
+                                                fsp->fsp_name->base_name,
+                                                &sbuf))
                                return map_nt_error_from_unix(errno);
 
                        /* If we successfully chowned, we know we must
@@ -777,7 +775,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
                return NT_STATUS_OK;
        }
 
-       theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params,
+       theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, &params,
                                  sbuf.st_ex_uid, sbuf.st_ex_gid);
        if (!theacl)
                return map_nt_error_from_unix(errno);
index 5c72d10a6baa908e6c7a42170f5bef1cdafc99b1..2753a9e885a919ca31da2fa29fd60b94b18753c0 100644 (file)
@@ -395,8 +395,8 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
 
                if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
                        DEBUG(10, ("Did not canonicalize ACLs because a "
-                           "Windows ACL set was found for file %s\n",
-                           fsp->fsp_name));
+                                  "Windows ACL set was found for file %s\n",
+                                  fsp_str_dbg(fsp)));
                        return true;
                }
                break;
@@ -436,7 +436,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
 
        SMB_ASSERT(new_aces_count == sd->dacl->num_aces);
        DEBUG(10, ("Performed canonicalization of ACLs for file %s\n",
-           fsp->fsp_name));
+                  fsp_str_dbg(fsp)));
 
        /*
         * At this point you would think we could just do this:
@@ -535,32 +535,21 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
        if (error) {
                DEBUG(0, ("Failed to stat %s in simple files sharing "
                          "compatibility mode. errno=%d\n",
-                         fsp->fsp_name, errno));
+                         fsp_str_dbg(fsp), errno));
                return false;
        }
 
        /* Only continue if this is a synthetic ACL and a directory. */
        if (S_ISDIR(sbuf.st_ex_mode) &&
            (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
-               struct smb_filename *smb_fname = NULL;
                struct ifs_ace new_aces[6];
                struct ifs_ace *old_aces;
                int i, num_aces_to_add = 0;
                mode_t file_mode = 0, dir_mode = 0;
-               NTSTATUS status;
-
-               status = create_synthetic_smb_fname_split(talloc_tos(),
-                                                         fsp->fsp_name, NULL,
-                                                         &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return false;
-               }
 
                /* Use existing samba logic to derive the mode bits. */
-               file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL);
-               dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL);
-
-               TALLOC_FREE(smb_fname);
+               file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL);
+               dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, NULL);
 
                /* Initialize ACEs. */
                new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
@@ -631,18 +620,18 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        *ppdesc = NULL;
 
        DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
-           fsp->fsp_name, security_info));
+                 fsp_str_dbg(fsp), security_info));
 
        if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
                PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
-               DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name));
+               DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp)));
                security_info &= ~SACL_SECURITY_INFORMATION;
        }
 
        if (fsp->fh->fd == -1) {
                if ((fsp->fh->fd = onefs_sys_create_file(handle->conn,
                                                         -1,
-                                                        fsp->fsp_name,
+                                                        fsp->fsp_name->base_name,
                                                         0,
                                                         0,
                                                         0,
@@ -655,7 +644,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                                         0,
                                                         NULL)) == -1) {
                        DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
-                                 fsp->fsp_name, errno, strerror(errno)));
+                                 fsp_str_dbg(fsp), errno, strerror(errno)));
                        status = map_nt_error_from_unix(errno);
                        goto out;
                }
@@ -801,6 +790,7 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
 {
        files_struct finfo;
        struct fd_handle fh;
+       NTSTATUS status;
 
        ZERO_STRUCT(finfo);
        ZERO_STRUCT(fh);
@@ -809,9 +799,16 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
        finfo.conn = handle->conn;
        finfo.fh = &fh;
        finfo.fh->fd = -1;
-       finfo.fsp_name = CONST_DISCARD(char *, name);
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+                                           &finfo.fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-       return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+       status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+
+       TALLOC_FREE(finfo.fsp_name);
+       return status;
 }
 
 /**
@@ -918,7 +915,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
 
        START_PROFILE(syscall_set_sd);
 
-       DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
+       DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp)));
 
        status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd,
                                      SNUM(handle->conn), &sec_info_effective);
@@ -930,10 +927,10 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
 
        fd = fsp->fh->fd;
        if (fd == -1) {
-               DEBUG(10,("Reopening file %s.\n", fsp->fsp_name));
+               DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp)));
                if ((fd = onefs_sys_create_file(handle->conn,
                                                -1,
-                                               fsp->fsp_name,
+                                               fsp->fsp_name->base_name,
                                                0,
                                                0,
                                                0,
@@ -946,7 +943,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                                0,
                                                NULL)) == -1) {
                        DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
-                                 fsp->fsp_name, errno, strerror(errno)));
+                                 fsp_str_dbg(fsp), errno, strerror(errno)));
                        status = map_nt_error_from_unix(errno);
                        goto out;
                }
index b51d516956c9791da6f9a3ae27aba6bee79db501..31f27e907ac5d37d355b8b7996d98274c089bf99 100644 (file)
@@ -81,7 +81,6 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                                struct security_descriptor *sd,
                                int *granted_oplock)
 {
-       char *path = NULL;
        struct smb_filename *smb_fname_onefs = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int accmode = (flags & O_ACCMODE);
@@ -157,7 +156,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                 * wildcard characters are allowed in stream names
                 * only test the basefilename
                 */
-               wild = fsp->base_fsp->fsp_name;
+               wild = fsp->base_fsp->fsp_name->base_name;
        } else {
                wild = smb_fname->base_name;
        }
@@ -323,15 +322,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                fsp->aio_write_behind = True;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &path);
+       status = fsp_set_smb_fname(fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
+               fd_close(fsp);
+               errno = map_errno_from_nt_status(status);
                return status;
        }
 
-       string_set(&fsp->fsp_name, path);
-       TALLOC_FREE(path);
-
        fsp->wcp = NULL; /* Write cache pointer. */
 
        DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -1592,7 +1589,12 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        fsp->is_directory = True;
        fsp->posix_open = posix_open;
 
-       string_set(&fsp->fsp_name, smb_dname->base_name);
+       status = fsp_set_smb_fname(fsp, smb_dname);
+       if (!NT_STATUS_IS_OK(status)) {
+               fd_close(fsp);
+               file_free(req, fsp);
+               return status;
+       }
 
        mtimespec = smb_dname->st.st_ex_mtime;
 
index ded7dc672d44e3e5d91ec1dfe5862d8848bd8f00..66eda57a34fd52dcc4c89d57d79235ca7539ea18 100644 (file)
@@ -376,7 +376,7 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
                }
        }
 
-       onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf);
+       onefs_adjust_stat_time(handle->conn, fsp->fsp_name->base_name, sbuf);
        return ret;
 }
 
@@ -600,7 +600,11 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
 
        fake_fs.conn = conn;
        fake_fs.fh = &fake_fh;
-       fake_fs.fsp_name = SMB_STRDUP(fname);
+       status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+                                           &fake_fs.fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
 
        /* Iterate over the streams in the ADS directory. */
        while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) {
@@ -667,7 +671,7 @@ out:
                close(base_fd);
        }
 
-       SAFE_FREE(fake_fs.fsp_name);
+       TALLOC_FREE(fake_fs.fsp_name);
        return status;
 }
 
index 64ad3e1a788ad6d8386b95ebecb4c840f3b143f1..ce84bd0e3af122edac2682a59ce6448f4ae0ca27 100644 (file)
@@ -272,27 +272,24 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
 {
        uint8 id_buf[16];
        struct file_id id;
-       SMB_STRUCT_STAT sbuf;
        TDB_DATA data;
        struct db_context *db;
        struct db_record *rec;
        int ret = -1;
 
        DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
-                       (unsigned int)pblob->length, fsp->fsp_name));
+                 (unsigned int)pblob->length, fsp_str_dbg(fsp)));
 
        SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
                return NT_STATUS_INTERNAL_DB_CORRUPTION);
 
        if (fsp->fh->fd != -1) {
-               ret = SMB_VFS_FSTAT(fsp, &sbuf);
+               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
        } else {
                if (fsp->posix_open) {
-                       ret = vfs_lstat_smb_fname(handle->conn, fsp->fsp_name,
-                                                 &sbuf);
+                       ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name);
                } else {
-                       ret = vfs_stat_smb_fname(handle->conn, fsp->fsp_name,
-                                                &sbuf);
+                       ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name);
                }
        }
 
@@ -300,7 +297,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
                return map_nt_error_from_unix(errno);
        }
 
-       id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+       id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st);
 
        /* For backwards compatibility only store the dev/inode. */
        push_file_id_16((char *)id_buf, &id);
@@ -381,7 +378,7 @@ static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle,
        NTSTATUS status;
 
        if (fsp && name == NULL) {
-               name = fsp->fsp_name;
+               name = fsp->fsp_name->base_name;
        }
 
        DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name));
@@ -450,7 +447,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
 *********************************************************************/
 
 static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
-                                       const char *fname,
+                                       struct smb_filename *smb_fname,
                                        files_struct *fsp,
                                        bool container)
 {
@@ -462,7 +459,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        size_t size;
        char *parent_name;
 
-       if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+       if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -508,25 +505,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        }
 
        if (!psd || psd->dacl == NULL) {
-               SMB_STRUCT_STAT sbuf;
                int ret;
 
                TALLOC_FREE(psd);
                if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
                } else {
                        if (fsp && fsp->posix_open) {
-                               ret = vfs_lstat_smb_fname(handle->conn,fname,
-                                                         &sbuf);
+                               ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
                        } else {
-                               ret = vfs_stat_smb_fname(handle->conn,fname,
-                                                        &sbuf);
+                               ret = SMB_VFS_STAT(handle->conn, smb_fname);
                        }
                }
                if (ret == -1) {
                        return map_nt_error_from_unix(errno);
                }
-               psd = default_file_sd(ctx, &sbuf);
+               psd = default_file_sd(ctx, &smb_fname->st);
                if (!psd) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -544,7 +538,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        if (fsp) {
                return store_acl_blob_fsp(handle, fsp, &blob);
        } else {
-               return store_acl_blob_pathname(handle, fname, &blob);
+               return store_acl_blob_pathname(handle, smb_fname->base_name,
+                                              &blob);
        }
 }
 
@@ -561,19 +556,11 @@ static int open_acl_tdb(vfs_handle_struct *handle,
        uint32_t access_granted = 0;
        struct security_descriptor *pdesc = NULL;
        bool file_existed = true;
-       char *fname = NULL;
        NTSTATUS status;
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
        status = get_nt_acl_tdb_internal(handle,
                                        NULL,
-                                       fname,
+                                       smb_fname->base_name,
                                        (OWNER_SECURITY_INFORMATION |
                                         GROUP_SECURITY_INFORMATION |
                                         DACL_SECURITY_INFORMATION),
@@ -605,10 +592,13 @@ static int open_acl_tdb(vfs_handle_struct *handle,
 
        if (!file_existed && fsp->fh->fd != -1) {
                /* File was created. Inherit from parent directory. */
-               string_set(&fsp->fsp_name, fname);
-               inherit_new_acl(handle, fname, fsp, false);
+               status = fsp_set_smb_fname(fsp, smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+               inherit_new_acl(handle, smb_fname, fsp, false);
        }
-
        return fsp->fh->fd;
 }
 
@@ -659,13 +649,24 @@ static int unlink_acl_tdb(vfs_handle_struct *handle,
 
 static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode)
 {
+       struct smb_filename *smb_fname = NULL;
        int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+       NTSTATUS status;
 
        if (ret == -1) {
                return ret;
        }
+
+       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
        /* New directory - inherit from parent. */
-       inherit_new_acl(handle, path, NULL, true);
+       inherit_new_acl(handle, smb_fname, NULL, true);
+       TALLOC_FREE(smb_fname);
        return ret;
 }
 
@@ -713,15 +714,14 @@ static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
        if (NT_STATUS_IS_OK(status)) {
                if (DEBUGLEVEL >= 10) {
                        DEBUG(10,("fget_nt_acl_tdb: returning tdb sd for file %s\n",
-                               fsp->fsp_name));
+                                 fsp_str_dbg(fsp)));
                        NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
                }
                return NT_STATUS_OK;
        }
 
        DEBUG(10,("fget_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n",
-                       fsp->fsp_name,
-                       nt_errstr(status) ));
+                 fsp_str_dbg(fsp), nt_errstr(status)));
 
        return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
                        security_info, ppdesc);
@@ -765,7 +765,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
 
        if (DEBUGLEVEL >= 10) {
                DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n",
-                       fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor,
                        CONST_DISCARD(struct security_descriptor *,psd));
        }
@@ -778,7 +778,6 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
        /* Ensure owner and group are set. */
        if (!psd->owner_sid || !psd->group_sid) {
                int ret;
-               SMB_STRUCT_STAT sbuf;
                DOM_SID owner_sid, group_sid;
                struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
 
@@ -787,23 +786,19 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
                }
                if (fsp->is_directory || fsp->fh->fd == -1) {
                        if (fsp->posix_open) {
-                               ret = vfs_lstat_smb_fname(fsp->conn,
-                                                         fsp->fsp_name,
-                                                         &sbuf);
+                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                        } else {
-                               ret = vfs_stat_smb_fname(fsp->conn,
-                                                        fsp->fsp_name,
-                                                        &sbuf);
+                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
                        }
                } else {
-                       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
                }
                if (ret == -1) {
                        /* Lower level acl set succeeded,
                         * so still return OK. */
                        return NT_STATUS_OK;
                }
-               create_file_sids(&sbuf, &owner_sid, &group_sid);
+               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
                /* This is safe as nc_psd is discarded at fn exit. */
                nc_psd->owner_sid = &owner_sid;
                nc_psd->group_sid = &group_sid;
@@ -831,7 +826,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
 
        if (DEBUGLEVEL >= 10) {
                DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n",
-                       fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor,
                        CONST_DISCARD(struct security_descriptor *,psd));
        }
@@ -913,7 +908,6 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
                             files_struct *fsp,
                             SMB_ACL_T theacl)
 {
-       SMB_STRUCT_STAT sbuf;
        struct db_context *db;
        int ret;
 
@@ -921,14 +915,12 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
 
        if (fsp->is_directory || fsp->fh->fd == -1) {
                if (fsp->posix_open) {
-                       ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name,
-                                                 &sbuf);
+                       ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                } else {
-                       ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name,
-                                                &sbuf);
+                       ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
                }
        } else {
-               ret = SMB_VFS_FSTAT(fsp, &sbuf);
+               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
        }
        if (ret == -1) {
                return -1;
@@ -941,7 +933,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
                return -1;
        }
 
-       acl_tdb_delete(handle, db, &sbuf);
+       acl_tdb_delete(handle, db, &fsp->fsp_name->st);
        return 0;
 }
 
index 66bf21c4f73501797146f63c0b77b8b70ed449b1..b18bc658ffc4ce972e84ae2e3413c095ffcd0658 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+                       DATA_BLOB *pblob,
+                       uint8_t hash[16]);
+
+#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
+                               GROUP_SECURITY_INFORMATION | \
+                               DACL_SECURITY_INFORMATION | \
+                               SACL_SECURITY_INFORMATION)
+
+/*******************************************************************
+ Hash a security descriptor.
+*******************************************************************/
+
+static NTSTATUS hash_sd(struct security_descriptor *psd,
+                       uint8_t hash[16])
+{
+       DATA_BLOB blob;
+       struct MD5Context tctx;
+       NTSTATUS status;
+
+       memset(hash, '\0', 16);
+       status = create_acl_blob(psd, &blob, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       MD5Init(&tctx);
+       MD5Update(&tctx, blob.data, blob.length);
+       MD5Final(hash, &tctx);
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  Parse out a struct security_descriptor from a DATA_BLOB.
 *******************************************************************/
 
 static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
                                uint32 security_info,
-                               struct security_descriptor **ppdesc)
+                               struct security_descriptor **ppdesc,
+                               uint8_t hash[16])
 {
        TALLOC_CTX *ctx = talloc_tos();
        struct xattr_NTACL xacl;
@@ -64,6 +96,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
                        ? xacl.info.sd_hs->sd->dacl : NULL,
                        &sd_size);
 
+       memcpy(hash, xacl.info.sd_hs->hash, 16);
        TALLOC_FREE(xacl.info.sd);
 
        return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
@@ -131,7 +164,9 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
  Create a DATA_BLOB from a security descriptor.
 *******************************************************************/
 
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+                       DATA_BLOB *pblob,
+                       uint8_t hash[16])
 {
        struct xattr_NTACL xacl;
        struct security_descriptor_hash sd_hs;
@@ -144,7 +179,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB
        xacl.version = 2;
        xacl.info.sd_hs = &sd_hs;
        xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd);
-       memset(&xacl.info.sd_hs->hash[0], '\0', 16);
+       memcpy(&xacl.info.sd_hs->hash[0], hash, 16);
 
        ndr_err = ndr_push_struct_blob(
                        pblob, ctx, NULL, &xacl,
@@ -171,14 +206,14 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
        int saved_errno = 0;
 
        DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
-                       (unsigned int)pblob->length, fsp->fsp_name));
+                 (unsigned int)pblob->length, fsp_str_dbg(fsp)));
 
        become_root();
        if (fsp->fh->fd != -1) {
                ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
                        pblob->data, pblob->length, 0);
        } else {
-               ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
+               ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
                                XATTR_NTACL_NAME,
                                pblob->data, pblob->length, 0);
        }
@@ -190,7 +225,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
                errno = saved_errno;
                DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
                        "with error %s\n",
-                       fsp->fsp_name,
+                       fsp_str_dbg(fsp),
                        strerror(errno) ));
                return map_nt_error_from_unix(errno);
        }
@@ -242,29 +277,86 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
                                        uint32 security_info,
                                        struct security_descriptor **ppdesc)
 {
-       TALLOC_CTX *ctx = talloc_tos();
        DATA_BLOB blob;
        NTSTATUS status;
+       uint8_t hash[16];
+       uint8_t hash_tmp[16];
+       struct security_descriptor *pdesc_next = NULL;
 
        if (fsp && name == NULL) {
-               name = fsp->fsp_name;
+               name = fsp->fsp_name->base_name;
        }
 
        DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name));
 
-       status = get_acl_blob(ctx, handle, fsp, name, &blob);
+       status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
                return status;
        }
 
-       status = parse_acl_blob(&blob, security_info, ppdesc);
+       status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("parse_acl_blob returned %s\n",
                                nt_errstr(status)));
                return status;
        }
 
+       /* If there was no stored hash, don't check. */
+       memset(&hash_tmp[0], '\0', 16);
+       if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+               /* No hash, goto return blob sd. */
+               goto out;
+       }
+
+       /* Get the full underlying sd, then hash. */
+       if (fsp) {
+               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       } else {
+               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+                               name,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       status = hash_sd(pdesc_next, hash_tmp);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+               TALLOC_FREE(pdesc_next);
+               /* Hash matches, return blob sd. */
+               goto out;
+       }
+
+       /* Hash doesn't match, return underlying sd. */
+
+       if (!(security_info & OWNER_SECURITY_INFORMATION)) {
+               pdesc_next->owner_sid = NULL;
+       }
+       if (!(security_info & GROUP_SECURITY_INFORMATION)) {
+               pdesc_next->group_sid = NULL;
+       }
+       if (!(security_info & DACL_SECURITY_INFORMATION)) {
+               pdesc_next->dacl = NULL;
+       }
+       if (!(security_info & SACL_SECURITY_INFORMATION)) {
+               pdesc_next->sacl = NULL;
+       }
+
+       TALLOC_FREE(*ppdesc);
+       *ppdesc = pdesc_next;
+
+  out:
+
        TALLOC_FREE(blob.data);
        return status;
 }
@@ -316,7 +408,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
 *********************************************************************/
 
 static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
-                                       const char *fname,
+                                       struct smb_filename *smb_fname,
                                        files_struct *fsp,
                                        bool container)
 {
@@ -324,11 +416,13 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        NTSTATUS status;
        struct security_descriptor *parent_desc = NULL;
        struct security_descriptor *psd = NULL;
+       struct security_descriptor *pdesc_next = NULL;
        DATA_BLOB blob;
        size_t size;
        char *parent_name;
+       uint8_t hash[16];
 
-       if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+       if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -374,25 +468,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        }
 
        if (!psd || psd->dacl == NULL) {
-               SMB_STRUCT_STAT sbuf;
                int ret;
 
                TALLOC_FREE(psd);
                if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
-                       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
                } else {
                        if (fsp && fsp->posix_open) {
-                               ret = vfs_lstat_smb_fname(handle->conn, fname,
-                                                         &sbuf);
+                               ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
                        } else {
-                               ret = vfs_stat_smb_fname(handle->conn, fname,
-                                                        &sbuf);
+                               ret = SMB_VFS_STAT(handle->conn, smb_fname);
                        }
                }
                if (ret == -1) {
                        return map_nt_error_from_unix(errno);
                }
-               psd = default_file_sd(ctx, &sbuf);
+               psd = default_file_sd(ctx, &smb_fname->st);
                if (!psd) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -403,14 +494,36 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
                }
        }
 
-       status = create_acl_blob(psd, &blob);
+       /* Object exists. Read the current SD to get the hash. */
+       if (fsp) {
+               status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       } else {
+               status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+                               smb_fname->base_name,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = hash_sd(pdesc_next, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       status = create_acl_blob(psd, &blob, hash);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
        if (fsp) {
                return store_acl_blob_fsp(handle, fsp, &blob);
        } else {
-               return store_acl_blob_pathname(handle, fname, &blob);
+               return store_acl_blob_pathname(handle, smb_fname->base_name,
+                                              &blob);
        }
 }
 
@@ -430,6 +543,13 @@ static int open_acl_xattr(vfs_handle_struct *handle,
        char *fname = NULL;
        NTSTATUS status;
 
+       if (fsp->base_fsp) {
+               /* Stream open. Base filename open already did the ACL check. */
+               DEBUG(10,("open_acl_xattr: stream open on %s\n",
+                       smb_fname_str_dbg(smb_fname) ));
+               return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+       }
+
        status = get_full_smb_filename(talloc_tos(), smb_fname,
                                       &fname);
        if (!NT_STATUS_IS_OK(status)) {
@@ -471,8 +591,12 @@ static int open_acl_xattr(vfs_handle_struct *handle,
 
        if (!file_existed && fsp->fh->fd != -1) {
                /* File was created. Inherit from parent directory. */
-               string_set(&fsp->fsp_name, fname);
-               inherit_new_acl(handle, fname, fsp, false);
+               status = fsp_set_smb_fname(fsp, smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       errno = map_errno_from_nt_status(status);
+                       return -1;
+               }
+               inherit_new_acl(handle, smb_fname, fsp, false);
        }
 
        return fsp->fh->fd;
@@ -480,13 +604,24 @@ static int open_acl_xattr(vfs_handle_struct *handle,
 
 static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode)
 {
+       struct smb_filename *smb_fname = NULL;
        int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+       NTSTATUS status;
 
        if (ret == -1) {
                return ret;
        }
+
+       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
        /* New directory - inherit from parent. */
-       inherit_new_acl(handle, path, NULL, true);
+       inherit_new_acl(handle, smb_fname, NULL, true);
+       TALLOC_FREE(smb_fname);
        return ret;
 }
 
@@ -497,23 +632,8 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m
 static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
         uint32 security_info, struct security_descriptor **ppdesc)
 {
-       NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
+       return get_nt_acl_xattr_internal(handle, fsp,
                                NULL, security_info, ppdesc);
-       if (NT_STATUS_IS_OK(status)) {
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n",
-                               fsp->fsp_name));
-                       NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
-               }
-               return NT_STATUS_OK;
-       }
-
-       DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
-                       fsp->fsp_name,
-                       nt_errstr(status) ));
-
-       return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
-                       security_info, ppdesc);
 }
 
 /*********************************************************************
@@ -523,23 +643,8 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
 static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
         const char *name, uint32 security_info, struct security_descriptor **ppdesc)
 {
-       NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
+       return get_nt_acl_xattr_internal(handle, NULL,
                                name, security_info, ppdesc);
-       if (NT_STATUS_IS_OK(status)) {
-               if (DEBUGLEVEL >= 10) {
-                       DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n",
-                               name));
-                       NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
-               }
-               return NT_STATUS_OK;
-       }
-
-       DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
-                       name,
-                       nt_errstr(status) ));
-
-       return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
-                       security_info, ppdesc);
 }
 
 /*********************************************************************
@@ -551,23 +656,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
 {
        NTSTATUS status;
        DATA_BLOB blob;
+       struct security_descriptor *pdesc_next = NULL;
+       uint8_t hash[16];
 
        if (DEBUGLEVEL >= 10) {
                DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
-                       fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor,
                        CONST_DISCARD(struct security_descriptor *,psd));
        }
 
-       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
        /* Ensure owner and group are set. */
        if (!psd->owner_sid || !psd->group_sid) {
                int ret;
-               SMB_STRUCT_STAT sbuf;
                DOM_SID owner_sid, group_sid;
                struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
 
@@ -576,23 +677,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                }
                if (fsp->is_directory || fsp->fh->fd == -1) {
                        if (fsp->posix_open) {
-                               ret = vfs_lstat_smb_fname(fsp->conn,
-                                                         fsp->fsp_name,
-                                                         &sbuf);
+                               ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                        } else {
-                               ret = vfs_stat_smb_fname(fsp->conn,
-                                                        fsp->fsp_name,
-                                                        &sbuf);
+                               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
                        }
                } else {
-                       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+                       ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
                }
                if (ret == -1) {
                        /* Lower level acl set succeeded,
                         * so still return OK. */
                        return NT_STATUS_OK;
                }
-               create_file_sids(&sbuf, &owner_sid, &group_sid);
+               create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
                /* This is safe as nc_psd is discarded at fn exit. */
                nc_psd->owner_sid = &owner_sid;
                nc_psd->group_sid = &group_sid;
@@ -600,6 +697,26 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                psd = nc_psd;
        }
 
+       status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /* Get the full underlying sd, then hash. */
+       status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+                               fsp,
+                               HASH_SECURITY_INFO,
+                               &pdesc_next);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = hash_sd(pdesc_next, hash);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
 #if 0
        if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
                        psd->dacl != NULL &&
@@ -620,11 +737,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
 
        if (DEBUGLEVEL >= 10) {
                DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
-                       fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor,
                        CONST_DISCARD(struct security_descriptor *,psd));
        }
-       create_acl_blob(psd, &blob);
+       create_acl_blob(psd, &blob, hash);
        store_acl_blob_fsp(handle, fsp, &blob);
 
        return NT_STATUS_OK;
index 55371c60f5e767094483f09e0f768d6dfb2042c0..e6f43c96809f258363a2fefbc856489954ec8c8e 100644 (file)
@@ -655,18 +655,17 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
 
 static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
                            struct connection_struct *conn,
-                           const char *name,
+                           struct smb_filename *smb_fname,
                            uint32 security_info,
                            struct security_descriptor **ppdesc)
 {
-       SMB_STRUCT_STAT sbuf;
-
        /* Get the stat struct for the owner info. */
-       if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
+       if(SMB_VFS_STAT(conn, smb_fname) != 0) {
                return 0;
        }
 
-       return afs_to_nt_acl_common(afs_acl, &sbuf, security_info, ppdesc);
+       return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info,
+                                   ppdesc);
 }
 
 static size_t afs_fto_nt_acl(struct afs_acl *afs_acl,
@@ -905,7 +904,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        ZERO_STRUCT(dir_acl);
        ZERO_STRUCT(file_acl);
 
-       name = talloc_strdup(talloc_tos(), fsp->fsp_name);
+       name = talloc_strdup(talloc_tos(), fsp->fsp_name->base_name);
        if (!name) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -925,7 +924,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        }
 
        if (!afs_get_afs_acl(name, &old_afs_acl)) {
-               DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name));
+               DEBUG(3, ("Could not get old ACL of %s\n", fsp_str_dbg(fsp)));
                goto done;
        }
 
@@ -941,7 +940,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                }
 
                free_afs_acl(&dir_acl);
-               if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+               if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+                                  security_info_sent, psd,
                                   nt_to_afs_dir_rights, &dir_acl))
                        goto done;
        } else {
@@ -956,7 +956,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                }
 
                free_afs_acl(&file_acl);
-               if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+               if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+                                  security_info_sent, psd,
                                   nt_to_afs_file_rights, &file_acl))
                        goto done;
        }
@@ -997,11 +998,11 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle,
        struct afs_acl acl;
        size_t sd_size;
 
-       DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp->fsp_name));
+       DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp_str_dbg(fsp)));
 
        sidpts = lp_parm_bool(SNUM(fsp->conn), "afsacl", "sidpts", False);
 
-       if (!afs_get_afs_acl(fsp->fsp_name, &acl)) {
+       if (!afs_get_afs_acl(fsp->fsp_name->base_name, &acl)) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -1018,6 +1019,8 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle,
 {
        struct afs_acl acl;
        size_t sd_size;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        DEBUG(5, ("afsacl_get_nt_acl: %s\n", name));
 
@@ -1027,8 +1030,16 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       sd_size = afs_to_nt_acl(&acl, handle->conn, name, security_info,
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               free_afs_acl(&acl);
+               return status;
+       }
+
+       sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info,
                                ppdesc);
+       TALLOC_FREE(smb_fname);
 
        free_afs_acl(&acl);
 
index 5ebc3a12f892294869fcce2ddd67a7e2dd733f5e..01de33ed0bd902a0d525e4e00422e9579357fa5f 100644 (file)
@@ -162,7 +162,8 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle,
        bool    retryPosix = False;
 
        *ppdesc = NULL;
-       result = aixjfs2_get_nfs4_acl(fsp->fsp_name, &pacl, &retryPosix);
+       result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl,
+                                     &retryPosix);
        if (retryPosix)
        {
                DEBUG(10, ("retrying with posix acl...\n"));
@@ -258,7 +259,7 @@ SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle,
         acl_type_t aixjfs2_type;
         aixjfs2_type.u64 = ACL_AIXC;
 
-       return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type);
+       return aixjfs2_get_posix_acl(fsp->fsp_name->base_name, aixjfs2_type);
 }
 
 /*
@@ -304,7 +305,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
        int     rc;
        acl_type_t      acltype;
 
-       DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name));
+       DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp)));
 
        /* no need to be freed which is alloced with mem_ctx */
        mem_ctx = talloc_tos();
@@ -353,7 +354,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
 
        /* won't set S_ISUID - the only one JFS2/NFS4 accepts */
        rc = aclx_put(
-               fsp->fsp_name,
+               fsp->fsp_name->base_name,
                SET_ACL, /* set only the ACL, not mode bits */
                acltype, /* not a pointer !!! */
                jfs2acl,
@@ -444,9 +445,10 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
        acl_type_t      acl_type_info;
        int     rc;
 
-       DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name));
+       DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp_str_dbg(fsp)));
 
-       rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info);
+       rc = aixjfs2_query_acl_support(fsp->fsp_name->base_name, ACL_AIXC,
+                                      &acl_type_info);
        if (rc) {
                DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
                return -1;
@@ -466,7 +468,7 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
        );
        if (rc) {
                DEBUG(2, ("aclx_fput failed with %s for %s\n",
-                       strerror(errno), fsp->fsp_name));
+                       strerror(errno), fsp_str_dbg(fsp)));
                return -1;
        }
 
index cf2e27301db040d9ba80829f1b522f202ca9f5ab..dab3d78ceceece668e421c57623a70bb4d0b3464 100644 (file)
@@ -237,7 +237,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod
        result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
 
        syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
-              fsp->fsp_name, mode,
+              fsp->fsp_name->base_name, mode,
               (result < 0) ? "failed: " : "",
               (result < 0) ? strerror(errno) : "");
 
@@ -251,7 +251,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t
        result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
 
        syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
-              fsp->fsp_name, mode,
+              fsp->fsp_name->base_name, mode,
               (result < 0) ? "failed: " : "",
               (result < 0) ? strerror(errno) : "");
 
index 71b850505a7232033458923d5d5793a9b740ccf5..3997dcbcfc90031a36515e9b0342a205536c2309 100644 (file)
@@ -72,7 +72,7 @@ static bool prime_cache(
         DEBUG(module_debug,
             ("%s: doing readahead of %lld bytes at %lld for %s\n",
             MODULE, (long long)g_readsz, (long long)*last,
-            fsp->fsp_name));
+           fsp_str_dbg(fsp)));
 
         nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last);
         if (nread < 0) {
index 7e363b6be77ef6ca3201c35fdc877fe43d09ce8e..aa77da7cd724d2329a84d68cc5abd0ce26b16eb8 100644 (file)
@@ -53,7 +53,9 @@ static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname,
        return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
 }
 
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle,
+                                     SMB_STRUCT_DIR *dirp,
+                                     SMB_STRUCT_STAT *sbuf)
 {
        SMB_STRUCT_DIRENT *result;
        SMB_STRUCT_DIRENT *newdirent;
@@ -334,7 +336,8 @@ static int cap_ntimes(vfs_handle_struct *handle,
 }
 
 
-static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
+                      const char *newpath)
 {
        char *capold = capencode(talloc_tos(), oldpath);
        char *capnew = capencode(talloc_tos(), newpath);
@@ -346,7 +349,8 @@ static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const ch
        return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
 }
 
-static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle, const char *path,
+                       char *buf, size_t bufsiz)
 {
        char *cappath = capencode(talloc_tos(), path);
 
index 1fd101282cda4579e7f2f46385d7575df052a749..3b691c03503eae1c98e6926548bee0fe20cc4934 100644 (file)
@@ -103,7 +103,8 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
 }
 
 static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
-                                       SMB_STRUCT_DIR *dirp)
+                                       SMB_STRUCT_DIR *dirp,
+                                       SMB_STRUCT_STAT *sbuf)
 {
        SMB_STRUCT_DIRENT *result = NULL;
        SMB_STRUCT_DIRENT *newdirent = NULL;
index c4db8fa393f6ed6209b44fc0de58a5dabee65456..cdfd28c57110615a72cba04cb0fa695a33da378c 100644 (file)
@@ -218,27 +218,17 @@ static int vfswrap_open(vfs_handle_struct *handle,
                        struct smb_filename *smb_fname,
                        files_struct *fsp, int flags, mode_t mode)
 {
-       int result;
-       NTSTATUS status;
-       char *fname = NULL;
+       int result = -1;
 
        START_PROFILE(syscall_open);
 
-       /*
-        * XXX: Should an error be returned if there is a stream rather than
-        * trying to open a filename with a ':'?
-        */
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
        }
 
-       result = sys_open(fname, flags, mode);
-
-       TALLOC_FREE(fname);
-
+       result = sys_open(smb_fname->base_name, flags, mode);
+ out:
        END_PROFILE(syscall_open);
        return result;
 }
@@ -562,23 +552,17 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
 static int vfswrap_stat(vfs_handle_struct *handle,
                        struct smb_filename *smb_fname)
 {
-       int result;
-       NTSTATUS status;
-       char *fname = NULL;
+       int result = -1;
 
        START_PROFILE(syscall_stat);
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
        }
 
-       result = sys_stat(fname, &smb_fname->st);
-
-       TALLOC_FREE(fname);
-
+       result = sys_stat(smb_fname->base_name, &smb_fname->st);
+ out:
        END_PROFILE(syscall_stat);
        return result;
 }
@@ -596,23 +580,17 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC
 static int vfswrap_lstat(vfs_handle_struct *handle,
                         struct smb_filename *smb_fname)
 {
-       int result;
-       NTSTATUS status;
-       char *fname = NULL;
+       int result = -1;
 
        START_PROFILE(syscall_lstat);
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
        }
 
-       result = sys_lstat(fname, &smb_fname->st);
-
-       TALLOC_FREE(fname);
-
+       result = sys_lstat(smb_fname->base_name, &smb_fname->st);
+ out:
        END_PROFILE(syscall_lstat);
        return result;
 }
@@ -866,7 +844,9 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
                uint64_t space_avail;
                uint64_t bsize,dfree,dsize;
 
-               space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+               space_avail = get_dfree_info(fsp->conn,
+                                            fsp->fsp_name->base_name, false,
+                                            &bsize, &dfree, &dsize);
                /* space_avail is 1k blocks */
                if (space_avail == (uint64_t)-1 ||
                                ((uint64_t)space_to_write/1024 > space_avail) ) {
@@ -1102,7 +1082,8 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
        return NT_STATUS_OK;
 }
 
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
+                          unsigned int flags)
 {
 #ifdef HAVE_CHFLAGS
        return chflags(path, flags);
@@ -1113,7 +1094,7 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag
 }
 
 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
-                                            SMB_STRUCT_STAT *sbuf)
+                                            const SMB_STRUCT_STAT *sbuf)
 {
        struct file_id key;
 
index 53d1820c11a1f816b178ec3587d5259fff664b1a..f6fc9256d07bba844d1a16ed2a4a01446b43ad56 100644 (file)
@@ -113,7 +113,8 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
 }
 
 static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle,
-                                         SMB_STRUCT_DIR *dirp)
+                                         SMB_STRUCT_DIR *dirp,
+                                         SMB_STRUCT_STAT *sbuf)
 {
        struct dirsort_privates *data = NULL;
        time_t current_mtime;
index 68b85516ea6a9f748da7d80dc2325d9ceb1692d1..c9d1862fa442a04fa98c3b359dfb3ea8e8517ec0 100644 (file)
@@ -304,12 +304,12 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod
 
        if (lp_syslog() > 0) {
                syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
-                      fsp->fsp_name, mode,
+                      fsp->fsp_name->base_name, mode,
                       (result < 0) ? "failed: " : "",
                       (result < 0) ? strerror(errno) : "");
        }
        DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
-              fsp->fsp_name,  (unsigned int)mode,
+              fsp_str_dbg(fsp), (unsigned int)mode,
               (result < 0) ? "failed: " : "",
               (result < 0) ? strerror(errno) : ""));
 
@@ -324,12 +324,12 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t
 
        if (lp_syslog() > 0) {
                syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
-                      fsp->fsp_name, mode,
+                      fsp->fsp_name->base_name, mode,
                       (result < 0) ? "failed: " : "",
                       (result < 0) ? strerror(errno) : "");
        }
        DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
-              fsp->fsp_name,  (unsigned int)mode,
+               fsp_str_dbg(fsp),  (unsigned int)mode,
               (result < 0) ? "failed: " : "",
               (result < 0) ? strerror(errno) : ""));
 
index e8702aa2c8fb06744c47db86ab6d8a4aec18652a..76fbc8a8aeaaef7e63157a7064054edcc9482111 100644 (file)
@@ -419,6 +419,13 @@ static const char *smb_fname_str_do_log(const struct smb_filename *smb_fname)
        return fname;
 }
 
+/**
+ * Return an fsp debug string using the do_log_ctx()
+ */
+static const char *fsp_str_do_log(const struct files_struct *fsp)
+{
+       return smb_fname_str_do_log(fsp->fsp_name);
+}
 
 /* Free function for the private data. */
 
@@ -561,7 +568,7 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
 {
        int result;
 
@@ -736,7 +743,8 @@ static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp)
        
        result = SMB_VFS_NEXT_CLOSE(handle, fsp);
 
-       do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -748,7 +756,8 @@ static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp,
 
        result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
 
-       do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -760,7 +769,8 @@ static ssize_t smb_full_audit_pread(vfs_handle_struct *handle, files_struct *fsp
 
        result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
 
-       do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -772,7 +782,8 @@ static ssize_t smb_full_audit_write(vfs_handle_struct *handle, files_struct *fsp
 
        result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
 
-       do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -785,7 +796,8 @@ static ssize_t smb_full_audit_pwrite(vfs_handle_struct *handle, files_struct *fs
 
        result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
 
-       do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -798,7 +810,7 @@ static SMB_OFF_T smb_full_audit_lseek(vfs_handle_struct *handle, files_struct *f
        result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
 
        do_log(SMB_VFS_OP_LSEEK, (result != (ssize_t)-1), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -813,7 +825,7 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd,
        result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n);
 
        do_log(SMB_VFS_OP_SENDFILE, (result >= 0), handle,
-              "%s", fromfsp->fsp_name);
+              "%s", fsp_str_do_log(fromfsp));
 
        return result;
 }
@@ -828,7 +840,7 @@ static ssize_t smb_full_audit_recvfile(vfs_handle_struct *handle, int fromfd,
        result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n);
 
        do_log(SMB_VFS_OP_RECVFILE, (result >= 0), handle,
-              "%s", tofsp->fsp_name);
+              "%s", fsp_str_do_log(tofsp));
 
        return result;
 }
@@ -854,7 +866,8 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp)
        
        result = SMB_VFS_NEXT_FSYNC(handle, fsp);
 
-       do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;    
 }
@@ -879,7 +892,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
        
        result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
 
-       do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -897,7 +911,7 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle,
        return result;    
 }
 
-static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
+static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
                       files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
 {
        int result;
@@ -942,7 +956,7 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp,
        result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
 
        do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle,
-              "%s|%o", fsp->fsp_name, mode);
+              "%s|%o", fsp_str_do_log(fsp), mode);
 
        return result;
 }
@@ -968,7 +982,7 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp,
        result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
 
        do_log(SMB_VFS_OP_FCHOWN, (result >= 0), handle, "%s|%ld|%ld",
-              fsp->fsp_name, (long int)uid, (long int)gid);
+              fsp_str_do_log(fsp), (long int)uid, (long int)gid);
 
        return result;
 }
@@ -1032,7 +1046,7 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp
        result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len);
 
        do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1044,7 +1058,7 @@ static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
 
        result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
 
-       do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1058,7 +1072,7 @@ static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode);
 
        do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s",
-              fsp->fsp_name);
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1071,7 +1085,7 @@ static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct
         result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
 
         do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s",
-               fsp->fsp_name);
+              fsp_str_do_log(fsp));
 
         return result;
 }
@@ -1083,7 +1097,7 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp,
 
        result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
 
-       do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1256,7 +1270,7 @@ static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle
            blocking_lock, blr);
 
        do_log(SMB_VFS_OP_BRL_LOCK_WINDOWS, NT_STATUS_IS_OK(result), handle,
-           "%s:%llu-%llu. type=%d. blocking=%d", br_lck->fsp->fsp_name,
+           "%s:%llu-%llu. type=%d. blocking=%d", fsp_str_do_log(br_lck->fsp),
            plock->start, plock->size, plock->lock_type, blocking_lock );
 
        return result;
@@ -1273,7 +1287,7 @@ static bool smb_full_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
            plock);
 
        do_log(SMB_VFS_OP_BRL_UNLOCK_WINDOWS, (result == 0), handle,
-           "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+           "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
            plock->size, plock->lock_type);
 
        return result;
@@ -1289,7 +1303,7 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr);
 
        do_log(SMB_VFS_OP_BRL_CANCEL_WINDOWS, (result == 0), handle,
-           "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+           "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
            plock->size);
 
        return result;
@@ -1304,7 +1318,7 @@ static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
 
        do_log(SMB_VFS_OP_STRICT_LOCK, result, handle,
-           "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+           "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
            plock->size);
 
        return result;
@@ -1317,7 +1331,7 @@ static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
        SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
 
        do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle,
-           "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+           "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
            plock->size);
 
        return;
@@ -1332,7 +1346,7 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru
        result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc);
 
        do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1360,7 +1374,8 @@ static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_stru
 
        result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
 
-       do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name);
+       do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s",
+              fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1386,7 +1401,7 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs
        result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
 
        do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle,
-              "%s|%o", fsp->fsp_name, mode);
+              "%s|%o", fsp_str_do_log(fsp), mode);
 
        return result;
 }
@@ -1475,7 +1490,7 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
 
        do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1635,7 +1650,7 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct
        result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
 
        do_log(SMB_VFS_OP_SYS_ACL_SET_FD, (result >= 0), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1749,7 +1764,7 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
 
        do_log(SMB_VFS_OP_FGETXATTR, (result >= 0), handle,
-              "%s|%s", fsp->fsp_name, name);
+              "%s|%s", fsp_str_do_log(fsp), name);
 
        return result;
 }
@@ -1787,7 +1802,7 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
 
        do_log(SMB_VFS_OP_FLISTXATTR, (result >= 0), handle,
-              "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1829,7 +1844,7 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
 
        do_log(SMB_VFS_OP_FREMOVEXATTR, (result >= 0), handle,
-              "%s|%s", fsp->fsp_name, name);
+              "%s|%s", fsp_str_do_log(fsp), name);
 
        return result;
 }
@@ -1875,7 +1890,7 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
 
        do_log(SMB_VFS_OP_FSETXATTR, (result >= 0), handle,
-              "%s|%s", fsp->fsp_name, name);
+              "%s|%s", fsp_str_do_log(fsp), name);
 
        return result;
 }
@@ -1886,7 +1901,7 @@ static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct file
 
        result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb);
        do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1897,7 +1912,7 @@ static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct fil
 
        result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb);
        do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1908,7 +1923,7 @@ static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struc
 
        result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb);
        do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1919,7 +1934,7 @@ static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct fi
 
        result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb);
        do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1930,7 +1945,7 @@ static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct fil
 
        result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb);
        do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+              "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1941,7 +1956,7 @@ static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct fil
 
        result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb);
        do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+               "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1952,7 +1967,7 @@ static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct f
 
        result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts);
        do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle,
-               "%s", fsp->fsp_name);
+               "%s", fsp_str_do_log(fsp));
 
        return result;
 }
@@ -1964,7 +1979,7 @@ static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle,
 
        result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
        do_log(SMB_VFS_OP_AIO_FORCE, result, handle,
-               "%s", fsp->fsp_name);
+               "%s", fsp_str_do_log(fsp));
 
        return result;
 }
index 47858cb3527d67da3cf35eebd3ea5794739e5182..cde80f0021b9b5350ac4d0b5e35c692b00ef2bf6 100644 (file)
@@ -303,7 +303,7 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle,
        int     result;
 
        *ppdesc = NULL;
-       result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl);
+       result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
 
        if (result == 0)
                return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl);
@@ -389,7 +389,7 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
                                 "merge_writeappend", True)) {
                        DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
                                  "WRITE^APPEND, setting WRITE|APPEND\n",
-                                 fsp->fsp_name));
+                                 fsp_str_dbg(fsp)));
                        gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
                }
 
@@ -423,7 +423,8 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
                gacl->acl_nace++;
        }
 
-       ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
+       ret = smbd_gpfs_putacl(fsp->fsp_name->base_name,
+                              GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
        if (ret != 0) {
                DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno)));
                gpfs_dumpacl(8, gacl);
@@ -439,12 +440,17 @@ 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, 0);
+       acl = gpfs_getacl_alloc(fsp->fsp_name->base_name, 0);
        if (acl == NULL)
                return result;
 
        if (acl->acl_version&GPFS_ACL_VERSION_NFS4)
        {
+               if ((psd->type&SEC_DESC_DACL_PROTECTED)) {
+                       DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n"));
+                       return NT_STATUS_NOT_SUPPORTED;
+               }
+
                result = smb_set_nt_acl_nfs4(
                        fsp, security_info_sent, psd,
                        gpfsacl_process_smbacl);
@@ -589,7 +595,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
 static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
                                        files_struct *fsp)
 {
-       return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
+       return gpfsacl_get_posix_acl(fsp->fsp_name->base_name,
+                                    GPFS_ACL_TYPE_ACCESS);
 }
 
 static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
@@ -702,7 +709,8 @@ static int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle,
                                  files_struct *fsp,
                                  SMB_ACL_T theacl)
 {
-       return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl);
+       return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name->base_name,
+                                       SMB_ACL_TYPE_ACCESS, theacl);
 }
 
 static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
@@ -759,6 +767,8 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode)
        int     i;
        files_struct    fake_fsp; /* TODO: rationalize parametrization */
        SMB4ACE_T       *smbace;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode));
 
@@ -828,11 +838,19 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode)
 
        /* don't add complementary DENY ACEs here */
        ZERO_STRUCT(fake_fsp);
-       fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */
-
+       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+                                           &fake_fsp.fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
        /* put the acl */
-       if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False)
+       if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) {
+               TALLOC_FREE(fake_fsp.fsp_name);
                return -1;
+       }
+
+       TALLOC_FREE(fake_fsp.fsp_name);
        return 0; /* ok for [f]chmod */
 }
 
@@ -870,7 +888,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t
                         return 0;
                 }
 
-                rc = gpfsacl_emu_chmod(fsp->fsp_name, mode);
+                rc = gpfsacl_emu_chmod(fsp->fsp_name->base_name, mode);
                 if (rc == 1)
                         return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
                 return rc;
index 35341a5c3e3088ec07a5b6ddd3d8233c407958c9..32e8539202de2f66f0a33cea102a74bd26062ae6 100644 (file)
@@ -201,23 +201,23 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
        DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to "
                "hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n"));
 
-        return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name, 
-                       SMB_ACL_TYPE_ACCESS);
+        return hpuxacl_sys_acl_get_file(handle,
+                                       file_struct_p->fsp_name->base_name,
+                                       SMB_ACL_TYPE_ACCESS);
 }
 
 
 int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
-                            const char *name,
+                            struct smb_filename *smb_fname,
                             SMB_ACL_TYPE_T type,
                             SMB_ACL_T theacl)
 {
        int ret = -1;
-       SMB_STRUCT_STAT s;
        HPUX_ACL_T hpux_acl = NULL;
        int count;
        
        DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
-                  name));
+                  smb_fname_str_dbg(smb_fname)));
 
 
        if(hpux_acl_call_present() == False) {
@@ -248,11 +248,11 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
         * that has _not_ been specified in "type" from the file first 
         * and concatenate it with the acl provided.
         */
-       if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) {
+       if (SMB_VFS_STAT(handle->conn, smb_fname) != 0) {
                DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
                goto done;
        }
-       if (S_ISDIR(s.st_ex_mode)) {
+       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
                HPUX_ACL_T other_acl; 
                int other_count;
                SMB_ACL_TYPE_T other_type;
@@ -261,7 +261,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
                        ? SMB_ACL_TYPE_DEFAULT
                        : SMB_ACL_TYPE_ACCESS;
                DEBUGADD(10, ("getting acl from filesystem\n"));
-               if (!hpux_acl_get_file(name, &other_acl, &other_count)) {
+               if (!hpux_acl_get_file(smb_fname->base_name, &other_acl,
+                                      &other_count)) {
                        DEBUG(10, ("error getting acl from directory\n"));
                        goto done;
                }
@@ -289,7 +290,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
        }
        DEBUG(10, ("resulting acl is valid.\n"));
 
-       ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl);
+       ret = acl(CONST_DISCARD(char *, smb_fname->base_name), ACL_SET, count,
+                 hpux_acl);
        if (ret != 0) {
                DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
        }
index 07b32d628cad3641f82e4dae8c857171100ca074..9baed5790a806551404506187ecd4a25a5b1a16f 100644 (file)
@@ -41,7 +41,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
                                 files_struct *fsp);
 
 int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
-                            const char *name,
+                            struct smb_filename *smb_fname,
                             SMB_ACL_TYPE_T type,
                             SMB_ACL_T theacl);
 
index 1f300a055caf34dde35da58387c14bea6dcfb141..7c338e726855d9a324cb9b5f41c391437ef7afcc 100644 (file)
@@ -406,8 +406,8 @@ static int shadow_copy2_lstat(vfs_handle_struct *handle,
 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);
+       if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) {
+               convert_sbuf(handle, fsp->fsp_name->base_name, sbuf);
        }
        return ret;
 }
@@ -549,7 +549,8 @@ 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)
+static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
+                               unsigned int flags)
 {
         SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
 }
index a7fbeadbbe09c06dd8edcf0764b1881949285185..6f7aee0e506aa7d149806fcc8d994b7f1534d495 100644 (file)
@@ -336,11 +336,11 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \
        ssize_t result;
 
        result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
-       DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp_str_dbg(fsp)));
 
        smb_traffic_analyzer_send_data(handle,
                        result,
-                       fsp->fsp_name,
+                       fsp->fsp_name->base_name,
                        false);
        return result;
 }
@@ -353,11 +353,12 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \
 
        result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
 
-       DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n",
+                  fsp_str_dbg(fsp)));
 
        smb_traffic_analyzer_send_data(handle,
                        result,
-                       fsp->fsp_name,
+                       fsp->fsp_name->base_name,
                        false);
 
        return result;
@@ -370,11 +371,12 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \
 
        result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
 
-       DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n",
+                  fsp_str_dbg(fsp)));
 
        smb_traffic_analyzer_send_data(handle,
                        result,
-                       fsp->fsp_name,
+                       fsp->fsp_name->base_name,
                        true);
        return result;
 }
@@ -386,11 +388,11 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \
 
        result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
 
-       DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp_str_dbg(fsp)));
 
        smb_traffic_analyzer_send_data(handle,
                        result,
-                       fsp->fsp_name,
+                       fsp->fsp_name->base_name,
                        true);
        return result;
 }
index eccc2379c9b1eacd5d64956c677b4a78a8a16f6b..c32c4f3190ec40360bad48232401fba956e308c4 100644 (file)
@@ -128,27 +128,20 @@ static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx,
 static bool streams_xattr_recheck(struct stream_io *sio)
 {
        NTSTATUS status;
-       struct smb_filename *smb_fname = NULL;
        char *xattr_name = NULL;
 
        if (sio->fsp->fsp_name == sio->fsp_name_ptr) {
                return true;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(),
-                                                 sio->fsp->fsp_name, NULL,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return false;
-       }
-
-       if (smb_fname->stream_name == NULL) {
+       if (sio->fsp->fsp_name->stream_name == NULL) {
                /* how can this happen */
                errno = EINVAL;
                return false;
        }
 
-       status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
+       status = streams_xattr_get_name(talloc_tos(),
+                                       sio->fsp->fsp_name->stream_name,
                                        &xattr_name);
        if (!NT_STATUS_IS_OK(status)) {
                return false;
@@ -159,10 +152,9 @@ static bool streams_xattr_recheck(struct stream_io *sio)
        sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
                                        xattr_name);
        sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
-                                 smb_fname->base_name);
+                                 sio->fsp->fsp_name->base_name);
        sio->fsp_name_ptr = sio->fsp->fsp_name;
 
-       TALLOC_FREE(smb_fname);
        TALLOC_FREE(xattr_name);
 
        if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
@@ -899,7 +891,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
                                sio->xattr_name,
                                ea.value.data, ea.value.length, 0);
        } else {
-               ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+               ret = SMB_VFS_SETXATTR(fsp->conn,
+                                      fsp->base_fsp->fsp_name->base_name,
                                sio->xattr_name,
                                ea.value.data, ea.value.length, 0);
        }
@@ -963,8 +956,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
                (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
 
        DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
-               fsp->fsp_name,
-               (double)offset ));
+                  fsp_str_dbg(fsp), (double)offset));
 
        if (sio == NULL) {
                return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
@@ -1004,7 +996,8 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
                                sio->xattr_name,
                                ea.value.data, ea.value.length, 0);
        } else {
-               ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+               ret = SMB_VFS_SETXATTR(fsp->conn,
+                                      fsp->base_fsp->fsp_name->base_name,
                                sio->xattr_name,
                                ea.value.data, ea.value.length, 0);
        }
index 57807105f6b3686969015cdb8a3b581796584dec..753b2bcd26088d8ef2be286f6a3501309f25ec98 100644 (file)
@@ -273,7 +273,7 @@ static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_s
        if(result >= 0) {
                notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                            fsp->fsp_name);
+                            fsp->fsp_name->base_name);
        }
 
        return result;
@@ -307,7 +307,7 @@ static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct
            */
                notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                            fsp->fsp_name);
+                            fsp->fsp_name->base_name);
        }
 
        return result;
@@ -325,7 +325,7 @@ static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struc
            */
                notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                            fsp->fsp_name);
+                            fsp->fsp_name->base_name);
        }
 
        return result;
index a5b0490c8dda577e39e1351e0768fa3ae18ea19c..a92d5dae263a9e75b4bdbdc86a970c25de3d9a6c 100644 (file)
@@ -145,14 +145,14 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
        SMB_ASSERT(i == naces);
 
        /* store acl */
-       if(acl(fsp->fsp_name, ACE_SETACL, naces, acebuf)) {
+       if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
                if(errno == ENOSYS) {
                        DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
                                  "supported on the filesystem where the file "
-                                 "reside", fsp->fsp_name));
+                                 "reside", fsp_str_dbg(fsp)));
                } else {
-                       DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp->fsp_name,
-                                       strerror(errno)));
+                       DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp),
+                                 strerror(errno)));
                }
                return 0;
        }
@@ -180,7 +180,8 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle,
        SMB4ACL_T *pacl;
        NTSTATUS status;
 
-       status = zfs_get_nt_acl_common(fsp->fsp_name, security_info, &pacl);
+       status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info,
+                                      &pacl);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index 848baeff3dbd9f66c12678703b66c9510a31f62d..961e9307280865475d8daa5cdb296b8d69793cd7 100644 (file)
@@ -82,6 +82,8 @@ static void terminate(void)
        /* If there was an async dns child - kill it. */
        kill_async_dns_child();
 
+       gencache_stabilize();
+
        pidfile_unlink();
 
        exit(0);
index 7e4371bf0ba99ece9148bb4eabf9732a4f883a78..dbbd6e327da718e1600c144da02884ce275d9db3 100644 (file)
@@ -5142,6 +5142,9 @@ static char *lp_string(const char *s)
 #if 0
        DEBUG(10, ("lp_string(%s)\n", s));
 #endif
+       if (!s) {
+               return NULL;
+       }
 
        ret = talloc_sub_basic(ctx,
                        get_current_username(),
index 4ed04e4e7a7c5104ab70ef8845f7191e3484d49f..0678181669d3e9259f2bc07650143359ed1f84bb 100644 (file)
@@ -1439,7 +1439,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
        }
 
        /* Change from V1 is addition of password history field. */
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
        if (pwHistLen) {
                uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
                if (!pw_hist) {
@@ -1674,7 +1674,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
                }
        }
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
        if (pwHistLen) {
                uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
                if (!pw_hist) {
@@ -1879,7 +1879,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool
                nt_pw_len = 0;
        }
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
        nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
        if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
                nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
@@ -2085,7 +2085,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
 }
 
 /*********************************************************************
- Update the bad password count checking the AP_RESET_COUNT_TIME 
+ Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
 *********************************************************************/
 
 bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
@@ -2102,7 +2102,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
        }
 
        become_root();
-       res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
+       res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
        unbecome_root();
 
        if (!res) {
@@ -2131,7 +2131,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
 }
 
 /*********************************************************************
- Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION 
+ Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
 *********************************************************************/
 
 bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
@@ -2147,7 +2147,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
        }
 
        become_root();
-       res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
+       res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
        unbecome_root();
 
        if (!res) {
@@ -2199,7 +2199,7 @@ bool pdb_increment_bad_password_count(struct samu *sampass)
 
        /* Retrieve the account lockout policy */
        become_root();
-       ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
+       ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
        unbecome_root();
        if ( !ret ) {
                DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
index eec63728cabcc1094c32c8f12b651e3a0e0da246..70d550042bfea4a89c6a41ed31de63769bf510c7 100644 (file)
@@ -203,7 +203,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
                pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
        }
        if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
-               pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
+               pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
        }
 
        str = tldap_talloc_single_attribute(entry, "displayName",
@@ -250,7 +250,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
                DEBUG(10, ("Could not pull userAccountControl\n"));
                goto fail;
        }
-       pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
+       pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
 
        if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
                if (blob.length != NT_HASH_LEN) {
@@ -310,7 +310,7 @@ static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
 
        ret &= tldap_make_mod_fmt(
                existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
-               "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
+               "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
 
        ret &= tldap_make_mod_fmt(
                existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
@@ -1682,7 +1682,7 @@ static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
                        DEBUG(10, ("no samAccountType"));
                        continue;
                }
-               lsa_attrs[i] = ads_atype_map(attr);
+               lsa_attrs[i] = ds_atype_map(attr);
                num_mapped += 1;
        }
 
@@ -1706,16 +1706,18 @@ static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
 }
 
 static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
-                                          int policy_index, uint32 *value)
+                                          enum pdb_policy_type type,
+                                          uint32_t *value)
 {
-       return account_policy_get(policy_index, value)
+       return account_policy_get(type, value)
                ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
 static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
-                                          int policy_index, uint32 value)
+                                          enum pdb_policy_type type,
+                                          uint32_t value)
 {
-       return account_policy_set(policy_index, value)
+       return account_policy_set(type, value)
                ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
@@ -2022,7 +2024,9 @@ static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
                                         uint32 *num_domains,
                                         struct trustdom_info ***domains)
 {
-       return NT_STATUS_NOT_IMPLEMENTED;
+       *num_domains = 0;
+       *domains = NULL;
+       return NT_STATUS_OK;
 }
 
 static void pdb_ads_init_methods(struct pdb_methods *m)
@@ -2111,7 +2115,7 @@ static void s3_tldap_debug(void *context, enum tldap_debug_level level,
                samba_level = 2;
                break;
        case TLDAP_DEBUG_TRACE:
-               samba_level = 10;
+               samba_level = 11;
                break;
 
        };
index f55b77f675ca80fd3b5171a293b531da2f946ba5..30775e49fe541684f8cbc35db32b3d651a2becc6 100644 (file)
@@ -88,7 +88,7 @@ time_t pdb_get_pass_can_change_time(const struct samu *sampass)
            pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
                return sampass->pass_can_change_time;
 
-       if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
+       if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
                allow = 0;
 
        /* in normal cases, just calculate it from policy */
@@ -112,7 +112,7 @@ time_t pdb_get_pass_must_change_time(const struct samu *sampass)
        if (sampass->acct_ctrl & ACB_PWNOEXP)
                return get_time_t_max();
 
-       if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
+       if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
            || expire == (uint32)-1 || expire == 0) 
                return get_time_t_max();
 
@@ -1013,7 +1013,7 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
        if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
                uchar *pwhistory;
                uint32 pwHistLen;
-               pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+               pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
                if (pwHistLen != 0){
                        uint32 current_history_len;
                        /* We need to make sure we don't have a race condition here - the
index 465a6bf5958f8af61a9a1a8d6604aa5afef11dd7..5d0b625da59d761cb1c7affa8fde858c568c49a6 100644 (file)
@@ -994,25 +994,25 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
 }
 #endif
 
-bool pdb_get_account_policy(int policy_index, uint32 *value)
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        NTSTATUS status;
 
        become_root();
-       status = pdb->get_account_policy(pdb, policy_index, value);
+       status = pdb->get_account_policy(pdb, type, value);
        unbecome_root();
 
        return NT_STATUS_IS_OK(status); 
 }
 
-bool pdb_set_account_policy(int policy_index, uint32 value)
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value)
 {
        struct pdb_methods *pdb = pdb_get_methods();
        NTSTATUS status;
 
        become_root();
-       status = pdb->set_account_policy(pdb, policy_index, value);
+       status = pdb->set_account_policy(pdb, type, value);
        unbecome_root();
 
        return NT_STATUS_IS_OK(status);
@@ -1174,14 +1174,14 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
 {
-       return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+       return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
-static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
 {
-       return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+       return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
 static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
index 35793257697785ac7b6be7150abf864ec0616c74..1b1e22f2c87304c4492fa28e4c8347caf19d96e4 100644 (file)
@@ -336,7 +336,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
                                          const char **attr)
 {
        char *filter = NULL;
-       char *escape_user = escape_ldap_string_alloc(user);
+       char *escape_user = escape_ldap_string(talloc_tos(), user);
        int ret = -1;
 
        if (!escape_user) {
@@ -350,7 +350,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
        filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
                get_objclass_filter(ldap_state->schema_ver));
        if (!filter) {
-               SAFE_FREE(escape_user);
+               TALLOC_FREE(escape_user);
                return LDAP_NO_MEMORY;
        }
        /*
@@ -360,7 +360,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
 
        filter = talloc_all_string_sub(talloc_tos(),
                                filter, "%u", escape_user);
-       SAFE_FREE(escape_user);
+       TALLOC_FREE(escape_user);
        if (!filter) {
                return LDAP_NO_MEMORY;
        }
@@ -902,7 +902,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
        pwHistLen = 0;
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
        if (pwHistLen > 0){
                uint8 *pwhist = NULL;
                int i;
@@ -1327,7 +1327,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                if (need_update(sampass, PDB_PWHISTORY)) {
                        char *pwstr = NULL;
                        uint32 pwHistLen = 0;
-                       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+                       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
 
                        pwstr = SMB_MALLOC_ARRAY(char, 1024);
                        if (!pwstr) {
@@ -1404,7 +1404,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                uint16 badcount = pdb_get_bad_password_count(sampass);
                time_t badtime = pdb_get_bad_password_time(sampass);
                uint32 pol;
-               pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
+               pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
 
                DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
                        (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
@@ -1701,6 +1701,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                char *utf8_password;
                char *utf8_dn;
                size_t converted_size;
+               int ret;
 
                if (!ldap_state->is_nds_ldap) {
 
@@ -1732,14 +1733,31 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                }
 
                if ((ber_printf (ber, "{") < 0) ||
-                   (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn) < 0) ||
-                   (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password) < 0) ||
-                   (ber_printf (ber, "n}") < 0)) {
-                       DEBUG(0,("ldapsam_modify_entry: ber_printf returns a value <0\n"));
-                       ber_free(ber,1);
-                       TALLOC_FREE(utf8_dn);
-                       TALLOC_FREE(utf8_password);
-                       return NT_STATUS_UNSUCCESSFUL;
+                   (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
+                                utf8_dn) < 0)) {
+                       DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+                                "value <0\n"));
+                       ber_free(ber,1);
+                       TALLOC_FREE(utf8_dn);
+                       TALLOC_FREE(utf8_password);
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+
+               if ((utf8_password != NULL) && (*utf8_password != '\0')) {
+                       ret = ber_printf(ber, "ts}",
+                                        LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
+                                        utf8_password);
+               } else {
+                       ret = ber_printf(ber, "}");
+               }
+
+               if (ret < 0) {
+                       DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+                                "value <0\n"));
+                       ber_free(ber,1);
+                       TALLOC_FREE(utf8_dn);
+                       TALLOC_FREE(utf8_password);
+                       return NT_STATUS_UNSUCCESSFUL;
                }
 
                if ((rc = ber_flatten (ber, &bv))<0) {
@@ -2120,18 +2138,18 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
        /* does the entry already exist but without a samba attributes?
           we need to return the samba attributes here */
 
-       escape_user = escape_ldap_string_alloc( username );
+       escape_user = escape_ldap_string(talloc_tos(), username);
        filter = talloc_strdup(attr_list, "(uid=%u)");
        if (!filter) {
                status = NT_STATUS_NO_MEMORY;
                goto fn_exit;
        }
        filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
+       TALLOC_FREE(escape_user);
        if (!filter) {
                status = NT_STATUS_NO_MEMORY;
                goto fn_exit;
        }
-       SAFE_FREE(escape_user);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state,
                                   filter, attr_list, &result);
@@ -2278,7 +2296,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
   fn_exit:
 
        TALLOC_FREE(ctx);
-       SAFE_FREE(escape_user);
        if (result) {
                ldap_msgfree(result);
        }
@@ -2528,7 +2545,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
                                 const char *name)
 {
        char *filter = NULL;
-       char *escape_name = escape_ldap_string_alloc(name);
+       char *escape_name = escape_ldap_string(talloc_tos(), name);
        NTSTATUS status;
 
        if (!escape_name) {
@@ -2540,11 +2557,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
                escape_name) < 0) {
-               SAFE_FREE(escape_name);
+               TALLOC_FREE(escape_name);
                return NT_STATUS_NO_MEMORY;
        }
 
-       SAFE_FREE(escape_name);
+       TALLOC_FREE(escape_name);
        status = ldapsam_getgroup(methods, filter, map);
        SAFE_FREE(filter);
        return status;
@@ -2665,20 +2682,19 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
                for (memberuid = values; *memberuid != NULL; memberuid += 1) {
                        char *escape_memberuid;
 
-                       escape_memberuid = escape_ldap_string_alloc(*memberuid);
+                       escape_memberuid = escape_ldap_string(talloc_tos(),
+                                                             *memberuid);
                        if (escape_memberuid == NULL) {
                                ret = NT_STATUS_NO_MEMORY;
                                goto done;
                        }
 
                        filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
+                       TALLOC_FREE(escape_memberuid);
                        if (filter == NULL) {
-                               SAFE_FREE(escape_memberuid);
                                ret = NT_STATUS_NO_MEMORY;
                                goto done;
                        }
-
-                       SAFE_FREE(escape_memberuid);
                }
 
                filter = talloc_asprintf_append_buffer(filter, "))");
@@ -2812,7 +2828,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       escape_name = escape_ldap_string_alloc(pdb_get_username(user));
+       escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
        if (escape_name == NULL)
                return NT_STATUS_NO_MEMORY;
 
@@ -2950,7 +2966,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
 
  done:
 
-       SAFE_FREE(escape_name);
+       TALLOC_FREE(escape_name);
        return ret;
 }
 
@@ -3764,7 +3780,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
-                                                  int policy_index,
+                                                  enum pdb_policy_type type,
                                                   uint32 value)
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
@@ -3782,7 +3798,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       policy_attr = get_account_policy_attr(policy_index);
+       policy_attr = get_account_policy_attr(type);
        if (policy_attr == NULL) {
                DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
                         "policy\n"));
@@ -3802,7 +3818,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
                return ntstatus;
        }
 
-       if (!cache_account_policy_set(policy_index, value)) {
+       if (!cache_account_policy_set(type, value)) {
                DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
                         "update local tdb cache\n"));
                return ntstatus;
@@ -3812,14 +3828,15 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
-                                          int policy_index, uint32 value)
+                                          enum pdb_policy_type type,
+                                          uint32_t value)
 {
-       return ldapsam_set_account_policy_in_ldap(methods, policy_index,
+       return ldapsam_set_account_policy_in_ldap(methods, type,
                                                  value);
 }
 
 static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
-                                                    int policy_index,
+                                                    enum pdb_policy_type type,
                                                     uint32 *value)
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
@@ -3841,10 +3858,10 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       policy_attr = get_account_policy_attr(policy_index);
+       policy_attr = get_account_policy_attr(type);
        if (!policy_attr) {
                DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
-                        "policy index: %d\n", policy_index));
+                        "policy index: %d\n", type));
                return ntstatus;
        }
 
@@ -3898,17 +3915,18 @@ out:
    Guenther
 */
 static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
-                                          int policy_index, uint32 *value)
+                                          enum pdb_policy_type type,
+                                          uint32_t *value)
 {
        NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
 
-       if (cache_account_policy_get(policy_index, value)) {
+       if (cache_account_policy_get(type, value)) {
                DEBUG(11,("ldapsam_get_account_policy: got valid value from "
                          "cache\n"));
                return NT_STATUS_OK;
        }
 
-       ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index,
+       ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
                                                        value);
        if (NT_STATUS_IS_OK(ntstatus)) {
                goto update_cache;
@@ -3919,27 +3937,27 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
 
 #if 0
        /* should we automagically migrate old tdb value here ? */
-       if (account_policy_get(policy_index, value))
+       if (account_policy_get(type, value))
                goto update_ldap;
 
        DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
-                 "default\n", policy_index));
+                 "default\n", type));
 #endif
 
-       if (!account_policy_get_default(policy_index, value)) {
+       if (!account_policy_get_default(type, value)) {
                return ntstatus;
        }
 
 /* update_ldap: */
 
-       ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
+       ntstatus = ldapsam_set_account_policy(methods, type, *value);
        if (!NT_STATUS_IS_OK(ntstatus)) {
                return ntstatus;
        }
 
  update_cache:
 
-       if (!cache_account_policy_set(policy_index, *value)) {
+       if (!cache_account_policy_set(type, *value)) {
                DEBUG(0,("ldapsam_get_account_policy: failed to update local "
                         "tdb as a cache\n"));
                return NT_STATUS_UNSUCCESSFUL;
@@ -4185,14 +4203,14 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
                goto done;
        }
 
-       escaped = escape_ldap_string_alloc(username);
+       escaped = escape_ldap_string(talloc_tos(), username);
        if (escaped == NULL) goto done;
 
        result = talloc_string_sub(mem_ctx, filter, "%u", username);
 
  done:
        SAFE_FREE(filter);
-       SAFE_FREE(escaped);
+       TALLOC_FREE(escaped);
 
        return result;
 }
@@ -4994,10 +5012,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
                is_machine = True;
        }
 
-       username = escape_ldap_string_alloc(name);
+       username = escape_ldap_string(talloc_tos(), name);
        filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
                                 username, LDAP_OBJ_POSIXACCOUNT);
-       SAFE_FREE(username);
+       TALLOC_FREE(username);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -5270,10 +5288,10 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
        gid_t gid = -1;
        int rc;
 
-       groupname = escape_ldap_string_alloc(name);
+       groupname = escape_ldap_string(talloc_tos(), name);
        filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
                                 groupname, LDAP_OBJ_POSIXGROUP);
-       SAFE_FREE(groupname);
+       TALLOC_FREE(groupname);
 
        rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
        if (rc != LDAP_SUCCESS) {
@@ -5702,7 +5720,8 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
                return NT_STATUS_NO_MEMORY;
        }
 
-       escape_username = escape_ldap_string_alloc(pdb_get_username(sampass));
+       escape_username = escape_ldap_string(talloc_tos(),
+                                            pdb_get_username(sampass));
        if (escape_username== NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -5715,7 +5734,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
                                 LDAP_OBJ_POSIXACCOUNT,
                                 LDAP_OBJ_SAMBASAMACCOUNT);
 
-       SAFE_FREE(escape_username);
+       TALLOC_FREE(escape_username);
 
        if (filter == NULL) {
                return NT_STATUS_NO_MEMORY;
index ec54d553d1d932153e0b2fd3d691319aafa1606a..df80411a7a284c190538497efaf3364f2056a18b 100644 (file)
@@ -167,12 +167,12 @@ done:
        return result;
 }
 
-static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
 {
        return NT_STATUS_UNSUCCESSFUL;
 }
 
-static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
 {
        return NT_STATUS_UNSUCCESSFUL;
 }
@@ -316,13 +316,12 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map
                                 const char *name)
 {
        NTSTATUS result = NT_STATUS_OK;
-       char *user_name = NULL;
-       char *domain = NULL;
+       const char *domain = "";
        DOM_SID sid;
        gid_t gid;
        enum lsa_SidType name_type;
 
-       if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) {
+       if (!winbind_lookup_name(domain, name, &sid, &name_type)) {
                result = NT_STATUS_NO_SUCH_GROUP;
                goto done;
        }
@@ -340,7 +339,7 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map
                goto done;
        }
 
-       if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) {
+       if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) {
                result = NT_STATUS_NO_SUCH_GROUP;
                goto done;
        }
index a8e175a6845d0500b2ccffaa350cf0abcf4b2c88..9185fc84b1ba43c62e0423a39d8c436da736dd80 100644 (file)
@@ -58,6 +58,13 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
                return NT_STATUS_ACCESS_DENIED; /* No errno around here */
        }
 
+       status = create_synthetic_smb_fname(fsp,
+           print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL,
+           NULL, &fsp->fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
+               return status;
+       }
        /* setup a full fsp */
        fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
        GetTimeOfDay(&fsp->open_time);
@@ -72,7 +79,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
        fsp->oplock_type = NO_OPLOCK;
        fsp->sent_oplock_break = NO_BREAK_SENT;
        fsp->is_directory = False;
-       string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
        fsp->wcp = NULL;
        SMB_VFS_FSTAT(fsp, psbuf);
        fsp->mode = psbuf->st_ex_mode;
@@ -98,7 +104,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
        }
 
        if (fsp->fsp_name) {
-               string_free(&fsp->fsp_name);
+               TALLOC_FREE(fsp->fsp_name);
        }
 
        if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
index e296d319e29cb75e56d6c3c7c5cfc3c9795119a3..dec43ae741a9f7160d83d07f82da5b84356abab3 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  Virtual Windows Registry Layer
  *  Copyright (C) Gerald Carter                     2002-2005
+ *  Copyright (C) Michael Adam                      2007-2009
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 static struct db_context *regdb = NULL;
 static int regdb_refcount;
 
-static bool regdb_key_exists(const char *key);
+static bool regdb_key_exists(struct db_context *db, const char *key);
 static bool regdb_key_is_base_key(const char *key);
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+                                       struct regsubkey_ctr *ctr);
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+                                     struct regsubkey_ctr *ctr);
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+                                      struct regval_ctr *values);
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+                                       struct regval_ctr *values);
 
 /* List the deepest path into the registry.  All part components will be created.*/
 
@@ -94,7 +103,8 @@ static struct builtin_regkey_value builtin_registry_values[] = {
  * Initialize a key in the registry:
  * create each component key of the specified path.
  */
-static WERROR init_registry_key_internal(const char *add_path)
+static WERROR init_registry_key_internal(struct db_context *db,
+                                        const char *add_path)
 {
        WERROR werr;
        TALLOC_CTX *frame = talloc_stackframe();
@@ -173,14 +183,20 @@ static WERROR init_registry_key_internal(const char *add_path)
                        goto fail;
                }
 
-               regdb_fetch_keys(base, subkeys);
+               werr = regdb_fetch_keys_internal(db, base, subkeys);
+               if (!W_ERROR_IS_OK(werr) &&
+                   !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+               {
+                       goto fail;
+               }
+
                if (*subkeyname) {
                        werr = regsubkey_ctr_addkey(subkeys, subkeyname);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto fail;
                        }
                }
-               if (!regdb_store_keys( base, subkeys)) {
+               if (!regdb_store_keys_internal(db, base, subkeys)) {
                        werr = WERR_CAN_NOT_COMPLETE;
                        goto fail;
                }
@@ -193,6 +209,20 @@ fail:
        return werr;
 }
 
+struct init_registry_key_context {
+       const char *add_path;
+};
+
+static NTSTATUS init_registry_key_action(struct db_context *db,
+                                        void *private_data)
+{
+       struct init_registry_key_context *init_ctx =
+               (struct init_registry_key_context *)private_data;
+
+       return werror_to_ntstatus(init_registry_key_internal(
+                                       db, init_ctx->add_path));
+}
+
 /**
  * Initialize a key in the registry:
  * create each component key of the specified path,
@@ -200,40 +230,104 @@ fail:
  */
 WERROR init_registry_key(const char *add_path)
 {
-       WERROR werr;
+       struct init_registry_key_context init_ctx;
 
-       if (regdb_key_exists(add_path)) {
+       if (regdb_key_exists(regdb, add_path)) {
                return WERR_OK;
        }
 
-       if (regdb->transaction_start(regdb) != 0) {
-               DEBUG(0, ("init_registry_key: transaction_start failed\n"));
-               return WERR_REG_IO_FAILURE;
-       }
+       init_ctx.add_path = add_path;
 
-       werr = init_registry_key_internal(add_path);
-       if (!W_ERROR_IS_OK(werr)) {
-               goto fail;
+       return ntstatus_to_werror(dbwrap_trans_do(regdb,
+                                                 init_registry_key_action,
+                                                 &init_ctx));
+}
+
+/***********************************************************************
+ Open the registry data in the tdb
+ ***********************************************************************/
+
+static void regdb_ctr_add_value(struct regval_ctr *ctr,
+                               struct builtin_regkey_value *value)
+{
+       UNISTR2 data;
+
+       switch(value->type) {
+       case REG_DWORD:
+               regval_ctr_addvalue(ctr, value->valuename, REG_DWORD,
+                                   (char*)&value->data.dw_value,
+                                   sizeof(uint32));
+               break;
+
+       case REG_SZ:
+               init_unistr2(&data, value->data.string, UNI_STR_TERMINATE);
+               regval_ctr_addvalue(ctr, value->valuename, REG_SZ,
+                                   (char*)data.buffer,
+                                   data.uni_str_len*sizeof(uint16));
+               break;
+
+       default:
+               DEBUG(0, ("regdb_ctr_add_value: invalid value type in "
+                         "registry values [%d]\n", value->type));
        }
+}
 
-       if (regdb->transaction_commit(regdb) != 0) {
-               DEBUG(0, ("init_registry_key: Could not commit transaction\n"));
-               return WERR_REG_IO_FAILURE;
+static NTSTATUS init_registry_data_action(struct db_context *db,
+                                         void *private_data)
+{
+       NTSTATUS status;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct regval_ctr *values;
+       int i;
+
+       /* loop over all of the predefined paths and add each component */
+
+       for (i=0; builtin_registry_paths[i] != NULL; i++) {
+               if (regdb_key_exists(db, builtin_registry_paths[i])) {
+                       continue;
+               }
+               status = werror_to_ntstatus(init_registry_key_internal(db,
+                                                 builtin_registry_paths[i]));
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
        }
 
-       return WERR_OK;
+       /* loop over all of the predefined values and add each component */
 
-fail:
-       if (regdb->transaction_cancel(regdb) != 0) {
-               smb_panic("init_registry_key: transaction_cancel failed\n");
+       for (i=0; builtin_registry_values[i].path != NULL; i++) {
+
+               values = TALLOC_ZERO_P(frame, struct regval_ctr);
+               if (values == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto done;
+               }
+
+               regdb_fetch_values_internal(db,
+                                           builtin_registry_values[i].path,
+                                           values);
+
+               /* preserve existing values across restarts. Only add new ones */
+
+               if (!regval_ctr_key_exists(values,
+                                       builtin_registry_values[i].valuename))
+               {
+                       regdb_ctr_add_value(values,
+                                           &builtin_registry_values[i]);
+                       regdb_store_values_internal(db,
+                                       builtin_registry_values[i].path,
+                                       values);
+               }
+               TALLOC_FREE(values);
        }
 
-       return werr;
-}
+       status = NT_STATUS_OK;
 
-/***********************************************************************
- Open the registry data in the tdb
- ***********************************************************************/
+done:
+
+       TALLOC_FREE(frame);
+       return status;
+}
 
 WERROR init_registry_data(void)
 {
@@ -241,14 +335,13 @@ WERROR init_registry_data(void)
        TALLOC_CTX *frame = talloc_stackframe();
        struct regval_ctr *values;
        int i;
-       UNISTR2 data;
 
        /*
         * First, check for the existence of the needed keys and values.
         * If all do already exist, we can save the writes.
         */
        for (i=0; builtin_registry_paths[i] != NULL; i++) {
-               if (!regdb_key_exists(builtin_registry_paths[i])) {
+               if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
                        goto do_init;
                }
        }
@@ -260,7 +353,9 @@ WERROR init_registry_data(void)
                        goto done;
                }
 
-               regdb_fetch_values(builtin_registry_values[i].path, values);
+               regdb_fetch_values_internal(regdb,
+                                           builtin_registry_values[i].path,
+                                           values);
                if (!regval_ctr_key_exists(values,
                                        builtin_registry_values[i].valuename))
                {
@@ -284,89 +379,9 @@ do_init:
         * transaction behaviour.
         */
 
-       if (regdb->transaction_start(regdb) != 0) {
-               DEBUG(0, ("init_registry_data: tdb_transaction_start "
-                         "failed\n"));
-               werr = WERR_REG_IO_FAILURE;
-               goto done;
-       }
-
-       /* loop over all of the predefined paths and add each component */
-
-       for (i=0; builtin_registry_paths[i] != NULL; i++) {
-               if (regdb_key_exists(builtin_registry_paths[i])) {
-                       continue;
-               }
-               werr = init_registry_key_internal(builtin_registry_paths[i]);
-               if (!W_ERROR_IS_OK(werr)) {
-                       goto fail;
-               }
-       }
-
-       /* loop over all of the predefined values and add each component */
-
-       for (i=0; builtin_registry_values[i].path != NULL; i++) {
-
-               values = TALLOC_ZERO_P(frame, struct regval_ctr);
-               if (values == NULL) {
-                       werr = WERR_NOMEM;
-                       goto fail;
-               }
-
-               regdb_fetch_values(builtin_registry_values[i].path, values);
-
-               /* preserve existing values across restarts. Only add new ones */
-
-               if (!regval_ctr_key_exists(values,
-                                       builtin_registry_values[i].valuename))
-               {
-                       switch(builtin_registry_values[i].type) {
-                       case REG_DWORD:
-                               regval_ctr_addvalue(values,
-                                       builtin_registry_values[i].valuename,
-                                       REG_DWORD,
-                                       (char*)&builtin_registry_values[i].data.dw_value,
-                                       sizeof(uint32));
-                               break;
-
-                       case REG_SZ:
-                               init_unistr2(&data,
-                                       builtin_registry_values[i].data.string,
-                                       UNI_STR_TERMINATE);
-                               regval_ctr_addvalue(values,
-                                       builtin_registry_values[i].valuename,
-                                       REG_SZ,
-                                       (char*)data.buffer,
-                                       data.uni_str_len*sizeof(uint16));
-                               break;
-
-                       default:
-                               DEBUG(0, ("init_registry_data: invalid value "
-                                         "type in builtin_registry_values "
-                                         "[%d]\n",
-                                         builtin_registry_values[i].type));
-                       }
-                       regdb_store_values(builtin_registry_values[i].path,
-                                          values);
-               }
-               TALLOC_FREE(values);
-       }
-
-       if (regdb->transaction_commit(regdb) != 0) {
-               DEBUG(0, ("init_registry_data: Could not commit "
-                         "transaction\n"));
-               werr = WERR_REG_IO_FAILURE;
-       } else {
-               werr = WERR_OK;
-       }
-
-       goto done;
-
-fail:
-       if (regdb->transaction_cancel(regdb) != 0) {
-               smb_panic("init_registry_data: tdb_transaction_cancel "
-                         "failed\n");
-       }
+       werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+                                                 init_registry_data_action,
+                                                 NULL));
 
 done:
        TALLOC_FREE(frame);
@@ -511,7 +526,8 @@ int regdb_get_seqnum(void)
 }
 
 
-static WERROR regdb_delete_key_with_prefix(const char *keyname,
+static WERROR regdb_delete_key_with_prefix(struct db_context *db,
+                                          const char *keyname,
                                           const char *prefix)
 {
        char *path;
@@ -537,7 +553,7 @@ static WERROR regdb_delete_key_with_prefix(const char *keyname,
                goto done;
        }
 
-       werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path));
+       werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path));
 
        /* treat "not" found" as ok */
        if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
@@ -550,40 +566,40 @@ done:
 }
 
 
-static WERROR regdb_delete_values(const char *keyname)
+static WERROR regdb_delete_values(struct db_context *db, const char *keyname)
 {
-       return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX);
+       return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX);
 }
 
-static WERROR regdb_delete_secdesc(const char *keyname)
+static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname)
 {
-       return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX);
+       return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX);
 }
 
-static WERROR regdb_delete_subkeylist(const char *keyname)
+static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname)
 {
-       return regdb_delete_key_with_prefix(keyname, NULL);
+       return regdb_delete_key_with_prefix(db, keyname, NULL);
 }
 
-static WERROR regdb_delete_key_lists(const char *keyname)
+static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
 {
        WERROR werr;
 
-       werr = regdb_delete_values(keyname);
+       werr = regdb_delete_values(db, keyname);
        if (!W_ERROR_IS_OK(werr)) {
                DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
                          REG_VALUE_PREFIX, keyname, win_errstr(werr)));
                goto done;
        }
 
-       werr = regdb_delete_secdesc(keyname);
+       werr = regdb_delete_secdesc(db, keyname);
        if (!W_ERROR_IS_OK(werr)) {
                DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
                          REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
                goto done;
        }
 
-       werr = regdb_delete_subkeylist(keyname);
+       werr = regdb_delete_subkeylist(db, keyname);
        if (!W_ERROR_IS_OK(werr)) {
                DEBUG(1, (__location__ " Deleting %s failed: %s\n",
                          keyname, win_errstr(werr)));
@@ -600,33 +616,42 @@ done:
  fstrings
  ***********************************************************************/
 
-static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_store_keys_internal2(struct db_context *db,
+                                        const char *key,
+                                        struct regsubkey_ctr *ctr)
 {
        TDB_DATA dbuf;
        uint8 *buffer = NULL;
        int i = 0;
        uint32 len, buflen;
-       bool ret = true;
        uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
        char *keyname = NULL;
        TALLOC_CTX *ctx = talloc_stackframe();
-       NTSTATUS status;
+       WERROR werr;
 
        if (!key) {
-               return false;
+               werr = WERR_INVALID_PARAM;
+               goto done;
        }
 
        keyname = talloc_strdup(ctx, key);
        if (!keyname) {
-               return false;
+               werr = WERR_NOMEM;
+               goto done;
        }
+
        keyname = normalize_reg_path(ctx, keyname);
+       if (!keyname) {
+               werr = WERR_NOMEM;
+               goto done;
+       }
 
        /* allocate some initial memory */
 
        buffer = (uint8 *)SMB_MALLOC(1024);
        if (buffer == NULL) {
-               return false;
+               werr = WERR_NOMEM;
+               goto done;
        }
        buflen = 1024;
        len = 0;
@@ -654,7 +679,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
                                DEBUG(0, ("regdb_store_keys: Failed to realloc "
                                          "memory of size [%u]\n",
                                          (unsigned int)(len+thistime)*2));
-                               ret = false;
+                               werr = WERR_NOMEM;
                                goto done;
                        }
                        buflen = (len+thistime)*2;
@@ -663,7 +688,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
                                regsubkey_ctr_specific_key(ctr, i));
                        if (thistime2 != thistime) {
                                DEBUG(0, ("tdb_pack failed\n"));
-                               ret = false;
+                               werr = WERR_CAN_NOT_COMPLETE;
                                goto done;
                        }
                }
@@ -674,11 +699,9 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
 
        dbuf.dptr = buffer;
        dbuf.dsize = len;
-       status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE);
-       if (!NT_STATUS_IS_OK(status)) {
-               ret = false;
-               goto done;
-       }
+       werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf,
+                                                       TDB_REPLACE));
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
 
        /*
         * Delete a sorted subkey cache for regdb_key_exists, will be
@@ -686,14 +709,22 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
         */
        keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
                                  keyname);
-       if (keyname != NULL) {
-               dbwrap_delete_bystring(regdb, keyname);
+       if (keyname == NULL) {
+               werr = WERR_NOMEM;
+               goto done;
+       }
+
+       werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
+
+       /* don't treat WERR_NOT_FOUND as an error here */
+       if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
+               werr = WERR_OK;
        }
 
 done:
        TALLOC_FREE(ctx);
        SAFE_FREE(buffer);
-       return ret;
+       return werr;
 }
 
 /***********************************************************************
@@ -701,73 +732,37 @@ done:
  do not currently exist
  ***********************************************************************/
 
-bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+struct regdb_store_keys_context {
+       const char *key;
+       struct regsubkey_ctr *ctr;
+};
+
+static NTSTATUS regdb_store_keys_action(struct db_context *db,
+                                       void *private_data)
 {
-       int num_subkeys, old_num_subkeys, i;
+       struct regdb_store_keys_context *store_ctx;
+       WERROR werr;
+       int num_subkeys, i;
        char *path = NULL;
        struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
        char *oldkeyname = NULL;
-       TALLOC_CTX *ctx = talloc_stackframe();
-       WERROR werr;
-
-       if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
-               goto fail;
-       }
-
-       /*
-        * fetch a list of the old subkeys so we can determine if anything has
-        * changed
-        */
-
-       werr = regsubkey_ctr_init(ctx, &old_subkeys);
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
-               return false;
-       }
-
-       regdb_fetch_keys(key, old_subkeys);
-
-       num_subkeys = regsubkey_ctr_numkeys(ctr);
-       old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
-       if ((num_subkeys && old_num_subkeys) &&
-           (num_subkeys == old_num_subkeys)) {
-
-               for (i = 0; i < num_subkeys; i++) {
-                       if (strcmp(regsubkey_ctr_specific_key(ctr, i),
-                                  regsubkey_ctr_specific_key(old_subkeys, i))
-                           != 0)
-                       {
-                               break;
-                       }
-               }
-               if (i == num_subkeys) {
-                       /*
-                        * Nothing changed, no point to even start a tdb
-                        * transaction
-                        */
-                       TALLOC_FREE(old_subkeys);
-                       return true;
-               }
-       }
-
-       TALLOC_FREE(old_subkeys);
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       if (regdb->transaction_start(regdb) != 0) {
-               DEBUG(0, ("regdb_store_keys: transaction_start failed\n"));
-               goto fail;
-       }
+       store_ctx = (struct regdb_store_keys_context *)private_data;
 
        /*
         * Re-fetch the old keys inside the transaction
         */
 
-       werr = regsubkey_ctr_init(ctx, &old_subkeys);
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
-               goto cancel;
-       }
+       werr = regsubkey_ctr_init(mem_ctx, &old_subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
 
-       regdb_fetch_keys(key, old_subkeys);
+       werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys);
+       if (!W_ERROR_IS_OK(werr) &&
+           !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+       {
+               goto done;
+       }
 
        /*
         * Make the store operation as safe as possible without transactions:
@@ -796,21 +791,22 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
        for (i=0; i<num_subkeys; i++) {
                oldkeyname = regsubkey_ctr_specific_key(old_subkeys, i);
 
-               if (regsubkey_ctr_key_exists(ctr, oldkeyname)) {
+               if (regsubkey_ctr_key_exists(store_ctx->ctr, oldkeyname)) {
                        /*
                         * It's still around, don't delete
                         */
-
                        continue;
                }
 
-               path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+               path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+                                      oldkeyname);
                if (!path) {
-                       goto cancel;
+                       werr = WERR_NOMEM;
+                       goto done;
                }
 
-               werr = regdb_delete_key_lists(path);
-               W_ERROR_NOT_OK_GOTO(werr, cancel);
+               werr = regdb_delete_key_lists(db, path);
+               W_ERROR_NOT_OK_GOTO_DONE(werr);
 
                TALLOC_FREE(path);
        }
@@ -819,51 +815,51 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
 
        /* (2) store the subkey list for the parent */
 
-       if (!regdb_store_keys_internal(key, ctr) ) {
+       werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr);
+       if (!W_ERROR_IS_OK(werr)) {
                DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
-                        "for parent [%s]\n", key));
-               goto cancel;
+                        "for parent [%s]: %s\n", store_ctx->key,
+                        win_errstr(werr)));
+               goto done;
        }
 
        /* (3) now create records for any subkeys that don't already exist */
 
-       num_subkeys = regsubkey_ctr_numkeys(ctr);
+       num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
 
        if (num_subkeys == 0) {
-               werr = regsubkey_ctr_init(ctx, &subkeys);
-               if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
-                       goto cancel;
-               }
+               werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+               W_ERROR_NOT_OK_GOTO_DONE(werr);
 
-               if (!regdb_store_keys_internal(key, subkeys)) {
+               werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys);
+               if (!W_ERROR_IS_OK(werr)) {
                        DEBUG(0,("regdb_store_keys: Failed to store "
-                                "new record for key [%s]\n", key));
-                       goto cancel;
+                                "new record for key [%s]: %s\n",
+                                store_ctx->key, win_errstr(werr)));
+                       goto done;
                }
                TALLOC_FREE(subkeys);
-
        }
 
        for (i=0; i<num_subkeys; i++) {
-               path = talloc_asprintf(ctx, "%s/%s",
-                                       key,
-                                       regsubkey_ctr_specific_key(ctr, i));
+               path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+                               regsubkey_ctr_specific_key(store_ctx->ctr, i));
                if (!path) {
-                       goto cancel;
-               }
-               werr = regsubkey_ctr_init(ctx, &subkeys);
-               if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
-                       goto cancel;
+                       werr = WERR_NOMEM;
+                       goto done;
                }
+               werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+               W_ERROR_NOT_OK_GOTO_DONE(werr);
 
-               if (regdb_fetch_keys( path, subkeys ) == -1) {
+               werr = regdb_fetch_keys_internal(db, path, subkeys);
+               if (!W_ERROR_IS_OK(werr)) {
                        /* create a record with 0 subkeys */
-                       if (!regdb_store_keys_internal(path, subkeys)) {
+                       werr = regdb_store_keys_internal2(db, path, subkeys);
+                       if (!W_ERROR_IS_OK(werr)) {
                                DEBUG(0,("regdb_store_keys: Failed to store "
-                                        "new record for key [%s]\n", path));
-                               goto cancel;
+                                        "new record for key [%s]: %s\n", path,
+                                        win_errstr(werr)));
+                               goto done;
                        }
                }
 
@@ -871,23 +867,129 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
                TALLOC_FREE(path);
        }
 
-       if (regdb->transaction_commit(regdb) != 0) {
-               DEBUG(0, ("regdb_store_keys: Could not commit transaction\n"));
-               goto fail;
+       werr = WERR_OK;
+
+done:
+       talloc_free(mem_ctx);
+       return werror_to_ntstatus(werr);
+}
+
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+                                     struct regsubkey_ctr *ctr)
+{
+       int num_subkeys, old_num_subkeys, i;
+       struct regsubkey_ctr *old_subkeys = NULL;
+       TALLOC_CTX *ctx = talloc_stackframe();
+       WERROR werr;
+       bool ret = false;
+       struct regdb_store_keys_context store_ctx;
+
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
+               goto done;
        }
 
-       TALLOC_FREE(ctx);
-       return true;
+       /*
+        * fetch a list of the old subkeys so we can determine if anything has
+        * changed
+        */
+
+       werr = regsubkey_ctr_init(ctx, &old_subkeys);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+               goto done;
+       }
 
-cancel:
-       if (regdb->transaction_cancel(regdb) != 0) {
-               smb_panic("regdb_store_keys: transaction_cancel failed\n");
+       werr = regdb_fetch_keys_internal(db, key, old_subkeys);
+       if (!W_ERROR_IS_OK(werr) &&
+           !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+       {
+               goto done;
        }
 
-fail:
+       num_subkeys = regsubkey_ctr_numkeys(ctr);
+       old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
+       if ((num_subkeys && old_num_subkeys) &&
+           (num_subkeys == old_num_subkeys)) {
+
+               for (i = 0; i < num_subkeys; i++) {
+                       if (strcmp(regsubkey_ctr_specific_key(ctr, i),
+                                  regsubkey_ctr_specific_key(old_subkeys, i))
+                           != 0)
+                       {
+                               break;
+                       }
+               }
+               if (i == num_subkeys) {
+                       /*
+                        * Nothing changed, no point to even start a tdb
+                        * transaction
+                        */
+
+                       ret = true;
+                       goto done;
+               }
+       }
+
+       TALLOC_FREE(old_subkeys);
+
+       store_ctx.key = key;
+       store_ctx.ctr = ctr;
+
+       werr = ntstatus_to_werror(dbwrap_trans_do(db,
+                                                 regdb_store_keys_action,
+                                                 &store_ctx));
+
+       ret = W_ERROR_IS_OK(werr);
+
+done:
        TALLOC_FREE(ctx);
 
-       return false;
+       return ret;
+}
+
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+       return regdb_store_keys_internal(regdb, key, ctr);
+}
+
+/**
+ * create a subkey of a given key
+ */
+
+struct regdb_create_subkey_context {
+       const char *key;
+       const char *subkey;
+};
+
+static NTSTATUS regdb_create_subkey_action(struct db_context *db,
+                                          void *private_data)
+{
+       WERROR werr;
+       struct regdb_create_subkey_context *create_ctx;
+       struct regsubkey_ctr *subkeys;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       create_ctx = (struct regdb_create_subkey_context *)private_data;
+
+       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0, (__location__ " failed to store new subkey list for "
+                        "parent key %s: %s\n", create_ctx->key,
+                        win_errstr(werr)));
+       }
+
+done:
+       talloc_free(mem_ctx);
+       return werror_to_ntstatus(werr);
 }
 
 static WERROR regdb_create_subkey(const char *key, const char *subkey)
@@ -895,8 +997,9 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
        WERROR werr;
        struct regsubkey_ctr *subkeys;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct regdb_create_subkey_context create_ctx;
 
-       if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
                werr = WERR_NOT_FOUND;
                goto done;
        }
@@ -904,10 +1007,8 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
        werr = regsubkey_ctr_init(mem_ctx, &subkeys);
        W_ERROR_NOT_OK_GOTO_DONE(werr);
 
-       if (regdb_fetch_keys(key, subkeys) < 0) {
-               werr = WERR_REG_IO_FAILURE;
-               goto done;
-       }
+       werr = regdb_fetch_keys_internal(regdb, key, subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
 
        if (regsubkey_ctr_key_exists(subkeys, subkey)) {
                werr = WERR_OK;
@@ -916,55 +1017,70 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
 
        talloc_free(subkeys);
 
-       werr = regdb_transaction_start();
-       W_ERROR_NOT_OK_GOTO_DONE(werr);
+       create_ctx.key = key;
+       create_ctx.subkey = subkey;
 
-       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
-       W_ERROR_NOT_OK_GOTO(werr, cancel);
+       werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+                                                 regdb_create_subkey_action,
+                                                 &create_ctx));
 
-       if (regdb_fetch_keys(key, subkeys) < 0) {
-               werr = WERR_REG_IO_FAILURE;
-               goto cancel;
-       }
+done:
+       talloc_free(mem_ctx);
+       return werr;
+}
 
-       werr = regsubkey_ctr_addkey(subkeys, subkey);
-       W_ERROR_NOT_OK_GOTO(werr, cancel);
+/**
+ * create a subkey of a given key
+ */
 
-       if (!regdb_store_keys_internal(key, subkeys)) {
-               DEBUG(0, (__location__ " failed to store new subkey list for "
-                        "parent key %s\n", key));
-               werr = WERR_REG_IO_FAILURE;
-               goto cancel;
-       }
+struct regdb_delete_subkey_context {
+       const char *key;
+       const char *subkey;
+       const char *path;
+};
 
-       werr = regdb_transaction_commit();
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0, (__location__ " failed to commit transaction: %s\n",
-                        win_errstr(werr)));
-       }
+static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
+                                          void *private_data)
+{
+       WERROR werr;
+       struct regdb_delete_subkey_context *delete_ctx;
+       struct regsubkey_ctr *subkeys;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       goto done;
+       delete_ctx = (struct regdb_delete_subkey_context *)private_data;
+
+       werr = regdb_delete_key_lists(db, delete_ctx->path);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
 
-cancel:
-       werr = regdb_transaction_cancel();
+       werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys);
        if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
+               DEBUG(0, (__location__ " failed to store new subkey_list for "
+                        "parent key %s: %s\n", delete_ctx->key,
                         win_errstr(werr)));
        }
 
 done:
        talloc_free(mem_ctx);
-       return werr;
+       return werror_to_ntstatus(werr);
 }
 
 static WERROR regdb_delete_subkey(const char *key, const char *subkey)
 {
-       WERROR werr, werr2;
-       struct regsubkey_ctr *subkeys;
+       WERROR werr;
        char *path;
+       struct regdb_delete_subkey_context delete_ctx;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+       if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
                werr = WERR_NOT_FOUND;
                goto done;
        }
@@ -975,56 +1091,26 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey)
                goto done;
        }
 
-       if (!regdb_key_exists(path)) {
+       if (!regdb_key_exists(regdb, path)) {
                werr = WERR_OK;
                goto done;
        }
 
-       werr = regdb_transaction_start();
-       W_ERROR_NOT_OK_GOTO_DONE(werr);
-
-       werr = regdb_delete_key_lists(path);
-       W_ERROR_NOT_OK_GOTO(werr, cancel);
-
-       werr = regsubkey_ctr_init(mem_ctx, &subkeys);
-       W_ERROR_NOT_OK_GOTO(werr, cancel);
-
-       if (regdb_fetch_keys(key, subkeys) < 0) {
-               werr = WERR_REG_IO_FAILURE;
-               goto cancel;
-       }
-
-       werr = regsubkey_ctr_delkey(subkeys, subkey);
-       W_ERROR_NOT_OK_GOTO(werr, cancel);
+       delete_ctx.key = key;
+       delete_ctx.subkey = subkey;
+       delete_ctx.path = path;
 
-       if (!regdb_store_keys_internal(key, subkeys)) {
-               DEBUG(0, (__location__ " failed to store new subkey_list for "
-                        "parent key %s\n", key));
-               werr = WERR_REG_IO_FAILURE;
-               goto cancel;
-       }
-
-       werr = regdb_transaction_commit();
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(0, (__location__ " failed to commit transaction: %s\n",
-                        win_errstr(werr)));
-       }
-
-       goto done;
-
-cancel:
-       werr2 = regdb_transaction_cancel();
-       if (!W_ERROR_IS_OK(werr2)) {
-               DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
-                        win_errstr(werr2)));
-       }
+       werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+                                                 regdb_delete_subkey_action,
+                                                 &delete_ctx));
 
 done:
        talloc_free(mem_ctx);
        return werr;
 }
 
-static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
+static TDB_DATA regdb_fetch_key_internal(struct db_context *db,
+                                        TALLOC_CTX *mem_ctx, const char *key)
 {
        char *path = NULL;
        TDB_DATA data;
@@ -1034,7 +1120,7 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
                return make_tdb_data(NULL, 0);
        }
 
-       data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+       data = dbwrap_fetch_bystring(db, mem_ctx, path);
 
        TALLOC_FREE(path);
        return data;
@@ -1091,7 +1177,7 @@ done:
  * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
  * the potentially large subkey record.
  *
- * The sorted subkey record is deleted in regdb_store_keys_internal and
+ * The sorted subkey record is deleted in regdb_store_keys_internal2 and
  * recreated on demand.
  */
 
@@ -1100,39 +1186,58 @@ static int cmp_keynames(const void *p1, const void *p2)
        return StrCaseCmp(*((char **)p1), *((char **)p2));
 }
 
-static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+struct create_sorted_subkeys_context {
+       const char *key;
+       const char *sorted_keyname;
+};
+
+static NTSTATUS create_sorted_subkeys_action(struct db_context *db,
+                                            void *private_data)
 {
        char **sorted_subkeys;
        struct regsubkey_ctr *ctr;
-       bool result = false;
        NTSTATUS status;
        char *buf;
        char *p;
-       int i, res;
+       int i;
        size_t len;
        int num_subkeys;
-       WERROR werr;
+       struct create_sorted_subkeys_context *sorted_ctx;
 
-       if (regdb->transaction_start(regdb) != 0) {
-               DEBUG(0, ("create_sorted_subkeys: transaction_start "
-                         "failed\n"));
-               return false;
-       }
+       sorted_ctx = (struct create_sorted_subkeys_context *)private_data;
 
-       werr = regsubkey_ctr_init(talloc_tos(), &ctr);
-       if (!W_ERROR_IS_OK(werr)) {
-               goto fail;
+       /*
+        * In this function, we only treat failing of the actual write to
+        * the db as a real error. All preliminary errors, at a stage when
+        * nothing has been written to the DB yet are treated as success
+        * to be committed (as an empty transaction).
+        *
+        * The reason is that this (disposable) call might be nested in other
+        * transactions. Doing a cancel here would destroy the possibility of
+        * a transaction_commit for transactions that we might be wrapped in.
+        */
+
+       status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr));
+       if (!NT_STATUS_IS_OK(status)) {
+               /* don't treat this as an error */
+               status = NT_STATUS_OK;
+               goto done;
        }
 
-       res = regdb_fetch_keys(key, ctr);
-       if (res == -1) {
-               goto fail;
+       status = werror_to_ntstatus(regdb_fetch_keys_internal(db,
+                                                             sorted_ctx->key,
+                                                             ctr));
+       if (!NT_STATUS_IS_OK(status)) {
+               /* don't treat this as an error */
+               status = NT_STATUS_OK;
+               goto done;
        }
 
        num_subkeys = regsubkey_ctr_numkeys(ctr);
        sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
        if (sorted_subkeys == NULL) {
-               goto fail;
+               /* don't treat this as an error */
+               goto done;
        }
 
        len = 4 + 4*num_subkeys;
@@ -1141,7 +1246,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
                sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
                                        regsubkey_ctr_specific_key(ctr, i));
                if (sorted_subkeys[i] == NULL) {
-                       goto fail;
+                       /* don't treat this as an error */
+                       goto done;
                }
                len += strlen(sorted_subkeys[i])+1;
        }
@@ -1150,7 +1256,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
 
        buf = talloc_array(ctr, char, len);
        if (buf == NULL) {
-               goto fail;
+               /* don't treat this as an error */
+               goto done;
        }
        p = buf + 4 + 4*num_subkeys;
 
@@ -1164,38 +1271,28 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
        }
 
        status = dbwrap_store_bystring(
-               regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len),
+               db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf,
+               len),
                TDB_REPLACE);
-       if (!NT_STATUS_IS_OK(status)) {
-               /*
-                * Don't use a "goto fail;" here, this would commit the broken
-                * transaction. See below for an explanation.
-                */
-               if (regdb->transaction_cancel(regdb) == -1) {
-                       DEBUG(0, ("create_sorted_subkeys: transaction_cancel "
-                                 "failed\n"));
-               }
-               TALLOC_FREE(ctr);
-               return false;
-       }
 
-       result = true;
- fail:
-       /*
-        * We only get here via the "goto fail" when we did not write anything
-        * yet. Using transaction_commit even in a failure case is necessary
-        * because this (disposable) call might be nested in other
-        * transactions. Doing a cancel here would destroy the possibility of
-        * a transaction_commit for transactions that we might be wrapped in.
-        */
-       if (regdb->transaction_commit(regdb) == -1) {
-               DEBUG(0, ("create_sorted_subkeys: transaction_start "
-                         "failed\n"));
-               goto fail;
-       }
+done:
+       talloc_free(ctr);
+       return status;
+}
 
-       TALLOC_FREE(ctr);
-       return result;
+static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+{
+       NTSTATUS status;
+       struct create_sorted_subkeys_context sorted_ctx;
+
+       sorted_ctx.key = key;
+       sorted_ctx.sorted_keyname = sorted_keyname;
+
+       status = dbwrap_trans_do(regdb,
+                                create_sorted_subkeys_action,
+                                &sorted_ctx);
+
+       return NT_STATUS_IS_OK(status);
 }
 
 struct scan_subkey_state {
@@ -1241,7 +1338,8 @@ static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data,
        return 0;
 }
 
-static bool scan_parent_subkeys(const char *parent, const char *name)
+static bool scan_parent_subkeys(struct db_context *db, const char *parent,
+                               const char *name)
 {
        char *path = NULL;
        char *key = NULL;
@@ -1268,8 +1366,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
        }
        state.scanned = false;
 
-       res = regdb->parse_record(regdb, string_term_tdb_data(key),
-                                 parent_subkey_scanner, &state);
+       res = db->parse_record(db, string_term_tdb_data(key),
+                              parent_subkey_scanner, &state);
 
        if (state.scanned) {
                result = state.found;
@@ -1277,8 +1375,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
                if (!create_sorted_subkeys(path, key)) {
                        goto fail;
                }
-               res = regdb->parse_record(regdb, string_term_tdb_data(key),
-                                         parent_subkey_scanner, &state);
+               res = db->parse_record(db, string_term_tdb_data(key),
+                                      parent_subkey_scanner, &state);
                if ((res == 0) && (state.scanned)) {
                        result = state.found;
                }
@@ -1298,7 +1396,7 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
  * The exeption of this are keys without a parent key,
  * i.e. the "base" keys (HKLM, HKCU, ...).
  */
-static bool regdb_key_exists(const char *key)
+static bool regdb_key_exists(struct db_context *db, const char *key)
 {
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        TDB_DATA value;
@@ -1322,11 +1420,11 @@ static bool regdb_key_exists(const char *key)
        p = strrchr(path, '/');
        if (p == NULL) {
                /* this is a base key */
-               value = regdb_fetch_key_internal(mem_ctx, path);
+               value = regdb_fetch_key_internal(db, mem_ctx, path);
                ret = (value.dptr != NULL);
        } else {
                *p = '\0';
-               ret = scan_parent_subkeys(path, p+1);
+               ret = scan_parent_subkeys(db, path, p+1);
        }
 
 done:
@@ -1340,35 +1438,36 @@ done:
  released by the caller.
  ***********************************************************************/
 
-int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+                                       struct regsubkey_ctr *ctr)
 {
        WERROR werr;
-       uint32 num_items;
+       uint32_t num_items;
        uint8 *buf;
        uint32 buflen, len;
        int i;
        fstring subkeyname;
-       int ret = -1;
        TALLOC_CTX *frame = talloc_stackframe();
        TDB_DATA value;
 
        DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
 
-       if (!regdb_key_exists(key)) {
-               goto done;
-       }
+       frame = talloc_stackframe();
 
-       werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum());
-       if (!W_ERROR_IS_OK(werr)) {
+       if (!regdb_key_exists(db, key)) {
+               DEBUG(10, ("key [%s] not found\n", key));
+               werr = WERR_NOT_FOUND;
                goto done;
        }
 
-       value = regdb_fetch_key_internal(frame, key);
+       werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db));
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+       value = regdb_fetch_key_internal(db, frame, key);
 
        if (value.dptr == NULL) {
                DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
                           key));
-               ret = 0;
                goto done;
        }
 
@@ -1376,22 +1475,37 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
        buflen = value.dsize;
        len = tdb_unpack( buf, buflen, "d", &num_items);
 
+       werr = regsubkey_ctr_reinit(ctr);
+       W_ERROR_NOT_OK_GOTO_DONE(werr);
+
        for (i=0; i<num_items; i++) {
                len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
                werr = regsubkey_ctr_addkey(ctr, subkeyname);
                if (!W_ERROR_IS_OK(werr)) {
                        DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
                                  "failed: %s\n", win_errstr(werr)));
+                       num_items = 0;
                        goto done;
                }
        }
 
        DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
 
-       ret = num_items;
 done:
        TALLOC_FREE(frame);
-       return ret;
+       return werr;
+}
+
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+       WERROR werr;
+
+       werr = regdb_fetch_keys_internal(regdb, key, ctr);
+       if (!W_ERROR_IS_OK(werr)) {
+               return -1;
+       }
+
+       return regsubkey_ctr_numkeys(ctr);
 }
 
 /****************************************************************************
@@ -1478,7 +1592,8 @@ static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen)
  released by the caller.
  ***********************************************************************/
 
-int regdb_fetch_values(const char* key, struct regval_ctr *values)
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+                                      struct regval_ctr *values)
 {
        char *keystr = NULL;
        TALLOC_CTX *ctx = talloc_stackframe();
@@ -1487,7 +1602,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values)
 
        DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(db, key)) {
                goto done;
        }
 
@@ -1496,9 +1611,9 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values)
                goto done;
        }
 
-       values->seqnum = regdb_get_seqnum();
+       values->seqnum = db->get_seqnum(db);
 
-       value = regdb_fetch_key_internal(ctx, keystr);
+       value = regdb_fetch_key_internal(db, ctx, keystr);
 
        if (!value.dptr) {
                /* all keys have zero values by default */
@@ -1513,7 +1628,13 @@ done:
        return ret;
 }
 
-bool regdb_store_values(const char *key, struct regval_ctr *values)
+int regdb_fetch_values(const char* key, struct regval_ctr *values)
+{
+       return regdb_fetch_values_internal(regdb, key, values);
+}
+
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+                                       struct regval_ctr *values)
 {
        TDB_DATA old_data, data;
        char *keystr = NULL;
@@ -1524,7 +1645,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
 
        DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(db, key)) {
                goto done;
        }
 
@@ -1552,7 +1673,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
                goto done;
        }
 
-       old_data = dbwrap_fetch_bystring(regdb, ctx, keystr);
+       old_data = dbwrap_fetch_bystring(db, ctx, keystr);
 
        if ((old_data.dptr != NULL)
            && (old_data.dsize == data.dsize)
@@ -1562,7 +1683,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
                goto done;
        }
 
-       status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE);
+       status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE);
 
        result = NT_STATUS_IS_OK(status);
 
@@ -1571,6 +1692,11 @@ done:
        return result;
 }
 
+bool regdb_store_values(const char *key, struct regval_ctr *values)
+{
+       return regdb_store_values_internal(regdb, key, values);
+}
+
 static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
                                struct security_descriptor **psecdesc)
 {
@@ -1582,7 +1708,7 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
 
        DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                err = WERR_BADFILE;
                goto done;
        }
@@ -1622,7 +1748,7 @@ static WERROR regdb_set_secdesc(const char *key,
        WERROR err = WERR_NOMEM;
        TDB_DATA tdbdata;
 
-       if (!regdb_key_exists(key)) {
+       if (!regdb_key_exists(regdb, key)) {
                err = WERR_BADFILE;
                goto done;
        }
index 682c7fe9a57537401935621b62ecd78a50a6f90b..6fc87efb1d3cbedf6213ef803cfd4a7cdc9014cd 100644 (file)
@@ -35,7 +35,7 @@ static int netlogon_params_fetch_values(const char *key, struct regval_ctr *regv
 {
        uint32 dwValue;
 
-       if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
+       if (!pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
                dwValue = 0;
        }
 
index 5ae1cd8aa7dec7f6b9585fb6cf295cef2e32b838..0c0455aadadb21bca029c37412d3daea4f336c01 100644 (file)
@@ -63,6 +63,29 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr)
        return WERR_OK;
 }
 
+/**
+ * re-initialize the list of subkeys (to the emtpy list)
+ * in an already allocated regsubkey_ctr
+ */
+
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr)
+{
+       if (ctr == NULL) {
+               return WERR_INVALID_PARAM;
+       }
+
+       talloc_free(ctr->subkeys_hash);
+       ctr->subkeys_hash = db_open_rbt(ctr);
+       W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash);
+
+       TALLOC_FREE(ctr->subkeys);
+
+       ctr->num_subkeys = 0;
+       ctr->seqnum = 0;
+
+       return WERR_OK;
+}
+
 WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
 {
        if (ctr == NULL) {
@@ -89,7 +112,7 @@ static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
 {
        WERROR werr;
 
-       werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash,
+       werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash,
                                                keyname,
                                                make_tdb_data((uint8 *)&idx,
                                                              sizeof(idx)),
@@ -107,7 +130,7 @@ static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr,
 {
        WERROR werr;
 
-       werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash,
+       werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash,
                                  keyname));
        if (!W_ERROR_IS_OK(werr)) {
                DEBUG(1, ("error unhashing key '%s' in container: %s\n",
@@ -127,7 +150,7 @@ static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
                return WERR_INVALID_PARAM;
        }
 
-       data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname);
+       data = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname);
        if (data.dptr == NULL) {
                return WERR_NOT_FOUND;
        }
index 0f4829dec3ac89dc67b5a9899cc5fc270b92e697..621ccf4bc90cac7bb8390151f2e8c74da81020ca 100644 (file)
@@ -636,42 +636,6 @@ bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
        return True;
 }
 
-/*******************************************************************
- Stream a uint16* (allocate memory if unmarshalling)
- ********************************************************************/
-
-bool prs_pointer( const char *name, prs_struct *ps, int depth, 
-                 void *dta, size_t data_size,
-                 bool (*prs_fn)(const char*, prs_struct*, int, void*) )
-{
-       void ** data = (void **)dta;
-       uint32 data_p;
-
-       /* output f000baaa to stream if the pointer is non-zero. */
-
-       data_p = *data ? 0xf000baaa : 0;
-
-       if ( !prs_uint32("ptr", ps, depth, &data_p ))
-               return False;
-
-       /* we're done if there is no data */
-
-       if ( !data_p )
-               return True;
-
-       if (UNMARSHALLING(ps)) {
-               if (data_size) {
-                       if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) )
-                               return False;
-               } else {
-                       *data = NULL;
-               }
-       }
-
-       return prs_fn(name, ps, depth, *data);
-}
-
-
 /*******************************************************************
  Stream a uint16.
  ********************************************************************/
@@ -783,36 +747,6 @@ bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
        }
 }
 
-/*******************************************************************
- Stream a NTSTATUS
- ********************************************************************/
-
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
-{
-       char *q = prs_mem_get(ps, sizeof(uint32));
-       if (q == NULL)
-               return False;
-
-       if (UNMARSHALLING(ps)) {
-               if (ps->bigendian_data)
-                       *status = NT_STATUS(RIVAL(q,0));
-               else
-                       *status = NT_STATUS(IVAL(q,0));
-       } else {
-               if (ps->bigendian_data)
-                       RSIVAL(q,0,NT_STATUS_V(*status));
-               else
-                       SIVAL(q,0,NT_STATUS_V(*status));
-       }
-
-       DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
-                nt_errstr(*status)));
-
-       ps->data_offset += sizeof(uint32);
-
-       return True;
-}
-
 /*******************************************************************
  Stream a DCE error code
  ********************************************************************/
@@ -843,38 +777,6 @@ bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *st
        return True;
 }
 
-
-/*******************************************************************
- Stream a WERROR
- ********************************************************************/
-
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
-{
-       char *q = prs_mem_get(ps, sizeof(uint32));
-       if (q == NULL)
-               return False;
-
-       if (UNMARSHALLING(ps)) {
-               if (ps->bigendian_data)
-                       *status = W_ERROR(RIVAL(q,0));
-               else
-                       *status = W_ERROR(IVAL(q,0));
-       } else {
-               if (ps->bigendian_data)
-                       RSIVAL(q,0,W_ERROR_V(*status));
-               else
-                       SIVAL(q,0,W_ERROR_V(*status));
-       }
-
-       DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
-                win_errstr(*status)));
-
-       ps->data_offset += sizeof(uint32);
-
-       return True;
-}
-
-
 /******************************************************************
  Stream an array of uint8s. Length is number of uint8s.
  ********************************************************************/
@@ -951,60 +853,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin
        return True;
 }
 
-/******************************************************************
- Start using a function for streaming unicode chars. If unmarshalling,
- output must be little-endian, if marshalling, input must be little-endian.
- ********************************************************************/
-
-static void dbg_rw_punival(bool charmode, const char *name, int depth, prs_struct *ps,
-                                                       char *in_buf, char *out_buf, int len)
-{
-       int i;
-
-       if (UNMARSHALLING(ps)) {
-               if (ps->bigendian_data) {
-                       for (i = 0; i < len; i++)
-                               SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i));
-               } else {
-                       for (i = 0; i < len; i++)
-                               SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i));
-               }
-       } else {
-               if (ps->bigendian_data) {
-                       for (i = 0; i < len; i++)
-                               RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
-               } else {
-                       for (i = 0; i < len; i++)
-                               SSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
-               }
-       }
-
-       DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name));
-       if (charmode)
-               print_asc(5, (unsigned char*)out_buf, 2*len);
-       else {
-               for (i = 0; i < len; i++)
-                       DEBUGADD(5,("%04x ", out_buf[i]));
-       }
-       DEBUGADD(5,("\n"));
-}
-
-/******************************************************************
- Stream a unistr. Always little endian.
- ********************************************************************/
-
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
-{
-       char *q = prs_mem_get(ps, len * sizeof(uint16));
-       if (q == NULL)
-               return False;
-
-       dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len);
-       ps->data_offset += (len * sizeof(uint16));
-
-       return True;
-}
-
 /******************************************************************
  Stream an array of uint32s. Length is number of uint32s.
  ********************************************************************/
@@ -1216,172 +1064,6 @@ bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_
        return True;
 }
 
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str)
-{
-       size_t len;
-       char *tmp_str;
-
-       if (UNMARSHALLING(ps)) {
-               len = strlen(&ps->data_p[ps->data_offset]);
-       } else {
-               len = strlen(*str);
-       }
-
-       tmp_str = PRS_ALLOC_MEM(ps, char, len+1);
-
-       if (tmp_str == NULL) {
-               return False;
-       }
-
-       if (MARSHALLING(ps)) {
-               strncpy(tmp_str, *str, len);
-       }
-
-       if (!prs_string(name, ps, depth, tmp_str, len+1)) {
-               return False;
-       }
-
-       *str = tmp_str;
-       return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
-{
-       *offset = ps->data_offset;
-       if (UNMARSHALLING(ps)) {
-               /* reading. */
-               return prs_uint16(name, ps, depth, data16);
-       } else {
-               char *q = prs_mem_get(ps, sizeof(uint16));
-               if(q ==NULL)
-                       return False;
-               ps->data_offset += sizeof(uint16);
-       }
-       return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper.  call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
-                               uint32 ptr_uint16, uint32 start_offset)
-{
-       if (MARSHALLING(ps)) {
-               /* 
-                * Writing - temporarily move the offset pointer.
-                */
-               uint16 data_size = ps->data_offset - start_offset;
-               uint32 old_offset = ps->data_offset;
-
-               ps->data_offset = ptr_uint16;
-               if(!prs_uint16(name, ps, depth, &data_size)) {
-                       ps->data_offset = old_offset;
-                       return False;
-               }
-               ps->data_offset = old_offset;
-       } else {
-               ps->data_offset = start_offset + (uint32)(*data16);
-       }
-       return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper. Call this and it sets up a pointer to where the
- uint32 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
-{
-       *offset = ps->data_offset;
-       if (UNMARSHALLING(ps) && (data32 != NULL)) {
-               /* reading. */
-               return prs_uint32(name, ps, depth, data32);
-       } else {
-               ps->data_offset += sizeof(uint32);
-       }
-       return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper.  call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
-                               uint32 ptr_uint32, uint32 data_size)
-{
-       if (MARSHALLING(ps)) {
-               /* 
-                * Writing - temporarily move the offset pointer.
-                */
-               uint32 old_offset = ps->data_offset;
-               ps->data_offset = ptr_uint32;
-               if(!prs_uint32(name, ps, depth, &data_size)) {
-                       ps->data_offset = old_offset;
-                       return False;
-               }
-               ps->data_offset = old_offset;
-       }
-       return True;
-}
-
-/* useful function to store a structure in rpc wire format */
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps)
-{
-       TDB_DATA dbuf;
-       dbuf.dptr = (uint8 *)ps->data_p;
-       dbuf.dsize = prs_offset(ps);
-       return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE);
-}
-
-/* useful function to fetch a structure into rpc wire format */
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx)
-{
-       TDB_DATA dbuf;
-
-       prs_init_empty(ps, mem_ctx, UNMARSHALL);
-
-       dbuf = tdb_fetch(tdb, kbuf);
-       if (!dbuf.dptr)
-               return -1;
-
-       prs_give_memory(ps, (char *)dbuf.dptr, dbuf.dsize, True);
-
-       return 0;
-}
-
-/*******************************************************************
- hash a stream.
- ********************************************************************/
-
-bool prs_hash1(prs_struct *ps, uint32 offset, int len)
-{
-       char *q;
-
-       q = ps->data_p;
-        q = &q[offset];
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100, ("prs_hash1\n"));
-       dump_data(100, (uint8 *)ps->sess_key, 16);
-       dump_data(100, (uint8 *)q, len);
-#endif
-       arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len);
-
-#ifdef DEBUG_PASSWORD
-       dump_data(100, (uint8 *)q, len);
-#endif
-
-       return True;
-}
-
 /*******************************************************************
  Create a digest over the entire packet (including the data), and 
  MD5 it with the session key.
index 324483b3ee174c03091cfed48c6341812a0a1a53..ace045cfa5df3a5addc63119ae60628a09745ae1 100644 (file)
@@ -349,7 +349,9 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
        NTSTATUS status;
 
        /* Work out max allowed. */
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        /* map the generic bits to the lsa policy ones */
        se_map_generic(&des_access, &lsa_policy_mapping);
@@ -503,6 +505,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
        const char *name;
        DOM_SID *sid = NULL;
        union lsa_PolicyInformation *info = NULL;
+       uint32_t acc_required = 0;
 
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
                return NT_STATUS_INVALID_HANDLE;
@@ -511,6 +514,47 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
                return NT_STATUS_INVALID_HANDLE;
        }
 
+       switch (r->in.level) {
+       case LSA_POLICY_INFO_AUDIT_LOG:
+       case LSA_POLICY_INFO_AUDIT_EVENTS:
+               acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_DOMAIN:
+               acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_PD:
+               acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
+               acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_ROLE:
+       case LSA_POLICY_INFO_REPLICA:
+               acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_QUOTA:
+               acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_MOD:
+       case LSA_POLICY_INFO_AUDIT_FULL_SET:
+               /* according to MS-LSAD 3.1.4.4.3 */
+               return NT_STATUS_INVALID_PARAMETER;
+       case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
+               acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+               break;
+       case LSA_POLICY_INFO_DNS:
+       case LSA_POLICY_INFO_DNS_INT:
+       case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
+               acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+               break;
+       default:
+               break;
+       }
+
+       if (!(handle->access & acc_required)) {
+               /* return NT_STATUS_ACCESS_DENIED; */
+       }
+
        info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
        if (!info) {
                return NT_STATUS_NO_MEMORY;
@@ -618,7 +662,8 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
                                break;
                }
                break;
-       case LSA_POLICY_INFO_DNS: {
+       case LSA_POLICY_INFO_DNS:
+       case LSA_POLICY_INFO_DNS_INT: {
                struct pdb_domain_info *dominfo;
 
                if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
@@ -656,6 +701,28 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
        return status;
 }
 
+/***************************************************************************
+ _lsa_QueryInfoPolicy2
+ ***************************************************************************/
+
+NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
+                              struct lsa_QueryInfoPolicy2 *r2)
+{
+       struct lsa_QueryInfoPolicy r;
+
+       if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
+               p->rng_fault_state = True;
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       ZERO_STRUCT(r);
+       r.in.handle = r2->in.handle;
+       r.in.level = r2->in.level;
+       r.out.info = r2->out.info;
+
+       return _lsa_QueryInfoPolicy(p, &r);
+}
+
 /***************************************************************************
  _lsa_lookup_sids_internal
  ***************************************************************************/
@@ -1302,12 +1369,22 @@ NTSTATUS _lsa_DeleteObject(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       status = privilege_delete_account(&info->sid);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
-                       nt_errstr(status)));
+       switch (info->type) {
+       case LSA_HANDLE_ACCOUNT_TYPE:
+               status = privilege_delete_account(&info->sid);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
+                               nt_errstr(status)));
+                       return status;
+               }
+               break;
+       default:
+               return NT_STATUS_INVALID_HANDLE;
        }
 
+       close_policy_hnd(p, r->in.handle);
+       ZERO_STRUCTP(r->out.handle);
+
        return status;
 }
 
@@ -1560,8 +1637,12 @@ NTSTATUS _lsa_GetUserName(pipes_struct *p,
 NTSTATUS _lsa_CreateAccount(pipes_struct *p,
                            struct lsa_CreateAccount *r)
 {
+       NTSTATUS status;
        struct lsa_info *handle;
        struct lsa_info *info;
+       uint32_t acc_granted;
+       struct security_descriptor *psd;
+       uint32_t sd_size;
 
        /* find the connection policy handle. */
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
@@ -1573,12 +1654,26 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
 
        /* check if the user has enough rights */
 
-       /*
-        * I don't know if it's the right one. not documented.
-        * but guessed with rpcclient.
-        */
-       if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT))
+       if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
                return NT_STATUS_ACCESS_DENIED;
+       }
+
+       /* map the generic bits to the lsa policy ones */
+       se_map_generic(&r->in.access_mask, &lsa_account_mapping);
+
+       status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
+                                   &lsa_account_mapping,
+                                   r->in.sid, LSA_POLICY_ALL_ACCESS);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+        status = access_check_object(psd, p->server_info->ptok,
+                NULL, 0, r->in.access_mask,
+                &acc_granted, "_lsa_CreateAccount");
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        if ( is_privileged_sid( r->in.sid ) )
                return NT_STATUS_OBJECT_NAME_COLLISION;
@@ -1591,7 +1686,7 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
        }
 
        info->sid = *r->in.sid;
-       info->access = r->in.access_mask;
+       info->access = acc_granted;
        info->type = LSA_HANDLE_ACCOUNT_TYPE;
 
        /* get a (unique) handle.  open a policy on it. */
@@ -1628,7 +1723,9 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p,
         * handle - so don't check against policy handle. */
 
        /* Work out max allowed. */
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        /* map the generic bits to the lsa account ones */
        se_map_generic(&des_access, &lsa_account_mapping);
@@ -1912,6 +2009,51 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
        return NT_STATUS_OK;
 }
 
+/***************************************************************************
+ _lsa_LookupPrivName
+ ***************************************************************************/
+
+NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
+                            struct lsa_LookupPrivName *r)
+{
+       struct lsa_info *info = NULL;
+       const char *name;
+       struct lsa_StringLarge *lsa_name;
+
+       /* find the connection policy handle. */
+       if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (info->type != LSA_HANDLE_POLICY_TYPE) {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       name = luid_to_privilege_name((LUID *)r->in.luid);
+       if (!name) {
+               return NT_STATUS_NO_SUCH_PRIVILEGE;
+       }
+
+       lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
+       if (!lsa_name) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       lsa_name->string = talloc_strdup(lsa_name, name);
+       if (!lsa_name->string) {
+               TALLOC_FREE(lsa_name);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *r->out.name = lsa_name;
+
+       return NT_STATUS_OK;
+}
+
 /***************************************************************************
  _lsa_QuerySecurity
  ***************************************************************************/
@@ -1943,19 +2085,9 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
                return status;
        }
 
-       switch (r->in.sec_info) {
-       case 1:
-               /* SD contains only the owner */
-               if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
-                       return NT_STATUS_NO_MEMORY;
-               break;
-       case 4:
-               /* SD contains only the ACL */
-               if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
-                       return NT_STATUS_NO_MEMORY;
-               break;
-       default:
-               return NT_STATUS_INVALID_LEVEL;
+       *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
+       if (!*r->out.sdbuf) {
+               return NT_STATUS_NO_MEMORY;
        }
 
        return status;
@@ -2242,18 +2374,79 @@ NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
        return NT_STATUS_OK;
 }
 
+/***************************************************************************
+ _lsa_EnumAccountsWithUserRight
+ ***************************************************************************/
+
+NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
+                                       struct lsa_EnumAccountsWithUserRight *r)
+{
+       NTSTATUS status;
+       struct lsa_info *info = NULL;
+       struct dom_sid *sids = NULL;
+       int num_sids = 0;
+       uint32_t i;
+       SE_PRIV mask;
+
+       if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (info->type != LSA_HANDLE_POLICY_TYPE) {
+               return NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
+       if (!r->in.name || !r->in.name->string) {
+               return NT_STATUS_NO_SUCH_PRIVILEGE;
+       }
+
+       if (!se_priv_from_name(r->in.name->string, &mask)) {
+               return NT_STATUS_NO_SUCH_PRIVILEGE;
+       }
+
+       status = privilege_enum_sids(&mask, p->mem_ctx,
+                                    &sids, &num_sids);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       r->out.sids->num_sids = num_sids;
+       r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
+                                        r->out.sids->num_sids);
+
+       for (i=0; i < r->out.sids->num_sids; i++) {
+               r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
+                                                         &sids[i]);
+               if (!r->out.sids->sids[i].sid) {
+                       TALLOC_FREE(r->out.sids->sids);
+                       r->out.sids->num_sids = 0;
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
+/***************************************************************************
+ _lsa_Delete
+ ***************************************************************************/
+
+NTSTATUS _lsa_Delete(pipes_struct *p,
+                    struct lsa_Delete *r)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
 /*
  * From here on the server routines are just dummy ones to make smbd link with
  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
  * pulling the server stubs across one by one.
  */
 
-NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
-{
-       p->rng_fault_state = True;
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
-
 NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
 {
        p->rng_fault_state = True;
@@ -2308,18 +2501,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
-{
-       p->rng_fault_state = True;
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
-{
-       p->rng_fault_state = True;
-       return NT_STATUS_NOT_IMPLEMENTED;
-}
-
 NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
 {
        p->rng_fault_state = True;
@@ -2350,24 +2531,6 @@ NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateDat
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
-                              struct lsa_QueryInfoPolicy2 *r2)
-{
-       struct lsa_QueryInfoPolicy r;
-
-       if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
-               p->rng_fault_state = True;
-               return NT_STATUS_NOT_IMPLEMENTED;
-       }
-
-       ZERO_STRUCT(r);
-       r.in.handle = r2->in.handle;
-       r.in.level = r2->in.level;
-       r.out.info = r2->out.info;
-
-       return _lsa_QueryInfoPolicy(p, &r);
-}
-
 NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
 {
        p->rng_fault_state = True;
index 8560ee97c61d5cc6254e40228f48ad19c04fcd60..b27603f261590921da446f3f2f0f64b32b91f2d0 100644 (file)
@@ -236,8 +236,9 @@ done:
  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
 ********************************************************************/
 
-void map_max_allowed_access(const NT_USER_TOKEN *token,
-                                       uint32_t *pacc_requested)
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+                           const struct unix_user_token *unix_token,
+                           uint32_t *pacc_requested)
 {
        if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
                return;
@@ -248,15 +249,15 @@ void map_max_allowed_access(const NT_USER_TOKEN *token,
        *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
 
        /* root gets anything. */
-       if (geteuid() == sec_initial_uid()) {
+       if (unix_token->uid == sec_initial_uid()) {
                *pacc_requested |= GENERIC_ALL_ACCESS;
                return;
        }
 
        /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
 
-       if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
-                       is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
+       if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
+                       is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
                *pacc_requested |= GENERIC_ALL_ACCESS;
                return;
        }
@@ -266,7 +267,7 @@ void map_max_allowed_access(const NT_USER_TOKEN *token,
                DOM_SID domadmin_sid;
                sid_copy( &domadmin_sid, get_global_sam_sid() );
                sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
-               if (is_sid_in_token(token, &domadmin_sid)) {
+               if (is_sid_in_token(nt_token, &domadmin_sid)) {
                        *pacc_requested |= GENERIC_ALL_ACCESS;
                        return;
                }
@@ -550,7 +551,9 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
        }
 
        /*check if access can be granted as requested by client. */
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
        se_map_generic( &des_access, &dom_generic_mapping );
@@ -636,9 +639,9 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
        switch (sid_type) {
                case SID_NAME_USER:
                        become_root();
-                       pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+                       pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
                                               &min_password_length);
-                       pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+                       pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                                               &password_properties);
                        unbecome_root();
 
@@ -2076,19 +2079,19 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
 
                /* AS ROOT !!! */
 
-               pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
+               pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
                dominfo->min_password_length = tmp;
 
-               pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
+               pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
                dominfo->password_history_length = tmp;
 
-               pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+               pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                                       &dominfo->password_properties);
 
-               pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+               pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
                u_expire = account_policy_temp;
 
-               pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+               pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
                u_min_age = account_policy_temp;
 
                /* !AS ROOT */
@@ -2260,8 +2263,9 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
                return NT_STATUS_NO_SUCH_USER;
 
        /* check if access can be granted as requested by client. */
-
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
        se_map_generic(&des_access, &usr_generic_mapping);
@@ -3301,19 +3305,19 @@ static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
 
        /* AS ROOT !!! */
 
-       pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
        r->min_password_length = account_policy_temp;
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
        r->password_history_length = account_policy_temp;
 
-       pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+       pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                               &r->password_properties);
 
-       pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
        u_expire = account_policy_temp;
 
-       pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
        u_min_age = account_policy_temp;
 
        /* !AS ROOT */
@@ -3348,7 +3352,7 @@ static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
        r->num_groups   = count_sam_groups(dinfo->disp_info);
        r->num_aliases  = count_sam_aliases(dinfo->disp_info);
 
-       pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
+       pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
 
        unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
 
@@ -3385,7 +3389,7 @@ static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
 
        {
                uint32_t ul;
-               pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
+               pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
                u_logout = (time_t)ul;
        }
 
@@ -3502,16 +3506,16 @@ static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
 
        become_root();
 
-       pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
        u_lock_duration = account_policy_temp;
        if (u_lock_duration != -1) {
                u_lock_duration *= 60;
        }
 
-       pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
        u_reset_time = account_policy_temp * 60;
 
-       pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
        r->lockout_threshold = account_policy_temp;
 
        /* !AS ROOT */
@@ -3537,16 +3541,16 @@ static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
 
        /* AS ROOT !!! */
 
-       pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
        u_lock_duration = account_policy_temp;
        if (u_lock_duration != -1) {
                u_lock_duration *= 60;
        }
 
-       pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
        u_reset_time = account_policy_temp * 60;
 
-       pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+       pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
        r->lockout_threshold = account_policy_temp;
 
        /* !AS ROOT */
@@ -3834,7 +3838,9 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 
        sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
 
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
                            &sid, SAMR_USR_RIGHTS_WRITE_PW);
@@ -3914,7 +3920,9 @@ NTSTATUS _samr_Connect(pipes_struct *p,
           was observed from a win98 client trying to enumerate users (when configured
           user level access control on shares)   --jerry */
 
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        se_map_generic( &des_access, &sam_generic_mapping );
 
@@ -3974,7 +3982,9 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
        se_map_generic(&des_access, &sam_generic_mapping);
@@ -4187,7 +4197,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
 
        /*check if access can be granted as requested by client. */
 
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&ali_generic_mapping);
@@ -6193,9 +6205,9 @@ NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
        }
 
        become_root();
-       pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+       pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
                               &min_password_length);
-       pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+       pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                               &password_properties);
        unbecome_root();
 
@@ -6237,7 +6249,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
        }
 
        /*check if access can be granted as requested by client. */
-       map_max_allowed_access(p->server_info->ptok, &des_access);
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &des_access);
 
        make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
        se_map_generic(&des_access,&grp_generic_mapping);
@@ -6362,14 +6376,14 @@ static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
        u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
        u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
 
-       pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+       pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
                               (uint32_t)r->min_password_length);
-       pdb_set_account_policy(AP_PASSWORD_HISTORY,
+       pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
                               (uint32_t)r->password_history_length);
-       pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+       pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                               (uint32_t)r->password_properties);
-       pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
-       pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
+       pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
+       pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
 
        return NT_STATUS_OK;
 }
@@ -6384,7 +6398,7 @@ static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
 
        u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
 
-       pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
+       pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
 
        return NT_STATUS_OK;
 }
@@ -6404,9 +6418,9 @@ static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
 
        u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
 
-       pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
-       pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
-       pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+       pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
+       pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
+       pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
                               (uint32_t)r->lockout_threshold);
 
        return NT_STATUS_OK;
index 69daa31e9c1621892928f07fd65d26fd4598e055..1e5988af330c15f2cb9ae8c5e621eefe2bdf58fb 100644 (file)
@@ -619,7 +619,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
                        uint32_t pwd_max_age = 0;
                        time_t now = time(NULL);
 
-                       pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
+                       pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age);
 
                        if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
                                pwd_max_age = get_time_t_max();
index 9d7216820293b368d4829aba789adebd97edb47b..9dc1a26e3b383e815ba8535c44b7910d390c04f0 100644 (file)
@@ -261,7 +261,7 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
  Delete a printer given a handle.
 ****************************************************************************/
 
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
+static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
 {
        char *cmd = lp_deleteprinter_cmd();
        char *command = NULL;
@@ -309,7 +309,9 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh
                return WERR_BADFID; /* What to return here? */
 
        /* go ahead and re-read the services immediately */
+       become_root();
        reload_services(false);
+       unbecome_root();
 
        if ( lp_servicenumber( sharename )  < 0 )
                return WERR_ACCESS_DENIED;
@@ -5920,7 +5922,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 /****************************************************************************
 ****************************************************************************/
 
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
+static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
 {
        char *cmd = lp_addport_cmd();
        char *command = NULL;
@@ -6034,7 +6036,9 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
        }
 
        /* reload our services immediately */
+       become_root();
        reload_services(false);
+       unbecome_root();
 
        numlines = 0;
        /* Get lines and convert them back to dos-codepage */
@@ -7316,7 +7320,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
  wrapper around the enumer ports command
 ****************************************************************************/
 
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
+static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
 {
        char *cmd = lp_enumports_cmd();
        char **qlines = NULL;
index 44acf4d647eb322d230764c761d423b91fc48abe..b9d1ed6d73e2dee8b196176ea0312f3fc076690f 100644 (file)
@@ -540,11 +540,13 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p,
                 if (lp_browseable(snum) && lp_snum_ok(snum) &&
                     is_enumeration_allowed(p, snum) &&
                     (all_shares || !is_hidden_share(snum)) ) {
-                        DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
+                        DEBUG(10, ("counting service %s\n",
+                               lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
                         allowed[snum] = true;
                         num_entries++;
                 } else {
-                        DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
+                        DEBUG(10, ("NOT counting service %s\n",
+                               lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
                 }
         }
 
@@ -2070,8 +2072,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
                                        conn,
                                        false,
                                        r->in.file,
-                                       &smb_fname,
-                                       NULL);
+                                       &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
@@ -2199,8 +2200,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
                                        conn,
                                        false,
                                        r->in.file,
-                                       &smb_fname,
-                                       NULL);
+                                       &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
                goto error_exit;
index ef3187579a3ab591671e00cc30c79ea8294e87e1..d7f8041779309c1b0cfe1158c9418d06a2a15921 100644 (file)
@@ -1356,6 +1356,366 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli,
        return result;
 }
 
+static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli,
+                                     TALLOC_CTX *mem_ctx, int argc,
+                                     const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle, sec_handle;
+       struct lsa_String name;
+
+       if (argc < 2) {
+               printf("Usage: %s name\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       status = rpccli_lsa_CreateSecret(cli, mem_ctx,
+                                        &handle,
+                                        name,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &sec_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+ done:
+       if (is_valid_policy_hnd(&sec_handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+       }
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
+static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli,
+                                     TALLOC_CTX *mem_ctx, int argc,
+                                     const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle, sec_handle;
+       struct lsa_String name;
+
+       if (argc < 2) {
+               printf("Usage: %s name\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+                                      &handle,
+                                      name,
+                                      SEC_FLAG_MAXIMUM_ALLOWED,
+                                      &sec_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = rpccli_lsa_DeleteObject(cli, mem_ctx,
+                                        &sec_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+ done:
+       if (is_valid_policy_hnd(&sec_handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+       }
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
+static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx, int argc,
+                                    const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle, sec_handle;
+       struct lsa_String name;
+       struct lsa_DATA_BUF_PTR new_val;
+       NTTIME new_mtime = 0;
+       struct lsa_DATA_BUF_PTR old_val;
+       NTTIME old_mtime = 0;
+       DATA_BLOB session_key;
+       DATA_BLOB new_blob = data_blob_null;
+       DATA_BLOB old_blob = data_blob_null;
+       char *new_secret, *old_secret;
+
+       if (argc < 2) {
+               printf("Usage: %s name\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+                                      &handle,
+                                      name,
+                                      SEC_FLAG_MAXIMUM_ALLOWED,
+                                      &sec_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       ZERO_STRUCT(new_val);
+       ZERO_STRUCT(old_val);
+
+       status = rpccli_lsa_QuerySecret(cli, mem_ctx,
+                                       &sec_handle,
+                                       &new_val,
+                                       &new_mtime,
+                                       &old_val,
+                                       &old_mtime);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = cli_get_session_key(mem_ctx, cli, &session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       if (new_val.buf) {
+               new_blob = data_blob_const(new_val.buf->data, new_val.buf->length);
+       }
+       if (old_val.buf) {
+               old_blob = data_blob_const(old_val.buf->data, old_val.buf->length);
+       }
+
+       new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key);
+       old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key);
+       if (new_secret) {
+               d_printf("new secret: %s\n", new_secret);
+       }
+       if (old_secret) {
+               d_printf("old secret: %s\n", old_secret);
+       }
+
+ done:
+       if (is_valid_policy_hnd(&sec_handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+       }
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
+static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx, int argc,
+                                  const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle, sec_handle;
+       struct lsa_String name;
+       struct lsa_DATA_BUF new_val;
+       struct lsa_DATA_BUF old_val;
+       DATA_BLOB enc_key;
+       DATA_BLOB session_key;
+
+       if (argc < 3) {
+               printf("Usage: %s name secret\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+                                      &handle,
+                                      name,
+                                      SEC_FLAG_MAXIMUM_ALLOWED,
+                                      &sec_handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       ZERO_STRUCT(new_val);
+       ZERO_STRUCT(old_val);
+
+       status = cli_get_session_key(mem_ctx, cli, &session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       enc_key = sess_encrypt_string(argv[2], &session_key);
+
+       new_val.length = enc_key.length;
+       new_val.size = enc_key.length;
+       new_val.data = enc_key.data;
+
+       status = rpccli_lsa_SetSecret(cli, mem_ctx,
+                                     &sec_handle,
+                                     &new_val,
+                                     NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+ done:
+       if (is_valid_policy_hnd(&sec_handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+       }
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
+static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli,
+                                             TALLOC_CTX *mem_ctx, int argc,
+                                             const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle;
+       struct lsa_String name;
+       struct lsa_DATA_BUF *val;
+       DATA_BLOB session_key;
+       DATA_BLOB blob;
+       char *secret;
+
+       if (argc < 2) {
+               printf("Usage: %s name\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       ZERO_STRUCT(val);
+
+       status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx,
+                                               &handle,
+                                               &name,
+                                               &val);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = cli_get_session_key(mem_ctx, cli, &session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       if (val) {
+               blob = data_blob_const(val->data, val->length);
+       }
+
+       secret = sess_decrypt_string(mem_ctx, &blob, &session_key);
+       if (secret) {
+               d_printf("secret: %s\n", secret);
+       }
+
+ done:
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
+static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli,
+                                          TALLOC_CTX *mem_ctx, int argc,
+                                          const char **argv)
+{
+       NTSTATUS status;
+       struct policy_handle handle;
+       struct lsa_String name;
+       struct lsa_DATA_BUF val;
+       DATA_BLOB session_key;
+       DATA_BLOB enc_key;
+
+       if (argc < 3) {
+               printf("Usage: %s name secret\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       status = rpccli_lsa_open_policy2(cli, mem_ctx,
+                                        true,
+                                        SEC_FLAG_MAXIMUM_ALLOWED,
+                                        &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       init_lsa_String(&name, argv[1]);
+
+       ZERO_STRUCT(val);
+
+       status = cli_get_session_key(mem_ctx, cli, &session_key);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       enc_key = sess_encrypt_string(argv[2], &session_key);
+
+       val.length = enc_key.length;
+       val.size = enc_key.length;
+       val.data = enc_key.data;
+
+       status = rpccli_lsa_StorePrivateData(cli, mem_ctx,
+                                            &handle,
+                                            &name,
+                                            &val);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+ done:
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_lsa_Close(cli, mem_ctx, &handle);
+       }
+
+       return status;
+}
+
 
 /* List of commands exported by this module */
 
@@ -1384,6 +1744,12 @@ struct cmd_set lsarpc_commands[] = {
        { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
        { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" },
        { "getusername",          RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" },
+       { "createsecret",         RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" },
+       { "deletesecret",         RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" },
+       { "querysecret",          RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" },
+       { "setsecret",            RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" },
+       { "retrieveprivatedata",  RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" },
+       { "storeprivatedata",     RPC_RTYPE_NTSTATUS, cmd_lsa_store_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Store Private Data", "" },
 
        { NULL }
 };
index cbff69ff17fd8c961685e823564624cd573af76f..48f9df3cacf71ef98cf80c9586a33fce67cc6d2c 100644 (file)
@@ -3430,6 +3430,48 @@ static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
        return werror;
 }
 
+static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
+                                           TALLOC_CTX *mem_ctx, int argc,
+                                           const char **argv)
+{
+       WERROR result;
+       NTSTATUS status;
+       struct policy_handle handle, gdi_handle;
+       const char *printername;
+       struct spoolss_DevmodeContainer devmode_ctr;
+
+       RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
+
+       result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
+                                              printername,
+                                              SEC_FLAG_MAXIMUM_ALLOWED,
+                                              &handle);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       ZERO_STRUCT(devmode_ctr);
+
+       status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
+                                               &handle,
+                                               &gdi_handle,
+                                               &devmode_ctr,
+                                               &result);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+ done:
+       if (is_valid_policy_hnd(&gdi_handle)) {
+               rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
+       }
+       if (is_valid_policy_hnd(&handle)) {
+               rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+       }
+
+       return result;
+}
+
 /* List of commands exported by this module */
 struct cmd_set spoolss_commands[] = {
 
@@ -3469,6 +3511,7 @@ struct cmd_set spoolss_commands[] = {
        { "enumprocs",          RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs,         &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors",          "" },
        { "enumprocdatatypes",  RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
        { "enummonitors",       RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors,      &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
+       { "createprinteric",    RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic,  &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },
 
        { NULL }
 };
index c577ed18d4244756cd57ec029e33e44c99385de4..602433bd91705ba017fe6bc4eb62985009eb8679 100755 (executable)
@@ -21,6 +21,9 @@ incdir=`dirname $0`
 . $incdir/test_functions.sh
 }
 
+SMB_CONF_PATH="$CONFFILE"
+export SMB_CONF_PATH
+
 tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7"
 #tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE "
 tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE "
@@ -29,6 +32,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3"
 tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K"
 tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1"
 tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST"
+tests="$tests LOCAL-BASE64 LOCAL-GENCACHE"
 
 skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN"
 skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST"
index c6f700f17a0901b0fb5856579ede1a22046dabfc..ed415c5e1304a7b4c6adb87c92c9852139425f4a 100644 (file)
@@ -188,7 +188,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
 
        DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
                  "offset %.0f, len = %u (mid = %u)\n",
-                 fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
+                 fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
                  (unsigned int)aio_ex->req->mid ));
 
        outstanding_aio_calls++;
@@ -241,7 +241,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
                DEBUG(10,("schedule_aio_write_and_X: failed to schedule "
                          "aio_write for file %s, offset %.0f, len = %u "
                          "(mid = %u)\n",
-                         fsp->fsp_name, (double)startpos,
+                         fsp_str_dbg(fsp), (double)startpos,
                          (unsigned int)numtowrite,
                          (unsigned int)req->mid ));
                return False;
@@ -300,14 +300,14 @@ bool schedule_aio_write_and_X(connection_struct *conn,
                                            "failed.");
                }
                DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
-                         "behind for file %s\n", fsp->fsp_name ));
+                         "behind for file %s\n", fsp_str_dbg(fsp)));
        }
        outstanding_aio_calls++;
 
        DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
                  "%s, offset %.0f, len = %u (mid = %u) "
                  "outstanding_aio_calls = %d\n",
-                 fsp->fsp_name, (double)startpos, (unsigned int)numtowrite,
+                 fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite,
                  (unsigned int)aio_ex->req->mid, outstanding_aio_calls ));
 
        return True;
@@ -341,7 +341,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 
                DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. "
                           "Error = %s\n",
-                          aio_ex->fsp->fsp_name, strerror(errno) ));
+                          fsp_str_dbg(aio_ex->fsp), strerror(errno)));
 
                ret = errno;
                ERROR_NT(map_nt_error_from_unix(ret));
@@ -359,7 +359,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 
                DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
                            "nread=%d\n",
-                           aio_ex->fsp->fsp_name,
+                           fsp_str_dbg(aio_ex->fsp),
                            (int)aio_ex->acb.aio_nbytes, (int)nread ) );
 
        }
@@ -374,7 +374,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 
        DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed "
                  "for file %s, offset %.0f, len = %u\n",
-                 aio_ex->fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+                 fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset,
                  (unsigned int)nread ));
 
        return ret;
@@ -399,13 +399,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                                DEBUG(5,("handle_aio_write_complete: "
                                         "aio_write_behind failed ! File %s "
                                         "is corrupt ! Error %s\n",
-                                        fsp->fsp_name, strerror(errno) ));
+                                        fsp_str_dbg(fsp), strerror(errno)));
                                ret = errno;
                        } else {
                                DEBUG(0,("handle_aio_write_complete: "
                                         "aio_write_behind failed ! File %s "
                                         "is corrupt ! Wanted %u bytes but "
-                                        "only wrote %d\n", fsp->fsp_name,
+                                        "only wrote %d\n", fsp_str_dbg(fsp),
                                         (unsigned int)numtowrite,
                                         (int)nwritten ));
                                ret = EIO;
@@ -413,7 +413,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                } else {
                        DEBUG(10,("handle_aio_write_complete: "
                                  "aio_write_behind completed for file %s\n",
-                                 fsp->fsp_name ));
+                                 fsp_str_dbg(fsp)));
                }
                return 0;
        }
@@ -424,7 +424,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
        if(nwritten == -1) {
                DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. "
                           "nwritten == %d. Error = %s\n",
-                          fsp->fsp_name, (unsigned int)numtowrite,
+                          fsp_str_dbg(fsp), (unsigned int)numtowrite,
                           (int)nwritten, strerror(errno) ));
 
                /* If errno is ECANCELED then don't return anything to the
@@ -456,7 +456,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                                   ERRHRD, ERRdiskfull);
                        srv_set_message(outbuf,0,0,true);
                        DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
-                               fsp->fsp_name, nt_errstr(status) ));
+                                fsp_str_dbg(fsp), nt_errstr(status)));
                }
 
                aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten;
@@ -472,7 +472,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
 
        DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
                  "for file %s, offset %.0f, requested %u, written = %u\n",
-                 fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+                 fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset,
                  (unsigned int)numtowrite, (unsigned int)nwritten ));
 
        return ret;
@@ -496,7 +496,7 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
        if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
                DEBUG(10,( "handle_aio_completed: operation mid %u still in "
                           "process for file %s\n",
-                          aio_ex->req->mid, aio_ex->fsp->fsp_name ));
+                          aio_ex->req->mid, fsp_str_dbg(aio_ex->fsp)));
                return False;
        }
 
index 4c61428692dc48d45ca76600d2e5cddd140f73b8..e752194ca5e385e678974da874026afd4fccf7e5 100644 (file)
@@ -202,7 +202,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
                "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
                (unsigned int)blr->expire_time.tv_sec,
                (unsigned int)blr->expire_time.tv_usec, lock_timeout,
-               blr->fsp->fnum, blr->fsp->fsp_name ));
+               blr->fsp->fnum, fsp_str_dbg(blr->fsp)));
 
        return True;
 }
@@ -418,8 +418,9 @@ static bool process_lockingX(struct blocking_lock_record *blr)
                 * Success - we got all the locks.
                 */
 
-               DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
-                        fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
+               DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
+                        "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
+                        (unsigned int)locktype, num_locks));
 
                reply_lockingX_success(blr);
                return True;
@@ -442,7 +443,7 @@ static bool process_lockingX(struct blocking_lock_record *blr)
 
        DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
 Waiting....\n", 
-                 blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
+                blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
 
        return False;
 }
@@ -533,7 +534,7 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo
 
                DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
                           "request type %d for file %s fnum = %d\n",
-                          blr->req->cmd, fsp->fsp_name, fsp->fnum));
+                          blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
 
                blr_cancelled = blocking_lock_cancel(fsp,
                                     blr->lock_pid,
@@ -583,7 +584,7 @@ void remove_pending_lock_requests_by_mid(int mid)
                if (br_lck) {
                        DEBUG(10, ("remove_pending_lock_requests_by_mid - "
                                   "removing request type %d for file %s fnum "
-                                  "= %d\n", blr->req->cmd, fsp->fsp_name,
+                                  "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
                                   fsp->fnum ));
 
                        brl_lock_cancel(br_lck,
@@ -703,7 +704,7 @@ void process_blocking_lock_queue(void)
                                DEBUG(5,("process_blocking_lock_queue: "
                                         "pending lock fnum = %d for file %s "
                                         "timed out.\n", blr->fsp->fnum,
-                                        blr->fsp->fsp_name ));
+                                        fsp_str_dbg(blr->fsp)));
 
                                brl_lock_cancel(br_lck,
                                        blr->lock_pid,
index 2eb09d176d38286828abc9786b376fe6280c007e..64f988f1f730e8eab0680a4aa66857844a87eae8 100644 (file)
@@ -1024,7 +1024,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
        int i;
        uint32 pwHisLen, curr_pwHisLen;
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen);
        if (pwHisLen == 0) {
                return False;
        }
@@ -1107,7 +1107,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
         * denies machines to change the password. *
         * Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */
        if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) {
-               if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
+               if (pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
                        DEBUG(1, ("Machine %s cannot change password now, "
                                  "denied by Refuse Machine Password Change policy\n",
                                  username));
@@ -1130,7 +1130,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
                return NT_STATUS_ACCOUNT_RESTRICTION;
        }
 
-       if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
+       if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
                DEBUG(1, ("user %s cannot change password - password too short\n", 
                          username));
                DEBUGADD(1, (" account policy min password len = %d\n", min_len));
index a0672f3949faa3a35f09d2acda7bf8e262de660e..788b0a7ceca6f3f12fe7dd7f4816199314f798f8 100644 (file)
@@ -36,90 +36,99 @@ static NTSTATUS check_magic(struct files_struct *fsp)
        TALLOC_CTX *ctx = NULL;
        const char *p;
        struct connection_struct *conn = fsp->conn;
+       char *fname = NULL;
+       NTSTATUS status;
 
        if (!*lp_magicscript(SNUM(conn))) {
                return NT_STATUS_OK;
        }
 
-       DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
+       DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
+
+       ctx = talloc_stackframe();
 
-       if (!(p = strrchr_m(fsp->fsp_name,'/'))) {
-               p = fsp->fsp_name;
+       fname = fsp->fsp_name->base_name;
+
+       if (!(p = strrchr_m(fname,'/'))) {
+               p = fname;
        } else {
                p++;
        }
 
        if (!strequal(lp_magicscript(SNUM(conn)),p)) {
-               return NT_STATUS_OK;
+               status = NT_STATUS_OK;
+               goto out;
        }
 
-       ctx = talloc_stackframe();
-
        if (*lp_magicoutput(SNUM(conn))) {
                magic_output = lp_magicoutput(SNUM(conn));
        } else {
                magic_output = talloc_asprintf(ctx,
                                "%s.out",
-                               fsp->fsp_name);
+                               fname);
        }
        if (!magic_output) {
-               TALLOC_FREE(ctx);
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
        }
 
        /* Ensure we don't depend on user's PATH. */
-       p = talloc_asprintf(ctx, "./%s", fsp->fsp_name);
+       p = talloc_asprintf(ctx, "./%s", fname);
        if (!p) {
-               TALLOC_FREE(ctx);
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
        }
 
-       if (chmod(fsp->fsp_name,0755) == -1) {
-               TALLOC_FREE(ctx);
-               return map_nt_error_from_unix(errno);
+       if (chmod(fname, 0755) == -1) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
        }
        ret = smbrun(p,&tmp_fd);
        DEBUG(3,("Invoking magic command %s gave %d\n",
                p,ret));
 
-       unlink(fsp->fsp_name);
+       unlink(fname);
        if (ret != 0 || tmp_fd == -1) {
                if (tmp_fd != -1) {
                        close(tmp_fd);
                }
-               TALLOC_FREE(ctx);
-               return NT_STATUS_UNSUCCESSFUL;
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto out;
        }
        outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
        if (outfd == -1) {
                int err = errno;
                close(tmp_fd);
-               TALLOC_FREE(ctx);
-               return map_nt_error_from_unix(err);
+               status = map_nt_error_from_unix(err);
+               goto out;
        }
 
        if (sys_fstat(tmp_fd,&st) == -1) {
                int err = errno;
                close(tmp_fd);
                close(outfd);
-               TALLOC_FREE(ctx);
-               return map_nt_error_from_unix(err);
+               status = map_nt_error_from_unix(err);
+               goto out;
        }
 
        if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
                int err = errno;
                close(tmp_fd);
                close(outfd);
-               TALLOC_FREE(ctx);
-               return map_nt_error_from_unix(err);
+               status = map_nt_error_from_unix(err);
+               goto out;
        }
        close(tmp_fd);
        if (close(outfd) == -1) {
-               TALLOC_FREE(ctx);
-               return map_nt_error_from_unix(errno);
+               status = map_nt_error_from_unix(errno);
+               goto out;
        }
+
+       status = NT_STATUS_OK;
+
+ out:
        TALLOC_FREE(ctx);
-       return NT_STATUS_OK;
+       return status;
 }
 
 /****************************************************************************
@@ -261,18 +270,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        bool delete_file = false;
        bool changed_user = false;
        struct share_mode_lock *lck = NULL;
-       struct smb_filename *smb_fname = NULL;
-       char *fname = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int ret;
        struct file_id id;
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto done;
-       }
-
        /*
         * Lock the share entries, and determine if we should delete
         * on close. If so delete whilst the lock is still in effect.
@@ -284,7 +285,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
        if (lck == NULL) {
                DEBUG(0, ("close_remove_share_mode: Could not get share mode "
-                         "lock for file %s\n", smb_fname_str_dbg(smb_fname)));
+                         "lock for file %s\n", fsp_str_dbg(fsp)));
                status = NT_STATUS_INVALID_PARAMETER;
                goto done;
        }
@@ -296,7 +297,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        if (!del_share_mode(lck, fsp)) {
                DEBUG(0, ("close_remove_share_mode: Could not delete share "
                          "entry for file %s\n",
-                         smb_fname_str_dbg(smb_fname)));
+                         fsp_str_dbg(fsp)));
        }
 
        if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
@@ -354,7 +355,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
         */
 
        DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
-                "- deleting file.\n", smb_fname_str_dbg(smb_fname)));
+                "- deleting file.\n", fsp_str_dbg(fsp)));
 
        /*
         * Don't try to update the write time when we delete the file
@@ -366,7 +367,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
                DEBUG(5,("close_remove_share_mode: file %s. "
                        "Change user to uid %u\n",
-                       smb_fname_str_dbg(smb_fname),
+                       fsp_str_dbg(fsp),
                        (unsigned int)lck->delete_token->uid));
 
                if (!push_sec_ctx()) {
@@ -387,30 +388,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
           hasn't been renamed. */
 
        if (fsp->posix_open) {
-               ret = SMB_VFS_LSTAT(conn, smb_fname);
+               ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
        } else {
-               ret = SMB_VFS_STAT(conn, smb_fname);
+               ret = SMB_VFS_STAT(conn, fsp->fsp_name);
        }
 
        if (ret != 0) {
                DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
                         "was set and stat failed with error %s\n",
-                        smb_fname_str_dbg(smb_fname), strerror(errno)));
+                        fsp_str_dbg(fsp), strerror(errno)));
                /*
                 * Don't save the errno here, we ignore this error
                 */
                goto done;
        }
 
-       id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+       id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
 
        if (!file_id_equal(&fsp->file_id, &id)) {
                DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
                         "was set and dev and/or inode does not match\n",
-                        smb_fname_str_dbg(smb_fname)));
+                        fsp_str_dbg(fsp)));
                DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
                         "stat file_id %s\n",
-                        smb_fname_str_dbg(smb_fname),
+                        fsp_str_dbg(fsp),
                         file_id_string_tos(&fsp->file_id),
                         file_id_string_tos(&id)));
                /*
@@ -420,9 +421,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        }
 
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-           && !is_ntfs_stream_smb_fname(smb_fname)) {
+           && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
 
-               status = delete_all_streams(conn, smb_fname->base_name);
+               status = delete_all_streams(conn, fsp->fsp_name->base_name);
 
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5, ("delete_all_streams failed: %s\n",
@@ -432,7 +433,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        }
 
 
-       if (SMB_VFS_UNLINK(conn, smb_fname) != 0) {
+       if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
                /*
                 * This call can potentially fail as another smbd may
                 * have had the file open with delete on close set and
@@ -443,21 +444,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
                DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
                         "was set and unlink failed with error %s\n",
-                        smb_fname_str_dbg(smb_fname), strerror(errno)));
+                        fsp_str_dbg(fsp), strerror(errno)));
 
                status = map_nt_error_from_unix(errno);
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto done;
-       }
-
        notify_fname(conn, NOTIFY_ACTION_REMOVED,
                     FILE_NOTIFY_CHANGE_FILE_NAME,
-                    fname);
-
-       TALLOC_FREE(fname);
+                    fsp->fsp_name->base_name);
 
        /* As we now have POSIX opens which can unlink
         * with other open files we may have taken
@@ -476,7 +470,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        }
 
        TALLOC_FREE(lck);
-       TALLOC_FREE(smb_fname);
        return status;
 }
 
@@ -499,7 +492,6 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts)
 
 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
 {
-       struct smb_filename *smb_fname = NULL;
        struct smb_file_time ft;
        NTSTATUS status;
        int ret = -1;
@@ -514,43 +506,32 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
                fsp->close_write_time = timespec_current();
        }
 
-       /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /* Ensure we have a valid stat struct for the source. */
        if (fsp->fh->fd != -1) {
-               ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+               ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
        } else {
                if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(fsp->conn, smb_fname);
+                       ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
                } else {
-                       ret = SMB_VFS_STAT(fsp->conn, smb_fname);
+                       ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
                }
        }
 
        if (ret == -1) {
-               status = map_nt_error_from_unix(errno);
-               goto out;
+               return map_nt_error_from_unix(errno);
        }
 
-       if (!VALID_STAT(smb_fname->st)) {
+       if (!VALID_STAT(fsp->fsp_name->st)) {
                /* if it doesn't seem to be a real file */
-               status = NT_STATUS_OK;
-               goto out;
+               return NT_STATUS_OK;
        }
 
        ft.mtime = fsp->close_write_time;
-       status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true);
+       status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
-               goto out;
+               return status;
        }
 
- out:
-       TALLOC_FREE(smb_fname);
        return status;
 }
 
@@ -647,7 +628,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
        status = ntstatus_keeperror(status, tmp);
 
        DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
-               conn->server_info->unix_name,fsp->fsp_name,
+               conn->server_info->unix_name, fsp_str_dbg(fsp),
                conn->num_files_open - 1,
                nt_errstr(status) ));
 
@@ -663,16 +644,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                                enum file_close_type close_type)
 {
        struct share_mode_lock *lck = NULL;
-       struct smb_filename *smb_dname = NULL;
        bool delete_dir = False;
        NTSTATUS status = NT_STATUS_OK;
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_dname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /*
         * NT can set delete_on_close of the last open
         * reference to a directory also.
@@ -683,14 +657,14 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 
        if (lck == NULL) {
                DEBUG(0, ("close_directory: Could not get share mode lock for "
-                         "%s\n", smb_fname_str_dbg(smb_dname)));
+                         "%s\n", fsp_str_dbg(fsp)));
                status = NT_STATUS_INVALID_PARAMETER;
                goto out;
        }
 
        if (!del_share_mode(lck, fsp)) {
                DEBUG(0, ("close_directory: Could not delete share entry for "
-                         "%s\n", smb_fname_str_dbg(smb_dname)));
+                         "%s\n", fsp_str_dbg(fsp)));
        }
 
        if (fsp->initial_delete_on_close) {
@@ -704,7 +678,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                        become_user(fsp->conn, fsp->vuid);
                        became_user = True;
                }
-               send_stat_cache_delete_message(fsp->fsp_name);
+               send_stat_cache_delete_message(fsp->fsp_name->base_name);
                set_delete_on_close_lck(lck, True, &current_user.ut);
                if (became_user) {
                        unbecome_user();
@@ -747,11 +721,12 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 
                TALLOC_FREE(lck);
 
-               status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname);
+               status = rmdir_internals(talloc_tos(), fsp->conn,
+                                        fsp->fsp_name);
 
                DEBUG(5,("close_directory: %s. Delete on close was set - "
                         "deleting directory returned %s.\n",
-                        smb_fname_str_dbg(smb_dname), nt_errstr(status)));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
 
                /* unbecome user. */
                pop_sec_ctx();
@@ -774,7 +749,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
-                         smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno,
+                         fsp_str_dbg(fsp), fsp->fh->fd, errno,
                          strerror(errno)));
        }
 
@@ -786,7 +761,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 
  out:
        TALLOC_FREE(lck);
-       TALLOC_FREE(smb_dname);
        return status;
 }
 
index ca926aa33c55a031e3bc05d7734f4289372a54a9..bd0c7df95974a3cc0427276d160fde063074aae5 100644 (file)
@@ -448,8 +448,8 @@ static bool get_stat_dos_flags(connection_struct *conn,
        if (S_ISDIR(smb_fname->st.st_ex_mode))
                *dosmode |= aDIR;
 
-       *dosmode |= set_sparse_flag(smb_fname->st);
-       *dosmode |= set_link_read_only_flag(smb_fname->st);
+       *dosmode |= set_sparse_flag(&smb_fname->st);
+       *dosmode |= set_link_read_only_flag(&smb_fname->st);
 
        return true;
 }
@@ -845,7 +845,7 @@ bool update_write_time(struct files_struct *fsp)
        }
 
        notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
-                       FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name);
+                    FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
 
        return true;
 }
index ce22f86414b385b7ff6faa0630e04aa21b83f137..874efa2a0b37fc3a5fd30b9f11afa53748c7c5e9 100644 (file)
@@ -136,33 +136,3 @@ void reply_openerror(struct smb_request *req, NTSTATUS status)
                reply_nterror(req, status);
        }
 }
-
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
-                       NTSTATUS defstatus, int line, const char *file)
-{
-       int eclass=defclass;
-       int ecode=defcode;
-       NTSTATUS ntstatus = defstatus;
-       int i=0;
-
-       TALLOC_FREE(req->outbuf);
-       reply_outbuf(req, 0, 0);
-
-       if (errno != 0) {
-               DEBUG(3,("unix_error_packet: error string = %s\n",
-                       strerror(errno)));
-
-               while (unix_dos_nt_errmap[i].dos_class != 0) {
-                       if (unix_dos_nt_errmap[i].unix_error == errno) {
-                               eclass = unix_dos_nt_errmap[i].dos_class;
-                               ecode = unix_dos_nt_errmap[i].dos_code;
-                               ntstatus = unix_dos_nt_errmap[i].nt_error;
-                               break;
-                       }
-                       i++;
-               }
-       }
-
-       error_packet_set((char *)req->outbuf, eclass, ecode, ntstatus,
-               line, file);
-}
index ef54398bc451338768b83a9436ed6106305a8b21..743d88f360c6d27d098c3611b01a4badf5cde7b4 100644 (file)
@@ -71,23 +71,32 @@ static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type)
  Does this name match a fake filename ?
 ****************************************************************************/
 
-enum FAKE_FILE_TYPE is_fake_file(const char *fname)
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
 {
 #ifdef HAVE_SYS_QUOTAS
        int i;
+       char *fname = NULL;
+       NTSTATUS status;
 #endif
 
-       if (!fname) {
+       if (!smb_fname) {
                return FAKE_FILE_TYPE_NONE;
        }
 
 #ifdef HAVE_SYS_QUOTAS
+       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return FAKE_FILE_TYPE_NONE;
+       }
+
        for (i=0;fake_files[i].name!=NULL;i++) {
                if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
                        DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
+                       TALLOC_FREE(fname);
                        return fake_files[i].type;
                }
        }
+       TALLOC_FREE(fname);
 #endif
 
        return FAKE_FILE_TYPE_NONE;
@@ -101,7 +110,7 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname)
 NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
                                uint16_t current_vuid,
                                enum FAKE_FILE_TYPE fake_file_type,
-                               const char *fname,
+                               const struct smb_filename *smb_fname,
                                uint32 access_mask,
                                files_struct **result)
 {
@@ -112,7 +121,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
        if (conn->server_info->utok.uid != 0) {
                DEBUG(3, ("open_fake_file_shared: access_denied to "
                          "service[%s] file[%s] user[%s]\n",
-                         lp_servicename(SNUM(conn)), fname,
+                         lp_servicename(SNUM(conn)),
+                         smb_fname_str_dbg(smb_fname),
                          conn->server_info->unix_name));
                return NT_STATUS_ACCESS_DENIED;
 
@@ -124,7 +134,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
        }
 
        DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
-               fname, fsp->fnum, (unsigned int)access_mask));
+                smb_fname_str_dbg(smb_fname), fsp->fnum,
+                (unsigned int)access_mask));
 
        fsp->conn = conn;
        fsp->fh->fd = -1;
@@ -132,8 +143,12 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
        fsp->fh->pos = -1;
        fsp->can_lock = False; /* Should this be true ? - No, JRA */
        fsp->access_mask = access_mask;
-       string_set(&fsp->fsp_name,fname);
-       
+       status = fsp_set_smb_fname(fsp, smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               file_free(req, fsp);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
        
        if (fsp->fake_file_handle==NULL) {
index d8fee1db06f538878b244a716b9648017e17c4fe..7d0a552956e508e7787764072d875a98929dc0ac 100644 (file)
@@ -33,7 +33,6 @@ bool can_access_file_acl(struct connection_struct *conn,
        NTSTATUS status;
        uint32_t access_granted;
        struct security_descriptor *secdesc = NULL;
-       char *fname = NULL;
        bool ret;
 
        if (conn->server_info->utok.uid == 0 || conn->admin_user) {
@@ -41,13 +40,7 @@ bool can_access_file_acl(struct connection_struct *conn,
                return true;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               ret = false;
-               goto out;
-       }
-
-       status = SMB_VFS_GET_NT_ACL(conn, fname,
+       status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
                                    (OWNER_SECURITY_INFORMATION |
                                     GROUP_SECURITY_INFORMATION |
                                     DACL_SECURITY_INFORMATION),
@@ -62,7 +55,6 @@ bool can_access_file_acl(struct connection_struct *conn,
                                 access_mask, &access_granted);
        ret = NT_STATUS_IS_OK(status);
  out:
-       TALLOC_FREE(fname);
        TALLOC_FREE(secdesc);
        return ret;
 }
index 0c13b845df86482cd7d8b74945013ed5105db316..bd609d3e867798e42163e8d0136f9756b9356cdb 100644 (file)
@@ -57,6 +57,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
 
        /* you can't read from print files */
        if (fsp->print_file) {
+               errno = EBADF;
                return -1;
        }
 
@@ -102,7 +103,7 @@ tryagain:
        }
 
        DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
-               fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+                 fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
 
        fsp->fh->pos += ret;
        fsp->fh->position_information = fsp->fh->pos;
@@ -135,7 +136,7 @@ static ssize_t real_write_file(struct smb_request *req,
        }
 
        DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
-               fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+                 fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
 
        if (ret != -1) {
                fsp->fh->pos += ret;
@@ -163,8 +164,9 @@ static int wcp_file_size_change(files_struct *fsp)
        wcp->file_size = wcp->offset + wcp->data_size;
        ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size);
        if (ret == -1) {
-               DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
-                       fsp->fsp_name, (double)wcp->file_size, strerror(errno) ));
+               DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f "
+                        "error %s\n", fsp_str_dbg(fsp),
+                        (double)wcp->file_size, strerror(errno)));
        }
        return ret;
 }
@@ -178,7 +180,7 @@ static void update_write_time_handler(struct event_context *ctx,
 
        /* Remove the timed event handler. */
        TALLOC_FREE(fsp->update_write_time_event);
-       DEBUG(5, ("Update write time on %s\n", fsp->fsp_name));
+       DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
 
        /* change the write time if not already changed by someone else */
        update_write_time(fsp);
@@ -243,7 +245,8 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
         }
 
        TALLOC_FREE(fsp->update_write_time_event);
-       DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name));
+       DEBUG(5, ("Update write time immediate on %s\n",
+                 fsp_str_dbg(fsp)));
 
        fsp->update_write_time_triggered = true;
 
@@ -284,28 +287,17 @@ ssize_t write_file(struct smb_request *req,
        }
 
        if (!fsp->modified) {
-               struct smb_filename *smb_fname = NULL;
-               NTSTATUS status;
-
                fsp->modified = True;
 
-               status = create_synthetic_smb_fname_split(talloc_tos(),
-                                                         fsp->fsp_name, NULL,
-                                                         &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       return -1;
-               }
-
-               if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) {
+               if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) {
                        int dosmode;
                        trigger_write_time_update(fsp);
-                       dosmode = dos_mode(fsp->conn, smb_fname);
+                       dosmode = dos_mode(fsp->conn, fsp->fsp_name);
                        if ((lp_store_dos_attributes(SNUM(fsp->conn)) ||
                                        MAP_ARCHIVE(fsp->conn)) &&
                                        !IS_DOS_ARCHIVE(dosmode)) {
-                               file_set_dosmode(fsp->conn, smb_fname,
-                                               dosmode | aARCH, NULL, false);
+                               file_set_dosmode(fsp->conn, fsp->fsp_name,
+                                                dosmode | aARCH, NULL, false);
                        }
 
                        /*
@@ -315,11 +307,10 @@ ssize_t write_file(struct smb_request *req,
 
                        if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
                                setup_write_cache(fsp,
-                                                 smb_fname->st.st_ex_size);
+                                                fsp->fsp_name->st.st_ex_size);
                                wcp = fsp->wcp;
                        }
                }
-               TALLOC_FREE(smb_fname);
        }
 
 #ifdef WITH_PROFILE
@@ -381,8 +372,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
                return total_written;
        }
 
-       DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
-               fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
+       DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f "
+                "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd,
+                (double)pos, (unsigned int)n, (double)wcp->offset,
+                (unsigned int)wcp->data_size));
 
        fsp->fh->pos = pos + n;
 
@@ -827,7 +820,8 @@ void delete_write_cache(files_struct *fsp)
        SAFE_FREE(wcp->data);
        SAFE_FREE(fsp->wcp);
 
-       DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name ));
+       DEBUG(10,("delete_write_cache: File %s deleted write cache\n",
+                 fsp_str_dbg(fsp)));
 }
 
 /****************************************************************************
@@ -870,7 +864,7 @@ static bool setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
        allocated_write_caches++;
 
        DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
-               fsp->fsp_name, (unsigned long)wcp->alloc_size ));
+                 fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size));
 
        return True;
 }
@@ -887,7 +881,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
                        char *msg;
                        if (asprintf(&msg, "set_filelen_write_cache: size change "
                                 "on file %s with write cache size = %lu\n",
-                                fsp->fsp_name,
+                                fsp->fsp_name->base_name,
                                 (unsigned long)fsp->wcp->data_size) != -1) {
                                smb_panic(msg);
                        } else {
@@ -969,7 +963,13 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug
 int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
 {
        if (fsp->fh->fd == -1) {
-               return vfs_stat_smb_fname(fsp->conn, fsp->fsp_name, pst);
+               int ret;
+
+               ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
+               if (ret != -1) {
+                       *pst = fsp->fsp_name->st;
+               }
+               return ret;
        } else {
                return SMB_VFS_FSTAT(fsp, pst);
        }
index 29ebc37d1a75a90576082a025c0f57d463a75e20..09f9a418bd7f499dd6112f901449b6f816d83081 100644 (file)
@@ -80,201 +80,6 @@ static NTSTATUS determine_path_error(const char *name,
        }
 }
 
-/**
- * XXX: This is temporary and there should be no callers of this outside of
- * this file once smb_filename is plumbed through all path based operations.
- * The one legitimate caller currently is smb_fname_str_dbg(), which this
- * could be made static for.
- */
-NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
-                              char **full_name)
-{
-       if (smb_fname->stream_name) {
-               *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
-                                            smb_fname->stream_name);
-       } else {
-               *full_name = talloc_strdup(ctx, smb_fname->base_name);
-       }
-
-       if (!*full_name) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       return NT_STATUS_OK;
-}
-
-/**
- * There are actually legitimate callers of this such as functions that
- * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
- * operate on each stream.
- */
-NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
-                                   const char *stream_name,
-                                   const SMB_STRUCT_STAT *psbuf,
-                                   struct smb_filename **smb_fname_out)
-{
-       struct smb_filename smb_fname_loc;
-
-       ZERO_STRUCT(smb_fname_loc);
-
-       /* Setup the base_name/stream_name. */
-       smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
-       smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
-
-       /* Copy the psbuf if one was given. */
-       if (psbuf)
-               smb_fname_loc.st = *psbuf;
-
-       /* Let copy_smb_filename() do the heavy lifting. */
-       return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
-                                         const char *fname,
-                                         const SMB_STRUCT_STAT *psbuf,
-                                         struct smb_filename **smb_fname_out)
-{
-       NTSTATUS status;
-       const char *stream_name = NULL;
-       char *base_name = NULL;
-
-       if (!lp_posix_pathnames()) {
-               stream_name = strchr_m(fname, ':');
-       }
-
-       /* Setup the base_name/stream_name. */
-       if (stream_name) {
-               base_name = talloc_strndup(ctx, fname,
-                                          PTR_DIFF(stream_name, fname));
-       } else {
-               base_name = talloc_strdup(ctx, fname);
-       }
-
-       if (!base_name) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
-                                           smb_fname_out);
-       TALLOC_FREE(base_name);
-       return status;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
-                      SMB_STRUCT_STAT *psbuf)
-{
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
-       int ret;
-
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       ret = SMB_VFS_STAT(conn, smb_fname);
-       if (ret != -1) {
-               *psbuf = smb_fname->st;
-       }
-
-       TALLOC_FREE(smb_fname);
-       return ret;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
-                       SMB_STRUCT_STAT *psbuf)
-{
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
-       int ret;
-
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               errno = map_errno_from_nt_status(status);
-               return -1;
-       }
-
-       ret = SMB_VFS_LSTAT(conn, smb_fname);
-       if (ret != -1) {
-               *psbuf = smb_fname->st;
-       }
-
-       TALLOC_FREE(smb_fname);
-       return ret;
-}
-
-/**
- * Return a string using the debug_ctx()
- */
-const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
-{
-       char *fname = NULL;
-       NTSTATUS status;
-
-       if (smb_fname == NULL) {
-               return "";
-       }
-       status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return "";
-       }
-       return fname;
-}
-
-NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
-                          const struct smb_filename *smb_fname_in,
-                          struct smb_filename **smb_fname_out)
-{
-
-       *smb_fname_out = talloc_zero(ctx, struct smb_filename);
-       if (*smb_fname_out == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (smb_fname_in->base_name) {
-               (*smb_fname_out)->base_name =
-                   talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
-               if (!(*smb_fname_out)->base_name)
-                       goto no_mem_err;
-       }
-
-       if (smb_fname_in->stream_name) {
-               (*smb_fname_out)->stream_name =
-                   talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
-               if (!(*smb_fname_out)->stream_name)
-                       goto no_mem_err;
-       }
-
-       if (smb_fname_in->original_lcomp) {
-               (*smb_fname_out)->original_lcomp =
-                   talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
-               if (!(*smb_fname_out)->original_lcomp)
-                       goto no_mem_err;
-       }
-
-       (*smb_fname_out)->st = smb_fname_in->st;
-       return NT_STATUS_OK;
-
- no_mem_err:
-       TALLOC_FREE(*smb_fname_out);
-       return NT_STATUS_NO_MEMORY;
-}
-
 /****************************************************************************
 This routine is called to convert names from the dos namespace to unix
 namespace. It needs to handle any case conversions, mangling, format changes,
@@ -312,23 +117,21 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                      struct smb_filename **smb_fname_out,
                      uint32_t ucf_flags)
 {
-       SMB_STRUCT_STAT st;
        struct smb_filename *smb_fname = NULL;
        char *start, *end;
        char *dirpath = NULL;
-       char *name = NULL;
        char *stream = NULL;
        bool component_was_mangled = False;
        bool name_has_wildcard = False;
        bool posix_pathnames = false;
        bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
        bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
-       NTSTATUS result;
+       NTSTATUS status;
        int ret = -1;
 
        *smb_fname_out = NULL;
 
-       smb_fname = talloc_zero(talloc_tos(), struct smb_filename);
+       smb_fname = talloc_zero(ctx, struct smb_filename);
        if (smb_fname == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -338,10 +141,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                        filename - so don't convert them */
                if (!(smb_fname->base_name = talloc_strdup(smb_fname,
                                                           orig_path))) {
-                       return NT_STATUS_NO_MEMORY;
+                       status = NT_STATUS_NO_MEMORY;
+                       goto err;
                }
-               *smb_fname_out = smb_fname;
-               return NT_STATUS_OK;
+               goto done;
        }
 
        DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
@@ -369,15 +172,16 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
         */
 
        if (!*orig_path) {
-               if (!(name = talloc_strdup(ctx,"."))) {
-                       return NT_STATUS_NO_MEMORY;
+               if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto err;
                }
-               if (vfs_stat_smb_fname(conn,name,&st) == 0) {
-                       smb_fname->st = st;
-               } else {
-                       return map_nt_error_from_unix(errno);
+               if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       goto err;
                }
-               DEBUG(5,("conversion finished \"\" -> %s\n",name));
+               DEBUG(5, ("conversion finished \"\" -> %s\n",
+                         smb_fname->base_name));
                goto done;
        }
 
@@ -385,17 +189,19 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                orig_path[1] == '\0')) {
                /* Start of pathname can't be "." only. */
                if (orig_path[1] == '\0' || orig_path[2] == '\0') {
-                       result = NT_STATUS_OBJECT_NAME_INVALID;
+                       status = NT_STATUS_OBJECT_NAME_INVALID;
                } else {
-                       result =determine_path_error(
-                               &orig_path[2], allow_wcard_last_component);
+                       status =determine_path_error(&orig_path[2],
+                           allow_wcard_last_component);
                }
-               return result;
+               goto err;
        }
 
-       if (!(name = talloc_strdup(ctx, orig_path))) {
+       /* Start with the full orig_path as given by the caller. */
+       if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) {
                DEBUG(0, ("talloc_strdup failed\n"));
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_NO_MEMORY;
+               goto err;
        }
 
        /*
@@ -409,7 +215,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 
        if (conn->case_sensitive && !conn->case_preserve &&
                        !conn->short_case_preserve) {
-               strnorm(name, lp_defaultcase(SNUM(conn)));
+               strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn)));
        }
 
        /*
@@ -417,44 +223,60 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
         */
 
        if(save_last_component) {
-               end = strrchr_m(name, '/');
+               end = strrchr_m(smb_fname->base_name, '/');
                if (end) {
-                       smb_fname->original_lcomp = talloc_strdup(ctx,
+                       smb_fname->original_lcomp = talloc_strdup(smb_fname,
                                                                  end + 1);
                } else {
-                       smb_fname->original_lcomp = talloc_strdup(ctx, name);
+                       smb_fname->original_lcomp =
+                           talloc_strdup(smb_fname, smb_fname->base_name);
+               }
+               if (smb_fname->original_lcomp == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto err;
                }
        }
 
        posix_pathnames = lp_posix_pathnames();
 
-       /* Strip off the stream. Should we use any of the other stream parsing
-        * at this point? Also, should we set the is_stream bit? */
+       /*
+        * Strip off the stream, and add it back when we're done with the
+        * base_name.
+        */
        if (!posix_pathnames) {
-               stream = strchr_m(name, ':');
+               stream = strchr_m(smb_fname->base_name, ':');
 
                if (stream != NULL) {
-                       char *tmp = talloc_strdup(ctx, stream);
+                       char *tmp = talloc_strdup(smb_fname, stream);
                        if (tmp == NULL) {
-                               TALLOC_FREE(name);
-                               return NT_STATUS_NO_MEMORY;
+                               status = NT_STATUS_NO_MEMORY;
+                               goto err;
                        }
+                       /*
+                        * Since this is actually pointing into
+                        * smb_fname->base_name this truncates base_name.
+                        */
                        *stream = '\0';
                        stream = tmp;
                }
        }
 
-       start = name;
+       start = smb_fname->base_name;
 
-       /* If we're providing case insentive semantics or
+       /*
+        * If we're providing case insentive semantics or
         * the underlying filesystem is case insensitive,
         * then a case-normalized hit in the stat-cache is
         * authoratitive. JRA.
+        *
+        * Note: We're only checking base_name.  The stream_name will be
+        * added and verified in build_stream_path().
         */
 
-       if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
-                       stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
-               smb_fname->st = st;
+       if((!conn->case_sensitive || !(conn->fs_capabilities &
+                                      FILE_CASE_SENSITIVE_SEARCH)) &&
+           stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start,
+                             &smb_fname->st)) {
                goto done;
        }
 
@@ -465,43 +287,46 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 
        if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
                DEBUG(0, ("talloc_strdup failed\n"));
-               TALLOC_FREE(name);
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_NO_MEMORY;
+               goto err;
        }
 
        /*
-        * stat the name - if it exists then we are all done!
+        * stat the name - if it exists then we can add the stream back (if
+        * there was one) and be done!
         */
 
        if (posix_pathnames) {
-               ret = vfs_lstat_smb_fname(conn,name,&st);
+               ret = SMB_VFS_LSTAT(conn, smb_fname);
        } else {
-               ret = vfs_stat_smb_fname(conn,name,&st);
+               ret = SMB_VFS_STAT(conn, smb_fname);
        }
 
        if (ret == 0) {
                /* Ensure we catch all names with in "/."
                   this is disallowed under Windows. */
-               const char *p = strstr(name, "/."); /* mb safe. */
+               const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
                if (p) {
                        if (p[2] == '/') {
                                /* Error code within a pathname. */
-                               result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+                               status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
                                goto fail;
                        } else if (p[2] == '\0') {
                                /* Error code at the end of a pathname. */
-                               result = NT_STATUS_OBJECT_NAME_INVALID;
+                               status = NT_STATUS_OBJECT_NAME_INVALID;
                                goto fail;
                        }
                }
-               stat_cache_add(orig_path, name, conn->case_sensitive);
-               DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
-               smb_fname->st = st;
+               /* Add the path (not including the stream) to the cache. */
+               stat_cache_add(orig_path, smb_fname->base_name,
+                              conn->case_sensitive);
+               DEBUG(5,("conversion of base_name finished %s -> %s\n",
+                        orig_path, smb_fname->base_name));
                goto done;
        }
 
        DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
-                               name, dirpath, start));
+                smb_fname->base_name, dirpath, start));
 
        /*
         * A special case - if we don't have any mangling chars and are case
@@ -509,8 +334,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
         * won't help.
         */
 
-       if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
-                       !mangle_is_mangled(name, conn->params)) {
+       if ((conn->case_sensitive || !(conn->fs_capabilities &
+                                      FILE_CASE_SENSITIVE_SEARCH)) &&
+           !mangle_is_mangled(smb_fname->base_name, conn->params)) {
                goto done;
        }
 
@@ -549,11 +375,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 
                if (save_last_component) {
                        TALLOC_FREE(smb_fname->original_lcomp);
-                       smb_fname->original_lcomp = talloc_strdup(ctx,
+                       smb_fname->original_lcomp = talloc_strdup(smb_fname,
                                                        end ? end + 1 : start);
                        if (!smb_fname->original_lcomp) {
                                DEBUG(0, ("talloc failed\n"));
-                               return NT_STATUS_NO_MEMORY;
+                               status = NT_STATUS_NO_MEMORY;
+                               goto err;
                        }
                }
 
@@ -562,9 +389,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                if (ISDOT(start)) {
                        if (!end)  {
                                /* Error code at the end of a pathname. */
-                               result = NT_STATUS_OBJECT_NAME_INVALID;
+                               status = NT_STATUS_OBJECT_NAME_INVALID;
                        } else {
-                               result = determine_path_error(end+1,
+                               status = determine_path_error(end+1,
                                                allow_wcard_last_component);
                        }
                        goto fail;
@@ -577,13 +404,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 
                /* Wildcard not valid anywhere. */
                if (name_has_wildcard && !allow_wcard_last_component) {
-                       result = NT_STATUS_OBJECT_NAME_INVALID;
+                       status = NT_STATUS_OBJECT_NAME_INVALID;
                        goto fail;
                }
 
                /* Wildcards never valid within a pathname. */
                if (name_has_wildcard && end) {
-                       result = NT_STATUS_OBJECT_NAME_INVALID;
+                       status = NT_STATUS_OBJECT_NAME_INVALID;
                        goto fail;
                }
 
@@ -592,9 +419,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                 */
 
                if (posix_pathnames) {
-                       ret = vfs_lstat_smb_fname(conn,name, &st);
+                       ret = SMB_VFS_LSTAT(conn, smb_fname);
                } else {
-                       ret = vfs_stat_smb_fname(conn,name, &st);
+                       ret = SMB_VFS_STAT(conn, smb_fname);
                }
 
                if (ret == 0) {
@@ -602,7 +429,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                         * It exists. it must either be a directory or this must
                         * be the last part of the path for it to be OK.
                         */
-                       if (end && !S_ISDIR(st.st_ex_mode)) {
+                       if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) {
                                /*
                                 * An intermediate part of the name isn't
                                 * a directory.
@@ -617,25 +444,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                 * applications depend on the difference between
                                 * these two errors.
                                 */
-                               result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+                               status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
                                goto fail;
                        }
 
-                       if (!end) {
-                               /*
-                                * We just scanned for, and found the end of
-                                * the path. We must return the valid stat
-                                * struct. JRA.
-                                */
-
-                               smb_fname->st = st;
-                       }
-
                } else {
                        char *found_name = NULL;
 
                        /* Stat failed - ensure we don't use it. */
-                       SET_STAT_INVALID(st);
+                       SET_STAT_INVALID(smb_fname->st);
 
                        /*
                         * Reset errno so we can detect
@@ -681,11 +498,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                        if (errno == ENOENT ||
                                                        errno == ENOTDIR ||
                                                        errno == ELOOP) {
-                                               result =
+                                               status =
                                                NT_STATUS_OBJECT_PATH_NOT_FOUND;
                                        }
                                        else {
-                                               result =
+                                               status =
                                                map_nt_error_from_unix(errno);
                                        }
                                        goto fail;
@@ -706,10 +523,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                         */
                                        if (errno == ENOTDIR ||
                                                        errno == ELOOP) {
-                                               result =
+                                               status =
                                                NT_STATUS_OBJECT_PATH_NOT_FOUND;
                                        } else {
-                                               result =
+                                               status =
                                                map_nt_error_from_unix(errno);
                                        }
                                        goto fail;
@@ -741,12 +558,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                                        &unmangled,
                                                        conn->params)) {
                                        char *tmp;
-                                       size_t start_ofs = start - name;
+                                       size_t start_ofs =
+                                           start - smb_fname->base_name;
 
                                        if (*dirpath != '\0') {
-                                               tmp = talloc_asprintf(ctx,
-                                                       "%s/%s", dirpath,
-                                                       unmangled);
+                                               tmp = talloc_asprintf(
+                                                       smb_fname, "%s/%s",
+                                                       dirpath, unmangled);
                                                TALLOC_FREE(unmangled);
                                        }
                                        else {
@@ -754,11 +572,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                        }
                                        if (tmp == NULL) {
                                                DEBUG(0, ("talloc failed\n"));
-                                               return NT_STATUS_NO_MEMORY;
+                                               status = NT_STATUS_NO_MEMORY;
+                                               goto err;
                                        }
-                                       TALLOC_FREE(name);
-                                       name = tmp;
-                                       start = name + start_ofs;
+                                       TALLOC_FREE(smb_fname->base_name);
+                                       smb_fname->base_name = tmp;
+                                       start =
+                                           smb_fname->base_name + start_ofs;
                                        end = start + strlen(start);
                                }
 
@@ -773,46 +593,50 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                         */
                        if (end) {
                                char *tmp;
-                               size_t start_ofs = start - name;
+                               size_t start_ofs =
+                                   start - smb_fname->base_name;
 
                                if (*dirpath != '\0') {
-                                       tmp = talloc_asprintf(ctx,
+                                       tmp = talloc_asprintf(smb_fname,
                                                "%s/%s/%s", dirpath,
                                                found_name, end+1);
                                }
                                else {
-                                       tmp = talloc_asprintf(ctx,
+                                       tmp = talloc_asprintf(smb_fname,
                                                "%s/%s", found_name,
                                                end+1);
                                }
                                if (tmp == NULL) {
                                        DEBUG(0, ("talloc_asprintf failed\n"));
-                                       return NT_STATUS_NO_MEMORY;
+                                       status = NT_STATUS_NO_MEMORY;
+                                       goto err;
                                }
-                               TALLOC_FREE(name);
-                               name = tmp;
-                               start = name + start_ofs;
+                               TALLOC_FREE(smb_fname->base_name);
+                               smb_fname->base_name = tmp;
+                               start = smb_fname->base_name + start_ofs;
                                end = start + strlen(found_name);
                                *end = '\0';
                        } else {
                                char *tmp;
-                               size_t start_ofs = start - name;
+                               size_t start_ofs =
+                                   start - smb_fname->base_name;
 
                                if (*dirpath != '\0') {
-                                       tmp = talloc_asprintf(ctx,
+                                       tmp = talloc_asprintf(smb_fname,
                                                "%s/%s", dirpath,
                                                found_name);
                                } else {
-                                       tmp = talloc_strdup(ctx,
+                                       tmp = talloc_strdup(smb_fname,
                                                found_name);
                                }
                                if (tmp == NULL) {
                                        DEBUG(0, ("talloc failed\n"));
-                                       return NT_STATUS_NO_MEMORY;
+                                       status = NT_STATUS_NO_MEMORY;
+                                       goto err;
                                }
-                               TALLOC_FREE(name);
-                               name = tmp;
-                               start = name + start_ofs;
+                               TALLOC_FREE(smb_fname->base_name);
+                               smb_fname->base_name = tmp;
+                               start = smb_fname->base_name + start_ofs;
 
                                /*
                                 * We just scanned for, and found the end of
@@ -821,17 +645,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                 */
 
                                if (posix_pathnames) {
-                                       ret = vfs_lstat_smb_fname(conn,name,
-                                                                 &st);
+                                       ret = SMB_VFS_LSTAT(conn, smb_fname);
                                } else {
-                                       ret = vfs_stat_smb_fname(conn,name,
-                                                                &st);
+                                       ret = SMB_VFS_STAT(conn, smb_fname);
                                }
 
-                               if (ret == 0) {
-                                       smb_fname->st = st;
-                               } else {
-                                       SET_STAT_INVALID(st);
+                               if (ret != 0) {
+                                       SET_STAT_INVALID(smb_fname->st);
                                }
                        }
 
@@ -844,12 +664,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                 * We should never provide different behaviors
                 * depending on DEVELOPER!!!
                 */
-               if (VALID_STAT(st)) {
+               if (VALID_STAT(smb_fname->st)) {
                        bool delete_pending;
-                       get_file_infos(vfs_file_id_from_sbuf(conn, &st),
+                       get_file_infos(vfs_file_id_from_sbuf(conn,
+                                                            &smb_fname->st),
                                       &delete_pending, NULL);
                        if (delete_pending) {
-                               result = NT_STATUS_DELETE_PENDING;
+                               status = NT_STATUS_DELETE_PENDING;
                                goto fail;
                        }
                }
@@ -864,7 +685,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                                        "%s/%s", dirpath, start);
                        if (!tmp) {
                                DEBUG(0, ("talloc_asprintf failed\n"));
-                               return NT_STATUS_NO_MEMORY;
+                               status = NT_STATUS_NO_MEMORY;
+                               goto err;
                        }
                        TALLOC_FREE(dirpath);
                        dirpath = tmp;
@@ -873,15 +695,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
                        TALLOC_FREE(dirpath);
                        if (!(dirpath = talloc_strdup(ctx,start))) {
                                DEBUG(0, ("talloc_strdup failed\n"));
-                               return NT_STATUS_NO_MEMORY;
+                               status = NT_STATUS_NO_MEMORY;
+                               goto err;
                        }
                }
 
                /*
-                * Don't cache a name with mangled or wildcard components
-                * as this can change the size.
+                * Cache the dirpath thus far. Don't cache a name with mangled
+                * or wildcard components as this can change the size.
                 */
-
                if(!component_was_mangled && !name_has_wildcard) {
                        stat_cache_add(orig_path, dirpath,
                                        conn->case_sensitive);
@@ -896,29 +718,30 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
        }
 
        /*
-        * Don't cache a name with mangled or wildcard components
-        * as this can change the size.
+        * Cache the full path. Don't cache a name with mangled or wildcard
+        * components as this can change the size.
         */
 
        if(!component_was_mangled && !name_has_wildcard) {
-               stat_cache_add(orig_path, name, conn->case_sensitive);
+               stat_cache_add(orig_path, smb_fname->base_name,
+                              conn->case_sensitive);
        }
 
        /*
         * The name has been resolved.
         */
 
-       DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
+       DEBUG(5,("conversion finished %s -> %s\n", orig_path,
+                smb_fname->base_name));
 
  done:
-       smb_fname->base_name = name;
-
+       /* Add back the stream if one was stripped off originally. */
        if (stream != NULL) {
                smb_fname->stream_name = stream;
 
                /* Check path now that the base_name has been converted. */
-               result = build_stream_path(ctx, conn, orig_path, smb_fname);
-               if (!NT_STATUS_IS_OK(result)) {
+               status = build_stream_path(ctx, conn, orig_path, smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
                        goto fail;
                }
        }
@@ -928,20 +751,23 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
  fail:
        DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
        if (*dirpath != '\0') {
-               smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath,
-                                                      start);
+               smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s",
+                                                      dirpath, start);
        } else {
-               smb_fname->base_name = talloc_strdup(ctx, start);
+               smb_fname->base_name = talloc_strdup(smb_fname, start);
        }
        if (!smb_fname->base_name) {
                DEBUG(0, ("talloc_asprintf failed\n"));
-               return NT_STATUS_NO_MEMORY;
+               status = NT_STATUS_NO_MEMORY;
+               goto err;
        }
 
        *smb_fname_out = smb_fname;
-       TALLOC_FREE(name);
        TALLOC_FREE(dirpath);
-       return result;
+       return status;
+ err:
+       TALLOC_FREE(smb_fname);
+       return status;
 }
 
 /****************************************************************************
@@ -1137,6 +963,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        struct stream_struct *streams = NULL;
 
        if (SMB_VFS_STAT(conn, smb_fname) == 0) {
+               DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
                return NT_STATUS_OK;
        }
 
@@ -1183,21 +1010,16 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
 
 
        TALLOC_FREE(smb_fname->stream_name);
-       smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name);
+       smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name);
+       if (smb_fname->stream_name == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
 
        SET_STAT_INVALID(smb_fname->st);
 
        if (SMB_VFS_STAT(conn, smb_fname) == 0) {
-               char *result = NULL;
-
-               status = get_full_smb_filename(mem_ctx, smb_fname, &result);
-               if (!NT_STATUS_IS_OK(status)) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto fail;
-               }
-
-               stat_cache_add(orig_path, result, conn->case_sensitive);
-               TALLOC_FREE(result);
+               DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
        }
        status = NT_STATUS_OK;
  fail:
@@ -1213,8 +1035,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
                                connection_struct *conn,
                                bool dfs_path,
                                const char *name_in,
-                               struct smb_filename **pp_smb_fname,
-                               char **pp_name)
+                               struct smb_filename **pp_smb_fname)
 {
        NTSTATUS status;
        char *fname = NULL;
@@ -1241,22 +1062,15 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
                return status;
        }
 
-       status = get_full_smb_filename(ctx, *pp_smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       status = check_name(conn, fname);
+       status = check_name(conn, (*pp_smb_fname)->base_name);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3,("filename_convert: check_name failed "
                        "for name %s with %s\n",
-                       fname,
+                       smb_fname_str_dbg(*pp_smb_fname),
                        nt_errstr(status) ));
+               TALLOC_FREE(*pp_smb_fname);
                return status;
        }
 
-       if (pp_name != NULL) {
-               *pp_name = fname;
-       }
        return status;
 }
diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c
new file mode 100644 (file)
index 0000000..867709a
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+   Unix SMB/CIFS implementation.
+   Filename utility functions.
+   Copyright (C) Tim Prouty 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "includes.h"
+
+/**
+ * XXX: This is temporary and there should be no callers of this outside of
+ * this file once smb_filename is plumbed through all path based operations.
+ * The one legitimate caller currently is smb_fname_str_dbg(), which this
+ * could be made static for.
+ */
+NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx,
+                              const struct smb_filename *smb_fname,
+                              char **full_name)
+{
+       if (smb_fname->stream_name) {
+               /* stream_name must always be NULL if there is no stream. */
+               SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+
+               *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
+                                            smb_fname->stream_name);
+       } else {
+               *full_name = talloc_strdup(ctx, smb_fname->base_name);
+       }
+
+       if (!*full_name) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
+}
+
+/**
+ * There are actually legitimate callers of this such as functions that
+ * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
+ * operate on each stream.
+ */
+NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
+                                   const char *stream_name,
+                                   const SMB_STRUCT_STAT *psbuf,
+                                   struct smb_filename **smb_fname_out)
+{
+       struct smb_filename smb_fname_loc;
+
+       ZERO_STRUCT(smb_fname_loc);
+
+       /* Setup the base_name/stream_name. */
+       smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
+       smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
+
+       /* Copy the psbuf if one was given. */
+       if (psbuf)
+               smb_fname_loc.st = *psbuf;
+
+       /* Let copy_smb_filename() do the heavy lifting. */
+       return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
+                                         const char *fname,
+                                         const SMB_STRUCT_STAT *psbuf,
+                                         struct smb_filename **smb_fname_out)
+{
+       NTSTATUS status;
+       const char *stream_name = NULL;
+       char *base_name = NULL;
+
+       if (!lp_posix_pathnames()) {
+               stream_name = strchr_m(fname, ':');
+       }
+
+       /* Setup the base_name/stream_name. */
+       if (stream_name) {
+               base_name = talloc_strndup(ctx, fname,
+                                          PTR_DIFF(stream_name, fname));
+       } else {
+               base_name = talloc_strdup(ctx, fname);
+       }
+
+       if (!base_name) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
+                                           smb_fname_out);
+       TALLOC_FREE(base_name);
+       return status;
+}
+
+/**
+ * Return a string using the debug_ctx()
+ */
+const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
+{
+       char *fname = NULL;
+       NTSTATUS status;
+
+       if (smb_fname == NULL) {
+               return "";
+       }
+       status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return "";
+       }
+       return fname;
+}
+
+/**
+ * Return a debug string using the debug_ctx().  This can only be called from
+ * DEBUG() macros due to the debut_ctx().
+ */
+const char *fsp_str_dbg(const struct files_struct *fsp)
+{
+       return smb_fname_str_dbg(fsp->fsp_name);
+}
+
+NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
+                          const struct smb_filename *smb_fname_in,
+                          struct smb_filename **smb_fname_out)
+{
+       /* stream_name must always be NULL if there is no stream. */
+       if (smb_fname_in->stream_name) {
+               SMB_ASSERT(smb_fname_in->stream_name[0] != '\0');
+       }
+
+       *smb_fname_out = talloc_zero(ctx, struct smb_filename);
+       if (*smb_fname_out == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (smb_fname_in->base_name) {
+               (*smb_fname_out)->base_name =
+                   talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
+               if (!(*smb_fname_out)->base_name)
+                       goto no_mem_err;
+       }
+
+       if (smb_fname_in->stream_name) {
+               (*smb_fname_out)->stream_name =
+                   talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
+               if (!(*smb_fname_out)->stream_name)
+                       goto no_mem_err;
+       }
+
+       if (smb_fname_in->original_lcomp) {
+               (*smb_fname_out)->original_lcomp =
+                   talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
+               if (!(*smb_fname_out)->original_lcomp)
+                       goto no_mem_err;
+       }
+
+       (*smb_fname_out)->st = smb_fname_in->st;
+       return NT_STATUS_OK;
+
+ no_mem_err:
+       TALLOC_FREE(*smb_fname_out);
+       return NT_STATUS_NO_MEMORY;
+}
+
+/****************************************************************************
+ Simple check to determine if the filename is a stream.
+ ***************************************************************************/
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+       /* stream_name must always be NULL if there is no stream. */
+       if (smb_fname->stream_name) {
+               SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+       }
+
+       if (lp_posix_pathnames()) {
+               return false;
+       }
+
+       return smb_fname->stream_name;
+}
+
+/****************************************************************************
+ Returns true if the filename's stream == "::$DATA"
+ ***************************************************************************/
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+       if (!is_ntfs_stream_smb_fname(smb_fname)) {
+               return false;
+       }
+
+       return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
+}
index 0e6dd7e457e6c264a2fe7c094c95e80d6b557ffc..a170f774fe64ecc6c8308b5db2bba9a66e326273 100644 (file)
@@ -44,6 +44,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
 {
        int i;
        files_struct *fsp;
+       NTSTATUS status;
 
        /* we want to give out file handles differently on each new
           connection because of a common bug in MS clients where they try to
@@ -65,21 +66,26 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
                return NT_STATUS_TOO_MANY_OPENED_FILES;
        }
 
-       fsp = SMB_MALLOC_P(files_struct);
+       /*
+        * Make a child of the connection_struct as an fsp can't exist
+        * indepenedent of a connection.
+        */
+       fsp = talloc_zero(conn, struct files_struct);
        if (!fsp) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       ZERO_STRUCTP(fsp);
-
-       fsp->fh = SMB_MALLOC_P(struct fd_handle);
+       /*
+        * This can't be a child of fsp because the file_handle can be ref'd
+        * when doing a dos/fcb open, which will then share the file_handle
+        * across multiple fsps.
+        */
+       fsp->fh = talloc_zero(conn, struct fd_handle);
        if (!fsp->fh) {
-               SAFE_FREE(fsp);
+               TALLOC_FREE(fsp);
                return NT_STATUS_NO_MEMORY;
        }
 
-       ZERO_STRUCTP(fsp->fh);
-
        fsp->fh->ref_count = 1;
        fsp->fh->fd = -1;
 
@@ -95,8 +101,18 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
        fsp->fnum = i + FILE_HANDLE_OFFSET;
        SMB_ASSERT(fsp->fnum < 65536);
 
-       string_set(&fsp->fsp_name,"");
-       
+       /*
+        * Create an smb_filename with "" for the base_name.  There are very
+        * few NULL checks, so make sure it's initialized with something. to
+        * be safe until an audit can be done.
+        */
+       status = create_synthetic_smb_fname(fsp, "", NULL, NULL,
+                                           &fsp->fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(fsp);
+               TALLOC_FREE(fsp->fh);
+       }
+
        DLIST_ADD(Files, fsp);
 
        DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n",
@@ -236,8 +252,9 @@ void file_dump_open_table(void)
        files_struct *fsp;
 
        for (fsp=Files;fsp;fsp=fsp->next,count++) {
-               DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n",
-                       count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
+               DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, "
+                         "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp),
+                         fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
                          file_id_string_tos(&fsp->file_id)));
        }
 }
@@ -283,8 +300,10 @@ files_struct *file_find_dif(struct file_id id, unsigned long gen_id)
                        if ((fsp->fh->fd == -1) &&
                            (fsp->oplock_type != NO_OPLOCK) &&
                            (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
-                               DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \
-oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, 
+                               DEBUG(0,("file_find_dif: file %s file_id = "
+                                        "%s, gen = %u oplock_type = %u is a "
+                                        "stat open with oplock type !\n",
+                                        fsp_str_dbg(fsp),
                                         file_id_string_tos(&fsp->file_id),
                                         (unsigned int)fsp->fh->gen_id,
                                         (unsigned int)fsp->oplock_type ));
@@ -385,10 +404,11 @@ bool file_find_subpath(files_struct *dir_fsp)
 {
        files_struct *fsp;
        size_t dlen;
-       char *d_fullname = talloc_asprintf(talloc_tos(),
-                                       "%s/%s",
-                                       dir_fsp->conn->connectpath,
-                                       dir_fsp->fsp_name);
+       char *d_fullname;
+
+       d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
+                                    dir_fsp->conn->connectpath,
+                                    dir_fsp->fsp_name->base_name);
 
        if (!d_fullname) {
                return false;
@@ -406,7 +426,7 @@ bool file_find_subpath(files_struct *dir_fsp)
                d1_fullname = talloc_asprintf(talloc_tos(),
                                        "%s/%s",
                                        fsp->conn->connectpath,
-                                       fsp->fsp_name);
+                                       fsp->fsp_name->base_name);
 
                if (strnequal(d_fullname, d1_fullname, dlen)) {
                        TALLOC_FREE(d_fullname);
@@ -444,12 +464,10 @@ void file_free(struct smb_request *req, files_struct *fsp)
 {
        DLIST_REMOVE(Files, fsp);
 
-       string_free(&fsp->fsp_name);
-
        TALLOC_FREE(fsp->fake_file_handle);
 
        if (fsp->fh->ref_count == 1) {
-               SAFE_FREE(fsp->fh);
+               TALLOC_FREE(fsp->fh);
        } else {
                fsp->fh->ref_count--;
        }
@@ -495,7 +513,8 @@ void file_free(struct smb_request *req, files_struct *fsp)
           information */
        ZERO_STRUCTP(fsp);
 
-       SAFE_FREE(fsp);
+       /* fsp->fsp_name is a talloc child and is free'd automatically. */
+       TALLOC_FREE(fsp);
 }
 
 /****************************************************************************
@@ -541,11 +560,11 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid)
  Duplicate the file handle part for a DOS or FCB open.
 ****************************************************************************/
 
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
                      uint32 access_mask, uint32 share_access,
                      uint32 create_options, files_struct *to)
 {
-       SAFE_FREE(to->fh);
+       TALLOC_FREE(to->fh);
 
        to->fh = from->fh;
        to->fh->ref_count++;
@@ -570,5 +589,25 @@ void dup_file_fsp(struct smb_request *req, files_struct *from,
        to->modified = from->modified;
        to->is_directory = from->is_directory;
        to->aio_write_behind = from->aio_write_behind;
-        string_set(&to->fsp_name,from->fsp_name);
+       return fsp_set_smb_fname(to, from->fsp_name);
+}
+
+/**
+ * The only way that the fsp->fsp_name field should ever be set.
+ */
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+                          const struct smb_filename *smb_fname_in)
+{
+       NTSTATUS status;
+       struct smb_filename *smb_fname_new;
+
+       status = copy_smb_filename(fsp, smb_fname_in, &smb_fname_new);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       TALLOC_FREE(fsp->fsp_name);
+       fsp->fsp_name = smb_fname_new;
+
+       return NT_STATUS_OK;
 }
index 15550ed455e43679c26c3ec9659b7e914e900b64..317304a86db0b0ec0ba4c03a804bbb2745d707e2 100644 (file)
@@ -153,4 +153,9 @@ void smbd_init_globals(void)
        ZERO_STRUCT(conn_ctx_stack);
 
        ZERO_STRUCT(sec_ctx_stack);
+
+       smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
+       if (!smbd_server_conn) {
+               exit_server("failed to create smbd_server_connection");
+       }
 }
index 3d195c84f021dfae745498d49693a883e2a7dbab..434204b60de706d68f1af69e0900b1fe8e22ef12 100644 (file)
@@ -168,6 +168,56 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
                                const struct iovec *vector,
                                int count);
 
+struct smbd_lock_element {
+       uint32_t smbpid;
+       enum brl_type brltype;
+       uint64_t offset;
+       uint64_t count;
+};
+
+NTSTATUS smbd_do_locking(struct smb_request *req,
+                        files_struct *fsp,
+                        uint8_t type,
+                        int32_t timeout,
+                        uint16_t num_ulocks,
+                        struct smbd_lock_element *ulocks,
+                        uint16_t num_locks,
+                        struct smbd_lock_element *locks,
+                        bool *async);
+
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+                              TALLOC_CTX *mem_ctx,
+                              uint16_t info_level,
+                              files_struct *fsp,
+                              const struct smb_filename *smb_fname,
+                              bool delete_pending,
+                              struct timespec write_time_ts,
+                              bool ms_dfs_link,
+                              struct ea_list *ea_list,
+                              int lock_data_count,
+                              char *lock_data,
+                              uint16_t flags2,
+                              unsigned int max_data_bytes,
+                              char **ppdata,
+                              unsigned int *pdata_size);
+
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+                               struct smb_request *req,
+                               TALLOC_CTX *mem_ctx,
+                               uint16_t info_level,
+                               files_struct *fsp,
+                               struct smb_filename *smb_fname,
+                               char **ppdata, int total_data,
+                               int *ret_data_size);
+
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+                        TALLOC_CTX *mem_ctx,
+                        uint16_t info_level,
+                        uint16_t flags2,
+                        unsigned int max_data_bytes,
+                        char **ppdata,
+                        int *ret_data_len);
+
 void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
                                         const char *reason,
                                         const char *location);
index 1067dab074877cbc680948f1a0ac2bcbbbbf1608..96a411dd704d8bd042c07392e8b1605d15b59184 100644 (file)
@@ -454,7 +454,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
        }
 
        DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n",
-                subcommand, fsp->fsp_name, pnum));
+                subcommand, fsp_str_dbg(fsp), pnum));
 
        DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt));
 
index d40b8a8902882237e0c0460477f5fbdd862a144e..2b63eb17432fc24ab1808125c94cd3954b2d5236 100644 (file)
@@ -411,7 +411,6 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
                        char **pp_link_target,
                        SMB_STRUCT_STAT *sbufp)
 {
-       SMB_STRUCT_STAT st;
        int referral_len = 0;
 #if defined(HAVE_BROKEN_READLINK)
        char link_target_buf[PATH_MAX];
@@ -420,6 +419,8 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
 #endif
        size_t bufsize = 0;
        char *link_target = NULL;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        if (pp_link_target) {
                bufsize = 1024;
@@ -433,21 +434,28 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
                link_target = link_target_buf;
        }
 
-       if (sbufp == NULL) {
-               sbufp = &st;
+       status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err;
        }
 
-       if (vfs_lstat_smb_fname(conn, path, sbufp) != 0) {
+       if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
                DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n",
                        path));
+               TALLOC_FREE(smb_fname);
                goto err;
        }
-
-       if (!S_ISLNK(sbufp->st_ex_mode)) {
+       if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
                DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
                                        path));
+               TALLOC_FREE(smb_fname);
                goto err;
        }
+       if (sbufp != NULL) {
+               *sbufp = smb_fname->st;
+       }
+       TALLOC_FREE(smb_fname);
 
        referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1);
        if (referral_len == -1) {
index ded888c021bd55903788ddee781c7dc910ec4658..8f37923865bedfaa444490203bfa7b171ae2e57c 100644 (file)
@@ -182,7 +182,7 @@ void change_notify_reply(connection_struct *conn,
 static void notify_callback(void *private_data, const struct notify_event *e)
 {
        files_struct *fsp = (files_struct *)private_data;
-       DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name));
+       DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
        notify_fsp(fsp, e->action, e->path);
 }
 
@@ -200,8 +200,9 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
                return NT_STATUS_NO_MEMORY;
        }
 
+       /* Do notify operations on the base_name. */
        if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath,
-                    fsp->fsp_name) == -1) {
+                    fsp->fsp_name->base_name) == -1) {
                DEBUG(0, ("asprintf failed\n"));
                TALLOC_FREE(fsp->notify);
                return NT_STATUS_NO_MEMORY;
@@ -236,7 +237,7 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
        struct smbd_server_connection *sconn = smbd_server_conn;
 
        DEBUG(10, ("change_notify_add_request: Adding request for %s: "
-                  "max_param = %d\n", fsp->fsp_name, (int)max_param));
+                  "max_param = %d\n", fsp_str_dbg(fsp), (int)max_param));
 
        if (!(request = talloc(NULL, struct notify_change_request))
            || !(map = talloc(request, struct notify_mid_map))) {
index b65af26ecaf570cf6f1efcaf70eaeab92667a2d1..43212dc800f94a0ed78fd104ecbcf2fa13323c55 100644 (file)
@@ -271,30 +271,6 @@ void send_nt_replies(connection_struct *conn,
        }
 }
 
-/****************************************************************************
- Simple check to determine if the filename is a stream.
- ***************************************************************************/
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
-{
-       if (lp_posix_pathnames()) {
-               return false;
-       }
-
-       return smb_fname->stream_name;
-}
-
-/****************************************************************************
- Returns true if the filename's stream == "::$DATA"
- ***************************************************************************/
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
-{
-       if (!is_ntfs_stream_smb_fname(smb_fname)) {
-               return false;
-       }
-
-       return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
-}
-
 /****************************************************************************
  Reply to an NT create and X call on a pipe
 ****************************************************************************/
@@ -502,8 +478,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -794,7 +769,7 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
        security_acl_map_generic(psd->sacl, &file_generic_mapping);
 
        if (DEBUGLEVEL >= 10) {
-               DEBUG(10,("set_sd for file %s\n", fsp->fsp_name ));
+               DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor, psd);
        }
 
@@ -992,8 +967,7 @@ static void call_nt_transact_create(connection_struct *conn,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1341,8 +1315,7 @@ void reply_ntrename(struct smb_request *req)
 
        if (req->wct < 4) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBntrename);
-               return;
+               goto out;
        }
 
        attrs = SVAL(req->vwv+0, 0);
@@ -1353,14 +1326,12 @@ void reply_ntrename(struct smb_request *req)
                                       &status, &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBntrename);
-               return;
+               goto out;
        }
 
        if (ms_has_wild(oldname)) {
                reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
-               END_PROFILE(SMBntrename);
-               return;
+               goto out;
        }
 
        p++;
@@ -1368,55 +1339,83 @@ void reply_ntrename(struct smb_request *req)
                                       &status, &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBntrename);
-               return;
+               goto out;
        }
 
-       status = filename_convert(ctx, conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
-                               oldname,
-                               &smb_fname_old,
-                               &oldname);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                                       ERRSRV, ERRbadpath);
-                       END_PROFILE(SMBntrename);
-                       return;
-               }
-               reply_nterror(req, status);
-               END_PROFILE(SMBntrename);
-               return;
+       /* The newname must begin with a ':' if the oldname contains a ':'. */
+       if (strchr_m(oldname, ':') && (newname[0] != ':')) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               goto out;
        }
 
-       status = filename_convert(ctx, conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
-                               newname,
-                               &smb_fname_new,
-                               &newname);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                                       ERRSRV, ERRbadpath);
-                       END_PROFILE(SMBntrename);
-                       return;
+       /* rename_internals() calls unix_convert(), so don't call it here. */
+       if (rename_type != RENAME_FLAG_RENAME) {
+               status = filename_convert(ctx, conn,
+                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                         oldname,
+                                         &smb_fname_old);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,
+                                           NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req,
+                                               NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               goto out;
+                       }
+                       reply_nterror(req, status);
+                       goto out;
                }
-               reply_nterror(req, status);
-               END_PROFILE(SMBntrename);
-               return;
-       }
 
-       /* The new name must begin with a ':' if the old name is a stream. */
-       if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBntrename);
-               return;
-       }
+               status = filename_convert(ctx, conn,
+                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                         newname,
+                                         &smb_fname_new);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,
+                                           NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req,
+                                               NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               goto out;
+                       }
+                       reply_nterror(req, status);
+                       goto out;
+               }
 
-       DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
+               DEBUG(3,("reply_ntrename: %s -> %s\n",
+                        smb_fname_str_dbg(smb_fname_old),
+                        smb_fname_str_dbg(smb_fname_new)));
+       }
 
        switch(rename_type) {
                case RENAME_FLAG_RENAME:
+                       status = resolve_dfspath(ctx, conn,
+                                                (req->flags2 &
+                                                    FLAGS2_DFS_PATHNAMES),
+                                                oldname, &oldname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(10,("resolve_dfspath failed for name %s "
+                                         "with %s\n", oldname,
+                                         nt_errstr(status)));
+                               reply_nterror(req, status);
+                               goto out;
+                       }
+
+                       status = resolve_dfspath(ctx, conn,
+                                                (req->flags2 &
+                                                    FLAGS2_DFS_PATHNAMES),
+                                                newname, &newname);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(10,("resolve_dfspath failed for name %s "
+                                         "with %s\n", newname,
+                                         nt_errstr(status)));
+                               reply_nterror(req, status);
+                               goto out;
+                       }
+
+                       DEBUG(3,("reply_ntrename: %s -> %s\n", oldname,
+                               newname));
+
                        status = rename_internals(ctx, conn, req, oldname,
                                        newname, attrs, False, src_has_wcard,
                                        dest_has_wcard, DELETE_ACCESS);
@@ -1454,17 +1453,15 @@ void reply_ntrename(struct smb_request *req)
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBntrename);
-                       return;
+                       goto out;
                }
 
                reply_nterror(req, status);
-               END_PROFILE(SMBntrename);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 0, 0);
-
+ out:
        END_PROFILE(SMBntrename);
        return;
 }
@@ -1523,7 +1520,7 @@ static void call_nt_transact_notify_change(connection_struct *conn,
 
                DEBUG(3,("call_nt_transact_notify_change: notify change "
                         "called on %s, filter = %s, recursive = %d\n",
-                        fsp->fsp_name, filter_string, recursive));
+                        fsp_str_dbg(fsp), filter_string, recursive));
 
                TALLOC_FREE(filter_string);
        }
@@ -1626,7 +1623,7 @@ static void call_nt_transact_rename(connection_struct *conn,
        send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
 
        DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
-                fsp->fsp_name, new_name));
+                fsp_str_dbg(fsp), new_name));
 
        return;
 }
@@ -1684,8 +1681,9 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
 
        security_info_wanted = IVAL(params,4);
 
-       DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
-                       (unsigned int)security_info_wanted ));
+       DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
+                "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
+                (unsigned int)security_info_wanted));
 
        params = nttrans_realloc(ppparams, 4);
        if(params == NULL) {
@@ -1722,7 +1720,8 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
        DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
 
        if (DEBUGLEVEL >= 10) {
-               DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name));
+               DEBUG(10,("call_nt_transact_query_security_desc for file %s\n",
+                         fsp_str_dbg(fsp)));
                NDR_PRINT_DEBUG(security_descriptor, psd);
        }
 
@@ -1796,8 +1795,8 @@ static void call_nt_transact_set_security_desc(connection_struct *conn,
 
        security_info_sent = IVAL(params,4);
 
-       DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
-               (unsigned int)security_info_sent ));
+       DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
+                fsp_str_dbg(fsp), (unsigned int)security_info_sent));
 
        if (data_count == 0) {
                reply_doserror(req, ERRDOS, ERRnoaccess);
@@ -2021,7 +2020,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
                cur_pdata+=12;
 
                DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
-                       shadow_data->num_volumes,fsp->fsp_name));
+                         shadow_data->num_volumes, fsp_str_dbg(fsp)));
                if (labels && shadow_data->labels) {
                        for (i=0;i<shadow_data->num_volumes;i++) {
                                srvstr_push(pdata, req->flags2,
index e01350f2bf32a8da6956afd55159f0b013eeb86f..87cab1966b443451b7e38a590e67b45f3fbc83a8 100644 (file)
@@ -94,6 +94,7 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
                        "on %s: %s\n",
                        smb_fname_str_dbg(smb_fname),
                        nt_errstr(status)));
+               TALLOC_FREE(sd);
                return status;
        }
 
@@ -218,13 +219,13 @@ void change_file_owner_to_parent(connection_struct *conn,
        if (ret == -1) {
                DEBUG(0,("change_file_owner_to_parent: failed to fchown "
                         "file %s to parent directory uid %u. Error "
-                        "was %s\n", fsp->fsp_name,
+                        "was %s\n", fsp_str_dbg(fsp),
                         (unsigned int)smb_fname_parent->st.st_ex_uid,
                         strerror(errno) ));
        }
 
        DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
-                 "parent directory uid %u.\n", fsp->fsp_name,
+                 "parent directory uid %u.\n", fsp_str_dbg(fsp),
                  (unsigned int)smb_fname_parent->st.st_ex_uid));
 
        TALLOC_FREE(smb_fname_parent);
@@ -349,7 +350,6 @@ static NTSTATUS open_file(files_struct *fsp,
                          uint32 access_mask, /* client requested access mask. */
                          uint32 open_access_mask) /* what we're actually using in the open. */
 {
-       char *path = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
@@ -434,7 +434,7 @@ static NTSTATUS open_file(files_struct *fsp,
                         * wildcard characters are allowed in stream names
                         * only test the basefilename
                         */
-                       wild = fsp->base_fsp->fsp_name;
+                       wild = fsp->base_fsp->fsp_name->base_name;
                } else {
                        wild = smb_fname->base_name;
                }
@@ -614,16 +614,13 @@ static NTSTATUS open_file(files_struct *fsp,
                       conn->case_sensitive)) {
                fsp->aio_write_behind = True;
        }
-
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &path);
+       status = fsp_set_smb_fname(fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
+               fd_close(fsp);
+               errno = map_errno_from_nt_status(status);
                return status;
        }
 
-       string_set(&fsp->fsp_name, path);
-       TALLOC_FREE(path);
-
        fsp->wcp = NULL; /* Write cache pointer. */
 
        DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -795,7 +792,8 @@ static void validate_my_share_entries(int num,
                str = talloc_asprintf(talloc_tos(),
                        "validate_my_share_entries: "
                        "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
-                        fsp->fsp_name, (unsigned int)fsp->oplock_type,
+                        fsp->fsp_name->base_name,
+                        (unsigned int)fsp->oplock_type,
                         (unsigned int)share_entry->op_type );
                smb_panic(str);
        }
@@ -1029,7 +1027,7 @@ static bool delay_for_oplocks(struct share_mode_lock *lck,
        }
 
        DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
-               fsp->oplock_type, fsp->fsp_name));
+                 fsp->oplock_type, fsp_str_dbg(fsp)));
 
        /* No delay. */
        return false;
@@ -1152,13 +1150,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
                                     uint32 create_options)
 {
        files_struct *fsp;
-       char *fname = NULL;
-       NTSTATUS status;
-
-       status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
 
        DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
                 "file %s.\n", smb_fname_str_dbg(smb_fname)));
@@ -1168,7 +1159,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
 
                DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
                          "vuid = %u, file_pid = %u, private_options = 0x%x "
-                         "access_mask = 0x%x\n", fsp->fsp_name,
+                         "access_mask = 0x%x\n", fsp_str_dbg(fsp),
                          fsp->fh->fd, (unsigned int)fsp->vuid,
                          (unsigned int)fsp->file_pid,
                          (unsigned int)fsp->fh->private_options,
@@ -1180,7 +1171,9 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
                    (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
                                                 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
                    (fsp->access_mask & FILE_WRITE_DATA) &&
-                   strequal(fsp->fsp_name, fname)) {
+                   strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
+                   strequal(fsp->fsp_name->stream_name,
+                            smb_fname->stream_name)) {
                        DEBUG(10,("fcb_or_dos_open: file match\n"));
                        break;
                }
@@ -1198,17 +1191,16 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
        }
 
        /* We need to duplicate this fsp. */
-       dup_file_fsp(req, fsp, access_mask, share_access,
-                       create_options, fsp_to_dup_into);
-
-       return NT_STATUS_OK;
+       return dup_file_fsp(req, fsp, access_mask, share_access,
+                           create_options, fsp_to_dup_into);
 }
 
 /****************************************************************************
  Open a file with a share mode - old openX method - map into NTCreate.
 ****************************************************************************/
 
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+                                int deny_mode, int open_func,
                                 uint32 *paccess_mask,
                                 uint32 *pshare_mode,
                                 uint32 *pcreate_disposition,
@@ -1221,7 +1213,8 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
 
        DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
                  "open_func = 0x%x\n",
-                 fname, (unsigned int)deny_mode, (unsigned int)open_func ));
+                 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
+                 (unsigned int)open_func ));
 
        /* Create the NT compatible access_mask. */
        switch (GET_OPENX_MODE(deny_mode)) {
@@ -1295,7 +1288,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
 
                case DENY_DOS:
                        create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
-                       if (is_executable(fname)) {
+                       if (is_executable(smb_fname->base_name)) {
                                share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
                        } else {
                                if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
@@ -1320,7 +1313,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
        DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
                  "share_mode = 0x%x, create_disposition = 0x%x, "
                  "create_options = 0x%x\n",
-                 fname,
+                 smb_fname_str_dbg(smb_fname),
                  (unsigned int)access_mask,
                  (unsigned int)share_mode,
                  (unsigned int)create_disposition,
@@ -2611,8 +2604,10 @@ static NTSTATUS open_directory(connection_struct *conn,
        fsp->sent_oplock_break = NO_BREAK_SENT;
        fsp->is_directory = True;
        fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
-
-       string_set(&fsp->fsp_name, smb_dname->base_name);
+       status = fsp_set_smb_fname(fsp, smb_dname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
        mtimespec = smb_dname->st.st_ex_mtime;
 
@@ -2730,6 +2725,11 @@ void msg_file_was_renamed(struct messaging_context *msg,
        bn_len = strlen(base_name);
        stream_name = sharepath + sp_len + 1 + bn_len + 1;
 
+       /* stream_name must always be NULL if there is no stream. */
+       if (stream_name[0] == '\0') {
+               stream_name = NULL;
+       }
+
        status = create_synthetic_smb_fname(talloc_tos(), base_name,
                                            stream_name, NULL, &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2743,18 +2743,14 @@ void msg_file_was_renamed(struct messaging_context *msg,
 
        for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
                if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
-                       char *newname = NULL;
 
                        DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
-                               fsp->fnum, fsp->fsp_name,
+                               fsp->fnum, fsp_str_dbg(fsp),
                                smb_fname_str_dbg(smb_fname)));
-                       status = get_full_smb_filename(talloc_tos(),
-                                                      smb_fname, &newname);
+                       status = fsp_set_smb_fname(fsp, smb_fname);
                        if (!NT_STATUS_IS_OK(status)) {
                                goto out;
                        }
-                       string_set(&fsp->fsp_name, newname);
-                       TALLOC_FREE(newname);
                } else {
                        /* TODO. JRA. */
                        /* Now we have the complete path we can work out if this is
@@ -2765,7 +2761,7 @@ void msg_file_was_renamed(struct messaging_context *msg,
                                fsp->conn->connectpath,
                                sharepath,
                                fsp->fnum,
-                               fsp->fsp_name,
+                               fsp_str_dbg(fsp),
                                smb_fname_str_dbg(smb_fname)));
                }
         }
@@ -2926,7 +2922,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
                }
 
                DEBUG(10, ("Closing stream # %d, %s\n", i,
-                          streams[i]->fsp_name));
+                          fsp_str_dbg(streams[i])));
                close_file(NULL, streams[i], NORMAL_CLOSE);
        }
 
@@ -3326,6 +3322,11 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
 
        dir_fsp = file_fsp(req, root_dir_fid);
 
+       if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
+               status = NT_STATUS_INVALID_HANDLE;
+               goto out;
+       }
+
        if (dir_fsp == NULL) {
                status = NT_STATUS_INVALID_HANDLE;
                goto out;
@@ -3354,7 +3355,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
                goto out;
        }
 
-       if (ISDOT(dir_fsp->fsp_name)) {
+       if (ISDOT(dir_fsp->fsp_name->base_name)) {
                /*
                 * We're at the toplevel dir, the final file name
                 * must not contain ./, as this is filtered out
@@ -3367,7 +3368,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
                        goto out;
                }
        } else {
-               size_t dir_name_len = strlen(dir_fsp->fsp_name);
+               size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
 
                /*
                 * Copy in the base directory name.
@@ -3379,7 +3380,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
-               memcpy(parent_fname, dir_fsp->fsp_name,
+               memcpy(parent_fname, dir_fsp->fsp_name->base_name,
                    dir_name_len+1);
 
                /*
@@ -3463,16 +3464,9 @@ NTSTATUS create_file_default(connection_struct *conn,
         */
 
        if (is_ntfs_stream_smb_fname(smb_fname)) {
-               char *fname = NULL;
                enum FAKE_FILE_TYPE fake_file_type;
 
-               status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                              &fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-
-               fake_file_type = is_fake_file(fname);
+               fake_file_type = is_fake_file(smb_fname);
 
                if (fake_file_type != FAKE_FILE_TYPE_NONE) {
 
@@ -3488,9 +3482,8 @@ NTSTATUS create_file_default(connection_struct *conn,
                         * close it
                         */
                        status = open_fake_file(req, conn, req->vuid,
-                                               fake_file_type, fname,
+                                               fake_file_type, smb_fname,
                                                access_mask, &fsp);
-                       TALLOC_FREE(fname);
                        if (!NT_STATUS_IS_OK(status)) {
                                goto fail;
                        }
@@ -3498,7 +3491,6 @@ NTSTATUS create_file_default(connection_struct *conn,
                        ZERO_STRUCT(smb_fname->st);
                        goto done;
                }
-               TALLOC_FREE(fname);
 
                if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
                        status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
index e9b2a6cf95f14dd92c087a8c21b22351357fd4a3..dd8d5372fb4995de476627243a1fe15dbbb5f98c 100644 (file)
@@ -81,7 +81,7 @@ bool set_file_oplock(files_struct *fsp, int oplock_type)
 
        DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, "
                    "tv_sec = %x, tv_usec = %x\n",
-                fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
                 fsp->fh->gen_id, (int)fsp->open_time.tv_sec,
                 (int)fsp->open_time.tv_usec ));
 
@@ -158,14 +158,15 @@ bool remove_oplock(files_struct *fsp)
                                  NULL);
        if (lck == NULL) {
                DEBUG(0,("remove_oplock: failed to lock share entry for "
-                        "file %s\n", fsp->fsp_name ));
+                        "file %s\n", fsp_str_dbg(fsp)));
                return False;
        }
        ret = remove_share_oplock(lck, fsp);
        if (!ret) {
                DEBUG(0,("remove_oplock: failed to remove share oplock for "
                         "file %s fnum %d, %s\n",
-                        fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+                        fsp_str_dbg(fsp), fsp->fnum,
+                        file_id_string_tos(&fsp->file_id)));
        }
        release_file_oplock(fsp);
        TALLOC_FREE(lck);
@@ -184,14 +185,15 @@ bool downgrade_oplock(files_struct *fsp)
                                  NULL);
        if (lck == NULL) {
                DEBUG(0,("downgrade_oplock: failed to lock share entry for "
-                        "file %s\n", fsp->fsp_name ));
+                        "file %s\n", fsp_str_dbg(fsp)));
                return False;
        }
        ret = downgrade_share_oplock(lck, fsp);
        if (!ret) {
                DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
                         "for file %s fnum %d, file_id %s\n",
-                        fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+                        fsp_str_dbg(fsp), fsp->fnum,
+                        file_id_string_tos(&fsp->file_id)));
        }
 
        downgrade_file_oplock(fsp);
@@ -294,7 +296,8 @@ static files_struct *initial_break_processing(struct file_id id, unsigned long f
 
        if(fsp->oplock_type == NO_OPLOCK) {
                if( DEBUGLVL( 3 ) ) {
-                       dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
+                       dbgtext( "initial_break_processing: file %s ",
+                                fsp_str_dbg(fsp));
                        dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n",
                                 file_id_string_tos(&id), fsp->fh->gen_id );
                        dbgtext( "Allowing break to succeed regardless.\n" );
@@ -314,7 +317,8 @@ static void oplock_timeout_handler(struct event_context *ctx,
 
        /* Remove the timed event handler. */
        TALLOC_FREE(fsp->oplock_timeout);
-       DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name));
+       DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n",
+                 fsp_str_dbg(fsp)));
        global_client_failed_oplock_break = True;
        remove_oplock(fsp);
        reply_to_oplock_break_requests(fsp);
@@ -375,7 +379,7 @@ void break_level2_to_none_async(files_struct *fsp)
 
        DEBUG(10,("process_oplock_async_level2_break_message: sending break "
                  "to none message for fid %d, file %s\n", fsp->fnum,
-                 fsp->fsp_name));
+                 fsp_str_dbg(fsp)));
 
        /* Now send a break to none message to our client. */
        break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
@@ -506,7 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
            !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
                DEBUG(3, ("Already downgraded oplock on %s: %s\n",
                          file_id_string_tos(&fsp->file_id),
-                         fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
                /* We just send the same message back. */
                messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
                                   (uint8 *)data->data,
@@ -740,7 +744,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
                                  NULL);
        if (lck == NULL) {
                DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
-                        "share mode entry for file %s.\n", fsp->fsp_name ));
+                        "share mode entry for file %s.\n", fsp_str_dbg(fsp)));
                return;
        }
 
index 89b8e0f7b58489c738c8d1f693c24e06f222bd72..dd32177988891d940e227242f06d35daa42aca03 100644 (file)
@@ -212,7 +212,8 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
                        DEBUG(0,("irix_set_kernel_oplock: Unable to get "
                                 "kernel oplock on file %s, file_id %s "
                                 "gen_id = %ul. Error was %s\n", 
-                                fsp->fsp_name, file_id_string_tos(&fsp->file_id), 
+                                fsp_str_dbg(fsp),
+                                file_id_string_tos(&fsp->file_id),
                                 fsp->fh->gen_id,
                                 strerror(errno) ));
                } else {
@@ -220,7 +221,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
                                 "file %s, fd = %d, file_id = %s, "
                                 "gen_id = %ul. Another process had the file "
                                 "open.\n",
-                                fsp->fsp_name, fsp->fh->fd,
+                                fsp_str_dbg(fsp), fsp->fh->fd,
                                 file_id_string_tos(&fsp->file_id),
                                 fsp->fh->gen_id ));
                }
@@ -229,7 +230,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
        
        DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s "
                  "gen_id = %ul\n",
-                 fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                 fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
                  fsp->fh->gen_id));
 
        return True;
@@ -250,7 +251,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx,
                int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1);
                dbgtext("irix_release_kernel_oplock: file %s, file_id = %s"
                        "gen_id = %ul, has kernel oplock state "
-                       "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                       "of %x.\n", fsp_str_dbg(fsp),
+                       file_id_string_tos(&fsp->file_id),
                         fsp->fh->gen_id, state );
        }
 
@@ -263,7 +265,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx,
                                "removing kernel oplock on file " );
                        dbgtext("%s, file_id = %s gen_id = %ul. "
                                "Error was %s\n",
-                               fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                               fsp_str_dbg(fsp),
+                               file_id_string_tos(&fsp->file_id),
                                fsp->fh->gen_id,
                                strerror(errno) );
                }
index 273fbfdc01e7ec33ab44cc22b6c1cf997df150c4..b4a5495e4b10b2b679d6d095bc0263db9fe64d4e 100644 (file)
@@ -111,7 +111,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx,
        if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) {
                DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, "
                         "fd = %d, file_id = %s. (%s)\n",
-                        fsp->fsp_name, fsp->fh->fd, 
+                        fsp_str_dbg(fsp), fsp->fh->fd,
                         file_id_string_tos(&fsp->file_id),
                         strerror(errno)));
                return False;
@@ -119,7 +119,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx,
        
        DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, "
                 "file_id = %s gen_id = %lu\n",
-                fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
                 fsp->fh->gen_id));
 
        return True;
@@ -140,7 +140,8 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx,
                int state = fcntl(fsp->fh->fd, F_GETLEASE, 0);
                dbgtext("linux_release_kernel_oplock: file %s, file_id = %s "
                        "gen_id = %lu has kernel oplock state "
-                       "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+                       "of %x.\n", fsp_str_dbg(fsp),
+                       file_id_string_tos(&fsp->file_id),
                        fsp->fh->gen_id, state );
        }
 
@@ -152,7 +153,7 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx,
                        dbgtext("linux_release_kernel_oplock: Error when "
                                "removing kernel oplock on file " );
                        dbgtext("%s, file_id = %s, gen_id = %lu. "
-                               "Error was %s\n", fsp->fsp_name,
+                               "Error was %s\n", fsp_str_dbg(fsp),
                                file_id_string_tos(&fsp->file_id),
                                fsp->fh->gen_id, strerror(errno) );
                }
index d359f9c6f201638956cf6545aa99532e2ce3965c..a73100abdf05b566ff2df55097b584a6b5db44a7 100644 (file)
@@ -60,29 +60,30 @@ struct onefs_callback_record {
 struct onefs_callback_record *callback_recs;
 
 /**
- * Convert a onefs_callback_record to a string.
+ * Convert a onefs_callback_record to a debug string using the dbg_ctx().
  */
-static char *onefs_callback_record_str_static(const struct onefs_callback_record *r)
+const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r)
 {
-       static fstring result;
+       char *result;
 
        if (r == NULL) {
-               fstrcpy(result, "NULL callback record");
+               result = talloc_strdup(dbg_ctx(), "NULL callback record");
                return result;
        }
 
        switch (r->state) {
        case ONEFS_OPEN_FILE:
-               fstr_sprintf(result, "cb record %llu for file %s",
-                            r->id, r->data.fsp->fsp_name);
-               break;
+               result = talloc_asprintf(dbg_ctx(), "cb record %llu for file "
+                                        "%s", r->id,
+                                        fsp_str_dbg(r->data.fsp));
        case ONEFS_WAITING_FOR_OPLOCK:
-               fstr_sprintf(result, "cb record %llu for pending mid %d",
-                            r->id, (int)r->data.mid);
+               result = talloc_asprintf(dbg_ctx(), "cb record %llu for "
+                                        "pending mid %d", r->id,
+                                        (int)r->data.mid);
                break;
        default:
-               fstr_sprintf(result, "cb record %llu unknown state %d",
-                            r->id, r->state);
+               result = talloc_asprintf(dbg_ctx(), "cb record %llu unknown "
+                                        "state %d", r->id, r->state);
                break;
        }
 
@@ -102,7 +103,7 @@ static void debug_cb_records(const char *fn)
        DEBUG(10, ("cb records (%s):\n", fn));
 
        for (rec = callback_recs; rec; rec = rec->next) {
-               DEBUGADD(10, ("%s\n", onefs_callback_record_str_static(rec)));
+               DEBUGADD(10, ("%s\n", onefs_cb_record_dbg_str(rec)));
        }
 }
 
@@ -127,7 +128,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id,
        for (rec = callback_recs; rec; rec = rec->next) {
                if (rec->id == id) {
                        DEBUG(10, ("found %s\n",
-                                  onefs_callback_record_str_static(rec)));
+                                  onefs_cb_record_dbg_str(rec)));
                        break;
                }
        }
@@ -139,7 +140,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id,
 
        if (rec->state != expected_state) {
                DEBUG(0, ("Expected cb type %d, got %s", expected_state,
-                         onefs_callback_record_str_static(rec)));
+                         onefs_cb_record_dbg_str(rec)));
                SMB_ASSERT(0);
                return NULL;
        }
@@ -299,7 +300,7 @@ static void oplock_break_to_none_handler(uint64_t id)
        }
 
        DEBUG(10, ("oplock_break_to_none_handler called for file %s\n",
-                  cb->data.fsp->fsp_name));
+                  cb->data.fsp_str_dbg(fsp)));
 
        init_share_mode_entry(&sme, cb, FORCE_OPLOCK_BREAK_TO_NONE);
        share_mode_entry_to_message(msg, &sme);
@@ -336,7 +337,7 @@ static void oplock_break_to_level_two_handler(uint64_t id)
        }
 
        DEBUG(10, ("oplock_break_to_level_two_handler called for file %s\n",
-                  cb->data.fsp->fsp_name));
+                  cb->data.fsp_str_dbg(fsp)));
 
        init_share_mode_entry(&sme, cb, LEVEL_II_OPLOCK);
        share_mode_entry_to_message(msg, &sme);
@@ -377,7 +378,7 @@ static void oplock_revoked_handler(uint64_t id)
        SMB_ASSERT(fsp->oplock_timeout == NULL);
 
        DEBUG(0,("Level 1 oplock break failed for file %s. Forcefully "
-                "revoking oplock\n", fsp->fsp_name));
+                "revoking oplock\n", fsp_str_dbg(fsp)));
 
        global_client_failed_oplock_break = True;
        remove_oplock(fsp);
@@ -413,7 +414,7 @@ static void semlock_available_handler(uint64_t id)
                char *msg;
                if (asprintf(&msg, "Semlock available on an open that wasn't "
                             "deferred: %s\n",
-                             onefs_callback_record_str_static(cb)) != -1) {
+                             onefs_cb_record_dbg_str(cb)) != -1) {
                        smb_panic(msg);
                }
                smb_panic("Semlock available on an open that wasn't "
@@ -457,7 +458,7 @@ static void semlock_async_failure_handler(uint64_t id)
                char *msg;
                if (asprintf(&msg, "Semlock failure on an open that wasn't "
                             "deferred: %s\n",
-                             onefs_callback_record_str_static(cb)) != -1) {
+                             onefs_cb_record_dbg_str(cb)) != -1) {
                        smb_panic(msg);
                }
                smb_panic("Semlock failure on an open that wasn't deferred\n");
@@ -501,7 +502,7 @@ static void onefs_release_kernel_oplock(struct kernel_oplocks *_ctx,
        enum oplock_type oplock = onefs_samba_oplock_to_oplock(oplock_type);
 
        DEBUG(10, ("onefs_release_kernel_oplock: Releasing %s to type %s\n",
-                  fsp->fsp_name, onefs_oplock_str(oplock)));
+                  fsp_str_dbg(fsp), onefs_oplock_str(oplock)));
 
        if (fsp->fh->fd == -1) {
                DEBUG(1, ("no fd\n"));
index 928ef0169ec93c8802ac9137e5844229e51bc45e..b1a749736d9756e919a4ea6860ae1f46b345a3ed 100644 (file)
@@ -428,27 +428,30 @@ bool user_in_netgroup(struct smbd_server_connection *sconn,
        if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) {
                DEBUG(5,("user_in_netgroup: Found\n"));
                return true;
-       } else {
+       }
 
-               /*
-                * Ok, innetgr is case sensitive. Try once more with lowercase
-                * just in case. Attempt to fix #703. JRA.
-                */
+       /*
+        * Ok, innetgr is case sensitive. Try once more with lowercase
+        * just in case. Attempt to fix #703. JRA.
+        */
+       fstrcpy(lowercase_user, user);
+       strlower_m(lowercase_user);
 
-               fstrcpy(lowercase_user, user);
-               strlower_m(lowercase_user);
+       if (strcmp(user,lowercase_user) == 0) {
+               /* user name was already lower case! */
+               return false;
+       }
 
-               DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
-                       lowercase_user,
-                       sconn->smb1.sessions.my_yp_domain?
-                       sconn->smb1.sessions.my_yp_domain:"(ANY)",
-                       ngname));
+       DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
+               lowercase_user,
+               sconn->smb1.sessions.my_yp_domain?
+               sconn->smb1.sessions.my_yp_domain:"(ANY)",
+               ngname));
 
-               if (innetgr(ngname, NULL, lowercase_user,
-                           sconn->smb1.sessions.my_yp_domain)) {
-                       DEBUG(5,("user_in_netgroup: Found\n"));
-                       return true;
-               }
+       if (innetgr(ngname, NULL, lowercase_user,
+                   sconn->smb1.sessions.my_yp_domain)) {
+               DEBUG(5,("user_in_netgroup: Found\n"));
+               return true;
        }
 #endif /* HAVE_NETGROUP */
        return false;
index 7ae74356462217a1b3baecf0486280f5eda18c38..091db099872a89ea5353c16b93b36c9a897dc9c0 100644 (file)
@@ -37,6 +37,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 {
        struct connection_struct *conn = smb_req->conn;
        struct files_struct *fsp;
+       struct smb_filename *smb_fname = NULL;
        NTSTATUS status;
 
        status = file_new(smb_req, conn, &fsp);
@@ -50,7 +51,19 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
        fsp->vuid = smb_req->vuid;
        fsp->can_lock = false;
        fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA;
-       string_set(&fsp->fsp_name, name);
+
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+                                           &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+               file_free(smb_req, fsp);
+               return status;
+       }
+       status = fsp_set_smb_fname(fsp, smb_fname);
+       TALLOC_FREE(smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               file_free(smb_req, fsp);
+               return status;
+       }
 
        status = np_open(NULL, name, conn->client_address,
                         conn->server_info, &fsp->fake_file_handle);
@@ -179,7 +192,7 @@ void reply_pipe_write(struct smb_request *req)
        data = req->buf + 3;
 
        DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
-                 fsp->fsp_name, (int)state->numtowrite));
+                 fsp_str_dbg(fsp), (int)state->numtowrite));
 
        subreq = np_write_send(state, smbd_event_context(),
                               fsp->fake_file_handle, data, state->numtowrite);
@@ -203,8 +216,14 @@ static void pipe_write_done(struct tevent_req *subreq)
 
        status = np_write_recv(subreq, &nwritten);
        TALLOC_FREE(subreq);
-       if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+       if (nwritten < 0) {
+               reply_nterror(req, status);
+               goto send;
+       }
+
+       /* Looks bogus to me now. Needs to be removed ? JRA. */
+       if ((nwritten == 0 && state->numtowrite != 0)) {
+               reply_doserror(req, ERRDOS, ERRnoaccess);
                goto send;
        }
 
@@ -269,7 +288,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
                 == (PIPE_START_MESSAGE|PIPE_RAW_MODE));
 
        DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
-                 (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite));
+                 (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite));
 
        data = (uint8_t *)smb_base(req->inbuf) + smb_doff;
 
@@ -283,7 +302,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
                        DEBUG(0,("reply_pipe_write_and_X: start of message "
                                 "set and not enough data sent.(%u)\n",
                                 (unsigned int)state->numtowrite ));
-                       reply_unixerror(req, ERRDOS, ERRnoaccess);
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                        return;
                }
 
@@ -313,8 +332,15 @@ static void pipe_write_andx_done(struct tevent_req *subreq)
 
        status = np_write_recv(subreq, &nwritten);
        TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) {
-               reply_unixerror(req, ERRDOS,ERRnoaccess);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               goto done;
+       }
+
+       /* Looks bogus to me now. Is this error message correct ? JRA. */
+       if (nwritten != state->numtowrite) {
+               reply_doserror(req, ERRDOS,ERRnoaccess);
                goto done;
        }
 
index 76eee9b56aa560bf8566248cc04ed2455b3ee14f..0a3b0dff7597a22d9da813465e9113262881252a 100644 (file)
@@ -256,15 +256,16 @@ static void store_inheritance_attributes(files_struct *fsp,
                ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
                                pai_buf, store_size, 0);
        } else {
-               ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
-                               pai_buf, store_size, 0);
+               ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+                                      SAMBA_POSIX_INHERITANCE_EA_NAME,
+                                      pai_buf, store_size, 0);
        }
 
        SAFE_FREE(pai_buf);
 
        DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n",
                (unsigned int)sd_type,
-               fsp->fsp_name));
+               fsp_str_dbg(fsp)));
 
        if (ret == -1 && !no_acl_syscall_error(errno)) {
                DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
@@ -599,8 +600,10 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
                        ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
                                        pai_buf, pai_buf_size);
                } else {
-                       ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
-                                       pai_buf, pai_buf_size);
+                       ret = SMB_VFS_GETXATTR(fsp->conn,
+                                              fsp->fsp_name->base_name,
+                                              SAMBA_POSIX_INHERITANCE_EA_NAME,
+                                              pai_buf, pai_buf_size);
                }
 
                if (ret == -1) {
@@ -618,7 +621,8 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
                }
        } while (ret == -1);
 
-       DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
+       DEBUG(10,("load_inherited_info: ret = %lu for file %s\n",
+                 (unsigned long)ret, fsp_str_dbg(fsp)));
 
        if (ret == -1) {
                /* No attribute or not supported. */
@@ -637,8 +641,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
 
        if (paiv) {
                DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n",
-                       (unsigned int)paiv->sd_type,
-                       fsp->fsp_name));
+                         (unsigned int)paiv->sd_type, fsp_str_dbg(fsp)));
        }
 
        SAFE_FREE(pai_buf);
@@ -1727,8 +1730,12 @@ static bool create_canon_ace_lists(files_struct *fsp,
                                        got_dir_allow = True;
 
                                if ((current_ace->attr == DENY_ACE) && got_dir_allow) {
-                                       DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+                                       DEBUG(0,("create_canon_ace_lists: "
+                                                "malformed ACL in "
+                                                "inheritable ACL! Deny entry "
+                                                "after Allow entry. Failing "
+                                                "to set on file %s.\n",
+                                                fsp_str_dbg(fsp)));
                                        free_canon_ace_list(file_ace);
                                        free_canon_ace_list(dir_ace);
                                        return False;
@@ -1785,8 +1792,10 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
                                got_file_allow = True;
 
                        if ((current_ace->attr == DENY_ACE) && got_file_allow) {
-                               DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+                               DEBUG(0,("create_canon_ace_lists: malformed "
+                                        "ACL in file ACL ! Deny entry after "
+                                        "Allow entry. Failing to set on file "
+                                        "%s.\n", fsp_str_dbg(fsp)));
                                free_canon_ace_list(file_ace);
                                free_canon_ace_list(dir_ace);
                                return False;
@@ -2169,17 +2178,8 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
        mode_t mode;
 
        if (interitable_mode) {
-               struct smb_filename *smb_fname = NULL;
-               NTSTATUS status;
-
-               status = create_synthetic_smb_fname_split(talloc_tos(),
-                                                         fsp->fsp_name, NULL,
-                                                         &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return 0;
-               }
-               mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname,
-                                NULL);
+               mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,
+                                fsp->fsp_name, NULL);
        } else {
                mode = S_IRUSR;
        }
@@ -2602,14 +2602,9 @@ static bool set_canon_ace_list(files_struct *fsp,
        SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS);
        bool needs_mask = False;
        mode_t mask_perms = 0;
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 psbuf, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto fail;
-       }
+       /* Use the psbuf that was passed in. */
+       fsp->fsp_name->st = *psbuf;
 
 #if defined(POSIX_ACL_NEEDS_MASK)
        /* HP-UX always wants to have a mask (called "class" there). */
@@ -2767,7 +2762,7 @@ static bool set_canon_ace_list(files_struct *fsp,
         */
 
        if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
-               if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+               if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name,
                                             the_acl_type, the_acl) == -1) {
                        /*
                         * Some systems allow all the above calls and only fail with no ACL support
@@ -2777,17 +2772,17 @@ static bool set_canon_ace_list(files_struct *fsp,
                                *pacl_set_support = False;
                        }
 
-                       if (acl_group_override(conn, smb_fname)) {
+                       if (acl_group_override(conn, fsp->fsp_name)) {
                                int sret;
 
                                DEBUG(5,("set_canon_ace_list: acl group "
                                         "control on and current user in file "
                                         "%s primary group.\n",
-                                        smb_fname_str_dbg(smb_fname)));
+                                        fsp_str_dbg(fsp)));
 
                                become_root();
                                sret = SMB_VFS_SYS_ACL_SET_FILE(conn,
-                                   smb_fname->base_name, the_acl_type,
+                                   fsp->fsp_name->base_name, the_acl_type,
                                    the_acl);
                                unbecome_root();
                                if (sret == 0) {
@@ -2801,8 +2796,7 @@ static bool set_canon_ace_list(files_struct *fsp,
                                         "file %s (%s).\n",
                                         the_acl_type == SMB_ACL_TYPE_DEFAULT ?
                                         "directory default" : "file",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno)));
+                                        fsp_str_dbg(fsp), strerror(errno)));
                                goto fail;
                        }
                }
@@ -2816,13 +2810,13 @@ static bool set_canon_ace_list(files_struct *fsp,
                                *pacl_set_support = False;
                        }
 
-                       if (acl_group_override(conn, smb_fname)) {
+                       if (acl_group_override(conn, fsp->fsp_name)) {
                                int sret;
 
                                DEBUG(5,("set_canon_ace_list: acl group "
                                         "control on and current user in file "
                                         "%s primary group.\n",
-                                        smb_fname_str_dbg(smb_fname)));
+                                        fsp_str_dbg(fsp)));
 
                                become_root();
                                sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl);
@@ -2836,8 +2830,7 @@ static bool set_canon_ace_list(files_struct *fsp,
                                DEBUG(2,("set_canon_ace_list: "
                                         "sys_acl_set_file failed for file %s "
                                         "(%s).\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno) ));
+                                        fsp_str_dbg(fsp), strerror(errno)));
                                goto fail;
                        }
                }
@@ -2850,7 +2843,6 @@ static bool set_canon_ace_list(files_struct *fsp,
        if (the_acl != NULL) {
                SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
        }
-       TALLOC_FREE(smb_fname);
 
        return ret;
 }
@@ -2906,8 +2898,9 @@ static bool convert_canon_ace_to_posix_perms( files_struct *fsp, canon_ace *file
        mode_t or_bits;
 
        if (ace_count != 3) {
-               DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \
-posix perms.\n", fsp->fsp_name ));
+               DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE "
+                        "entries for file %s to convert to posix perms.\n",
+                        fsp_str_dbg(fsp)));
                return False;
        }
 
@@ -2921,8 +2914,8 @@ posix perms.\n", fsp->fsp_name ));
        }
 
        if (!owner_ace || !group_ace || !other_ace) {
-               DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n",
-                               fsp->fsp_name ));
+               DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get "
+                        "standard entries for file %s.\n", fsp_str_dbg(fsp)));
                return False;
        }
 
@@ -2956,9 +2949,10 @@ posix perms.\n", fsp->fsp_name ));
 
        *posix_perms = (((*posix_perms) & and_bits)|or_bits);
 
-       DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n",
-               (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms,
-               fsp->fsp_name ));
+       DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o "
+                 "to perm=0%o for file %s.\n", (int)owner_ace->perms,
+                 (int)group_ace->perms, (int)other_ace->perms,
+                 (int)*posix_perms, fsp_str_dbg(fsp)));
 
        return True;
 }
@@ -3351,11 +3345,12 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
 
        *ppdesc = NULL;
 
-       DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name ));
+       DEBUG(10,("posix_fget_nt_acl: called for file %s\n",
+                 fsp_str_dbg(fsp)));
 
        /* can it happen that fsp_name == NULL ? */
        if (fsp->is_directory ||  fsp->fh->fd == -1) {
-               return posix_get_nt_acl(fsp->conn, fsp->fsp_name,
+               return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name,
                                        security_info, ppdesc);
        }
 
@@ -3369,40 +3364,53 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
 
        pal = fload_inherited_info(fsp);
 
-       return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal,
-                                      posix_acl, NULL, security_info, ppdesc);
+       return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name,
+                                      &sbuf, pal, posix_acl, NULL,
+                                      security_info, ppdesc);
 }
 
 NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
                          uint32_t security_info, SEC_DESC **ppdesc)
 {
-       SMB_STRUCT_STAT sbuf;
        SMB_ACL_T posix_acl = NULL;
        SMB_ACL_T def_acl = NULL;
        struct pai_val *pal;
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        *ppdesc = NULL;
 
        DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
 
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+                                           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        /* Get the stat struct for the owner info. */
-       if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
-               return map_nt_error_from_unix(errno);
+       if(SMB_VFS_STAT(conn, smb_fname) != 0) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
        }
 
        /* Get the ACL from the path. */
        posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
 
        /* If it's a directory get the default POSIX ACL. */
-       if(S_ISDIR(sbuf.st_ex_mode)) {
+       if(S_ISDIR(smb_fname->st.st_ex_mode)) {
                def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
                def_acl = free_empty_sys_acl(conn, def_acl);
        }
 
        pal = load_inherited_info(conn, name);
 
-       return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl,
-                                      def_acl, security_info, ppdesc);
+       status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal,
+                                        posix_acl, def_acl, security_info,
+                                        ppdesc);
+ out:
+       TALLOC_FREE(smb_fname);
+       return status;
 }
 
 /****************************************************************************
@@ -3514,7 +3522,8 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) {
+       if (!parent_dirname(mem_ctx, fsp->fsp_name->base_name, &parent_name,
+                           NULL)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -3596,7 +3605,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                                        "ignoring non container "
                                        "inherit flags %u on ACE with sid %s "
                                        "from parent %s\n",
-                                       fsp->fsp_name,
+                                       fsp_str_dbg(fsp),
                                        (unsigned int)se->flags,
                                        sid_string_dbg(&se->trustee),
                                        parent_name));
@@ -3609,7 +3618,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                                        "ignoring non object "
                                        "inherit flags %u on ACE with sid %s "
                                        "from parent %s\n",
-                                       fsp->fsp_name,
+                                       fsp_str_dbg(fsp),
                                        (unsigned int)se->flags,
                                        sid_string_dbg(&se->trustee),
                                        parent_name));
@@ -3633,7 +3642,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                                DEBUG(10,("append_parent_acl: path %s "
                                        "ignoring ACE with protected sid %s "
                                        "from parent %s\n",
-                                       fsp->fsp_name,
+                                       fsp_str_dbg(fsp),
                                        sid_string_dbg(&se->trustee),
                                        parent_name));
                                continue;
@@ -3671,7 +3680,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                DEBUG(10,("append_parent_acl: path %s "
                        "inheriting ACE with sid %s "
                        "from parent %s\n",
-                       fsp->fsp_name,
+                       fsp_str_dbg(fsp),
                        sid_string_dbg(&se->trustee),
                        parent_name));
        }
@@ -3707,21 +3716,13 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        bool set_acl_as_root = false;
        bool acl_set_support = false;
        bool ret = false;
-       struct smb_filename *smb_fname = NULL;
-
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
 
        DEBUG(10,("set_nt_acl: called for file %s\n",
-                 smb_fname_str_dbg(smb_fname)));
+                 fsp_str_dbg(fsp)));
 
        if (!CAN_WRITE(conn)) {
                DEBUG(10,("set acl rejected on read-only share\n"));
-               status = NT_STATUS_MEDIA_WRITE_PROTECTED;
-               goto out;
+               return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
        /*
@@ -3729,19 +3730,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         */
 
        if(fsp->is_directory || fsp->fh->fd == -1) {
-               if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
+               if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+                       return map_nt_error_from_unix(errno);
                }
        } else {
-               if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
+               if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+                       return map_nt_error_from_unix(errno);
                }
        }
 
        /* Save the original element we check against. */
-       orig_mode = smb_fname->st.st_ex_mode;
+       orig_mode = fsp->fsp_name->st.st_ex_mode;
 
        /*
         * Unpack the user/group/world id's.
@@ -3749,7 +3748,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
 
        status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd);
        if (!NT_STATUS_IS_OK(status)) {
-               goto out;
+               return status;
        }
 
        /*
@@ -3758,24 +3757,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
         * Noticed by Simo.
         */
 
-       if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) ||
-           (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) {
+       if (((user != (uid_t)-1) && (fsp->fsp_name->st.st_ex_uid != user)) ||
+           (( grp != (gid_t)-1) && (fsp->fsp_name->st.st_ex_gid != grp))) {
 
                DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
-                        smb_fname_str_dbg(smb_fname), (unsigned int)user,
-                        (unsigned int)grp ));
+                        fsp_str_dbg(fsp), (unsigned int)user,
+                        (unsigned int)grp));
 
-               if(try_chown(fsp->conn, smb_fname, user, grp) == -1) {
+               if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) {
                        DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error "
-                                "= %s.\n", smb_fname_str_dbg(smb_fname),
+                                "= %s.\n", fsp_str_dbg(fsp),
                                 (unsigned int)user, (unsigned int)grp,
                                 strerror(errno)));
                        if (errno == EPERM) {
-                               status = NT_STATUS_INVALID_OWNER;
-                               goto out;
+                               return NT_STATUS_INVALID_OWNER;
                        }
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
+                       return map_nt_error_from_unix(errno);
                }
 
                /*
@@ -3784,25 +3781,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                 */
 
                if(fsp->is_directory) {
-                       if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
-                               status = map_nt_error_from_unix(errno);
-                               goto out;
+                       if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+                               return map_nt_error_from_unix(errno);
                        }
                } else {
 
                        int sret;
 
                        if(fsp->fh->fd == -1)
-                               sret = SMB_VFS_STAT(fsp->conn, smb_fname);
+                               sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
                        else
-                               sret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+                               sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
 
                        if(sret != 0)
                                return map_nt_error_from_unix(errno);
                }
 
                /* Save the original element we check against. */
-               orig_mode = smb_fname->st.st_ex_mode;
+               orig_mode = fsp->fsp_name->st.st_ex_mode;
 
                /* If we successfully chowned, we know we must
                 * be able to set the acl, so do it as root.
@@ -3810,24 +3806,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                set_acl_as_root = true;
        }
 
-       create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid);
+       create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid);
 
-       acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid,
+       acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid,
                                     &file_grp_sid, &file_ace_list,
                                     &dir_ace_list, security_info_sent, psd);
 
        /* Ignore W2K traverse DACL set. */
        if (!file_ace_list && !dir_ace_list) {
-               status = NT_STATUS_OK;
-               goto out;
+               return NT_STATUS_OK;
        }
 
        if (!acl_perms) {
                DEBUG(3,("set_nt_acl: cannot set permissions\n"));
                free_canon_ace_list(file_ace_list);
                free_canon_ace_list(dir_ace_list);
-               status = NT_STATUS_ACCESS_DENIED;
-               goto out;
+               return NT_STATUS_ACCESS_DENIED;
        }
 
        /*
@@ -3837,8 +3831,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
                free_canon_ace_list(file_ace_list);
                free_canon_ace_list(dir_ace_list);
-               status = NT_STATUS_OK;
-               goto out;
+               return NT_STATUS_OK;
        }
 
        /*
@@ -3851,18 +3844,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                        become_root();
                }
                ret = set_canon_ace_list(fsp, file_ace_list, false,
-                                        &smb_fname->st, &acl_set_support);
+                                        &fsp->fsp_name->st, &acl_set_support);
                if (set_acl_as_root) {
                        unbecome_root();
                }
                if (acl_set_support && ret == false) {
                        DEBUG(3,("set_nt_acl: failed to set file acl on file "
-                                "%s (%s).\n", smb_fname_str_dbg(smb_fname),
+                                "%s (%s).\n", fsp_str_dbg(fsp),
                                 strerror(errno)));
                        free_canon_ace_list(file_ace_list);
                        free_canon_ace_list(dir_ace_list);
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
+                       return map_nt_error_from_unix(errno);
                }
        }
 
@@ -3872,7 +3864,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                                become_root();
                        }
                        ret = set_canon_ace_list(fsp, dir_ace_list, true,
-                                                &smb_fname->st,
+                                                &fsp->fsp_name->st,
                                                 &acl_set_support);
                        if (set_acl_as_root) {
                                unbecome_root();
@@ -3880,12 +3872,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                        if (ret == false) {
                                DEBUG(3,("set_nt_acl: failed to set default "
                                         "acl on directory %s (%s).\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno) ));
+                                        fsp_str_dbg(fsp), strerror(errno)));
                                free_canon_ace_list(file_ace_list);
                                free_canon_ace_list(dir_ace_list);
-                               status = map_nt_error_from_unix(errno);
-                               goto out;
+                               return map_nt_error_from_unix(errno);
                        }
                } else {
                        int sret = -1;
@@ -3898,23 +3888,23 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                                become_root();
                        }
                        sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn,
-                           smb_fname->base_name);
+                           fsp->fsp_name->base_name);
                        if (set_acl_as_root) {
                                unbecome_root();
                        }
                        if (sret == -1) {
-                               if (acl_group_override(conn, smb_fname)) {
+                               if (acl_group_override(conn, fsp->fsp_name)) {
                                        DEBUG(5,("set_nt_acl: acl group "
                                                 "control on and current user "
                                                 "in file %s primary group. "
                                                 "Override delete_def_acl\n",
-                                               smb_fname_str_dbg(smb_fname)));
+                                                fsp_str_dbg(fsp)));
 
                                        become_root();
                                        sret =
                                            SMB_VFS_SYS_ACL_DELETE_DEF_FILE(
                                                    conn,
-                                                   smb_fname->base_name);
+                                                   fsp->fsp_name->base_name);
                                        unbecome_root();
                                }
 
@@ -3922,8 +3912,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                                        DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
                                        free_canon_ace_list(file_ace_list);
                                        free_canon_ace_list(dir_ace_list);
-                                       status = map_nt_error_from_unix(errno);
-                                       goto out;
+                                       return map_nt_error_from_unix(errno);
                                }
                        }
                }
@@ -3954,52 +3943,48 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
                        free_canon_ace_list(dir_ace_list);
                        DEBUG(3,("set_nt_acl: failed to convert file acl to "
                                 "posix permissions for file %s.\n",
-                                smb_fname_str_dbg(smb_fname)));
-                       status = NT_STATUS_ACCESS_DENIED;
-                       goto out;
+                                fsp_str_dbg(fsp)));
+                       return NT_STATUS_ACCESS_DENIED;
                }
 
                if (orig_mode != posix_perms) {
                        int sret = -1;
 
                        DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
-                                smb_fname_str_dbg(smb_fname),
-                                (unsigned int)posix_perms));
+                                fsp_str_dbg(fsp), (unsigned int)posix_perms));
 
                        if (set_acl_as_root) {
                                become_root();
                        }
-                       sret = SMB_VFS_CHMOD(conn, smb_fname->base_name,
+                       sret = SMB_VFS_CHMOD(conn, fsp->fsp_name->base_name,
                                             posix_perms);
                        if (set_acl_as_root) {
                                unbecome_root();
                        }
                        if(sret == -1) {
-                               if (acl_group_override(conn, smb_fname)) {
+                               if (acl_group_override(conn, fsp->fsp_name)) {
                                        DEBUG(5,("set_nt_acl: acl group "
                                                 "control on and current user "
                                                 "in file %s primary group. "
                                                 "Override chmod\n",
-                                               smb_fname_str_dbg(smb_fname)));
+                                                fsp_str_dbg(fsp)));
 
                                        become_root();
-                                       sret =
-                                           SMB_VFS_CHMOD(conn,
-                                                         smb_fname->base_name,
-                                                         posix_perms);
+                                       sret = SMB_VFS_CHMOD(conn,
+                                           fsp->fsp_name->base_name,
+                                           posix_perms);
                                        unbecome_root();
                                }
 
                                if (sret == -1) {
                                        DEBUG(3,("set_nt_acl: chmod %s, 0%o "
                                                 "failed. Error = %s.\n",
-                                                smb_fname_str_dbg(smb_fname),
+                                                fsp_str_dbg(fsp),
                                                 (unsigned int)posix_perms,
                                                 strerror(errno)));
                                        free_canon_ace_list(file_ace_list);
                                        free_canon_ace_list(dir_ace_list);
-                                       status = map_nt_error_from_unix(errno);
-                                       goto out;
+                                       return map_nt_error_from_unix(errno);
                                }
                        }
                }
@@ -4008,10 +3993,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
        free_canon_ace_list(file_ace_list);
        free_canon_ace_list(dir_ace_list);
 
-       status = NT_STATUS_OK;
- out:
-       TALLOC_FREE(smb_fname);
-       return status;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************
@@ -4614,6 +4596,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
        connection_struct *conn;
        files_struct finfo;
        struct fd_handle fh;
+       NTSTATUS status;
 
        conn = TALLOC_ZERO_P(ctx, connection_struct);
        if (conn == NULL) {
@@ -4644,16 +4627,24 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
        finfo.conn = conn;
        finfo.fh = &fh;
        finfo.fh->fd = -1;
-       finfo.fsp_name = CONST_DISCARD(char *,fname);
+
+       status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+                                           &finfo.fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               conn_free_internal( conn );
+               return NULL;
+       }
 
        if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
                DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
+               TALLOC_FREE(finfo.fsp_name);
                conn_free_internal( conn );
                return NULL;
        }
 
        ret_sd = dup_sec_desc( ctx, psd );
 
+       TALLOC_FREE(finfo.fsp_name);
        conn_free_internal( conn );
 
        return ret_sd;
index b26bc150dbdbcc1c558b6892b7bd8d3d7aa880fd..c2065caf798b246a7f223f8893de81c1939f8ec9 100644 (file)
@@ -2015,11 +2015,6 @@ void smbd_process(void)
        TALLOC_CTX *frame = talloc_stackframe();
        char remaddr[INET6_ADDRSTRLEN];
 
-       smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
-       if (!smbd_server_conn) {
-               exit_server("failed to create smbd_server_connection");
-       }
-
        if (lp_maxprotocol() == PROTOCOL_SMB2 &&
            lp_security() != SEC_SHARE) {
                smbd_server_conn->allow_smb2 = true;
index 1fd4e50ea66c77392608898990970827885b3e8a..76d32a2f98e57b7656bae19eec489a881b97a19d 100644 (file)
@@ -856,6 +856,7 @@ void reply_tcon_and_X(struct smb_request *req)
 
        END_PROFILE(SMBtconX);
 
+       req->tid = conn->cnum;
        chain_reply(req);
        return;
 }
@@ -993,8 +994,7 @@ void reply_checkpath(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                name,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1090,8 +1090,7 @@ void reply_getatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1106,7 +1105,7 @@ void reply_getatr(struct smb_request *req)
                        DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
                                 smb_fname_str_dbg(smb_fname),
                                 strerror(errno)));
-                       reply_unixerror(req, ERRDOS,ERRbadfile);
+                       reply_nterror(req,  map_nt_error_from_unix(errno));
                        goto out;
                }
 
@@ -1192,8 +1191,7 @@ void reply_setatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1220,7 +1218,7 @@ void reply_setatr(struct smb_request *req)
        ft.mtime = convert_time_t_to_timespec(mtime);
        status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, status);
                goto out;
        }
 
@@ -1232,7 +1230,7 @@ void reply_setatr(struct smb_request *req)
 
                if (file_set_dosmode(conn, smb_fname, mode, NULL,
                                     false) != 0) {
-                       reply_unixerror(req, ERRDOS, ERRnoaccess);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        goto out;
                }
        }
@@ -1258,7 +1256,7 @@ void reply_dskattr(struct smb_request *req)
        START_PROFILE(SMBdskattr);
 
        if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
-               reply_unixerror(req, ERRHRD, ERRgeneral);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBdskattr);
                return;
        }
@@ -1342,6 +1340,7 @@ void reply_search(struct smb_request *req)
        char *path = NULL;
        const char *mask = NULL;
        char *directory = NULL;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        SMB_OFF_T size;
        uint32 mode;
@@ -1366,14 +1365,12 @@ void reply_search(struct smb_request *req)
 
        if (req->wct < 2) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        if (lp_posix_pathnames()) {
                reply_unknown_new(req, req->cmd);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        /* If we were called as SMBffirst then we must expect close. */
@@ -1389,8 +1386,7 @@ void reply_search(struct smb_request *req)
                                       &nt_status, &mask_contains_wcard);
        if (!NT_STATUS_IS_OK(nt_status)) {
                reply_nterror(req, nt_status);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        p++;
@@ -1400,8 +1396,6 @@ void reply_search(struct smb_request *req)
        /* dirtype &= ~aDIR; */
 
        if (status_len == 0) {
-               struct smb_filename *smb_fname = NULL;
-
                nt_status = resolve_dfspath_wcard(ctx, conn,
                                          req->flags2 & FLAGS2_DFS_PATHNAMES,
                                          path,
@@ -1411,35 +1405,25 @@ void reply_search(struct smb_request *req)
                        if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                                ERRSRV, ERRbadpath);
-                               END_PROFILE(SMBsearch);
-                               return;
+                               goto out;
                        }
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
                nt_status = unix_convert(ctx, conn, path, &smb_fname,
                                         UCF_ALLOW_WCARD_LCOMP);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
-               nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
-               TALLOC_FREE(smb_fname);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
-               }
+               directory = smb_fname->base_name;
 
                nt_status = check_name(conn, directory);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
                p = strrchr_m(directory,'/');
@@ -1454,8 +1438,7 @@ void reply_search(struct smb_request *req)
 
                if (!directory) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
                memset((char *)status,'\0',21);
@@ -1472,8 +1455,7 @@ void reply_search(struct smb_request *req)
                                        &conn->dirptr);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
                dptr_num = dptr_dnum(conn->dirptr);
        } else {
@@ -1513,8 +1495,7 @@ void reply_search(struct smb_request *req)
                if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
                                0,aVOLID,0,!allow_long_path_components)) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
                dptr_fill(buf+12,dptr_num);
                if (dptr_zero(buf+12) && (status_len==0)) {
@@ -1526,8 +1507,7 @@ void reply_search(struct smb_request *req)
                                      data_blob_const(buf, sizeof(buf)))
                    == -1) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
        } else {
                unsigned int i;
@@ -1566,8 +1546,7 @@ void reply_search(struct smb_request *req)
                                                convert_timespec_to_time_t(date),
                                                !allow_long_path_components)) {
                                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                                       END_PROFILE(SMBsearch);
-                                       return;
+                                       goto out;
                                }
                                if (!dptr_fill(buf+12,dptr_num)) {
                                        break;
@@ -1576,8 +1555,7 @@ void reply_search(struct smb_request *req)
                                                      data_blob_const(buf, sizeof(buf)))
                                    == -1) {
                                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                                       END_PROFILE(SMBsearch);
-                                       return;
+                                       goto out;
                                }
                                numentries++;
                        }
@@ -1604,8 +1582,7 @@ void reply_search(struct smb_request *req)
 
        if ((numentries == 0) && !mask_contains_wcard) {
                reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        SSVAL(req->outbuf,smb_vwv0,numentries);
@@ -1637,7 +1614,8 @@ void reply_search(struct smb_request *req)
                dirtype,
                numentries,
                maxentries ));
-
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBsearch);
        return;
 }
@@ -1746,8 +1724,7 @@ void reply_open(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1759,10 +1736,10 @@ void reply_open(struct smb_request *req)
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(
-                   smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN,
-                   &access_mask, &share_mode, &create_disposition,
-                   &create_options)) {
+       if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
+                                        OPENX_FILE_EXISTS_OPEN, &access_mask,
+                                        &share_mode, &create_disposition,
+                                        &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
        }
@@ -1811,7 +1788,8 @@ void reply_open(struct smb_request *req)
        mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
 
        if (fattr & aDIR) {
-               DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
+               DEBUG(3,("attempt to open a directory %s\n",
+                        fsp_str_dbg(fsp)));
                close_file(req, fsp, ERROR_CLOSE);
                reply_doserror(req, ERRDOS,ERRnoaccess);
                goto out;
@@ -1916,8 +1894,7 @@ void reply_open_and_X(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1929,9 +1906,10 @@ void reply_open_and_X(struct smb_request *req)
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(
-                   smb_fname->base_name, deny_mode, smb_ofun, &access_mask,
-                   &share_mode, &create_disposition, &create_options)) {
+       if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
+                                        &access_mask, &share_mode,
+                                        &create_disposition,
+                                        &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
        }
@@ -2076,6 +2054,7 @@ void reply_ulogoffX(struct smb_request *req)
        DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
 
        END_PROFILE(SMBulogoffX);
+       req->vuid = UID_FIELD_INVALID;
        chain_reply(req);
 }
 
@@ -2124,8 +2103,7 @@ void reply_mknew(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -2257,8 +2235,7 @@ void reply_ctemp(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2271,7 +2248,7 @@ void reply_ctemp(struct smb_request *req)
 
        tmpfd = mkstemp(smb_fname->base_name);
        if (tmpfd == -1) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                goto out;
        }
 
@@ -2311,9 +2288,9 @@ void reply_ctemp(struct smb_request *req)
        SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
 
        /* the returned filename is relative to the directory */
-       s = strrchr_m(fsp->fsp_name, '/');
+       s = strrchr_m(fsp->fsp_name->base_name, '/');
        if (!s) {
-               s = fsp->fsp_name;
+               s = fsp->fsp_name->base_name;
        } else {
                s++;
        }
@@ -2339,8 +2316,8 @@ void reply_ctemp(struct smb_request *req)
                      CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
        }
 
-       DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
-       DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+       DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
+       DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
                    fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
  out:
        TALLOC_FREE(smb_fname);
@@ -2355,22 +2332,13 @@ void reply_ctemp(struct smb_request *req)
 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
                           uint16 dirtype, SMB_STRUCT_STAT *pst)
 {
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
        uint32 fmode;
 
        if (!CAN_WRITE(conn)) {
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 pst, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       fmode = dos_mode(conn, smb_fname);
-       TALLOC_FREE(smb_fname);
+       fmode = dos_mode(conn, fsp->fsp_name);
        if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
                return NT_STATUS_NO_SUCH_FILE;
        }
@@ -2646,18 +2614,23 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
 
                while ((dname = ReadDirName(dir_hnd, &offset,
                                            &smb_fname->st))) {
+                       TALLOC_CTX *frame = talloc_stackframe();
+
                        if (!is_visible_file(conn, fname_dir, dname,
                                             &smb_fname->st, true)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        /* Quick check for "." and ".." */
                        if (ISDOT(dname) || ISDOTDOT(dname)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        if(!mask_match(dname, fname_mask,
                                       conn->case_sensitive)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
@@ -2669,23 +2642,28 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
                        if (!smb_fname->base_name) {
                                TALLOC_FREE(dir_hnd);
                                status = NT_STATUS_NO_MEMORY;
+                               TALLOC_FREE(frame);
                                goto out;
                        }
 
                        status = check_name(conn, smb_fname->base_name);
                        if (!NT_STATUS_IS_OK(status)) {
                                TALLOC_FREE(dir_hnd);
+                               TALLOC_FREE(frame);
                                goto out;
                        }
 
                        status = do_unlink(conn, req, smb_fname, dirtype);
                        if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        count++;
                        DEBUG(3,("unlink_internals: successful unlink [%s]\n",
                                 smb_fname->base_name));
+
+                       TALLOC_FREE(frame);
                }
                TALLOC_FREE(dir_hnd);
        }
@@ -2854,7 +2832,7 @@ static void sendfile_short_send(files_struct *fsp,
        if (nread < headersize) {
                DEBUG(0,("sendfile_short_send: sendfile failed to send "
                        "header for file %s (%s). Terminating\n",
-                       fsp->fsp_name, strerror(errno) ));
+                       fsp_str_dbg(fsp), strerror(errno)));
                exit_server_cleanly("sendfile_short_send failed");
        }
 
@@ -2868,7 +2846,7 @@ static void sendfile_short_send(files_struct *fsp,
                }
 
                DEBUG(0,("sendfile_short_send: filling truncated file %s "
-                       "with zeros !\n", fsp->fsp_name));
+                       "with zeros !\n", fsp_str_dbg(fsp)));
 
                while (nread < smb_maxcnt) {
                        /*
@@ -2963,15 +2941,19 @@ static void send_file_readbraw(connection_struct *conn,
                                DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
 
                                if (fake_sendfile(fsp, startpos, nread) == -1) {
-                                       DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
-                                               fsp->fsp_name, strerror(errno) ));
+                                       DEBUG(0,("send_file_readbraw: "
+                                                "fake_sendfile failed for "
+                                                "file %s (%s).\n",
+                                                fsp_str_dbg(fsp),
+                                                strerror(errno)));
                                        exit_server_cleanly("send_file_readbraw fake_sendfile failed");
                                }
                                return;
                        }
 
-                       DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readbraw: sendfile failed for "
+                                "file %s (%s). Terminating\n",
+                                fsp_str_dbg(fsp), strerror(errno)));
                        exit_server_cleanly("send_file_readbraw sendfile failed");
                } else if (sendfile_read == 0) {
                        /*
@@ -2983,7 +2965,7 @@ static void send_file_readbraw(connection_struct *conn,
                         */
                        DEBUG(3, ("send_file_readbraw: sendfile sent zero "
                                  "bytes falling back to the normal read: "
-                                 "%s\n", fsp->fsp_name));
+                                 "%s\n", fsp_str_dbg(fsp)));
                        goto normal_readbraw;
                }
 
@@ -3269,7 +3251,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
        nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBlockread);
                return;
        }
@@ -3363,7 +3345,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
                nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS,ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                goto strict_unlock;
        }
 
@@ -3425,9 +3407,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
        SMB_STRUCT_STAT sbuf;
        ssize_t nread = -1;
        struct lock_struct lock;
+       int saved_errno = 0;
 
        if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                return;
        }
 
@@ -3494,8 +3477,11 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                nread = fake_sendfile(fsp, startpos,
                                                      smb_maxcnt);
                                if (nread == -1) {
-                                       DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
-                                               fsp->fsp_name, strerror(errno) ));
+                                       DEBUG(0,("send_file_readX: "
+                                                "fake_sendfile failed for "
+                                                "file %s (%s).\n",
+                                                fsp_str_dbg(fsp),
+                                                strerror(errno)));
                                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
                                }
                                DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
@@ -3504,8 +3490,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                goto strict_unlock;
                        }
 
-                       DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: sendfile failed for file "
+                                "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX sendfile failed");
                } else if (nread == 0) {
                        /*
@@ -3517,7 +3504,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                         */
                        DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
                                  "falling back to the normal read: %s\n",
-                                 fsp->fsp_name));
+                                 fsp_str_dbg(fsp)));
                        goto normal_read;
                }
 
@@ -3547,14 +3534,16 @@ normal_read:
                /* Send out the header. */
                if (write_data(smbd_server_fd(), (char *)headerbuf,
                               sizeof(headerbuf)) != sizeof(headerbuf)) {
-                       DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: write_data failed for file "
+                                "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX sendfile failed");
                }
                nread = fake_sendfile(fsp, startpos, smb_maxcnt);
                if (nread == -1) {
-                       DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: fake_sendfile failed for "
+                                "file %s (%s).\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
                }
                goto strict_unlock;
@@ -3565,11 +3554,12 @@ nosendfile_read:
        reply_outbuf(req, 12, smb_maxcnt);
 
        nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+       saved_errno = errno;
 
        SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
                return;
        }
 
@@ -3810,7 +3800,7 @@ void reply_writebraw(struct smb_request *req)
                (int)nwritten, (int)write_through));
 
        if (nwritten < (ssize_t)numtowrite)  {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                error_to_writebrawerr(req);
                goto strict_unlock;
        }
@@ -3879,7 +3869,7 @@ void reply_writebraw(struct smb_request *req)
                nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
                if (nwritten == -1) {
                        TALLOC_FREE(buf);
-                       reply_unixerror(req, ERRHRD, ERRdiskfull);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        error_to_writebrawerr(req);
                        goto strict_unlock;
                }
@@ -3900,7 +3890,7 @@ void reply_writebraw(struct smb_request *req)
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                error_to_writebrawerr(req);
                goto strict_unlock;
@@ -3958,6 +3948,7 @@ void reply_writeunlock(struct smb_request *req)
        NTSTATUS status = NT_STATUS_OK;
        files_struct *fsp;
        struct lock_struct lock;
+       int saved_errno = 0;
 
        START_PROFILE(SMBwriteunlock);
 
@@ -4003,18 +3994,24 @@ void reply_writeunlock(struct smb_request *req)
                nwritten = 0;
        } else {
                nwritten = write_file(req,fsp,data,startpos,numtowrite);
+               saved_errno = errno;
        }
 
        status = sync_file(conn, fsp, False /* write through */);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
 
-       if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten < numtowrite) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4065,6 +4062,7 @@ void reply_write(struct smb_request *req)
        files_struct *fsp;
        struct lock_struct lock;
        NTSTATUS status;
+       int saved_errno = 0;
 
        START_PROFILE(SMBwrite);
 
@@ -4136,13 +4134,18 @@ void reply_write(struct smb_request *req)
        status = sync_file(conn, fsp, False);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_write: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
 
-       if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten == 0) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4389,8 +4392,13 @@ void reply_write_and_X(struct smb_request *req)
                nwritten = write_file(req,fsp,data,startpos,numtowrite);
        }
 
-       if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten == 0) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4409,7 +4417,7 @@ void reply_write_and_X(struct smb_request *req)
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
@@ -4484,8 +4492,8 @@ void reply_lseek(struct smb_request *req)
                                SMB_STRUCT_STAT sbuf;
 
                                if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-                                       reply_unixerror(req, ERRDOS,
-                                                       ERRnoaccess);
+                                       reply_nterror(req,
+                                               map_nt_error_from_unix(errno));
                                        END_PROFILE(SMBlseek);
                                        return;
                                }
@@ -4497,7 +4505,7 @@ void reply_lseek(struct smb_request *req)
                }
 
                if(res == -1) {
-                       reply_unixerror(req, ERRDOS, ERRnoaccess);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        END_PROFILE(SMBlseek);
                        return;
                }
@@ -4545,7 +4553,7 @@ void reply_flush(struct smb_request *req)
                NTSTATUS status = sync_file(conn, fsp, True);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
-                               fsp->fsp_name, nt_errstr(status) ));
+                               fsp_str_dbg(fsp), nt_errstr(status)));
                        reply_nterror(req, status);
                        END_PROFILE(SMBflush);
                        return;
@@ -4713,8 +4721,8 @@ void reply_writeclose(struct smb_request *req)
         */
 
        if (numtowrite) {
-               DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
-                       fsp->fsp_name ));
+               DEBUG(3,("reply_writeclose: zero length write doesn't close "
+                        "file %s\n", fsp_str_dbg(fsp)));
                close_status = close_file(req, fsp, NORMAL_CLOSE);
        }
 
@@ -5197,7 +5205,7 @@ void reply_printwrite(struct smb_request *req)
        data = (const char *)req->buf + 3;
 
        if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBsplwr);
                return;
        }
@@ -5232,8 +5240,7 @@ void reply_mkdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
-                                &smb_dname,
-                                NULL);
+                                &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5540,8 +5547,7 @@ void reply_rmdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
-                                &smb_dname,
-                                NULL);
+                                &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5711,7 +5717,6 @@ static void rename_open_files(connection_struct *conn,
 {
        files_struct *fsp;
        bool did_rename = False;
-       char *fname_dst = NULL;
        NTSTATUS status;
 
        for(fsp = file_find_di_first(lck->id); fsp;
@@ -5725,17 +5730,13 @@ static void rename_open_files(connection_struct *conn,
                }
                DEBUG(10, ("rename_open_files: renaming file fnum %d "
                           "(file_id %s) from %s -> %s\n", fsp->fnum,
-                          file_id_string_tos(&fsp->file_id), fsp->fsp_name,
+                          file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
                           smb_fname_str_dbg(smb_fname_dst)));
 
-               status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
-                                              &fname_dst);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return;
+               status = fsp_set_smb_fname(fsp, smb_fname_dst);
+               if (NT_STATUS_IS_OK(status)) {
+                       did_rename = True;
                }
-               string_set(&fsp->fsp_name, fname_dst);
-               did_rename = True;
-               TALLOC_FREE(fname_dst);
        }
 
        if (!did_rename) {
@@ -5790,9 +5791,6 @@ static void notify_rename(connection_struct *conn, bool is_dir,
 {
        char *parent_dir_src = NULL;
        char *parent_dir_dst = NULL;
-       char *fname_src = NULL;
-       char *fname_dst = NULL;
-       NTSTATUS status;
        uint32 mask;
 
        mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
@@ -5805,24 +5803,17 @@ static void notify_rename(connection_struct *conn, bool is_dir,
                goto out;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname_src,
-                                      &fname_src);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-       status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
-                                      &fname_dst);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        if (strcmp(parent_dir_src, parent_dir_dst) == 0) {
-               notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src);
-               notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst);
+               notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask,
+                            smb_fname_src->base_name);
+               notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask,
+                            smb_fname_dst->base_name);
        }
        else {
-               notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src);
-               notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst);
+               notify_fname(conn, NOTIFY_ACTION_REMOVED, mask,
+                            smb_fname_src->base_name);
+               notify_fname(conn, NOTIFY_ACTION_ADDED, mask,
+                            smb_fname_dst->base_name);
        }
 
        /* this is a strange one. w2k3 gives an additional event for
@@ -5832,13 +5823,11 @@ static void notify_rename(connection_struct *conn, bool is_dir,
                notify_fname(conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_ATTRIBUTES
                             |FILE_NOTIFY_CHANGE_CREATION,
-                            fname_dst);
+                            smb_fname_dst->base_name);
        }
  out:
        TALLOC_FREE(parent_dir_src);
        TALLOC_FREE(parent_dir_dst);
-       TALLOC_FREE(fname_src);
-       TALLOC_FREE(fname_dst);
 }
 
 /****************************************************************************
@@ -5867,17 +5856,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        }
 
        /* Make a copy of the src and dst smb_fname structs */
-       status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
+       status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
 
-       /*
-        * This will be replaced with copy_smb_filename() when fsp->fsp_name
-        * is converted to store an smb_filename struct.
-        */
-       status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL,
-                                                 &smb_fname_src);
+       status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
@@ -6635,8 +6619,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
        if (!target_is_directory && count) {
                new_create_disposition = FILE_OPEN;
        } else {
-               if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name,
-                                                0, ofun, NULL, NULL,
+               if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
+                                                NULL, NULL,
                                                 &new_create_disposition,
                                                 NULL)) {
                        status = NT_STATUS_INVALID_PARAMETER;
@@ -6756,7 +6740,6 @@ void reply_copy(struct smb_request *req)
        const char *p;
        int count=0;
        int error = ERRnoaccess;
-       int err = 0;
        int tid2;
        int ofun;
        int flags;
@@ -7059,13 +7042,6 @@ void reply_copy(struct smb_request *req)
        }
 
        if (count == 0) {
-               if(err) {
-                       /* Error on close... */
-                       errno = err;
-                       reply_unixerror(req, ERRHRD, ERRgeneral);
-                       goto out;
-               }
-
                reply_doserror(req, ERRDOS, error);
                goto out;
        }
@@ -7223,6 +7199,205 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset,
        return offset;
 }
 
+NTSTATUS smbd_do_locking(struct smb_request *req,
+                        files_struct *fsp,
+                        uint8_t type,
+                        int32_t timeout,
+                        uint16_t num_ulocks,
+                        struct smbd_lock_element *ulocks,
+                        uint16_t num_locks,
+                        struct smbd_lock_element *locks,
+                        bool *async)
+{
+       connection_struct *conn = req->conn;
+       int i;
+       NTSTATUS status = NT_STATUS_OK;
+
+       *async = false;
+
+       /* Data now points at the beginning of the list
+          of smb_unlkrng structs */
+       for(i = 0; i < (int)num_ulocks; i++) {
+               struct smbd_lock_element *e = &ulocks[i];
+
+               DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for "
+                         "pid %u, file %s\n",
+                         (double)e->offset,
+                         (double)e->count,
+                         (unsigned int)e->smbpid,
+                         fsp_str_dbg(fsp)));
+
+               if (e->brltype != UNLOCK_LOCK) {
+                       /* this can only happen with SMB2 */
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               status = do_unlock(smbd_messaging_context(),
+                               fsp,
+                               e->smbpid,
+                               e->count,
+                               e->offset,
+                               WINDOWS_LOCK);
+
+               DEBUG(10, ("smbd_do_locking: unlock returned %s\n",
+                   nt_errstr(status)));
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       /* Setup the timeout in seconds. */
+
+       if (!lp_blocking_locks(SNUM(conn))) {
+               timeout = 0;
+       }
+
+       /* Data now points at the beginning of the list
+          of smb_lkrng structs */
+
+       for(i = 0; i < (int)num_locks; i++) {
+               struct smbd_lock_element *e = &locks[i];
+
+               DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for pid "
+                         "%u, file %s timeout = %d\n",
+                         (double)e->offset,
+                         (double)e->count,
+                         (unsigned int)e->smbpid,
+                         fsp_str_dbg(fsp),
+                         (int)timeout));
+
+               if (type & LOCKING_ANDX_CANCEL_LOCK) {
+                       struct blocking_lock_record *blr = NULL;
+
+                       if (lp_blocking_locks(SNUM(conn))) {
+
+                               /* Schedule a message to ourselves to
+                                  remove the blocking lock record and
+                                  return the right error. */
+
+                               blr = blocking_lock_cancel(fsp,
+                                               e->smbpid,
+                                               e->offset,
+                                               e->count,
+                                               WINDOWS_LOCK,
+                                               type,
+                                               NT_STATUS_FILE_LOCK_CONFLICT);
+                               if (blr == NULL) {
+                                       return NT_STATUS_DOS(
+                                                       ERRDOS,
+                                                       ERRcancelviolation);
+                               }
+                       }
+                       /* Remove a matching pending lock. */
+                       status = do_lock_cancel(fsp,
+                                               e->smbpid,
+                                               e->count,
+                                               e->offset,
+                                               WINDOWS_LOCK,
+                                               blr);
+               } else {
+                       bool blocking_lock = timeout ? true : false;
+                       bool defer_lock = false;
+                       struct byte_range_lock *br_lck;
+                       uint32_t block_smbpid;
+
+                       br_lck = do_lock(smbd_messaging_context(),
+                                       fsp,
+                                       e->smbpid,
+                                       e->count,
+                                       e->offset, 
+                                       e->brltype,
+                                       WINDOWS_LOCK,
+                                       blocking_lock,
+                                       &status,
+                                       &block_smbpid,
+                                       NULL);
+
+                       if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
+                               /* Windows internal resolution for blocking locks seems
+                                  to be about 200ms... Don't wait for less than that. JRA. */
+                               if (timeout != -1 && timeout < lp_lock_spin_time()) {
+                                       timeout = lp_lock_spin_time();
+                               }
+                               defer_lock = true;
+                       }
+
+                       /* This heuristic seems to match W2K3 very well. If a
+                          lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
+                          it pretends we asked for a timeout of between 150 - 300 milliseconds as
+                          far as I can tell. Replacement for do_lock_spin(). JRA. */
+
+                       if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
+                                       NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
+                               defer_lock = true;
+                               timeout = lp_lock_spin_time();
+                       }
+
+                       if (br_lck && defer_lock) {
+                               /*
+                                * A blocking lock was requested. Package up
+                                * this smb into a queued request and push it
+                                * onto the blocking lock queue.
+                                */
+                               if(push_blocking_lock_request(br_lck,
+                                                       req,
+                                                       fsp,
+                                                       timeout,
+                                                       i,
+                                                       e->smbpid,
+                                                       e->brltype,
+                                                       WINDOWS_LOCK,
+                                                       e->offset,
+                                                       e->count,
+                                                       block_smbpid)) {
+                                       TALLOC_FREE(br_lck);
+                                       *async = true;
+                                       return NT_STATUS_OK;
+                               }
+                       }
+
+                       TALLOC_FREE(br_lck);
+               }
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       break;
+               }
+       }
+
+       /* If any of the above locks failed, then we must unlock
+          all of the previous locks (X/Open spec). */
+
+       if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
+
+               if (type & LOCKING_ANDX_CANCEL_LOCK) {
+                       i = -1; /* we want to skip the for loop */
+               }
+
+               /*
+                * Ensure we don't do a remove on the lock that just failed,
+                * as under POSIX rules, if we have a lock already there, we
+                * will delete it (and we shouldn't) .....
+                */
+               for(i--; i >= 0; i--) {
+                       struct smbd_lock_element *e = &locks[i];
+
+                       do_unlock(smbd_messaging_context(),
+                               fsp,
+                               e->smbpid,
+                               e->count,
+                               e->offset,
+                               WINDOWS_LOCK);
+               }
+               return status;
+       }
+
+       DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+                 fsp->fnum, (unsigned int)type, num_locks, num_ulocks));
+
+       return NT_STATUS_OK;
+}
+
 /****************************************************************************
  Reply to a lockingX request.
 ****************************************************************************/
@@ -7235,14 +7410,15 @@ void reply_lockingX(struct smb_request *req)
        unsigned char oplocklevel;
        uint16 num_ulocks;
        uint16 num_locks;
-       uint64_t count = 0, offset = 0;
-       uint32 lock_pid;
        int32 lock_timeout;
        int i;
        const uint8_t *data;
        bool large_file_format;
        bool err;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+       struct smbd_lock_element *ulocks;
+       struct smbd_lock_element *locks;
+       bool async = false;
 
        START_PROFILE(SMBlockingX);
 
@@ -7304,7 +7480,8 @@ void reply_lockingX(struct smb_request *req)
                        DEBUG(5,("reply_lockingX: Error : oplock break from "
                                 "client for fnum = %d (oplock=%d) and no "
                                 "oplock granted on this file (%s).\n",
-                                fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+                                fsp->fnum, fsp->oplock_type,
+                                fsp_str_dbg(fsp)));
 
                        /* if this is a pure oplock break request then don't
                         * send a reply */
@@ -7327,7 +7504,7 @@ void reply_lockingX(struct smb_request *req)
 
                if (!result) {
                        DEBUG(0, ("reply_lockingX: error in removing "
-                                 "oplock on file %s\n", fsp->fsp_name));
+                                 "oplock on file %s\n", fsp_str_dbg(fsp)));
                        /* Hmmm. Is this panic justified? */
                        smb_panic("internal tdb error");
                }
@@ -7355,12 +7532,27 @@ void reply_lockingX(struct smb_request *req)
                return;
        }
 
+       ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks);
+       if (ulocks == NULL) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
+               END_PROFILE(SMBlockingX);
+               return;
+       }
+
+       locks = talloc_array(req, struct smbd_lock_element, num_locks);
+       if (locks == NULL) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
+               END_PROFILE(SMBlockingX);
+               return;
+       }
+
        /* Data now points at the beginning of the list
           of smb_unlkrng structs */
        for(i = 0; i < (int)num_ulocks; i++) {
-               lock_pid = get_lock_pid( data, i, large_file_format);
-               count = get_lock_count( data, i, large_file_format);
-               offset = get_lock_offset( data, i, large_file_format, &err);
+               ulocks[i].smbpid = get_lock_pid(data, i, large_file_format);
+               ulocks[i].count = get_lock_count(data, i, large_file_format);
+               ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+               ulocks[i].brltype = UNLOCK_LOCK;
 
                /*
                 * There is no error code marked "stupid client bug".... :-).
@@ -7370,32 +7562,6 @@ void reply_lockingX(struct smb_request *req)
                        reply_doserror(req, ERRDOS, ERRnoaccess);
                        return;
                }
-
-               DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
-                         "pid %u, file %s\n", (double)offset, (double)count,
-                         (unsigned int)lock_pid, fsp->fsp_name ));
-
-               status = do_unlock(smbd_messaging_context(),
-                               fsp,
-                               lock_pid,
-                               count,
-                               offset,
-                               WINDOWS_LOCK);
-
-               DEBUG(10, ("reply_lockingX: unlock returned %s\n",
-                   nt_errstr(status)));
-
-               if (NT_STATUS_V(status)) {
-                       END_PROFILE(SMBlockingX);
-                       reply_nterror(req, status);
-                       return;
-               }
-       }
-
-       /* Setup the timeout in seconds. */
-
-       if (!lp_blocking_locks(SNUM(conn))) {
-               lock_timeout = 0;
        }
 
        /* Now do any requested locks */
@@ -7405,11 +7571,23 @@ void reply_lockingX(struct smb_request *req)
           of smb_lkrng structs */
 
        for(i = 0; i < (int)num_locks; i++) {
-               enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
-                               READ_LOCK:WRITE_LOCK);
-               lock_pid = get_lock_pid( data, i, large_file_format);
-               count = get_lock_count( data, i, large_file_format);
-               offset = get_lock_offset( data, i, large_file_format, &err);
+               locks[i].smbpid = get_lock_pid(data, i, large_file_format);
+               locks[i].count = get_lock_count(data, i, large_file_format);
+               locks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+
+               if (locktype & LOCKING_ANDX_SHARED_LOCK) {
+                       if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+                               locks[i].brltype = PENDING_READ_LOCK;
+                       } else {
+                               locks[i].brltype = READ_LOCK;
+                       }
+               } else {
+                       if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+                               locks[i].brltype = PENDING_WRITE_LOCK;
+                       } else {
+                               locks[i].brltype = WRITE_LOCK;
+                       }
+               }
 
                /*
                 * There is no error code marked "stupid client bug".... :-).
@@ -7419,154 +7597,22 @@ void reply_lockingX(struct smb_request *req)
                        reply_doserror(req, ERRDOS, ERRnoaccess);
                        return;
                }
-
-               DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
-                         "%u, file %s timeout = %d\n", (double)offset,
-                         (double)count, (unsigned int)lock_pid,
-                         fsp->fsp_name, (int)lock_timeout ));
-
-               if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
-                       struct blocking_lock_record *blr = NULL;
-
-                       if (lp_blocking_locks(SNUM(conn))) {
-
-                               /* Schedule a message to ourselves to
-                                  remove the blocking lock record and
-                                  return the right error. */
-
-                               blr = blocking_lock_cancel(fsp,
-                                               lock_pid,
-                                               offset,
-                                               count,
-                                               WINDOWS_LOCK,
-                                               locktype,
-                                               NT_STATUS_FILE_LOCK_CONFLICT);
-                               if (blr == NULL) {
-                                       END_PROFILE(SMBlockingX);
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_DOS(
-                                                       ERRDOS,
-                                                       ERRcancelviolation));
-                                       return;
-                               }
-                       }
-                       /* Remove a matching pending lock. */
-                       status = do_lock_cancel(fsp,
-                                               lock_pid,
-                                               count,
-                                               offset,
-                                               WINDOWS_LOCK,
-                                               blr);
-               } else {
-                       bool blocking_lock = lock_timeout ? True : False;
-                       bool defer_lock = False;
-                       struct byte_range_lock *br_lck;
-                       uint32 block_smbpid;
-
-                       br_lck = do_lock(smbd_messaging_context(),
-                                       fsp,
-                                       lock_pid,
-                                       count,
-                                       offset, 
-                                       lock_type,
-                                       WINDOWS_LOCK,
-                                       blocking_lock,
-                                       &status,
-                                       &block_smbpid,
-                                       NULL);
-
-                       if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
-                               /* Windows internal resolution for blocking locks seems
-                                  to be about 200ms... Don't wait for less than that. JRA. */
-                               if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
-                                       lock_timeout = lp_lock_spin_time();
-                               }
-                               defer_lock = True;
-                       }
-
-                       /* This heuristic seems to match W2K3 very well. If a
-                          lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
-                          it pretends we asked for a timeout of between 150 - 300 milliseconds as
-                          far as I can tell. Replacement for do_lock_spin(). JRA. */
-
-                       if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
-                                       NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
-                               defer_lock = True;
-                               lock_timeout = lp_lock_spin_time();
-                       }
-
-                       if (br_lck && defer_lock) {
-                               /*
-                                * A blocking lock was requested. Package up
-                                * this smb into a queued request and push it
-                                * onto the blocking lock queue.
-                                */
-                               if(push_blocking_lock_request(br_lck,
-                                                       req,
-                                                       fsp,
-                                                       lock_timeout,
-                                                       i,
-                                                       lock_pid,
-                                                       lock_type,
-                                                       WINDOWS_LOCK,
-                                                       offset,
-                                                       count,
-                                                       block_smbpid)) {
-                                       TALLOC_FREE(br_lck);
-                                       END_PROFILE(SMBlockingX);
-                                       return;
-                               }
-                       }
-
-                       TALLOC_FREE(br_lck);
-               }
-
-               if (NT_STATUS_V(status)) {
-                       break;
-               }
        }
 
-       /* If any of the above locks failed, then we must unlock
-          all of the previous locks (X/Open spec). */
-       if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
-
-               if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
-                       i = -1; /* we want to skip the for loop */
-               }
-
-               /*
-                * Ensure we don't do a remove on the lock that just failed,
-                * as under POSIX rules, if we have a lock already there, we
-                * will delete it (and we shouldn't) .....
-                */
-               for(i--; i >= 0; i--) {
-                       lock_pid = get_lock_pid( data, i, large_file_format);
-                       count = get_lock_count( data, i, large_file_format);
-                       offset = get_lock_offset( data, i, large_file_format,
-                                                 &err);
-
-                       /*
-                        * There is no error code marked "stupid client
-                        * bug".... :-).
-                        */
-                       if(err) {
-                               END_PROFILE(SMBlockingX);
-                               reply_doserror(req, ERRDOS, ERRnoaccess);
-                               return;
-                       }
-
-                       do_unlock(smbd_messaging_context(),
-                               fsp,
-                               lock_pid,
-                               count,
-                               offset,
-                               WINDOWS_LOCK);
-               }
+       status = smbd_do_locking(req, fsp,
+                                locktype, lock_timeout,
+                                num_ulocks, ulocks,
+                                num_locks, locks,
+                                &async);
+       if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBlockingX);
                reply_nterror(req, status);
                return;
        }
+       if (async) {
+               END_PROFILE(SMBlockingX);
+               return;
+       }
 
        reply_outbuf(req, 2, 0);
 
@@ -7615,7 +7661,6 @@ void reply_readbs(struct smb_request *req)
 void reply_setattrE(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
-       struct smb_filename *smb_fname = NULL;
        struct smb_file_time ft;
        files_struct *fsp;
        NTSTATUS status;
@@ -7635,14 +7680,6 @@ void reply_setattrE(struct smb_request *req)
                goto out;
        }
 
-       /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        /*
         * Convert the DOS times into unix times.
         */
@@ -7663,7 +7700,7 @@ void reply_setattrE(struct smb_request *req)
 
        /* Ensure we have a valid stat struct for the source. */
        if (fsp->fh->fd != -1) {
-               if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) {
+               if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) {
                        status = map_nt_error_from_unix(errno);
                        reply_nterror(req, status);
                        goto out;
@@ -7672,9 +7709,9 @@ void reply_setattrE(struct smb_request *req)
                int ret = -1;
 
                if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(conn, smb_fname);
+                       ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
                } else {
-                       ret = SMB_VFS_STAT(conn, smb_fname);
+                       ret = SMB_VFS_STAT(conn, fsp->fsp_name);
                }
                if (ret == -1) {
                        status = map_nt_error_from_unix(errno);
@@ -7683,7 +7720,7 @@ void reply_setattrE(struct smb_request *req)
                }
        }
 
-       status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+       status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
                reply_doserror(req, ERRDOS, ERRnoaccess);
                goto out;
@@ -7743,8 +7780,6 @@ void reply_getattrE(struct smb_request *req)
        int mode;
        files_struct *fsp;
        struct timespec create_ts;
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
 
        START_PROFILE(SMBgetattrE);
 
@@ -7764,21 +7799,14 @@ void reply_getattrE(struct smb_request *req)
 
        /* Do an fstat on this file */
        if(fsp_stat(fsp, &sbuf)) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBgetattrE);
                return;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 &sbuf, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               END_PROFILE(SMBgetattrE);
-               return;
-       }
+       fsp->fsp_name->st = sbuf;
 
-       mode = dos_mode(conn, smb_fname);
-       TALLOC_FREE(smb_fname);
+       mode = dos_mode(conn, fsp->fsp_name);
 
        /*
         * Convert the times into dos times. Set create
index 6951fac1718b97e73a57b2317de9b11d404d3f03..4b1c803d759530db9e3bd47b42f5cf7d9fbb23d3 100644 (file)
@@ -94,6 +94,7 @@ static void smb_conf_updated(struct messaging_context *msg,
 {
        DEBUG(10,("smb_conf_updated: Got message saying smb.conf was "
                  "updated. Reloading.\n"));
+       change_to_root_user();
        reload_services(False);
 }
 
@@ -868,6 +869,7 @@ static void exit_server_common(enum server_exit_reason how,
                if (am_parent) {
                        pidfile_unlink();
                }
+               gencache_stabilize();
        }
 
        /* if we had any open SMB connections when we exited then we
index 0124b2b047cbdabf72bd816b5ad8acd5315ad1e6..a043288bc90000bc35686b803ca1ba4985d2c122 100644 (file)
@@ -182,8 +182,8 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
        if (do_chdir &&
            vfs_ChDir(conn,conn->connectpath) != 0 &&
            vfs_ChDir(conn,conn->origpath) != 0) {
-               DEBUG(0,("chdir (%s) failed\n",
-                        conn->connectpath));
+                DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n",
+                         conn->connectpath, strerror(errno)));
                return(False);
        }
 
index 3988105fa41e36232992495c576744ac6358633f..2d2e5141eeb3194db2c02a53d85ecd8f5e5659f4 100644 (file)
@@ -1807,6 +1807,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
 
        SSVAL(req->outbuf,smb_uid,sess_vuid);
        SSVAL(req->inbuf,smb_uid,sess_vuid);
+       req->vuid = sess_vuid;
 
        if (!sconn->smb1.sessions.done_sesssetup) {
                sconn->smb1.sessions.max_send =
index 6724e5cc1589afdf5a981c72ecfaff9121abb212..acb5da775133076b21edc7765bdae206301865b4 100644 (file)
@@ -107,11 +107,6 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
                return NT_STATUS_NO_MEMORY;
        }
 
-       /* If it's an IPC, pass off the pipe handler. */
-       if (IS_IPC(conn)) {
-               return NT_STATUS_NOT_IMPLEMENTED;
-       }
-
        fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
        if (fsp == NULL) {
                return NT_STATUS_FILE_CLOSED;
@@ -126,7 +121,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
        status = close_file(smbreq, fsp, NORMAL_CLOSE);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n",
-                       fsp->fsp_name, nt_errstr(status)));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                return status;
        }
 
index bdff1939e5f7447e86b0456ad9bfed334acf5a05..b455f82d80c1835406c09ea5cf97b5c82a422bc8 100644 (file)
@@ -259,7 +259,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        files_struct *result;
        int info;
        SMB_STRUCT_STAT sbuf;
-       struct smb_filename *smb_fname = NULL;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smbd_smb2_create_state);
@@ -316,6 +315,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                }
                info = FILE_WAS_CREATED;
        } else {
+               struct smb_filename *smb_fname = NULL;
+
                /* these are ignored for SMB2 */
                in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
                in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
@@ -324,10 +325,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                                        smbreq->conn,
                                        smbreq->flags2 & FLAGS2_DFS_PATHNAMES,
                                        in_name,
-                                       &smb_fname,
-                                       NULL);
+                                       &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
+                       TALLOC_FREE(smb_fname);
                        goto out;
                }
 
@@ -348,19 +349,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                                             &info);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
+                       TALLOC_FREE(smb_fname);
                        goto out;
                }
                sbuf = smb_fname->st;
-       }
-
-       if (!smb_fname) {
-               status = create_synthetic_smb_fname_split(talloc_tos(),
-                                                         result->fsp_name,
-                                                         &sbuf, &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       tevent_req_nterror(req, status);
-                       goto out;
-               }
+               TALLOC_FREE(smb_fname);
        }
 
        smb2req->compat_chain_fsp = smbreq->chain_fsp;
@@ -379,7 +372,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        state->out_allocation_size      = sbuf.st_ex_blksize * sbuf.st_ex_blocks;
        state->out_end_of_file          = sbuf.st_ex_size;
        state->out_file_attributes      = dos_mode(result->conn,
-                                                  smb_fname);
+                                                  result->fsp_name);
        if (state->out_file_attributes == 0) {
                state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
        }
@@ -387,7 +380,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
        tevent_req_done(req);
  out:
-       TALLOC_FREE(smb_fname);
        return tevent_req_post(req, ev);
 }
 
index 8ce683923b570a8daaaa9be29b538c867b12404d..1d3ae2eb06b3484e4ee85e277bf03844be1afff0 100644 (file)
@@ -176,7 +176,7 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
        status = sync_file(smbreq->conn, fsp, true);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("smbd_smb2_flush: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status)));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                tevent_req_nterror(req, status);
                return tevent_req_post(req, ev);
        }
index ba725fdec9fa268ba921ee94bd074270bf386a44..5a6e3d7ecbf40088864e917db9591f4e757ad16c 100644 (file)
@@ -233,7 +233,177 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+       if (IS_IPC(conn)) {
+               tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+               return tevent_req_post(req, ev);
+       }
+
+       switch (in_info_type) {
+       case 0x01:/* SMB2_GETINFO_FILE */
+       {
+               uint16_t file_info_level;
+               char *data = NULL;
+               unsigned int data_size = 0;
+               bool delete_pending = false;
+               struct timespec write_time_ts;
+               struct file_id fileid;
+               struct ea_list *ea_list = NULL;
+               int lock_data_count = 0;
+               char *lock_data = NULL;
+               bool ms_dfs_link = false;
+               NTSTATUS status;
+
+               ZERO_STRUCT(write_time_ts);
+
+               switch (in_file_info_class) {
+               case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
+                       file_info_level = 0xFF00 | in_file_info_class;
+                       break;
+
+               case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
+                       file_info_level = 0xFF00 | in_file_info_class;
+                       break;
+
+               default:
+                       /* the levels directly map to the passthru levels */
+                       file_info_level = in_file_info_class + 1000;
+                       break;
+               }
+
+               if (fsp->fake_file_handle) {
+                       /*
+                        * This is actually for the QUOTA_FAKE_FILE --metze
+                        */
+
+                       /* We know this name is ok, it's already passed the checks. */
+
+               } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
+                       /*
+                        * This is actually a QFILEINFO on a directory
+                        * handle (returned from an NT SMB). NT5.0 seems
+                        * to do this call. JRA.
+                        */
+
+                       if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+                                       DEBUG(3,("smbd_smb2_getinfo_send: "
+                                                "SMB_VFS_LSTAT of %s failed "
+                                                "(%s)\n", fsp_str_dbg(fsp),
+                                                strerror(errno)));
+                                       status = map_nt_error_from_unix(errno);
+                                       tevent_req_nterror(req, status);
+                                       return tevent_req_post(req, ev);
+                               }
+                       } else if (SMB_VFS_STAT(conn, fsp->fsp_name)) {
+                               DEBUG(3,("smbd_smb2_getinfo_send: "
+                                        "SMB_VFS_STAT of %s failed (%s)\n",
+                                        fsp_str_dbg(fsp),
+                                        strerror(errno)));
+                               status = map_nt_error_from_unix(errno);
+                               tevent_req_nterror(req, status);
+                               return tevent_req_post(req, ev);
+                       }
+
+                       fileid = vfs_file_id_from_sbuf(conn,
+                                                      &fsp->fsp_name->st);
+                       get_file_infos(fileid, &delete_pending, &write_time_ts);
+               } else {
+                       /*
+                        * Original code - this is an open file.
+                        */
+
+                       if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+                               DEBUG(3, ("smbd_smb2_getinfo_send: "
+                                         "fstat of fnum %d failed (%s)\n",
+                                         fsp->fnum, strerror(errno)));
+                               status = map_nt_error_from_unix(errno);
+                               tevent_req_nterror(req, status);
+                               return tevent_req_post(req, ev);
+                       }
+                       fileid = vfs_file_id_from_sbuf(conn,
+                                                      &fsp->fsp_name->st);
+                       get_file_infos(fileid, &delete_pending, &write_time_ts);
+               }
+
+               status = smbd_do_qfilepathinfo(conn, state,
+                                              file_info_level,
+                                              fsp,
+                                              fsp->fsp_name,
+                                              delete_pending,
+                                              write_time_ts,
+                                              ms_dfs_link,
+                                              ea_list,
+                                              lock_data_count,
+                                              lock_data,
+                                              STR_UNICODE,
+                                              in_output_buffer_length,
+                                              &data,
+                                              &data_size);
+               if (!NT_STATUS_IS_OK(status)) {
+                       SAFE_FREE(data);
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+                               status = NT_STATUS_INVALID_INFO_CLASS;
+                       }
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+               if (data_size > 0) {
+                       state->out_output_buffer = data_blob_talloc(state,
+                                                                   data,
+                                                                   data_size);
+                       SAFE_FREE(data);
+                       if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+                               return tevent_req_post(req, ev);
+                       }
+               }
+               SAFE_FREE(data);
+               break;
+       }
+
+       case 0x02:/* SMB2_GETINFO_FS */
+       {
+               uint16_t file_info_level;
+               char *data = NULL;
+               int data_size = 0;
+               NTSTATUS status;
+
+               /* the levels directly map to the passthru levels */
+               file_info_level = in_file_info_class + 1000;
+
+               status = smbd_do_qfsinfo(conn, state,
+                                        file_info_level,
+                                        STR_UNICODE,
+                                        in_output_buffer_length,
+                                        &data,
+                                        &data_size);
+               if (!NT_STATUS_IS_OK(status)) {
+                       SAFE_FREE(data);
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+                               status = NT_STATUS_INVALID_INFO_CLASS;
+                       }
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+               if (data_size > 0) {
+                       state->out_output_buffer = data_blob_talloc(state,
+                                                                   data,
+                                                                   data_size);
+                       SAFE_FREE(data);
+                       if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+                               return tevent_req_post(req, ev);
+                       }
+               }
+               SAFE_FREE(data);
+               break;
+       }
+
+       default:
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_done(req);
        return tevent_req_post(req, ev);
 }
 
index 3ffe053481b3b7673afeb801a2d0815265d1f18d..121b4eb24d83f692335067f6d5fc4f2b7caa9862 100644 (file)
@@ -31,6 +31,7 @@ struct smbd_smb2_lock_element {
 static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
                                                 struct tevent_context *ev,
                                                 struct smbd_smb2_request *smb2req,
+                                                uint32_t in_smbpid,
                                                 uint64_t in_file_id_volatile,
                                                 uint16_t in_lock_count,
                                                 struct smbd_smb2_lock_element *in_locks);
@@ -41,15 +42,17 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
 {
        const uint8_t *inhdr;
        const uint8_t *inbody;
-       int i = req->current_idx;
+       const int i = req->current_idx;
        size_t expected_body_size = 0x30;
        size_t body_size;
+       uint32_t in_smbpid;
        uint16_t in_lock_count;
        uint64_t in_file_id_persistent;
        uint64_t in_file_id_volatile;
        struct smbd_smb2_lock_element *in_locks;
        struct tevent_req *subreq;
        const uint8_t *lock_buffer;
+       uint16_t l;
 
        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
        if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
@@ -63,8 +66,10 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
 
+       in_smbpid                       = IVAL(inhdr, SMB2_HDR_PID);
+
        in_lock_count                   = CVAL(inbody, 0x02);
-       /* 0x04 4 bytes reserved */
+       /* 0x04 4 bytes reserved */
        in_file_id_persistent           = BVAL(inbody, 0x08);
        in_file_id_volatile             = BVAL(inbody, 0x10);
 
@@ -88,19 +93,21 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
        }
 
-       i = 0;
+       l = 0;
        lock_buffer = inbody + 0x18;
 
-       in_locks[i].offset      = BVAL(lock_buffer, 0x00);
-       in_locks[i].length      = BVAL(lock_buffer, 0x08);
-       in_locks[i].flags       = BVAL(lock_buffer, 0x10);
+       in_locks[l].offset      = BVAL(lock_buffer, 0x00);
+       in_locks[l].length      = BVAL(lock_buffer, 0x08);
+       in_locks[l].flags       = IVAL(lock_buffer, 0x10);
+       /* 0x14 - 4 reserved bytes */
 
        lock_buffer = (const uint8_t *)req->in.vector[i+2].iov_base;
 
-       for (i=1; i < in_lock_count; i++) {
-               in_locks[i].offset      = BVAL(lock_buffer, 0x00);
-               in_locks[i].length      = BVAL(lock_buffer, 0x08);
-               in_locks[i].flags       = BVAL(lock_buffer, 0x10);
+       for (l=1; l < in_lock_count; l++) {
+               in_locks[l].offset      = BVAL(lock_buffer, 0x00);
+               in_locks[l].length      = BVAL(lock_buffer, 0x08);
+               in_locks[l].flags       = IVAL(lock_buffer, 0x10);
+               /* 0x14 - 4 reserved bytes */
 
                lock_buffer += 0x18;
        }
@@ -108,6 +115,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
        subreq = smbd_smb2_lock_send(req,
                                     req->conn->smb2.event_ctx,
                                     req,
+                                    in_smbpid,
                                     in_file_id_volatile,
                                     in_lock_count,
                                     in_locks);
@@ -172,6 +180,7 @@ struct smbd_smb2_lock_state {
 static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
                                                 struct tevent_context *ev,
                                                 struct smbd_smb2_request *smb2req,
+                                                uint32_t in_smbpid,
                                                 uint64_t in_file_id_volatile,
                                                 uint16_t in_lock_count,
                                                 struct smbd_smb2_lock_element *in_locks)
@@ -181,6 +190,12 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
        struct smb_request *smbreq;
        connection_struct *conn = smb2req->tcon->compat_conn;
        files_struct *fsp;
+       int32_t timeout = -1;
+       bool isunlock = false;
+       uint16_t i;
+       struct smbd_lock_element *locks;
+       NTSTATUS status;
+       bool async = false;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smbd_smb2_lock_state);
@@ -211,7 +226,150 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+       locks = talloc_array(state, struct smbd_lock_element, in_lock_count);
+       if (locks == NULL) {
+               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+               return tevent_req_post(req, ev);
+       }
+
+       switch (in_locks[0].flags) {
+       case SMB2_LOCK_FLAG_SHARED:
+       case SMB2_LOCK_FLAG_EXCLUSIVE:
+               if (in_lock_count > 1) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+               timeout = -1;
+               break;
+
+       case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+       case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+               timeout = 0;
+               break;
+
+       case SMB2_LOCK_FLAG_UNLOCK:
+               /* only the first lock gives the UNLOCK bit - see
+                  MS-SMB2 3.3.5.14 */
+               isunlock = true;
+               timeout = 0;
+               break;
+
+       default:
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+
+       for (i=0; i<in_lock_count; i++) {
+               uint64_t max_count;
+               bool invalid = false;
+
+               switch (in_locks[i].flags) {
+               case SMB2_LOCK_FLAG_SHARED:
+               case SMB2_LOCK_FLAG_EXCLUSIVE:
+                       if (i > 0) {
+                               tevent_req_nterror(req,
+                                                  NT_STATUS_INVALID_PARAMETER);
+                               return tevent_req_post(req, ev);
+                       }
+                       if (isunlock) {
+                               tevent_req_nterror(req,
+                                                  NT_STATUS_INVALID_PARAMETER);
+                               return tevent_req_post(req, ev);
+                       }
+                       break;
+
+               case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+               case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+                       if (isunlock) {
+                               tevent_req_nterror(req,
+                                                  NT_STATUS_INVALID_PARAMETER);
+                               return tevent_req_post(req, ev);
+                       }
+                       break;
+
+               case SMB2_LOCK_FLAG_UNLOCK:
+                       if (!isunlock) {
+                               tevent_req_nterror(req,
+                                                  NT_STATUS_INVALID_PARAMETER);
+                               return tevent_req_post(req, ev);
+                       }
+                       break;
+
+               default:
+                       if (isunlock) {
+                               /*
+                                * is the first element was a UNLOCK
+                                * we need to deferr the error response
+                                * to the backend, because we need to process
+                                * all unlock elements before
+                                */
+                               invalid = true;
+                               break;
+                       }
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               locks[i].smbpid = in_smbpid;
+               locks[i].offset = in_locks[i].offset;
+               locks[i].count  = in_locks[i].length;
+
+               if (in_locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE) {
+                       locks[i].brltype = WRITE_LOCK;
+               } else if (in_locks[i].flags & SMB2_LOCK_FLAG_SHARED) {
+                       locks[i].brltype = READ_LOCK;
+               } else if (invalid) {
+                       /*
+                        * this is an invalid UNLOCK element
+                        * and the backend needs to test for
+                        * brltype != UNLOCK_LOCK and return
+                        * NT_STATUS_INVALID_PARAMER
+                        */
+                       locks[i].brltype = READ_LOCK;
+               } else {
+                       locks[i].brltype = UNLOCK_LOCK;
+               }
+
+               max_count = UINT64_MAX - locks[i].offset;
+               if (locks[i].count > max_count) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_RANGE);
+                       return tevent_req_post(req, ev);
+               }
+       }
+
+       if (isunlock) {
+               status = smbd_do_locking(smbreq, fsp,
+                                        0,
+                                        timeout,
+                                        in_lock_count,
+                                        locks,
+                                        0,
+                                        NULL,
+                                        &async);
+       } else {
+               status = smbd_do_locking(smbreq, fsp,
+                                        0,
+                                        timeout,
+                                        0,
+                                        NULL,
+                                        in_lock_count,
+                                        locks,
+                                        &async);
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+                      status = NT_STATUS_LOCK_NOT_GRANTED;
+               }
+               tevent_req_nterror(req, status);
+               return tevent_req_post(req, ev);
+       }
+
+       if (async) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_done(req);
        return tevent_req_post(req, ev);
 }
 
index 7ab93ce574b368657f89043432cb19e8c7223d6f..f6d83aeeed921b2b6ef55c1dc64aa516cf66b660 100644 (file)
@@ -231,7 +231,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx,
 
                DEBUG(3,("smbd_smb2_notify_send: notify change "
                         "called on %s, filter = %s, recursive = %d\n",
-                        fsp->fsp_name, filter_string, recursive));
+                        fsp_str_dbg(fsp), filter_string, recursive));
 
                TALLOC_FREE(filter_string);
        }
index c9f281f73eceeae1efd36ac56810a4e9b5006608..42993511ec56fb01e4b497aac8dcb67b9678dfb8 100644 (file)
@@ -281,13 +281,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
 
        if (nread < 0) {
                DEBUG(5,("smbd_smb2_read: read_file[%s] nread[%lld]\n",
-                       fsp->fsp_name, (long long)nread));
+                        fsp_str_dbg(fsp), (long long)nread));
                tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
                return tevent_req_post(req, ev);
        }
        if (nread == 0 && in_length != 0) {
                DEBUG(5,("smbd_smb2_read: read_file[%s] end of file\n",
-                       fsp->fsp_name));
+                        fsp_str_dbg(fsp)));
                tevent_req_nterror(req, NT_STATUS_END_OF_FILE);
                return tevent_req_post(req, ev);
        }
index 43afb1b901e78f0c12b5655da6bd56ca4efbc896..204e57d8601b5da0c66c7d48d8f2c0ef7bdd9fc2 100644 (file)
@@ -1339,7 +1339,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
 
                if (invalid) {
                        /* the caller should check this */
-                       body_size = 0;
+                       body_size = 2;
                }
 
                if ((body_size % 2) != 0) {
@@ -1376,7 +1376,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
                 */
                memcpy(body, hdr + SMB2_HDR_BODY, 2);
                vector[0].iov_base = body + 2;
-               vector[0].iov_len = req->in.vector[idx].iov_len - 2;
+               vector[0].iov_len = body_size - 2;
 
                vector[1] = req->in.vector[idx+1];
 
index 110ce6c64ad6a95187948fa23006f43c45a4d710..08c4a7f5bf8b563e62d410d9ce4fd6f3aba47a7e 100644 (file)
@@ -200,7 +200,123 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+       if (IS_IPC(conn)) {
+               tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+               return tevent_req_post(req, ev);
+       }
+
+       switch (in_info_type) {
+       case 0x01:/* SMB2_SETINFO_FILE */
+       {
+               uint16_t file_info_level;
+               char *data;
+               int data_size;
+               int ret_size = 0;
+               NTSTATUS status;
+
+
+               file_info_level = in_file_info_class + 1000;
+               if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
+                       file_info_level = 0xFF00 + in_file_info_class;
+               }
+
+               if (fsp->is_directory || fsp->fh->fd == -1) {
+                       /*
+                        * This is actually a SETFILEINFO on a directory
+                        * handle (returned from an NT SMB). NT5.0 seems
+                        * to do this call. JRA.
+                        */
+                       if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+                                       DEBUG(3,("smbd_smb2_setinfo_send: "
+                                                "SMB_VFS_LSTAT of %s failed "
+                                                "(%s)\n", fsp_str_dbg(fsp),
+                                                strerror(errno)));
+                                       status = map_nt_error_from_unix(errno);
+                                       tevent_req_nterror(req, status);
+                                       return tevent_req_post(req, ev);
+                               }
+                       } else {
+                               if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) {
+                                       DEBUG(3,("smbd_smb2_setinfo_send: "
+                                                "fileinfo of %s failed (%s)\n",
+                                                fsp_str_dbg(fsp),
+                                                strerror(errno)));
+                                       status = map_nt_error_from_unix(errno);
+                                       tevent_req_nterror(req, status);
+                                       return tevent_req_post(req, ev);
+                               }
+                       }
+               } else if (fsp->print_file) {
+                       /*
+                        * Doing a DELETE_ON_CLOSE should cancel a print job.
+                        */
+                       if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO)
+                           && in_input_buffer.length >= 1
+                           && CVAL(in_input_buffer.data,0)) {
+                               fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+                               DEBUG(3,("smbd_smb2_setinfo_send: "
+                                        "Cancelling print job (%s)\n",
+                                        fsp_str_dbg(fsp)));
+
+                               tevent_req_done(req);
+                               return tevent_req_post(req, ev);
+                       } else {
+                               tevent_req_nterror(req,
+                                       NT_STATUS_OBJECT_PATH_INVALID);
+                               return tevent_req_post(req, ev);
+                       }
+               } else {
+                       /*
+                        * Original code - this is an open file.
+                        */
+
+                       if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+                               DEBUG(3,("smbd_smb2_setinfo_send: fstat "
+                                        "of fnum %d failed (%s)\n", fsp->fnum,
+                                        strerror(errno)));
+                               status = map_nt_error_from_unix(errno);
+                               tevent_req_nterror(req, status);
+                               return tevent_req_post(req, ev);
+                       }
+               }
+
+               data = NULL;
+               data_size = in_input_buffer.length;
+               if (data_size > 0) {
+                       data = (char *)SMB_MALLOC_ARRAY(char, data_size);
+                       if (tevent_req_nomem(data, req)) {
+
+                       }
+                       memcpy(data, in_input_buffer.data, data_size);
+               }
+
+               status = smbd_do_setfilepathinfo(conn, smbreq, state,
+                                                file_info_level,
+                                                fsp,
+                                                fsp->fsp_name,
+                                                &data,
+                                                data_size,
+                                                &ret_size);
+               SAFE_FREE(data);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+                               status = NT_STATUS_INVALID_INFO_CLASS;
+                       }
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+               break;
+       }
+
+       default:
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_done(req);
        return tevent_req_post(req, ev);
 }
 
index 31460a01a17e01e3feece1a5bd21b7692231442f..f1606be62354fd9d967af73b1c10972bf7b42424 100644 (file)
@@ -272,14 +272,14 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
 
        if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) {
                DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n",
-                       fsp->fsp_name));
+                        fsp_str_dbg(fsp)));
                SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
                tevent_req_nterror(req, NT_STATUS_DISK_FULL);
                return tevent_req_post(req, ev);
        }
 
        DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n",
-               fsp->fnum, fsp->fsp_name, (int)in_data.length,
+               fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length,
                (int)in_offset, (int)nwritten));
 
        if (in_flags & 0x00000001) {
@@ -289,7 +289,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status)));
+                       fsp_str_dbg(fsp), nt_errstr(status)));
                SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
                tevent_req_nterror(req, status);
                return tevent_req_post(req, ev);
index daed9f8225dbfeb4ed1264fd00efe76ab0344900..da52cc05d4e0f0dab797afd063f0f33cb85c6a90 100644 (file)
@@ -175,6 +175,8 @@ bool stat_cache_lookup(connection_struct *conn,
        DATA_BLOB data_val;
        char *name;
        TALLOC_CTX *ctx = talloc_tos();
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
 
        *pp_dirpath = NULL;
        *pp_start = *pp_name;
@@ -274,14 +276,25 @@ bool stat_cache_lookup(connection_struct *conn,
                  "-> [%s]\n", chk_name, translated_path ));
        DO_PROFILE_INC(statcache_hits);
 
-       if (vfs_stat_smb_fname(conn, translated_path, pst) != 0) {
+       status = create_synthetic_smb_fname(talloc_tos(), translated_path,
+                                           NULL, NULL, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(chk_name);
+               TALLOC_FREE(translated_path);
+               return false;
+       }
+
+       if (SMB_VFS_STAT(conn, smb_fname) != 0) {
                /* Discard this entry - it doesn't exist in the filesystem. */
                memcache_delete(smbd_memcache(), STAT_CACHE,
                                data_blob_const(chk_name, strlen(chk_name)));
                TALLOC_FREE(chk_name);
                TALLOC_FREE(translated_path);
+               TALLOC_FREE(smb_fname);
                return False;
        }
+       *pst = smb_fname->st;
+       TALLOC_FREE(smb_fname);
 
        if (!sizechanged) {
                memcpy(*pp_name, translated_path,
index 4bf27863bdec1821ed9f3da0123d0bff3c1421cf..856fd9432d072cc924b6eddffe6815a9e9b13692 100644 (file)
@@ -367,6 +367,69 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in
        return ret_data_size;
 }
 
+static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
+                                      char *pdata,
+                                      unsigned int total_data_size,
+                                      unsigned int *ret_data_size,
+                                      connection_struct *conn,
+                                      struct ea_list *ea_list)
+{
+       uint8_t *p = (uint8_t *)pdata;
+       uint8_t *last_start = NULL;
+
+       *ret_data_size = 0;
+
+       if (!lp_ea_support(SNUM(conn))) {
+               return NT_STATUS_NO_EAS_ON_FILE;
+       }
+
+       for (; ea_list; ea_list = ea_list->next) {
+               size_t dos_namelen;
+               fstring dos_ea_name;
+               size_t this_size;
+
+               if (last_start) {
+                       SIVAL(last_start, 0, PTR_DIFF(p, last_start));
+               }
+               last_start = p;
+
+               push_ascii_fstring(dos_ea_name, ea_list->ea.name);
+               dos_namelen = strlen(dos_ea_name);
+               if (dos_namelen > 255 || dos_namelen == 0) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+               if (ea_list->ea.value.length > 65535) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
+
+               if (ea_list->next) {
+                       size_t pad = 4 - (this_size % 4);
+                       this_size += pad;
+               }
+
+               if (this_size > total_data_size) {
+                       return NT_STATUS_INFO_LENGTH_MISMATCH;
+               }
+
+               /* We know we have room. */
+               SIVAL(p, 0x00, 0); /* next offset */
+               SCVAL(p, 0x04, ea_list->ea.flags);
+               SCVAL(p, 0x05, dos_namelen);
+               SSVAL(p, 0x06, ea_list->ea.value.length);
+               fstrcpy((char *)(p+0x08), dos_ea_name);
+               memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
+
+               total_data_size -= this_size;
+               p += this_size;
+       }
+
+       *ret_data_size = PTR_DIFF(p, pdata);
+       DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
+       return NT_STATUS_OK;
+}
+
 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
 {
        size_t total_ea_len = 0;
@@ -408,17 +471,13 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                const struct smb_filename *smb_fname, struct ea_list *ea_list)
 {
        char *fname = NULL;
-       NTSTATUS status;
 
        if (!lp_ea_support(SNUM(conn))) {
                return NT_STATUS_EAS_NOT_SUPPORTED;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname,
-                                      &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
+       /* For now setting EAs on streams isn't supported. */
+       fname = smb_fname->base_name;
 
        for (;ea_list; ea_list = ea_list->next) {
                int ret;
@@ -439,8 +498,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                if (ea_list->ea.value.length == 0) {
                        /* Remove the attribute. */
                        if (fsp && (fsp->fh->fd != -1)) {
-                               DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
-                                       unix_ea_name, fsp->fsp_name));
+                               DEBUG(10,("set_ea: deleting ea name %s on "
+                                         "file %s by file descriptor.\n",
+                                         unix_ea_name, fsp_str_dbg(fsp)));
                                ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
                        } else {
                                DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
@@ -457,8 +517,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
 #endif
                } else {
                        if (fsp && (fsp->fh->fd != -1)) {
-                               DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
-                                       unix_ea_name, fsp->fsp_name));
+                               DEBUG(10,("set_ea: setting ea name %s on file "
+                                         "%s by file descriptor.\n",
+                                         unix_ea_name, fsp_str_dbg(fsp)));
                                ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
                                                        ea_list->ea.value.data, ea_list->ea.value.length, 0);
                        } else {
@@ -963,8 +1024,7 @@ static void call_trans2open(connection_struct *conn,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -981,12 +1041,10 @@ static void call_trans2open(connection_struct *conn,
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
-                               open_ofun,
-                               &access_mask,
-                               &share_mode,
-                               &create_disposition,
-                               &create_options)) {
+       if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
+                                        &access_mask, &share_mode,
+                                        &create_disposition,
+                                        &create_options)) {
                reply_doserror(req, ERRDOS, ERRbadaccess);
                goto out;
        }
@@ -1085,7 +1143,8 @@ static void call_trans2open(connection_struct *conn,
        SIVAL(params,20,inode);
        SSVAL(params,24,0); /* Padding. */
        if (flags & 8) {
-               uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
+               uint32 ea_size = estimate_ea_size(conn, fsp,
+                                                 fsp->fsp_name->base_name);
                SIVAL(params, 26, ea_size);
        } else {
                SIVAL(params, 26, 0);
@@ -1976,7 +2035,7 @@ static void call_trans2findfirst(connection_struct *conn,
 
        if (total_params < 13) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
+               goto out;
        }
 
        dirtype = SVAL(params,0);
@@ -2014,12 +2073,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                        ask_sharemode = false;
                        if (!lp_unix_extensions()) {
                                reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               goto out;
                        }
                        break;
                default:
                        reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                       return;
+                       goto out;
        }
 
        srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
@@ -2027,7 +2086,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                              STR_TERMINATE, &ntstatus, &mask_contains_wcard);
        if (!NT_STATUS_IS_OK(ntstatus)) {
                reply_nterror(req, ntstatus);
-               return;
+               goto out;
        }
 
        ntstatus = resolve_dfspath_wcard(ctx, conn,
@@ -2039,32 +2098,27 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                        ERRSRV, ERRbadpath);
-                       return;
+                       goto out;
                }
                reply_nterror(req, ntstatus);
-               return;
+               goto out;
        }
 
        ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
                                (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
        if (!NT_STATUS_IS_OK(ntstatus)) {
                reply_nterror(req, ntstatus);
-               return;
+               goto out;
        }
 
        mask = smb_dname->original_lcomp;
 
-       ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
-       TALLOC_FREE(smb_dname);
-       if (!NT_STATUS_IS_OK(ntstatus)) {
-               reply_nterror(req, ntstatus);
-               return;
-       }
+       directory = smb_dname->base_name;
 
        ntstatus = check_name(conn, directory);
        if (!NT_STATUS_IS_OK(ntstatus)) {
                reply_nterror(req, ntstatus);
-               return;
+               goto out;
        }
 
        p = strrchr_m(directory,'/');
@@ -2074,14 +2128,14 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                        mask = talloc_strdup(ctx,"*");
                        if (!mask) {
                                reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               return;
+                               goto out;
                        }
                        mask_contains_wcard = True;
                }
                directory = talloc_strdup(talloc_tos(), "./");
                if (!directory) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
+                       goto out;
                }
        } else {
                *p = 0;
@@ -2094,7 +2148,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
 
                if (total_data < 4) {
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
 
                ea_size = IVAL(pdata,0);
@@ -2102,19 +2156,19 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                        DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
 
                if (!lp_ea_support(SNUM(conn))) {
                        reply_doserror(req, ERRDOS, ERReasnotsupported);
-                       return;
+                       goto out;
                }
 
                /* Pull out the list of names. */
                ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
                if (!ea_list) {
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+                       goto out;
                }
        }
 
@@ -2122,7 +2176,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
        if(*ppdata == NULL ) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
+               goto out;
        }
        pdata = *ppdata;
        data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
@@ -2131,7 +2185,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        *pparams = (char *)SMB_REALLOC(*pparams, 10);
        if (*pparams == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
+               goto out;
        }
        params = *pparams;
 
@@ -2150,7 +2204,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
        if (!NT_STATUS_IS_OK(ntstatus)) {
                reply_nterror(req, ntstatus);
-               return;
+               goto out;
        }
 
        dptr_num = dptr_dnum(conn->dirptr);
@@ -2233,11 +2287,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                dptr_close(&dptr_num);
                if (Protocol < PROTOCOL_NT1) {
                        reply_doserror(req, ERRDOS, ERRnofiles);
-                       return;
+                       goto out;
                } else {
                        reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
                                        ERRDOS, ERRbadfile);
-                       return;
+                       goto out;
                }
        }
 
@@ -2276,7 +2330,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                char mangled_name[13];
                name_to_8_3(mask, mangled_name, True, conn->params);
        }
-
+ out:
+       TALLOC_FREE(smb_dname);
        return;
 }
 
@@ -2624,67 +2679,54 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info)
                  "%s", samba_version_string());
 }
 
-/****************************************************************************
- Reply to a TRANS2_QFSINFO (query filesystem info).
-****************************************************************************/
-
-static void call_trans2qfsinfo(connection_struct *conn,
-                              struct smb_request *req,
-                              char **pparams, int total_params,
-                              char **ppdata, int total_data,
-                              unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+                        TALLOC_CTX *mem_ctx,
+                        uint16_t info_level,
+                        uint16_t flags2,
+                        unsigned int max_data_bytes,
+                        char **ppdata,
+                        int *ret_data_len)
 {
        char *pdata, *end_data;
-       char *params = *pparams;
-       uint16 info_level;
-       int data_len, len;
-       SMB_STRUCT_STAT st;
+       int data_len = 0, len;
        const char *vname = volume_label(SNUM(conn));
        int snum = SNUM(conn);
        char *fstype = lp_fstype(SNUM(conn));
        uint32 additional_flags = 0;
-
-       if (total_params < 2) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
-       }
-
-       info_level = SVAL(params,0);
+       struct smb_filename *smb_fname_dot = NULL;
+       SMB_STRUCT_STAT st;
+       NTSTATUS status;
 
        if (IS_IPC(conn)) {
                if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
-                       DEBUG(0,("call_trans2qfsinfo: not an allowed "
+                       DEBUG(0,("smbd_do_qfsinfo: not an allowed "
                                "info level (0x%x) on IPC$.\n",
                                (unsigned int)info_level));
-                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
-                       return;
+                       return NT_STATUS_ACCESS_DENIED;
                }
        }
 
-       if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
-               if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
-                       DEBUG(0,("call_trans2qfsinfo: encryption required "
-                               "and info level 0x%x sent.\n",
-                               (unsigned int)info_level));
-                       exit_server_cleanly("encryption required "
-                               "on connection");
-                       return;
-               }
-       }
+       DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
 
-       DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+       status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL,
+                                           &smb_fname_dot);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-       if(vfs_stat_smb_fname(conn,".",&st)!=0) {
-               DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
-               reply_doserror(req, ERRSRV, ERRinvdevice);
-               return;
+       if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) {
+               DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
+               TALLOC_FREE(smb_fname_dot);
+               return map_nt_error_from_unix(errno);
        }
 
+       st = smb_fname_dot->st;
+       TALLOC_FREE(smb_fname_dot);
+
        *ppdata = (char *)SMB_REALLOC(
                *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
-       if (*ppdata == NULL ) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
+       if (*ppdata == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
 
        pdata = *ppdata;
@@ -2697,8 +2739,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
                        data_len = 18;
                        if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
-                               reply_unixerror(req, ERRHRD, ERRgeneral);
-                               return;
+                               return map_nt_error_from_unix(errno);
                        }
 
                        block_size = lp_block_size(snum);
@@ -2717,7 +2758,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
                        bytes_per_sector = 512;
                        sectors_per_unit = bsize/bytes_per_sector;
 
-                       DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
+                       DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
                                (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
 
@@ -2743,13 +2784,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                         * the pushed string. The change here was adding the STR_TERMINATE. JRA.
                         */
                        len = srvstr_push(
-                               pdata, req->flags2,
+                               pdata, flags2,
                                pdata+l2_vol_szVolLabel, vname,
                                PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
                                STR_NOALIGN|STR_TERMINATE);
                        SCVAL(pdata,l2_vol_cch,len);
                        data_len = l2_vol_szVolLabel + len;
-                       DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
+                       DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
                                 (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
                                 len, vname));
                        break;
@@ -2776,7 +2817,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                        SIVAL(pdata,4,255); /* Max filename component length */
                        /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
                                and will think we can't do long filenames */
-                       len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
+                       len = srvstr_push(pdata, flags2, pdata+12, fstype,
                                          PTR_DIFF(end_data, pdata+12),
                                          STR_UNICODE);
                        SIVAL(pdata,8,len);
@@ -2785,7 +2826,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
 
                case SMB_QUERY_FS_LABEL_INFO:
                case SMB_FS_LABEL_INFORMATION:
-                       len = srvstr_push(pdata, req->flags2, pdata+4, vname,
+                       len = srvstr_push(pdata, flags2, pdata+4, vname,
                                          PTR_DIFF(end_data, pdata+4), 0);
                        data_len = 4 + len;
                        SIVAL(pdata,0,len);
@@ -2802,13 +2843,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                                (str_checksum(get_local_machine_name())<<16));
 
                        /* Max label len is 32 characters. */
-                       len = srvstr_push(pdata, req->flags2, pdata+18, vname,
+                       len = srvstr_push(pdata, flags2, pdata+18, vname,
                                          PTR_DIFF(end_data, pdata+18),
                                          STR_UNICODE);
                        SIVAL(pdata,12,len);
                        data_len = 18+len;
 
-                       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 
+                       DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
                                (int)strlen(vname),vname, lp_servicename(snum)));
                        break;
 
@@ -2818,8 +2859,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
                        data_len = 24;
                        if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
-                               reply_unixerror(req, ERRHRD, ERRgeneral);
-                               return;
+                               return map_nt_error_from_unix(errno);
                        }
                        block_size = lp_block_size(snum);
                        if (bsize < block_size) {
@@ -2836,7 +2876,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
                        }
                        bytes_per_sector = 512;
                        sectors_per_unit = bsize/bytes_per_sector;
-                       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+                       DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
                                (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
                        SBIG_UINT(pdata,0,dsize);
@@ -2851,8 +2891,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
                        data_len = 32;
                        if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
-                               reply_unixerror(req, ERRHRD, ERRgeneral);
-                               return;
+                               return map_nt_error_from_unix(errno);
                        }
                        block_size = lp_block_size(snum);
                        if (bsize < block_size) {
@@ -2869,7 +2908,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        }
                        bytes_per_sector = 512;
                        sectors_per_unit = bsize/bytes_per_sector;
-                       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+                       DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
                                (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
                        SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
@@ -2922,24 +2961,23 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        fsp.fnum = -1;
 
                        /* access check */
-                       if (conn->server_info->utok.uid != 0) {
+                       if (conn->server_info->utok.uid != sec_initial_uid()) {
                                DEBUG(0,("set_user_quota: access_denied "
                                         "service [%s] user [%s]\n",
                                         lp_servicename(SNUM(conn)),
                                         conn->server_info->unix_name));
-                               reply_doserror(req, ERRDOS, ERRnoaccess);
-                               return;
+                               return NT_STATUS_ACCESS_DENIED;
                        }
 
                        if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
                                DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
-                               reply_doserror(req, ERRSRV, ERRerror);
-                               return;
+                               return map_nt_error_from_unix(errno);
                        }
 
                        data_len = 48;
 
-                       DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));          
+                       DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
+                                 lp_servicename(SNUM(conn))));
 
                        /* Unknown1 24 NULL bytes*/
                        SBIG_UINT(pdata,0,(uint64_t)0);
@@ -2990,8 +3028,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        int encrypt_caps = 0;
 
                        if (!lp_unix_extensions()) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
 
                        switch (conn->encrypt_level) {
@@ -3036,8 +3073,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        vfs_statvfs_struct svfs;
 
                        if (!lp_unix_extensions()) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
 
                        rc = SMB_VFS_STATVFS(conn, ".", &svfs);
@@ -3052,16 +3088,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                SBIG_UINT(pdata,32,svfs.TotalFileNodes);
                                SBIG_UINT(pdata,40,svfs.FreeFileNodes);
                                SBIG_UINT(pdata,48,svfs.FsIdentifier);
-                               DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
+                               DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
 #ifdef EOPNOTSUPP
                        } else if (rc == EOPNOTSUPP) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
 #endif /* EOPNOTSUPP */
                        } else {
                                DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
-                               reply_doserror(req, ERRSRV, ERRerror);
-                               return;
+                               return NT_STATUS_DOS(ERRSRV, ERRerror);
                        }
                        break;
                }
@@ -3073,13 +3107,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        int i;
 
                        if (!lp_unix_extensions()) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
 
                        if (max_data_bytes < 40) {
-                               reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
-                               return;
+                               return NT_STATUS_BUFFER_TOO_SMALL;
                        }
 
                        /* We ARE guest if global_sid_Builtin_Guests is
@@ -3193,12 +3225,59 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                        }
                        /* drop through */
                default:
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return NT_STATUS_INVALID_LEVEL;
+       }
+
+       *ret_data_len = data_len;
+       return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFSINFO (query filesystem info).
+****************************************************************************/
+
+static void call_trans2qfsinfo(connection_struct *conn,
+                              struct smb_request *req,
+                              char **pparams, int total_params,
+                              char **ppdata, int total_data,
+                              unsigned int max_data_bytes)
+{
+       char *params = *pparams;
+       uint16_t info_level;
+       int data_len = 0;
+       NTSTATUS status;
+
+       if (total_params < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       info_level = SVAL(params,0);
+
+       if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
+               if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+                       DEBUG(0,("call_trans2qfsinfo: encryption required "
+                               "and info level 0x%x sent.\n",
+                               (unsigned int)info_level));
+                       exit_server_cleanly("encryption required "
+                               "on connection");
                        return;
+               }
        }
 
+       DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+
+       status = smbd_do_qfsinfo(conn, req,
+                                info_level,
+                                req->flags2,
+                                max_data_bytes,
+                                ppdata, &data_len);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
 
-       send_trans2_replies(conn, req, params, 0, pdata, data_len,
+       send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
                            max_data_bytes);
 
        DEBUG( 4, ( "%s info_level = %d\n",
@@ -3369,12 +3448,12 @@ cap_low = 0x%x, cap_high = 0x%x\n",
                                ZERO_STRUCT(quotas);
 
                                /* access check */
-                               if ((conn->server_info->utok.uid != 0)
+                               if ((conn->server_info->utok.uid != sec_initial_uid())
                                    ||!CAN_WRITE(conn)) {
                                        DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
                                                 lp_servicename(SNUM(conn)),
                                                 conn->server_info->unix_name));
-                                       reply_doserror(req, ERRSRV, ERRaccess);
+                                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                                        return;
                                }
 
@@ -3443,7 +3522,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
                                /* now set the quotas */
                                if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
                                        DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
-                                       reply_doserror(req, ERRSRV, ERRerror);
+                                       reply_nterror(req, map_nt_error_from_unix(errno));
                                        return;
                                }
 
@@ -3878,521 +3957,260 @@ static void call_trans2qpipeinfo(connection_struct *conn,
        return;
 }
 
-/****************************************************************************
- Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
- file name or file id).
-****************************************************************************/
-
-static void call_trans2qfilepathinfo(connection_struct *conn,
-                                    struct smb_request *req,
-                                    unsigned int tran_call,
-                                    char **pparams, int total_params,
-                                    char **ppdata, int total_data,
-                                    unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+                              TALLOC_CTX *mem_ctx,
+                              uint16_t info_level,
+                              files_struct *fsp,
+                              const struct smb_filename *smb_fname,
+                              bool delete_pending,
+                              struct timespec write_time_ts,
+                              bool ms_dfs_link,
+                              struct ea_list *ea_list,
+                              int lock_data_count,
+                              char *lock_data,
+                              uint16_t flags2,
+                              unsigned int max_data_bytes,
+                              char **ppdata,
+                              unsigned int *pdata_size)
 {
-       char *params = *pparams;
        char *pdata = *ppdata;
        char *dstart, *dend;
-       uint16 info_level;
-       int mode=0;
-       int nlink;
-       SMB_OFF_T file_size=0;
-       uint64_t allocation_size=0;
-       unsigned int data_size = 0;
-       unsigned int param_size = 2;
+       unsigned int data_size;
+       struct timespec create_time_ts, mtime_ts, atime_ts;
+       time_t create_time, mtime, atime;
        SMB_STRUCT_STAT sbuf;
-       char *dos_fname = NULL;
-       char *fname = NULL;
-       struct smb_filename *smb_fname = NULL;
-       char *fullpathname;
-       char *base_name;
        char *p;
-       SMB_OFF_T pos = 0;
-       bool delete_pending = False;
-       int len;
-       time_t create_time, mtime, atime;
-       struct timespec create_time_ts, mtime_ts, atime_ts;
-       struct timespec write_time_ts;
-       files_struct *fsp = NULL;
-       struct file_id fileid;
-       struct ea_list *ea_list = NULL;
-       char *lock_data = NULL;
-       bool ms_dfs_link = false;
-       TALLOC_CTX *ctx = talloc_tos();
-       NTSTATUS status = NT_STATUS_OK;
+       char *fname;
+       char *base_name;
+       char *dos_fname;
+       int mode;
+       int nlink;
+       NTSTATUS status;
+       uint64_t file_size = 0;
+       uint64_t pos = 0;
+       uint64_t allocation_size = 0;
+       uint64_t file_index = 0;
+       uint32_t access_mask = 0;
 
-       if (!params) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
-       }
+       sbuf = smb_fname->st;
 
-       ZERO_STRUCT(write_time_ts);
+       if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+               return NT_STATUS_INVALID_LEVEL;
+       }
 
-       if (tran_call == TRANSACT2_QFILEINFO) {
-               if (total_params < 4) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
-               }
+       status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-               if (IS_IPC(conn)) {
-                       call_trans2qpipeinfo(conn, req, tran_call,
-                                            pparams, total_params,
-                                            ppdata, total_data,
-                                            max_data_bytes);
-                       return;
-               }
+       DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
+                smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
+                info_level, max_data_bytes));
 
-               fsp = file_fsp(req, SVAL(params,0));
-               info_level = SVAL(params,2);
+       if (ms_dfs_link) {
+               mode = dos_mode_msdfs(conn, smb_fname);
+       } else {
+               mode = dos_mode(conn, smb_fname);
+       }
+       if (!mode)
+               mode = FILE_ATTRIBUTE_NORMAL;
 
-               DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+       nlink = sbuf.st_ex_nlink;
 
-               if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                       return;
-               }
-
-               /* Initial check for valid fsp ptr. */
-               if (!check_fsp_open(conn, req, fsp)) {
-                       return;
-               }
+       if (nlink && (mode&aDIR)) {
+               nlink = 1;
+       }
 
-               fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
-               if (!fname) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
-               }
+       if ((nlink > 0) && delete_pending) {
+               nlink -= 1;
+       }
 
-               status = create_synthetic_smb_fname_split(talloc_tos(), fname,
-                                                         NULL, &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
+       data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
+       *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
+       if (*ppdata == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       pdata = *ppdata;
+       dstart = pdata;
+       dend = dstart + data_size - 1;
 
-               if(fsp->fake_file_handle) {
-                       /*
-                        * This is actually for the QUOTA_FAKE_FILE --metze
-                        */
+       if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
+               update_stat_ex_mtime(&sbuf, write_time_ts);
+       }
 
-                       /* We know this name is ok, it's already passed the checks. */
+       create_time_ts = sbuf.st_ex_btime;
+       mtime_ts = sbuf.st_ex_mtime;
+       atime_ts = sbuf.st_ex_atime;
 
-               } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
-                       /*
-                        * This is actually a QFILEINFO on a directory
-                        * handle (returned from an NT SMB). NT5.0 seems
-                        * to do this call. JRA.
-                        */
+       if (lp_dos_filetime_resolution(SNUM(conn))) {
+               dos_filetime_timespec(&create_time_ts);
+               dos_filetime_timespec(&mtime_ts);
+               dos_filetime_timespec(&atime_ts);
+       }
 
-                       if (INFO_LEVEL_IS_UNIX(info_level)) {
-                               /* Always do lstat for UNIX calls. */
-                               if (SMB_VFS_LSTAT(conn, smb_fname)) {
-                                       DEBUG(3,("call_trans2qfilepathinfo: "
-                                                "SMB_VFS_LSTAT of %s failed "
-                                                "(%s)\n",
-                                                smb_fname_str_dbg(smb_fname),
-                                                strerror(errno)));
-                                       reply_unixerror(req,ERRDOS,ERRbadpath);
-                                       return;
-                               }
-                       } else if (SMB_VFS_STAT(conn, smb_fname)) {
-                               DEBUG(3,("call_trans2qfilepathinfo: "
-                                        "SMB_VFS_STAT of %s failed (%s)\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno)));
-                               reply_unixerror(req, ERRDOS, ERRbadpath);
-                               return;
-                       }
+       create_time = convert_timespec_to_time_t(create_time_ts);
+       mtime = convert_timespec_to_time_t(mtime_ts);
+       atime = convert_timespec_to_time_t(atime_ts);
 
-                       fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
-                       get_file_infos(fileid, &delete_pending, &write_time_ts);
-               } else {
-                       /*
-                        * Original code - this is an open file.
-                        */
-                       if (!check_fsp(conn, req, fsp)) {
-                               return;
-                       }
+       p = strrchr_m(smb_fname->base_name,'/');
+       if (!p)
+               base_name = smb_fname->base_name;
+       else
+               base_name = p+1;
 
-                       if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
-                               DEBUG(3, ("fstat of fnum %d failed (%s)\n",
-                                         fsp->fnum, strerror(errno)));
-                               reply_unixerror(req, ERRDOS, ERRbadfid);
-                               return;
-                       }
-                       pos = fsp->fh->position_information;
-                       fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
-                       get_file_infos(fileid, &delete_pending, &write_time_ts);
+       /* NT expects the name to be in an exact form of the *full*
+          filename. See the trans2 torture test */
+       if (ISDOT(base_name)) {
+               dos_fname = talloc_strdup(mem_ctx, "\\");
+               if (!dos_fname) {
+                       return NT_STATUS_NO_MEMORY;
                }
-
        } else {
-               /* qpathinfo */
-               if (total_params < 7) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
+               dos_fname = talloc_asprintf(mem_ctx,
+                               "\\%s",
+                               fname);
+               if (!dos_fname) {
+                       return NT_STATUS_NO_MEMORY;
                }
+               string_replace(dos_fname, '/', '\\');
+       }
 
-               info_level = SVAL(params,0);
-
-               DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+       allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf);
 
-               if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                       return;
+       if (!fsp) {
+               /* Do we have this path open ? */
+               files_struct *fsp1;
+               struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+               fsp1 = file_find_di_first(fileid);
+               if (fsp1 && fsp1->initial_allocation_size) {
+                       allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
                }
+       }
 
-               srvstr_get_path(ctx, params, req->flags2, &fname, &params[6],
-                               total_params - 6,
-                               STR_TERMINATE, &status);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
+       if (!(mode & aDIR)) {
+               file_size = get_file_size_stat(&sbuf);
+       }
 
-               status = filename_convert(ctx,
-                                       conn,
-                                       req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                       fname,
-                                       &smb_fname,
-                                       &fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                               reply_botherror(req,
-                                               NT_STATUS_PATH_NOT_COVERED,
-                                               ERRSRV, ERRbadpath);
-                               return;
-                       }
-                       reply_nterror(req, status);
-                       return;
-               }
+       if (fsp) {
+               pos = fsp->fh->position_information;
+       }
 
-               /* If this is a stream, check if there is a delete_pending. */
-               if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-                   && is_ntfs_stream_smb_fname(smb_fname)) {
-                       struct smb_filename *smb_fname_base = NULL;
+       if (fsp) {
+               access_mask = fsp->access_mask;
+       } else {
+               /* GENERIC_EXECUTE mapping from Windows */
+               access_mask = 0x12019F;
+       }
 
-                       /* Create an smb_filename with stream_name == NULL. */
-                       status =
-                           create_synthetic_smb_fname(talloc_tos(),
-                                                      smb_fname->base_name,
-                                                      NULL, NULL,
-                                                      &smb_fname_base);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               reply_nterror(req, status);
-                               return;
-                       }
+       /* This should be an index number - looks like
+          dev/ino to me :-)
 
-                       if (INFO_LEVEL_IS_UNIX(info_level)) {
-                               /* Always do lstat for UNIX calls. */
-                               if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
-                                       DEBUG(3,("call_trans2qfilepathinfo: "
-                                                "SMB_VFS_LSTAT of %s failed "
-                                                "(%s)\n",
-                                                smb_fname_str_dbg(smb_fname_base),
-                                                strerror(errno)));
-                                       TALLOC_FREE(smb_fname_base);
-                                       reply_unixerror(req,ERRDOS,ERRbadpath);
-                                       return;
-                               }
-                       } else {
-                               if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
-                                       DEBUG(3,("call_trans2qfilepathinfo: "
-                                                "fileinfo of %s failed "
-                                                "(%s)\n",
-                                                smb_fname_str_dbg(smb_fname_base),
-                                                strerror(errno)));
-                                       TALLOC_FREE(smb_fname_base);
-                                       reply_unixerror(req,ERRDOS,ERRbadpath);
-                                       return;
-                               }
-                       }
+          I think this causes us to fail the IFSKIT
+          BasicFileInformationTest. -tpot */
+       file_index =  ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */
+       file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
 
-                       fileid = vfs_file_id_from_sbuf(conn,
-                                                      &smb_fname_base->st);
-                       TALLOC_FREE(smb_fname_base);
-                       get_file_infos(fileid, &delete_pending, NULL);
-                       if (delete_pending) {
-                               reply_nterror(req, NT_STATUS_DELETE_PENDING);
-                               return;
-                       }
+       switch (info_level) {
+               case SMB_INFO_STANDARD:
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
+                       data_size = 22;
+                       srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
+                       srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
+                       srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
+                       SIVAL(pdata,l1_cbFile,(uint32)file_size);
+                       SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
+                       SSVAL(pdata,l1_attrFile,mode);
+                       break;
+
+               case SMB_INFO_QUERY_EA_SIZE:
+               {
+                       unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
+                       data_size = 26;
+                       srv_put_dos_date2(pdata,0,create_time);
+                       srv_put_dos_date2(pdata,4,atime);
+                       srv_put_dos_date2(pdata,8,mtime); /* write time */
+                       SIVAL(pdata,12,(uint32)file_size);
+                       SIVAL(pdata,16,(uint32)allocation_size);
+                       SSVAL(pdata,20,mode);
+                       SIVAL(pdata,22,ea_size);
+                       break;
                }
 
-               if (INFO_LEVEL_IS_UNIX(info_level)) {
-                       /* Always do lstat for UNIX calls. */
-                       if (SMB_VFS_LSTAT(conn, smb_fname)) {
-                               DEBUG(3,("call_trans2qfilepathinfo: "
-                                        "SMB_VFS_LSTAT of %s failed (%s)\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno)));
-                               reply_unixerror(req, ERRDOS, ERRbadpath);
-                               return;
+               case SMB_INFO_IS_NAME_VALID:
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
+                       if (fsp) {
+                               /* os/2 needs this ? really ?*/
+                               return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
                        }
+                       /* This is only reached for qpathinfo */
+                       data_size = 0;
+                       break;
 
-               } else if (!VALID_STAT(smb_fname->st) &&
-                          SMB_VFS_STAT(conn, smb_fname) &&
-                          (info_level != SMB_INFO_IS_NAME_VALID)) {
-                       ms_dfs_link = check_msdfs_link(conn, fname,
-                                                      &smb_fname->st);
+               case SMB_INFO_QUERY_EAS_FROM_LIST:
+               {
+                       size_t total_ea_len = 0;
+                       struct ea_list *ea_file_list = NULL;
 
-                       if (!ms_dfs_link) {
-                               DEBUG(3,("call_trans2qfilepathinfo: "
-                                        "SMB_VFS_STAT of %s failed (%s)\n",
-                                        smb_fname_str_dbg(smb_fname),
-                                        strerror(errno)));
-                               reply_unixerror(req, ERRDOS, ERRbadpath);
-                               return;
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
+
+                       ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
+                       ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+
+                       if (!ea_list || (total_ea_len > data_size)) {
+                               data_size = 4;
+                               SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
+                               break;
                        }
-               }
 
-               fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
-               get_file_infos(fileid, &delete_pending, &write_time_ts);
-               if (delete_pending) {
-                       reply_nterror(req, NT_STATUS_DELETE_PENDING);
-                       return;
+                       data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
+                       break;
                }
-       }
 
-       /* Set sbuf for use below. */
-       sbuf = smb_fname->st;
-
-       if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-               return;
-       }
-
-       DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
-               fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
-
-       p = strrchr_m(smb_fname->base_name,'/');
-       if (!p)
-               base_name = smb_fname->base_name;
-       else
-               base_name = p+1;
-
-       if (ms_dfs_link) {
-               mode = dos_mode_msdfs(conn, smb_fname);
-       } else {
-               mode = dos_mode(conn, smb_fname);
-       }
-       if (!mode)
-               mode = FILE_ATTRIBUTE_NORMAL;
-
-       nlink = sbuf.st_ex_nlink;
-
-       if (nlink && (mode&aDIR)) {
-               nlink = 1;
-       }
-
-       if ((nlink > 0) && delete_pending) {
-               nlink -= 1;
-       }
-
-       fullpathname = fname;
-       if (!(mode & aDIR))
-               file_size = get_file_size_stat(&sbuf);
-
-       /* Pull out any data sent here before we realloc. */
-       switch (info_level) {
-               case SMB_INFO_QUERY_EAS_FROM_LIST:
-               {
-                       /* Pull any EA list from the data portion. */
-                       uint32 ea_size;
-
-                       if (total_data < 4) {
-                               reply_nterror(
-                                       req, NT_STATUS_INVALID_PARAMETER);
-                               return;
-                       }
-                       ea_size = IVAL(pdata,0);
-
-                       if (total_data > 0 && ea_size != total_data) {
-                               DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
-total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
-                               reply_nterror(
-                                       req, NT_STATUS_INVALID_PARAMETER);
-                               return;
-                       }
-
-                       if (!lp_ea_support(SNUM(conn))) {
-                               reply_doserror(req, ERRDOS,
-                                              ERReasnotsupported);
-                               return;
-                       }
-
-                       /* Pull out the list of names. */
-                       ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
-                       if (!ea_list) {
-                               reply_nterror(
-                                       req, NT_STATUS_INVALID_PARAMETER);
-                               return;
-                       }
-                       break;
-               }
-
-               case SMB_QUERY_POSIX_LOCK:
-               {
-                       if (fsp == NULL || fsp->fh->fd == -1) {
-                               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
-                               return;
-                       }
-
-                       if (total_data != POSIX_LOCK_DATA_SIZE) {
-                               reply_nterror(
-                                       req, NT_STATUS_INVALID_PARAMETER);
-                               return;
-                       }
-
-                       /* Copy the lock range data. */
-                       lock_data = (char *)TALLOC_MEMDUP(
-                               ctx, pdata, total_data);
-                       if (!lock_data) {
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               return;
-                       }
-               }
-               default:
-                       break;
-       }
-
-       *pparams = (char *)SMB_REALLOC(*pparams,2);
-       if (*pparams == NULL) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
-       params = *pparams;
-       SSVAL(params,0,0);
-       data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
-       *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 
-       if (*ppdata == NULL ) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
-       pdata = *ppdata;
-       dstart = pdata;
-       dend = dstart + data_size - 1;
-
-       allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
-
-       if (!fsp) {
-               /* Do we have this path open ? */
-               files_struct *fsp1;
-               fileid = vfs_file_id_from_sbuf(conn, &sbuf);
-               fsp1 = file_find_di_first(fileid);
-               if (fsp1 && fsp1->initial_allocation_size) {
-                       allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
-               }
-       }
-
-       if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
-               update_stat_ex_mtime(&sbuf, write_time_ts);
-       }
-
-       create_time_ts = sbuf.st_ex_btime;
-       mtime_ts = sbuf.st_ex_mtime;
-       atime_ts = sbuf.st_ex_atime;
-
-       if (lp_dos_filetime_resolution(SNUM(conn))) {
-               dos_filetime_timespec(&create_time_ts);
-               dos_filetime_timespec(&mtime_ts);
-               dos_filetime_timespec(&atime_ts);
-       }
-
-       create_time = convert_timespec_to_time_t(create_time_ts);
-       mtime = convert_timespec_to_time_t(mtime_ts);
-       atime = convert_timespec_to_time_t(atime_ts);
-
-       /* NT expects the name to be in an exact form of the *full*
-          filename. See the trans2 torture test */
-       if (ISDOT(base_name)) {
-               dos_fname = talloc_strdup(ctx, "\\");
-               if (!dos_fname) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
-               }
-       } else {
-               dos_fname = talloc_asprintf(ctx,
-                               "\\%s",
-                               fname);
-               if (!dos_fname) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
-               }
-               string_replace(dos_fname, '/', '\\');
-       }
-
-       switch (info_level) {
-               case SMB_INFO_STANDARD:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
-                       data_size = 22;
-                       srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
-                       srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
-                       srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
-                       SIVAL(pdata,l1_cbFile,(uint32)file_size);
-                       SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
-                       SSVAL(pdata,l1_attrFile,mode);
-                       break;
-
-               case SMB_INFO_QUERY_EA_SIZE:
-               {
-                       unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
-                       data_size = 26;
-                       srv_put_dos_date2(pdata,0,create_time);
-                       srv_put_dos_date2(pdata,4,atime);
-                       srv_put_dos_date2(pdata,8,mtime); /* write time */
-                       SIVAL(pdata,12,(uint32)file_size);
-                       SIVAL(pdata,16,(uint32)allocation_size);
-                       SSVAL(pdata,20,mode);
-                       SIVAL(pdata,22,ea_size);
-                       break;
-               }
-
-               case SMB_INFO_IS_NAME_VALID:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
-                       if (tran_call == TRANSACT2_QFILEINFO) {
-                               /* os/2 needs this ? really ?*/
-                               reply_doserror(req, ERRDOS, ERRbadfunc);
-                               return;
-                       }
-                       data_size = 0;
-                       param_size = 0;
-                       break;
-
-               case SMB_INFO_QUERY_EAS_FROM_LIST:
+               case SMB_INFO_QUERY_ALL_EAS:
                {
+                       /* We have data_size bytes to put EA's into. */
                        size_t total_ea_len = 0;
-                       struct ea_list *ea_file_list = NULL;
-
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
 
-                       ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
-                       ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
 
+                       ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
                        if (!ea_list || (total_ea_len > data_size)) {
                                data_size = 4;
                                SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
                                break;
                        }
 
-                       data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+                       data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
                        break;
                }
 
-               case SMB_INFO_QUERY_ALL_EAS:
+               case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
                {
                        /* We have data_size bytes to put EA's into. */
                        size_t total_ea_len = 0;
+                       struct ea_list *ea_file_list = NULL;
 
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
 
-                       ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
-                       if (!ea_list || (total_ea_len > data_size)) {
-                               data_size = 4;
-                               SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
-                               break;
+                       /*TODO: add filtering and index handling */
+
+                       ea_file_list = get_ea_list_from_file(mem_ctx,
+                                                            conn, fsp,
+                                                            fname,
+                                                            &total_ea_len);
+                       if (!ea_file_list) {
+                               return NT_STATUS_NO_EAS_ON_FILE;
                        }
 
-                       data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+                       status = fill_ea_chained_buffer(mem_ctx,
+                                                       pdata,
+                                                       data_size,
+                                                       &data_size,
+                                                       conn, ea_file_list);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
                        break;
                }
 
@@ -4400,10 +4218,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_QUERY_FILE_BASIC_INFO:
 
                        if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
-                               DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
+                               DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
                                data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
                        } else {
-                               DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
+                               DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
                                data_size = 40;
                                SIVAL(pdata,36,0);
                        }
@@ -4424,7 +4242,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_FILE_STANDARD_INFORMATION:
                case SMB_QUERY_FILE_STANDARD_INFO:
 
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
                        data_size = 24;
                        SOFF_T(pdata,0,allocation_size);
                        SOFF_T(pdata,8,file_size);
@@ -4438,7 +4256,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_QUERY_FILE_EA_INFO:
                {
                        unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
                        data_size = 4;
                        SIVAL(pdata,0,ea_size);
                        break;
@@ -4448,15 +4266,14 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_QUERY_FILE_ALT_NAME_INFO:
                case SMB_FILE_ALTERNATE_NAME_INFORMATION:
                {
+                       int len;
                        char mangled_name[13];
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
                        if (!name_to_8_3(base_name,mangled_name,
                                                True,conn->params)) {
-                               reply_nterror(
-                                       req,
-                                       NT_STATUS_NO_MEMORY);
+                               return NT_STATUS_NO_MEMORY;
                        }
-                       len = srvstr_push(dstart, req->flags2,
+                       len = srvstr_push(dstart, flags2,
                                          pdata+4, mangled_name,
                                          PTR_DIFF(dend, pdata+4),
                                          STR_UNICODE);
@@ -4466,28 +4283,31 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                }
 
                case SMB_QUERY_FILE_NAME_INFO:
+               {
+                       int len;
                        /*
                          this must be *exactly* right for ACLs on mapped drives to work
                         */
-                       len = srvstr_push(dstart, req->flags2,
+                       len = srvstr_push(dstart, flags2,
                                          pdata+4, dos_fname,
                                          PTR_DIFF(dend, pdata+4),
                                          STR_UNICODE);
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
                        data_size = 4 + len;
                        SIVAL(pdata,0,len);
                        break;
+               }
 
                case SMB_FILE_ALLOCATION_INFORMATION:
                case SMB_QUERY_FILE_ALLOCATION_INFO:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
                        data_size = 8;
                        SOFF_T(pdata,0,allocation_size);
                        break;
 
                case SMB_FILE_END_OF_FILE_INFORMATION:
                case SMB_QUERY_FILE_END_OF_FILEINFO:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
                        data_size = 8;
                        SOFF_T(pdata,0,file_size);
                        break;
@@ -4495,8 +4315,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                case SMB_QUERY_FILE_ALL_INFO:
                case SMB_FILE_ALL_INFORMATION:
                {
+                       int len;
                        unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
                        put_long_date_timespec(pdata,create_time_ts);
                        put_long_date_timespec(pdata+8,atime_ts);
                        put_long_date_timespec(pdata+16,mtime_ts); /* write time */
@@ -4513,7 +4334,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        pdata += 24;
                        SIVAL(pdata,0,ea_size);
                        pdata += 4; /* EA info */
-                       len = srvstr_push(dstart, req->flags2,
+                       len = srvstr_push(dstart, flags2,
                                          pdata+4, dos_fname,
                                          PTR_DIFF(dend, pdata+4),
                                          STR_UNICODE);
@@ -4522,27 +4343,52 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        data_size = PTR_DIFF(pdata,(*ppdata));
                        break;
                }
-               case SMB_FILE_INTERNAL_INFORMATION:
-                       /* This should be an index number - looks like
-                          dev/ino to me :-) 
 
-                          I think this causes us to fail the IFSKIT
-                          BasicFileInformationTest. -tpot */
+               case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
+               {
+                       int len;
+                       unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
+                       put_long_date_timespec(pdata+0x00,create_time_ts);
+                       put_long_date_timespec(pdata+0x08,atime_ts);
+                       put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */
+                       put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */
+                       SIVAL(pdata,    0x20, mode);
+                       SIVAL(pdata,    0x24, 0); /* padding. */
+                       SBVAL(pdata,    0x28, allocation_size);
+                       SBVAL(pdata,    0x30, file_size);
+                       SIVAL(pdata,    0x38, nlink);
+                       SCVAL(pdata,    0x3C, delete_pending);
+                       SCVAL(pdata,    0x3D, (mode&aDIR)?1:0);
+                       SSVAL(pdata,    0x3E, 0); /* padding */
+                       SBVAL(pdata,    0x40, file_index);
+                       SIVAL(pdata,    0x48, ea_size);
+                       SIVAL(pdata,    0x4C, access_mask);
+                       SBVAL(pdata,    0x50, pos);
+                       SIVAL(pdata,    0x58, mode); /*TODO: mode != mode fix this!!! */
+                       SIVAL(pdata,    0x5C, 0); /* No alignment needed. */
+
+                       pdata += 0x60;
+
+                       len = srvstr_push(dstart, flags2,
+                                         pdata+4, dos_fname,
+                                         PTR_DIFF(dend, pdata+4),
+                                         STR_UNICODE);
+                       SIVAL(pdata,0,len);
+                       pdata += 4 + len;
+                       data_size = PTR_DIFF(pdata,(*ppdata));
+                       break;
+               }
+               case SMB_FILE_INTERNAL_INFORMATION:
 
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
-                       SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
-                       SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
+                       SBVAL(pdata, 0, file_index);
                        data_size = 8;
                        break;
 
                case SMB_FILE_ACCESS_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
-                       if (fsp) {
-                               SIVAL(pdata,0,fsp->access_mask);
-                       } else {
-                               /* GENERIC_EXECUTE mapping from Windows */
-                               SIVAL(pdata,0,0x12019F);
-                       }
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
+                       SIVAL(pdata, 0, access_mask);
                        data_size = 4;
                        break;
 
@@ -4551,32 +4397,32 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        {
                                size_t byte_len;
                                byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
-                               DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
+                               DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
                                SIVAL(pdata,0,byte_len);
                                data_size = 4 + byte_len;
                                break;
                        }
 
                case SMB_FILE_DISPOSITION_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
                        data_size = 1;
                        SCVAL(pdata,0,delete_pending);
                        break;
 
                case SMB_FILE_POSITION_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
                        data_size = 8;
                        SOFF_T(pdata,0,pos);
                        break;
 
                case SMB_FILE_MODE_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
                        SIVAL(pdata,0,mode);
                        data_size = 4;
                        break;
 
                case SMB_FILE_ALIGNMENT_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
                        SIVAL(pdata,0,0); /* No alignment needed. */
                        data_size = 4;
                        break;
@@ -4594,7 +4440,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        unsigned int num_streams;
                        struct stream_struct *streams;
 
-                       DEBUG(10,("call_trans2qfilepathinfo: "
+                       DEBUG(10,("smbd_do_qfilepathinfo: "
                                  "SMB_FILE_STREAM_INFORMATION\n"));
 
                        status = SMB_VFS_STREAMINFO(
@@ -4604,8 +4450,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(10, ("could not get stream info: %s\n",
                                           nt_errstr(status)));
-                               reply_nterror(req, status);
-                               return;
+                               return status;
                        }
 
                        status = marshall_stream_info(num_streams, streams,
@@ -4615,8 +4460,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(10, ("marshall_stream_info failed: %s\n",
                                           nt_errstr(status)));
-                               reply_nterror(req, status);
-                               return;
+                               return status;
                        }
 
                        TALLOC_FREE(streams);
@@ -4625,7 +4469,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                }
                case SMB_QUERY_COMPRESSION_INFO:
                case SMB_FILE_COMPRESSION_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
                        SOFF_T(pdata,0,file_size);
                        SIVAL(pdata,8,0); /* ??? */
                        SIVAL(pdata,12,0); /* ??? */
@@ -4633,7 +4477,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        break;
 
                case SMB_FILE_NETWORK_OPEN_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
                        put_long_date_timespec(pdata,create_time_ts);
                        put_long_date_timespec(pdata+8,atime_ts);
                        put_long_date_timespec(pdata+16,mtime_ts); /* write time */
@@ -4646,7 +4490,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        break;
 
                case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
+                       DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
                        SIVAL(pdata,0,mode);
                        SIVAL(pdata,4,0);
                        data_size = 8;
@@ -4663,7 +4507,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                        {
                                int i;
-                               DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
+                               DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
 
                                for (i=0; i<100; i++)
                                        DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
@@ -4679,7 +4523,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                        {
                                int i;
-                               DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
+                               DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
 
                                for (i=0; i<100; i++)
                                        DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
@@ -4690,33 +4534,28 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                case SMB_QUERY_FILE_UNIX_LINK:
                        {
-                               char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1);
+                               int len;
+                               char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
 
                                if (!buffer) {
-                                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                                       return;
+                                       return NT_STATUS_NO_MEMORY;
                                }
 
-                               DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
+                               DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
 #ifdef S_ISLNK
                                if(!S_ISLNK(sbuf.st_ex_mode)) {
-                                       reply_unixerror(req, ERRSRV,
-                                                       ERRbadlink);
-                                       return;
+                                       return NT_STATUS_DOS(ERRSRV, ERRbadlink);
                                }
 #else
-                               reply_unixerror(req, ERRDOS, ERRbadlink);
-                               return;
+                               return NT_STATUS_DOS(ERRDOS, ERRbadlink);
 #endif
-                               len = SMB_VFS_READLINK(conn,fullpathname,
+                               len = SMB_VFS_READLINK(conn,fname,
                                                buffer, PATH_MAX);
                                if (len == -1) {
-                                       reply_unixerror(req, ERRDOS,
-                                                       ERRnoaccess);
-                                       return;
+                                       return map_nt_error_from_unix(errno);
                                }
                                buffer[len] = 0;
-                               len = srvstr_push(dstart, req->flags2,
+                               len = srvstr_push(dstart, flags2,
                                                  pdata, buffer,
                                                  PTR_DIFF(dend, pdata),
                                                  STR_TERMINATE);
@@ -4741,17 +4580,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                }
 
                                if (file_acl == NULL && no_acl_syscall_error(errno)) {
-                                       DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
+                                       DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
                                                fname ));
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_NOT_IMPLEMENTED);
-                                       return;
+                                       return NT_STATUS_NOT_IMPLEMENTED;
                                }
 
                                if (S_ISDIR(sbuf.st_ex_mode)) {
                                        if (fsp && fsp->is_directory) {
-                                               def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+                                               def_acl =
+                                                   SMB_VFS_SYS_ACL_GET_FILE(
+                                                           conn,
+                                                           fsp->fsp_name->base_name,
+                                                           SMB_ACL_TYPE_DEFAULT);
                                        } else {
                                                def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
                                        }
@@ -4762,7 +4602,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                num_def_acls = count_acl_entries(conn, def_acl);
 
                                if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
-                                       DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
+                                       DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
                                                data_size,
                                                (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
                                                        SMB_POSIX_ACL_HEADER_SIZE) ));
@@ -4772,10 +4612,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                        if (def_acl) {
                                                SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
                                        }
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_BUFFER_TOO_SMALL);
-                                       return;
+                                       return NT_STATUS_BUFFER_TOO_SMALL;
                                }
 
                                SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
@@ -4788,9 +4625,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                        if (def_acl) {
                                                SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
                                        }
-                                       reply_nterror(
-                                               req, NT_STATUS_INTERNAL_ERROR);
-                                       return;
+                                       return NT_STATUS_INTERNAL_ERROR;
                                }
                                if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
                                        if (file_acl) {
@@ -4799,10 +4634,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                        if (def_acl) {
                                                SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
                                        }
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_INTERNAL_ERROR);
-                                       return;
+                                       return NT_STATUS_INTERNAL_ERROR;
                                }
 
                                if (file_acl) {
@@ -4824,10 +4656,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        uint32 lock_pid;
                        enum brl_type lock_type;
 
-                       if (total_data != POSIX_LOCK_DATA_SIZE) {
-                               reply_nterror(
-                                       req, NT_STATUS_INVALID_PARAMETER);
-                               return;
+                       /* We need an open file with a real fd for this. */
+                       if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+
+                       if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
+                               return NT_STATUS_INVALID_PARAMETER;
                        }
 
                        switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
@@ -4840,10 +4675,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                case POSIX_LOCK_TYPE_UNLOCK:
                                default:
                                        /* There's no point in asking for an unlock... */
-                                       reply_nterror(
-                                               req,
-                                               NT_STATUS_INVALID_PARAMETER);
-                                       return;
+                                       return NT_STATUS_INVALID_PARAMETER;
                        }
 
                        lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
@@ -4888,15 +4720,393 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                                memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
                                SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
                        } else {
+                               return status;
+                       }
+                       break;
+               }
+
+               default:
+                       return NT_STATUS_INVALID_LEVEL;
+       }
+
+       *pdata_size = data_size;
+       return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
+ file name or file id).
+****************************************************************************/
+
+static void call_trans2qfilepathinfo(connection_struct *conn,
+                                    struct smb_request *req,
+                                    unsigned int tran_call,
+                                    char **pparams, int total_params,
+                                    char **ppdata, int total_data,
+                                    unsigned int max_data_bytes)
+{
+       char *params = *pparams;
+       char *pdata = *ppdata;
+       uint16 info_level;
+       unsigned int data_size = 0;
+       unsigned int param_size = 2;
+       struct smb_filename *smb_fname = NULL;
+       bool delete_pending = False;
+       struct timespec write_time_ts;
+       files_struct *fsp = NULL;
+       struct file_id fileid;
+       struct ea_list *ea_list = NULL;
+       int lock_data_count = 0;
+       char *lock_data = NULL;
+       bool ms_dfs_link = false;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (!params) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       ZERO_STRUCT(write_time_ts);
+
+       if (tran_call == TRANSACT2_QFILEINFO) {
+               if (total_params < 4) {
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
+               }
+
+               if (IS_IPC(conn)) {
+                       call_trans2qpipeinfo(conn, req, tran_call,
+                                            pparams, total_params,
+                                            ppdata, total_data,
+                                            max_data_bytes);
+                       return;
+               }
+
+               fsp = file_fsp(req, SVAL(params,0));
+               info_level = SVAL(params,2);
+
+               DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+               if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+
+               /* Initial check for valid fsp ptr. */
+               if (!check_fsp_open(conn, req, fsp)) {
+                       return;
+               }
+
+               status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+                                          &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               if(fsp->fake_file_handle) {
+                       /*
+                        * This is actually for the QUOTA_FAKE_FILE --metze
+                        */
+
+                       /* We know this name is ok, it's already passed the checks. */
+
+               } else if(fsp->is_directory || fsp->fh->fd == -1) {
+                       /*
+                        * This is actually a QFILEINFO on a directory
+                        * handle (returned from an NT SMB). NT5.0 seems
+                        * to do this call. JRA.
+                        */
+
+                       if (INFO_LEVEL_IS_UNIX(info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn, smb_fname)) {
+                                       DEBUG(3,("call_trans2qfilepathinfo: "
+                                                "SMB_VFS_LSTAT of %s failed "
+                                                "(%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno)));
+                                       reply_nterror(req,
+                                               map_nt_error_from_unix(errno));
+                                       return;
+                               }
+                       } else if (SMB_VFS_STAT(conn, smb_fname)) {
+                               DEBUG(3,("call_trans2qfilepathinfo: "
+                                        "SMB_VFS_STAT of %s failed (%s)\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno)));
+                               reply_nterror(req,
+                                       map_nt_error_from_unix(errno));
+                               return;
+                       }
+
+                       fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+                       get_file_infos(fileid, &delete_pending, &write_time_ts);
+               } else {
+                       /*
+                        * Original code - this is an open file.
+                        */
+                       if (!check_fsp(conn, req, fsp)) {
+                               return;
+                       }
+
+                       if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+                               DEBUG(3, ("fstat of fnum %d failed (%s)\n",
+                                         fsp->fnum, strerror(errno)));
+                               reply_nterror(req,
+                                       map_nt_error_from_unix(errno));
+                               return;
+                       }
+                       fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+                       get_file_infos(fileid, &delete_pending, &write_time_ts);
+               }
+
+       } else {
+               char *fname = NULL;
+
+               /* qpathinfo */
+               if (total_params < 7) {
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
+               }
+
+               info_level = SVAL(params,0);
+
+               DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+
+               if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+
+               srvstr_get_path(req, params, req->flags2, &fname, &params[6],
+                               total_params - 6,
+                               STR_TERMINATE, &status);
+               if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               status = filename_convert(req,
+                                       conn,
+                                       req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                       fname,
+                                       &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req,
+                                               NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               return;
+                       }
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               /* If this is a stream, check if there is a delete_pending. */
+               if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
+                   && is_ntfs_stream_smb_fname(smb_fname)) {
+                       struct smb_filename *smb_fname_base = NULL;
+
+                       /* Create an smb_filename with stream_name == NULL. */
+                       status =
+                           create_synthetic_smb_fname(talloc_tos(),
+                                                      smb_fname->base_name,
+                                                      NULL, NULL,
+                                                      &smb_fname_base);
+                       if (!NT_STATUS_IS_OK(status)) {
                                reply_nterror(req, status);
                                return;
                        }
+
+                       if (INFO_LEVEL_IS_UNIX(info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
+                                       DEBUG(3,("call_trans2qfilepathinfo: "
+                                                "SMB_VFS_LSTAT of %s failed "
+                                                "(%s)\n",
+                                                smb_fname_str_dbg(smb_fname_base),
+                                                strerror(errno)));
+                                       TALLOC_FREE(smb_fname_base);
+                                       reply_nterror(req,
+                                               map_nt_error_from_unix(errno));
+                                       return;
+                               }
+                       } else {
+                               if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
+                                       DEBUG(3,("call_trans2qfilepathinfo: "
+                                                "fileinfo of %s failed "
+                                                "(%s)\n",
+                                                smb_fname_str_dbg(smb_fname_base),
+                                                strerror(errno)));
+                                       TALLOC_FREE(smb_fname_base);
+                                       reply_nterror(req,
+                                               map_nt_error_from_unix(errno));
+                                       return;
+                               }
+                       }
+
+                       fileid = vfs_file_id_from_sbuf(conn,
+                                                      &smb_fname_base->st);
+                       TALLOC_FREE(smb_fname_base);
+                       get_file_infos(fileid, &delete_pending, NULL);
+                       if (delete_pending) {
+                               reply_nterror(req, NT_STATUS_DELETE_PENDING);
+                               return;
+                       }
+               }
+
+               if (INFO_LEVEL_IS_UNIX(info_level)) {
+                       /* Always do lstat for UNIX calls. */
+                       if (SMB_VFS_LSTAT(conn, smb_fname)) {
+                               DEBUG(3,("call_trans2qfilepathinfo: "
+                                        "SMB_VFS_LSTAT of %s failed (%s)\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno)));
+                               reply_nterror(req,
+                                       map_nt_error_from_unix(errno));
+                               return;
+                       }
+
+               } else if (!VALID_STAT(smb_fname->st) &&
+                          SMB_VFS_STAT(conn, smb_fname) &&
+                          (info_level != SMB_INFO_IS_NAME_VALID)) {
+                       ms_dfs_link = check_msdfs_link(conn,
+                                                      smb_fname->base_name,
+                                                      &smb_fname->st);
+
+                       if (!ms_dfs_link) {
+                               DEBUG(3,("call_trans2qfilepathinfo: "
+                                        "SMB_VFS_STAT of %s failed (%s)\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        strerror(errno)));
+                               reply_nterror(req,
+                                       map_nt_error_from_unix(errno));
+                               return;
+                       }
+               }
+
+               fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+               get_file_infos(fileid, &delete_pending, &write_time_ts);
+               if (delete_pending) {
+                       reply_nterror(req, NT_STATUS_DELETE_PENDING);
+                       return;
+               }
+       }
+
+       DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
+                "total_data=%d\n", smb_fname_str_dbg(smb_fname),
+                fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+
+       /* Pull out any data sent here before we realloc. */
+       switch (info_level) {
+               case SMB_INFO_QUERY_EAS_FROM_LIST:
+               {
+                       /* Pull any EA list from the data portion. */
+                       uint32 ea_size;
+
+                       if (total_data < 4) {
+                               reply_nterror(
+                                       req, NT_STATUS_INVALID_PARAMETER);
+                               return;
+                       }
+                       ea_size = IVAL(pdata,0);
+
+                       if (total_data > 0 && ea_size != total_data) {
+                               DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+                               reply_nterror(
+                                       req, NT_STATUS_INVALID_PARAMETER);
+                               return;
+                       }
+
+                       if (!lp_ea_support(SNUM(conn))) {
+                               reply_doserror(req, ERRDOS,
+                                              ERReasnotsupported);
+                               return;
+                       }
+
+                       /* Pull out the list of names. */
+                       ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
+                       if (!ea_list) {
+                               reply_nterror(
+                                       req, NT_STATUS_INVALID_PARAMETER);
+                               return;
+                       }
                        break;
                }
 
+               case SMB_QUERY_POSIX_LOCK:
+               {
+                       if (fsp == NULL || fsp->fh->fd == -1) {
+                               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+                               return;
+                       }
+
+                       if (total_data != POSIX_LOCK_DATA_SIZE) {
+                               reply_nterror(
+                                       req, NT_STATUS_INVALID_PARAMETER);
+                               return;
+                       }
+
+                       /* Copy the lock range data. */
+                       lock_data = (char *)TALLOC_MEMDUP(
+                               req, pdata, total_data);
+                       if (!lock_data) {
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               return;
+                       }
+                       lock_data_count = total_data;
+               }
                default:
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                       return;
+                       break;
+       }
+
+       *pparams = (char *)SMB_REALLOC(*pparams,2);
+       if (*pparams == NULL) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
+               return;
+       }
+       params = *pparams;
+       SSVAL(params,0,0);
+
+       /*
+        * draft-leach-cifs-v1-spec-02.txt
+        * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
+        * says:
+        *
+        *  The requested information is placed in the Data portion of the
+        *  transaction response. For the information levels greater than 0x100,
+        *  the transaction response has 1 parameter word which should be
+        *  ignored by the client.
+        *
+        * However Windows only follows this rule for the IS_NAME_VALID call.
+        */
+       switch (info_level) {
+       case SMB_INFO_IS_NAME_VALID:
+               param_size = 0;
+               break;
+       }
+
+       if ((info_level & 0xFF00) == 0xFF00) {
+               /*
+                * We use levels that start with 0xFF00
+                * internally to represent SMB2 specific levels
+                */
+               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+               return;
+       }
+
+       status = smbd_do_qfilepathinfo(conn, req, info_level,
+                                      fsp, smb_fname,
+                                      delete_pending, write_time_ts,
+                                      ms_dfs_link, ea_list,
+                                      lock_data_count, lock_data,
+                                      req->flags2, max_data_bytes,
+                                      ppdata, &data_size);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
        }
 
        send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
@@ -4915,8 +5125,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                const struct smb_filename *smb_fname_old,
                const struct smb_filename *smb_fname_new)
 {
-       char *oldname = NULL;
-       char *newname = NULL;
        NTSTATUS status = NT_STATUS_OK;
 
        /* source must already exist. */
@@ -4934,25 +5142,22 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                return NT_STATUS_FILE_IS_A_DIRECTORY;
        }
 
-       status = get_full_smb_filename(ctx, smb_fname_new, &newname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-       status = get_full_smb_filename(ctx, smb_fname_old, &oldname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
+       /* Setting a hardlink to/from a stream isn't currently supported. */
+       if (is_ntfs_stream_smb_fname(smb_fname_old) ||
+           is_ntfs_stream_smb_fname(smb_fname_new)) {
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
-       DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
+       DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
+                 smb_fname_old->base_name, smb_fname_new->base_name));
 
-       if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
+       if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
+                        smb_fname_new->base_name) != 0) {
                status = map_nt_error_from_unix(errno);
                DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
-                                nt_errstr(status), newname, oldname));
+                        nt_errstr(status), smb_fname_old->base_name,
+                        smb_fname_new->base_name));
        }
- out:
-       TALLOC_FREE(newname);
-       TALLOC_FREE(oldname);
        return status;
 }
 
@@ -5317,8 +5522,9 @@ static NTSTATUS smb_file_position_information(connection_struct *conn,
        }
 #endif /* LARGE_SMB_OFF_T */
 
-       DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
-               fsp->fsp_name, (double)position_information ));
+       DEBUG(10,("smb_file_position_information: Set file position "
+                 "information for file %s to %.0f\n", fsp_str_dbg(fsp),
+                 (double)position_information));
        fsp->fh->position_information = position_information;
        return NT_STATUS_OK;
 }
@@ -5351,10 +5557,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
                                       struct smb_request *req,
                                       const char *pdata,
                                       int total_data,
-                                      const char *fname)
+                                      const struct smb_filename *smb_fname)
 {
        char *link_target = NULL;
-       const char *newname = fname;
+       const char *newname = smb_fname->base_name;
        NTSTATUS status = NT_STATUS_OK;
        TALLOC_CTX *ctx = talloc_tos();
 
@@ -5454,8 +5660,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                oldname,
-                               &smb_fname_old,
-                               NULL);
+                               &smb_fname_old);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -5529,8 +5734,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
 
                /* Create an smb_fname to call rename_internals_fsp() with. */
                status = create_synthetic_smb_fname(talloc_tos(),
-                                                   fsp->base_fsp->fsp_name,
-                                                   newname, NULL, &smb_fname);
+                   fsp->base_fsp->fsp_name->base_name, newname, NULL,
+                   &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        goto out;
                }
@@ -5547,7 +5752,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
 
                /* Create a char * to call rename_internals() with. */
                base_name = talloc_asprintf(ctx, "%s%s",
-                                          fsp->base_fsp->fsp_name,
+                                          fsp->base_fsp->fsp_name->base_name,
                                           newname);
                if (!base_name) {
                        status = NT_STATUS_NO_MEMORY;
@@ -5604,13 +5809,15 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
        }
 
        if (fsp) {
-               DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
-                       fsp->fnum, fsp->fsp_name, base_name ));
+               DEBUG(10,("smb_file_rename_information: "
+                         "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
+                         fsp->fnum, fsp_str_dbg(fsp), base_name));
                status = rename_internals_fsp(conn, fsp, smb_fname, 0,
                                              overwrite);
        } else {
-               DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
-                       fname, base_name ));
+               DEBUG(10,("smb_file_rename_information: "
+                         "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
+                         fname, base_name));
                status = rename_internals(ctx, conn, req, fname, base_name, 0,
                                        overwrite, False, dest_has_wcard,
                                        FILE_WRITE_ATTRIBUTES);
@@ -5629,8 +5836,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
                                const char *pdata,
                                int total_data,
                                files_struct *fsp,
-                               const char *fname,
-                               SMB_STRUCT_STAT *psbuf)
+                               const struct smb_filename *smb_fname)
 {
        uint16 posix_acl_version;
        uint16 num_file_acls;
@@ -5665,18 +5871,20 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
        }
 
        DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
-               fname ? fname : fsp->fsp_name,
+               smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
                (unsigned int)num_file_acls,
                (unsigned int)num_def_acls));
 
-       if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
-                       pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+       if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
+               smb_fname->base_name, num_file_acls,
+               pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
                return map_nt_error_from_unix(errno);
        }
 
-       if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls,
-                       pdata + SMB_POSIX_ACL_HEADER_SIZE +
-                       (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+       if (valid_def_acls && !set_unix_posix_default_acl(conn,
+               smb_fname->base_name, &smb_fname->st, num_def_acls,
+               pdata + SMB_POSIX_ACL_HEADER_SIZE +
+               (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
                return map_nt_error_from_unix(errno);
        }
        return NT_STATUS_OK;
@@ -5752,7 +5960,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
 
        DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
                        "lock_pid = %u, count = %.0f, offset = %.0f\n",
-               fsp->fsp_name,
+               fsp_str_dbg(fsp),
                (unsigned int)lock_type,
                (unsigned int)lock_pid,
                (double)count,
@@ -6444,11 +6652,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
                                struct smb_request *req,
                                char **ppdata,
                                int total_data,
-                               const char *fname,
-                               SMB_STRUCT_STAT *psbuf,
+                               struct smb_filename *smb_fname,
                                int *pdata_return_size)
 {
-       struct smb_filename *smb_fname;
        NTSTATUS status = NT_STATUS_OK;
        uint32 raw_unixmode = 0;
        uint32 mod_unixmode = 0;
@@ -6465,7 +6671,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
        raw_unixmode = IVAL(pdata,8);
        /* Next 4 bytes are not yet defined. */
 
-       status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode);
+       status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+                                     PERM_NEW_DIR, &unixmode);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -6473,13 +6680,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
        mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
 
        DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
-               fname, (unsigned int)unixmode ));
-
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
+                 smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
 
         status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
@@ -6498,9 +6699,6 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
                &fsp,                                   /* result */
                &info);                                 /* pinfo */
 
-       *psbuf = smb_fname->st;
-       TALLOC_FREE(smb_fname);
-
         if (NT_STATUS_IS_OK(status)) {
                 close_file(req, fsp, NORMAL_CLOSE);
         }
@@ -6531,12 +6729,14 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
                case SMB_QUERY_FILE_UNIX_BASIC:
                        SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
                        SSVAL(pdata,10,0); /* Padding. */
-                       store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+                       store_file_unix_basic(conn, pdata + 12, fsp,
+                                             &smb_fname->st);
                        break;
                case SMB_QUERY_FILE_UNIX_INFO2:
                        SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
                        SSVAL(pdata,10,0); /* Padding. */
-                       store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+                       store_file_unix_basic_info2(conn, pdata + 12, fsp,
+                                                   &smb_fname->st);
                        break;
                default:
                        SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
@@ -6555,11 +6755,9 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
                               struct smb_request *req,
                                char **ppdata,
                                int total_data,
-                               const char *fname,
-                               SMB_STRUCT_STAT *psbuf,
+                               struct smb_filename *smb_fname,
                                int *pdata_return_size)
 {
-       struct smb_filename *smb_fname = NULL;
        bool extended_oplock_granted = False;
        char *pdata = *ppdata;
        uint32 flags = 0;
@@ -6592,8 +6790,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
                return smb_posix_mkdir(conn, req,
                                        ppdata,
                                        total_data,
-                                       fname,
-                                       psbuf,
+                                       smb_fname,
                                        pdata_return_size);
        }
 
@@ -6632,11 +6829,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
        raw_unixmode = IVAL(pdata,8);
        /* Next 4 bytes are not yet defined. */
 
-       status = unix_perms_from_wire(conn,
-                               psbuf,
-                               raw_unixmode,
-                               VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE,
-                               &unixmode);
+       status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+                                     (VALID_STAT(smb_fname->st) ?
+                                         PERM_EXISTING_FILE : PERM_NEW_FILE),
+                                     &unixmode);
 
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -6655,16 +6851,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
        }
 
        DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
-               fname,
+               smb_fname_str_dbg(smb_fname),
                (unsigned int)wire_open_mode,
                (unsigned int)unixmode ));
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
-                                                 &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
         status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                req,                                    /* req */
@@ -6683,9 +6873,6 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
                &fsp,                                   /* result */
                &info);                                 /* pinfo */
 
-       *psbuf = smb_fname->st;
-       TALLOC_FREE(smb_fname);
-
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -6738,12 +6925,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
                case SMB_QUERY_FILE_UNIX_BASIC:
                        SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
                        SSVAL(pdata,10,0); /* padding. */
-                       store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+                       store_file_unix_basic(conn, pdata + 12, fsp,
+                                             &smb_fname->st);
                        break;
                case SMB_QUERY_FILE_UNIX_INFO2:
                        SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
                        SSVAL(pdata,10,0); /* padding. */
-                       store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+                       store_file_unix_basic_info2(conn, pdata + 12, fsp,
+                                                   &smb_fname->st);
                        break;
                default:
                        SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
@@ -6825,242 +7014,84 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
        lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
                                  NULL);
        if (lck == NULL) {
-               DEBUG(0, ("smb_posix_unlink: Could not get share mode "
-                       "lock for file %s\n", fsp->fsp_name));
-               close_file(req, fsp, NORMAL_CLOSE);
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       /*
-        * See if others still have the file open. If this is the case, then
-        * don't delete. If all opens are POSIX delete we can set the delete
-        * on close disposition.
-        */
-       for (i=0; i<lck->num_share_modes; i++) {
-               struct share_mode_entry *e = &lck->share_modes[i];
-               if (is_valid_share_mode_entry(e)) {
-                       if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
-                               continue;
-                       }
-                       /* Fail with sharing violation. */
-                       close_file(req, fsp, NORMAL_CLOSE);
-                       TALLOC_FREE(lck);
-                       return NT_STATUS_SHARING_VIOLATION;
-               }
-       }
-
-       /*
-        * Set the delete on close.
-        */
-       status = smb_set_file_disposition_info(conn,
-                                               &del,
-                                               1,
-                                               fsp,
-                                               smb_fname);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               close_file(req, fsp, NORMAL_CLOSE);
-               TALLOC_FREE(lck);
-               return status;
-       }
-       TALLOC_FREE(lck);
-       return close_file(req, fsp, NORMAL_CLOSE);
-}
-
-/****************************************************************************
- Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
-****************************************************************************/
-
-static void call_trans2setfilepathinfo(connection_struct *conn,
-                                      struct smb_request *req,
-                                      unsigned int tran_call,
-                                      char **pparams, int total_params,
-                                      char **ppdata, int total_data,
-                                      unsigned int max_data_bytes)
-{
-       char *params = *pparams;
-       char *pdata = *ppdata;
-       uint16 info_level;
-       SMB_STRUCT_STAT sbuf;
-       char *fname = NULL;
-       struct smb_filename *smb_fname = NULL;
-       files_struct *fsp = NULL;
-       NTSTATUS status = NT_STATUS_OK;
-       int data_return_size = 0;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       if (!params) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
-       }
-
-       if (tran_call == TRANSACT2_SETFILEINFO) {
-               if (total_params < 4) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
-               }
-
-               fsp = file_fsp(req, SVAL(params,0));
-               /* Basic check for non-null fsp. */
-               if (!check_fsp_open(conn, req, fsp)) {
-                       return;
-               }
-               info_level = SVAL(params,2);
-
-               fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
-               if (!fname) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       return;
-               }
-
-               status = create_synthetic_smb_fname_split(talloc_tos(), fname,
-                                                         NULL, &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               if(fsp->is_directory || fsp->fh->fd == -1) {
-                       /*
-                        * This is actually a SETFILEINFO on a directory
-                        * handle (returned from an NT SMB). NT5.0 seems
-                        * to do this call. JRA.
-                        */
-                       if (INFO_LEVEL_IS_UNIX(info_level)) {
-                               /* Always do lstat for UNIX calls. */
-                               if (SMB_VFS_LSTAT(conn, smb_fname)) {
-                                       DEBUG(3,("call_trans2setfilepathinfo: "
-                                                "SMB_VFS_LSTAT of %s failed "
-                                                "(%s)\n",
-                                                smb_fname_str_dbg(smb_fname),
-                                                strerror(errno)));
-                                       reply_unixerror(req,ERRDOS,ERRbadpath);
-                                       return;
-                               }
-                       } else {
-                               if (SMB_VFS_STAT(conn, smb_fname) != 0) {
-                                       DEBUG(3,("call_trans2setfilepathinfo: "
-                                                "fileinfo of %s failed (%s)\n",
-                                                smb_fname_str_dbg(smb_fname),
-                                                strerror(errno)));
-                                       reply_unixerror(req,ERRDOS,ERRbadpath);
-                                       return;
-                               }
-                       }
-               } else if (fsp->print_file) {
-                       /*
-                        * Doing a DELETE_ON_CLOSE should cancel a print job.
-                        */
-                       if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
-                               fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
-
-                               DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
-
-                               SSVAL(params,0,0);
-                               send_trans2_replies(conn, req, params, 2,
-                                                   *ppdata, 0,
-                                                   max_data_bytes);
-                               return;
-                       } else {
-                               reply_unixerror(req, ERRDOS, ERRbadpath);
-                               return;
-                       }
-               } else {
-                       /*
-                        * Original code - this is an open file.
-                        */
-                       if (!check_fsp(conn, req, fsp)) {
-                               return;
-                       }
-
-                       if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
-                               DEBUG(3,("call_trans2setfilepathinfo: fstat "
-                                        "of fnum %d failed (%s)\n", fsp->fnum,
-                                        strerror(errno)));
-                               reply_unixerror(req, ERRDOS, ERRbadfid);
-                               return;
-                       }
-               }
-       } else {
-               /* set path info */
-               if (total_params < 7) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
-               }
-
-               info_level = SVAL(params,0);
-               srvstr_get_path(ctx, params, req->flags2, &fname, &params[6],
-                               total_params - 6, STR_TERMINATE,
-                               &status);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               status = filename_convert(ctx, conn,
-                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                        fname,
-                                        &smb_fname,
-                                        &fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                               reply_botherror(req,
-                                               NT_STATUS_PATH_NOT_COVERED,
-                                               ERRSRV, ERRbadpath);
-                               return;
+               DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+                         "lock for file %s\n", fsp_str_dbg(fsp)));
+               close_file(req, fsp, NORMAL_CLOSE);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /*
+        * See if others still have the file open. If this is the case, then
+        * don't delete. If all opens are POSIX delete we can set the delete
+        * on close disposition.
+        */
+       for (i=0; i<lck->num_share_modes; i++) {
+               struct share_mode_entry *e = &lck->share_modes[i];
+               if (is_valid_share_mode_entry(e)) {
+                       if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+                               continue;
                        }
-                       reply_nterror(req, status);
-                       return;
+                       /* Fail with sharing violation. */
+                       close_file(req, fsp, NORMAL_CLOSE);
+                       TALLOC_FREE(lck);
+                       return NT_STATUS_SHARING_VIOLATION;
                }
+       }
 
-               if (INFO_LEVEL_IS_UNIX(info_level)) {
-                       /*
-                        * For CIFS UNIX extensions the target name may not exist.
-                        */
-
-                       /* Always do lstat for UNIX calls. */
-                       SMB_VFS_LSTAT(conn, smb_fname);
+       /*
+        * Set the delete on close.
+        */
+       status = smb_set_file_disposition_info(conn,
+                                               &del,
+                                               1,
+                                               fsp,
+                                               smb_fname);
 
-               } else if (!VALID_STAT(smb_fname->st) &&
-                          SMB_VFS_STAT(conn, smb_fname)) {
-                       DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
-                                "%s failed (%s)\n",
-                                smb_fname_str_dbg(smb_fname),
-                                strerror(errno)));
-                       reply_unixerror(req, ERRDOS, ERRbadpath);
-                       return;
-               }
+       if (!NT_STATUS_IS_OK(status)) {
+               close_file(req, fsp, NORMAL_CLOSE);
+               TALLOC_FREE(lck);
+               return status;
        }
+       TALLOC_FREE(lck);
+       return close_file(req, fsp, NORMAL_CLOSE);
+}
 
-       /* Set sbuf for use below. */
-       sbuf = smb_fname->st;
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+                               struct smb_request *req,
+                               TALLOC_CTX *mem_ctx,
+                               uint16_t info_level,
+                               files_struct *fsp,
+                               struct smb_filename *smb_fname,
+                               char **ppdata, int total_data,
+                               int *ret_data_size)
+{
+       char *pdata = *ppdata;
+       char *fname = NULL;
+       NTSTATUS status = NT_STATUS_OK;
+       int data_return_size = 0;
+
+       *ret_data_size = 0;
 
        if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-               return;
+               return NT_STATUS_INVALID_LEVEL;
        }
 
        if (!CAN_WRITE(conn)) {
                /* Allow POSIX opens. The open path will deny
                 * any non-readonly opens. */
                if (info_level != SMB_POSIX_PATH_OPEN) {
-                       reply_doserror(req, ERRSRV, ERRaccess);
-                       return;
+                       return NT_STATUS_DOS(ERRSRV, ERRaccess);
                }
        }
 
-       DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
-               tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
-
-       /* Realloc the parameter size */
-       *pparams = (char *)SMB_REALLOC(*pparams,2);
-       if (*pparams == NULL) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               return;
+       status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
-       params = *pparams;
 
-       SSVAL(params,0,0);
+       DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
+                "totdata=%d\n", smb_fname_str_dbg(smb_fname),
+                fsp ? fsp->fnum : -1, info_level, total_data));
 
        switch (info_level) {
 
@@ -7186,22 +7217,20 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
 
                case SMB_SET_FILE_UNIX_LINK:
                {
-                       if (tran_call != TRANSACT2_SETPATHINFO) {
+                       if (fsp) {
                                /* We must have a pathname for this. */
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
                        status = smb_set_file_unix_link(conn, req, pdata,
-                                                       total_data, fname);
+                                                       total_data, smb_fname);
                        break;
                }
 
                case SMB_SET_FILE_UNIX_HLINK:
                {
-                       if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) {
+                       if (fsp) {
                                /* We must have a pathname for this. */
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
                        status = smb_set_file_unix_hlink(conn, req,
                                                         pdata, total_data,
@@ -7224,17 +7253,15 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                                                pdata,
                                                total_data,
                                                fsp,
-                                               fname,
-                                               &sbuf);
+                                               smb_fname);
                        break;
                }
 #endif
 
                case SMB_SET_POSIX_LOCK:
                {
-                       if (tran_call != TRANSACT2_SETFILEINFO) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                       if (!fsp) {
+                               return NT_STATUS_INVALID_LEVEL;
                        }
                        status = smb_set_posix_lock(conn, req,
                                                    pdata, total_data, fsp);
@@ -7243,27 +7270,24 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
 
                case SMB_POSIX_PATH_OPEN:
                {
-                       if (tran_call != TRANSACT2_SETPATHINFO) {
+                       if (fsp) {
                                /* We must have a pathname for this. */
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
 
                        status = smb_posix_open(conn, req,
                                                ppdata,
                                                total_data,
-                                               fname,
-                                               &sbuf,
+                                               smb_fname,
                                                &data_return_size);
                        break;
                }
 
                case SMB_POSIX_PATH_UNLINK:
                {
-                       if (tran_call != TRANSACT2_SETPATHINFO) {
+                       if (fsp) {
                                /* We must have a pathname for this. */
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
+                               return NT_STATUS_INVALID_LEVEL;
                        }
 
                        status = smb_posix_unlink(conn, req,
@@ -7274,10 +7298,196 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                }
 
                default:
-                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       *ret_data_size = data_return_size;
+       return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
+****************************************************************************/
+
+static void call_trans2setfilepathinfo(connection_struct *conn,
+                                      struct smb_request *req,
+                                      unsigned int tran_call,
+                                      char **pparams, int total_params,
+                                      char **ppdata, int total_data,
+                                      unsigned int max_data_bytes)
+{
+       char *params = *pparams;
+       char *pdata = *ppdata;
+       uint16 info_level;
+       struct smb_filename *smb_fname = NULL;
+       files_struct *fsp = NULL;
+       NTSTATUS status = NT_STATUS_OK;
+       int data_return_size = 0;
+
+       if (!params) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       if (tran_call == TRANSACT2_SETFILEINFO) {
+               if (total_params < 4) {
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
+               }
+
+               fsp = file_fsp(req, SVAL(params,0));
+               /* Basic check for non-null fsp. */
+               if (!check_fsp_open(conn, req, fsp)) {
+                       return;
+               }
+               info_level = SVAL(params,2);
+
+               status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+                                          &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               if(fsp->is_directory || fsp->fh->fd == -1) {
+                       /*
+                        * This is actually a SETFILEINFO on a directory
+                        * handle (returned from an NT SMB). NT5.0 seems
+                        * to do this call. JRA.
+                        */
+                       if (INFO_LEVEL_IS_UNIX(info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn, smb_fname)) {
+                                       DEBUG(3,("call_trans2setfilepathinfo: "
+                                                "SMB_VFS_LSTAT of %s failed "
+                                                "(%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno)));
+                                       reply_nterror(req, map_nt_error_from_unix(errno));
+                                       return;
+                               }
+                       } else {
+                               if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+                                       DEBUG(3,("call_trans2setfilepathinfo: "
+                                                "fileinfo of %s failed (%s)\n",
+                                                smb_fname_str_dbg(smb_fname),
+                                                strerror(errno)));
+                                       reply_nterror(req, map_nt_error_from_unix(errno));
+                                       return;
+                               }
+                       }
+               } else if (fsp->print_file) {
+                       /*
+                        * Doing a DELETE_ON_CLOSE should cancel a print job.
+                        */
+                       if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
+                               fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+                               DEBUG(3,("call_trans2setfilepathinfo: "
+                                        "Cancelling print job (%s)\n",
+                                        fsp_str_dbg(fsp)));
+
+                               SSVAL(params,0,0);
+                               send_trans2_replies(conn, req, params, 2,
+                                                   *ppdata, 0,
+                                                   max_data_bytes);
+                               return;
+                       } else {
+                               reply_doserror(req, ERRDOS, ERRbadpath);
+                               return;
+                       }
+               } else {
+                       /*
+                        * Original code - this is an open file.
+                        */
+                       if (!check_fsp(conn, req, fsp)) {
+                               return;
+                       }
+
+                       if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+                               DEBUG(3,("call_trans2setfilepathinfo: fstat "
+                                        "of fnum %d failed (%s)\n", fsp->fnum,
+                                        strerror(errno)));
+                               reply_nterror(req, map_nt_error_from_unix(errno));
+                               return;
+                       }
+               }
+       } else {
+               char *fname = NULL;
+
+               /* set path info */
+               if (total_params < 7) {
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
+               }
+
+               info_level = SVAL(params,0);
+               srvstr_get_path(req, params, req->flags2, &fname, &params[6],
+                               total_params - 6, STR_TERMINATE,
+                               &status);
+               if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               status = filename_convert(req, conn,
+                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                        fname,
+                                        &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req,
+                                               NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               return;
+                       }
+                       reply_nterror(req, status);
+                       return;
+               }
+
+               if (INFO_LEVEL_IS_UNIX(info_level)) {
+                       /*
+                        * For CIFS UNIX extensions the target name may not exist.
+                        */
+
+                       /* Always do lstat for UNIX calls. */
+                       SMB_VFS_LSTAT(conn, smb_fname);
+
+               } else if (!VALID_STAT(smb_fname->st) &&
+                          SMB_VFS_STAT(conn, smb_fname)) {
+                       DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
+                                "%s failed (%s)\n",
+                                smb_fname_str_dbg(smb_fname),
+                                strerror(errno)));
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        return;
+               }
+       }
+
+       DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
+                "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
+                fsp ? fsp->fnum : -1, info_level,total_data));
+
+       /* Realloc the parameter size */
+       *pparams = (char *)SMB_REALLOC(*pparams,2);
+       if (*pparams == NULL) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
+               return;
        }
+       params = *pparams;
+
+       SSVAL(params,0,0);
 
+       status = smbd_do_setfilepathinfo(conn, req, req,
+                                        info_level,
+                                        fsp,
+                                        smb_fname,
+                                        ppdata, total_data,
+                                        &data_return_size);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
@@ -7301,7 +7511,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                return;
        }
 
-       SSVAL(params,0,0);
        send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
                            max_data_bytes);
 
@@ -7349,8 +7558,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                directory,
-                               &smb_dname,
-                               NULL);
+                               &smb_dname);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
index 2b4124bf7b6030e14f3006d0e1c8a03451825be6..cd78c7962ee0d6e34da802ce0caf9565ef3ea265 100644 (file)
@@ -487,10 +487,12 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
         * Actually try and commit the space on disk....
         */
 
-       DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
+       DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
+                 fsp_str_dbg(fsp), (double)len));
 
        if (((SMB_OFF_T)len) < 0) {
-               DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
+               DEBUG(0,("vfs_allocate_file_space: %s negative len "
+                        "requested.\n", fsp_str_dbg(fsp)));
                errno = EINVAL;
                return -1;
        }
@@ -505,8 +507,9 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
        if (len < (uint64_t)st.st_ex_size) {
                /* Shrink - use ftruncate. */
 
-               DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
-                               fsp->fsp_name, (double)st.st_ex_size ));
+               DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
+                         "size %.0f\n", fsp_str_dbg(fsp),
+                         (double)st.st_ex_size));
 
                contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
 
@@ -530,13 +533,16 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
 
        len -= st.st_ex_size;
        len /= 1024; /* Len is now number of 1k blocks needed. */
-       space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
+       space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
+                                    &bsize, &dfree, &dsize);
        if (space_avail == (uint64_t)-1) {
                return -1;
        }
 
-       DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
-                       fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail ));
+       DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
+                 "needed blocks = %.0f, space avail = %.0f\n",
+                 fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len,
+                 (double)space_avail));
 
        if (len > space_avail) {
                errno = ENOSPC;
@@ -558,14 +564,15 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
 
        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
 
-       DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
+       DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
+                 fsp_str_dbg(fsp), (double)len));
        flush_write_cache(fsp, SIZECHANGE_FLUSH);
        if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
                set_filelen_write_cache(fsp, len);
                notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_SIZE
                             | FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                            fsp->fsp_name);
+                            fsp->fsp_name->base_name);
        }
 
        contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
@@ -600,8 +607,10 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
                return 0;
        }
 
-       DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
-               fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size)));
+       DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
+                 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
+                 (double)st.st_ex_size, (double)len,
+                 (double)(len - st.st_ex_size)));
 
        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
 
@@ -625,8 +634,9 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
 
                pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
                if (pwrite_ret == -1) {
-                       DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file "
+                                 "%s failed with error %s\n",
+                                 fsp_str_dbg(fsp), strerror(errno)));
                        ret = -1;
                        goto out;
                }
@@ -962,15 +972,28 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
 
 #ifdef S_ISLNK
         if (!lp_symlinks(SNUM(conn))) {
-                SMB_STRUCT_STAT statbuf;
-                if ( (vfs_lstat_smb_fname(conn,fname,&statbuf) != -1) &&
-                                (S_ISLNK(statbuf.st_ex_mode)) ) {
+               struct smb_filename *smb_fname = NULL;
+               NTSTATUS status;
+
+               status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+                                                   NULL, &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       if (free_resolved_name) {
+                               SAFE_FREE(resolved_name);
+                       }
+                        return status;
+               }
+
+               if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
+                                (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
                        if (free_resolved_name) {
                                SAFE_FREE(resolved_name);
                        }
                         DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name));
+                       TALLOC_FREE(smb_fname);
                        return NT_STATUS_ACCESS_DENIED;
                 }
+               TALLOC_FREE(smb_fname);
         }
 #endif
 
@@ -980,3 +1003,58 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
        }
        return NT_STATUS_OK;
 }
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+                      SMB_STRUCT_STAT *psbuf)
+{
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+       int ret;
+
+       status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+       ret = SMB_VFS_STAT(conn, smb_fname);
+       if (ret != -1) {
+               *psbuf = smb_fname->st;
+       }
+
+       TALLOC_FREE(smb_fname);
+       return ret;
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+                       SMB_STRUCT_STAT *psbuf)
+{
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+       int ret;
+
+       status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               errno = map_errno_from_nt_status(status);
+               return -1;
+       }
+
+       ret = SMB_VFS_LSTAT(conn, smb_fname);
+       if (ret != -1) {
+               *psbuf = smb_fname->st;
+       }
+
+       TALLOC_FREE(smb_fname);
+       return ret;
+}
+
index 33ced8fa54ee548b1f14635ddb46a724ea75113e..cd550a4f4849d3e58b51ac62022a0f0979591f89 100644 (file)
@@ -317,11 +317,6 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
        if (fsp == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       fsp->fsp_name = SMB_STRDUP(argv[1]);
-       if (fsp->fsp_name == NULL) {
-               SAFE_FREE(fsp);
-               return NT_STATUS_NO_MEMORY;
-       }
        fsp->fh = SMB_MALLOC_P(struct fd_handle);
        if (fsp->fh == NULL) {
                SAFE_FREE(fsp->fsp_name);
@@ -333,18 +328,18 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
        status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
                                                  &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
-               SAFE_FREE(fsp->fsp_name);
                SAFE_FREE(fsp);
                return status;
        }
 
+       fsp->fsp_name = smb_fname;
+
        fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode);
-       TALLOC_FREE(smb_fname);
        if (fsp->fh->fd == -1) {
                printf("open: error=%d (%s)\n", errno, strerror(errno));
                SAFE_FREE(fsp->fh);
-               SAFE_FREE(fsp->fsp_name);
                SAFE_FREE(fsp);
+               TALLOC_FREE(smb_fname);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -415,7 +410,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
        else
                printf("close: ok\n");
 
-       SAFE_FREE(vfs->files[fd]->fsp_name);
+       TALLOC_FREE(vfs->files[fd]->fsp_name);
        SAFE_FREE(vfs->files[fd]->fh);
        SAFE_FREE(vfs->files[fd]);
        vfs->files[fd] = NULL;
index 30b84c073dbb90979764ba75f87cefce370901b3..a90c2e2dfee02227c7b30bf0e619e5014f1e5b76 100644 (file)
@@ -341,9 +341,9 @@ static bool test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
        case OP_UNLOCK:
                /* unset a lock */
                for (server=0;server<NSERVERS;server++) {
-                       ret[server] = cli_unlock64(cli[server][conn], 
+                       ret[server] = NT_STATUS_IS_OK(cli_unlock64(cli[server][conn], 
                                                   fnum[server][conn][f],
-                                                  start, len);
+                                                  start, len));
                        status[server] = cli_nt_error(cli[server][conn]);
                }
                if (showall || 
index 93adcb51a6f8df75cb8d01730f36587ee1702505..5c8a2d8019ed953a7b1ca87419dfe85d54d66a06 100644 (file)
@@ -132,7 +132,7 @@ static bool try_unlock(struct cli_state *c, int fstype,
 
        switch (fstype) {
        case FSTYPE_SMB:
-               return cli_unlock(c, fd, start, len);
+               return NT_STATUS_IS_OK(cli_unlock(c, fd, start, len));
 
        case FSTYPE_NFS:
                lock.l_type = F_UNLCK;
index ab7edde85dc930dbbe08309c587f5fb62918efee..950177c3ca97a636af2f964981f49d8b67ed0422 100644 (file)
@@ -288,7 +288,7 @@ int main(int argc, char **argv)
        pdb_set_homedir(out, "\\\\torture\\home", PDB_SET);
        pdb_set_logon_script(out, "torture_script.cmd", PDB_SET);
 
-       pdb_get_account_policy(AP_PASSWORD_HISTORY, &history);
+       pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &history);
        if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) {
                buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN);
        } else {
@@ -311,8 +311,8 @@ int main(int argc, char **argv)
        }
        pdb_set_pw_history(out, buf, history, PDB_SET);
 
-       pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire);
-       pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age);
+       pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire);
+       pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &min_age);
        pdb_set_pass_last_set_time(out, time(NULL), PDB_SET);
        
        if (expire == 0 || expire == (uint32)-1) {
index aa7e83bcc83c3387b18d8b2d797e287863bfe3ba..f9192b12b7645ec4dea1b1de85d4f3fca92a9803 100644 (file)
@@ -492,7 +492,7 @@ static bool rw_torture(struct cli_state *c)
                        correct = False;
                }
 
-               if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
+               if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
                        printf("unlock failed (%s)\n", cli_errstr(c));
                        correct = False;
                }
@@ -1429,12 +1429,12 @@ static bool run_locktest2(int dummy)
                printf("lock at 100 failed (%s)\n", cli_errstr(cli));
        }
        cli_setpid(cli, 2);
-       if (cli_unlock(cli, fnum1, 100, 4)) {
+       if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
                printf("unlock at 100 succeeded! This is a locking bug\n");
                correct = False;
        }
 
-       if (cli_unlock(cli, fnum1, 0, 4)) {
+       if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
                printf("unlock1 succeeded! This is a locking bug\n");
                correct = False;
        } else {
@@ -1443,7 +1443,7 @@ static bool run_locktest2(int dummy)
                                 NT_STATUS_RANGE_NOT_LOCKED)) return False;
        }
 
-       if (cli_unlock(cli, fnum1, 0, 8)) {
+       if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
                printf("unlock2 succeeded! This is a locking bug\n");
                correct = False;
        } else {
@@ -1565,14 +1565,14 @@ static bool run_locktest3(int dummy)
        for (offset=i=0;i<torture_numops;i++) {
                NEXT_OFFSET;
 
-               if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
+               if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
                        printf("unlock1 %d failed (%s)\n", 
                               i,
                               cli_errstr(cli1));
                        return False;
                }
 
-               if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
+               if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
                        printf("unlock2 %d failed (%s)\n", 
                               i,
                               cli_errstr(cli1));
@@ -1703,7 +1703,7 @@ static bool run_locktest4(int dummy)
 
        ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
              cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
-             cli_unlock(cli1, fnum1, 110, 6);
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
        EXPECTED(ret, False);
        printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
 
@@ -1721,30 +1721,30 @@ static bool run_locktest4(int dummy)
 
        ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
              cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
-             cli_unlock(cli1, fnum1, 140, 4) &&
-             cli_unlock(cli1, fnum1, 140, 4);
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
        EXPECTED(ret, True);
        printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
 
 
        ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
              cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
-             cli_unlock(cli1, fnum1, 150, 4) &&
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
              (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
              !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
-             cli_unlock(cli1, fnum1, 150, 4);
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
        EXPECTED(ret, True);
        printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
 
        ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
-             cli_unlock(cli1, fnum1, 160, 4) &&
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
              (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
              (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
        EXPECTED(ret, True);
        printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
 
        ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
-             cli_unlock(cli1, fnum1, 170, 4) &&
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
              (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
              (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
        EXPECTED(ret, True);
@@ -1752,7 +1752,7 @@ static bool run_locktest4(int dummy)
 
        ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
              cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
-             cli_unlock(cli1, fnum1, 190, 4) &&
+             NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
              !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
              (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
        EXPECTED(ret, True);
@@ -1861,7 +1861,7 @@ static bool run_locktest5(int dummy)
        /* Unlock the first process lock, then check this was the WRITE lock that was
                removed. */
 
-       ret = cli_unlock(cli1, fnum1, 0, 4) &&
+       ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
                        cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
 
        EXPECTED(ret, True);
@@ -1872,15 +1872,15 @@ static bool run_locktest5(int dummy)
 
        /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
 
-       ret = cli_unlock(cli1, fnum1, 1, 1) &&
-                 cli_unlock(cli1, fnum1, 0, 4) &&
-                 cli_unlock(cli1, fnum1, 0, 4);
+       ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
+                 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
+                 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
 
        EXPECTED(ret, True);
        printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
 
        /* Ensure the next unlock fails. */
-       ret = cli_unlock(cli1, fnum1, 0, 4);
+       ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
        EXPECTED(ret, False);
        printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
 
@@ -4295,6 +4295,18 @@ static bool run_simple_posix_open_test(int dummy)
                goto out;
        }
 
+       /* Do a POSIX lock/unlock. */
+       if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
+               printf("POSIX lock failed %s\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Punch a hole in the locked area. */
+       if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
+               printf("POSIX unlock failed %s\n", cli_errstr(cli1));
+               goto out;
+       }
+
        cli_close(cli1, fnum1);
 
        /* Open the symlink for read - this should fail. A POSIX
@@ -5749,17 +5761,45 @@ static bool run_local_substitute(int dummy)
        return ok;
 }
 
+static bool run_local_base64(int dummy)
+{
+       int i;
+       bool ret = true;
+
+       for (i=1; i<2000; i++) {
+               DATA_BLOB blob1, blob2;
+               char *b64;
+
+               blob1.data = talloc_array(talloc_tos(), uint8_t, i);
+               blob1.length = i;
+               generate_random_buffer(blob1.data, blob1.length);
+
+               b64 = base64_encode_data_blob(talloc_tos(), blob1);
+               if (b64 == NULL) {
+                       d_fprintf(stderr, "base64_encode_data_blob failed "
+                                 "for %d bytes\n", i);
+                       ret = false;
+               }
+               blob2 = base64_decode_data_blob(b64);
+               TALLOC_FREE(b64);
+
+               if (data_blob_cmp(&blob1, &blob2)) {
+                       d_fprintf(stderr, "data_blob_cmp failed for %d "
+                                 "bytes\n", i);
+                       ret = false;
+               }
+               TALLOC_FREE(blob1.data);
+               data_blob_free(&blob2);
+       }
+       return ret;
+}
+
 static bool run_local_gencache(int dummy)
 {
        char *val;
        time_t tm;
        DATA_BLOB blob;
 
-       if (!gencache_init()) {
-               d_printf("%s: gencache_init() failed\n", __location__);
-               return False;
-       }
-
        if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
                d_printf("%s: gencache_set() failed\n", __location__);
                return False;
@@ -5796,15 +5836,13 @@ static bool run_local_gencache(int dummy)
        }
 
        blob = data_blob_string_const_null("bar");
-       tm = time(NULL);
+       tm = time(NULL) + 60;
 
        if (!gencache_set_data_blob("foo", &blob, tm)) {
                d_printf("%s: gencache_set_data_blob() failed\n", __location__);
                return False;
        }
 
-       data_blob_free(&blob);
-
        if (!gencache_get_data_blob("foo", &blob, NULL)) {
                d_printf("%s: gencache_get_data_blob() failed\n", __location__);
                return False;
@@ -5835,17 +5873,6 @@ static bool run_local_gencache(int dummy)
                return False;
        }
 
-       if (!gencache_shutdown()) {
-               d_printf("%s: gencache_shutdown() failed\n", __location__);
-               return False;
-       }
-
-       if (gencache_shutdown()) {
-               d_printf("%s: second gencache_shutdown() succeeded\n",
-                        __location__);
-               return False;
-       }
-
        return True;
 }
 
@@ -6487,6 +6514,7 @@ static struct {
        { "STREAMERROR", run_streamerror },
        { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
        { "LOCAL-GENCACHE", run_local_gencache, 0},
+       { "LOCAL-BASE64", run_local_base64, 0},
        { "LOCAL-RBTREE", run_local_rbtree, 0},
        { "LOCAL-MEMCACHE", run_local_memcache, 0},
        { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
index 0e3946f5a518dfafe2eae93e58d3c4879d954f30..f8bfab3e99d8ec8f87fe0c50b82bd0c21f444f47 100644 (file)
@@ -625,6 +625,7 @@ static struct functable net_func[] = {
  int main(int argc, const char **argv)
 {
        int opt,i;
+       char *p;
        int rc = 0;
        int argc_new = 0;
        const char ** argv_new;
@@ -635,10 +636,12 @@ static struct functable net_func[] = {
        struct poptOption long_options[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
                {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
+               {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
                {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
                {"port",        'p', POPT_ARG_INT,    &c->opt_port},
                {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
                {"server",      'S', POPT_ARG_STRING, &c->opt_host},
+               {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
                {"container",   'c', POPT_ARG_STRING, &c->opt_container},
                {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
                {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
@@ -649,13 +652,15 @@ static struct functable net_func[] = {
                {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
                {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
                {"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
+               {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
+               {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
                {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
                {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
                {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
                /* Options for 'net groupmap set' */
                {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
                {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
-               {"ntname",        0, POPT_ARG_STRING, &c->opt_newntname},
+               {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
                {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
                /* Options for 'net rpc share migrate' */
                {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
@@ -670,7 +675,6 @@ static struct functable net_func[] = {
                {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
 
                POPT_COMMON_SAMBA
-               POPT_COMMON_CREDENTIALS
                { 0, 0, 0, 0}
        };
 
@@ -684,13 +688,6 @@ static struct functable net_func[] = {
        dbf = x_stderr;
        c->private_data = net_func;
 
-       c->auth_info = user_auth_info_init(frame);
-       if (c->auth_info == NULL) {
-               d_fprintf(stderr, "\nOut of memory!\n");
-               exit(1);
-       }
-       popt_common_set_auth_info(c->auth_info);
-
        pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
                            POPT_CONTEXT_KEEP_FIRST);
 
@@ -698,7 +695,9 @@ static struct functable net_func[] = {
                switch (opt) {
                case 'h':
                        c->display_usage = true;
-                       set_cmdline_auth_info_password(c->auth_info, "");
+                       break;
+               case 'e':
+                       c->smb_encrypt = true;
                        break;
                case 'I':
                        if (!interpret_string_addr(&c->opt_dest_ip,
@@ -708,6 +707,15 @@ static struct functable net_func[] = {
                                c->opt_have_ip = true;
                        }
                        break;
+               case 'U':
+                       c->opt_user_specified = true;
+                       c->opt_user_name = SMB_STRDUP(c->opt_user_name);
+                       p = strchr(c->opt_user_name,'%');
+                       if (p) {
+                               *p = 0;
+                               c->opt_password = p+1;
+                       }
+                       break;
                default:
                        d_fprintf(stderr, "\nInvalid option %s: %s\n",
                                 poptBadOption(pc, 0), poptStrerror(opt));
@@ -741,6 +749,10 @@ static struct functable net_func[] = {
                set_global_myname(c->opt_requester_name);
        }
 
+       if (!c->opt_user_name && getenv("LOGNAME")) {
+               c->opt_user_name = getenv("LOGNAME");
+       }
+
        if (!c->opt_workgroup) {
                c->opt_workgroup = smb_xstrdup(lp_workgroup());
        }
@@ -758,10 +770,23 @@ static struct functable net_func[] = {
           that it won't assert becouse we are not root */
        sec_init();
 
+       if (c->opt_machine_pass) {
+               /* it is very useful to be able to make ads queries as the
+                  machine account for testing purposes and for domain leave */
+
+               net_use_krb_machine_account(c);
+       }
+
+       if (!c->opt_password) {
+               c->opt_password = getenv("PASSWD");
+       }
+
        rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
 
        DEBUG(2,("return code = %d\n", rc));
 
+       gencache_stabilize();
+
        libnetapi_free(c->netapi_ctx);
 
        poptFreeContext(pc);
index f604d96361a66972a667149a7844e4a8cb8fb5ae..d88f962d41e6d8b1c5e7d6d325695c149e455cd4 100644 (file)
 struct net_context {
        const char *opt_requester_name;
        const char *opt_host;
-       int opt_long_list_entries;
+       const char *opt_password;
+       const char *opt_user_name;
+       bool opt_user_specified;
        const char *opt_workgroup;
+       int opt_long_list_entries;
        int opt_reboot;
        int opt_force;
        int opt_stdin;
@@ -42,6 +45,7 @@ struct net_context {
        int opt_timeout;
        int opt_request_timeout;
        const char *opt_target_workgroup;
+       int opt_machine_pass;
        int opt_localgroup;
        int opt_domaingroup;
        int do_talloc_report;
@@ -53,14 +57,15 @@ struct net_context {
        const char *opt_exclude;
        const char *opt_destination;
        int opt_testmode;
+       bool opt_kerberos;
        int opt_force_full_repl;
        int opt_single_obj_repl;
        int opt_clean_old_entries;
 
        int opt_have_ip;
        struct sockaddr_storage opt_dest_ip;
+       bool smb_encrypt;
        struct libnetapi_ctx *netapi_ctx;
-       struct user_auth_info *auth_info;
 
        bool display_usage;
        void *private_data;
index d82715eb45ec1199e324339b2b4155bce9dfd8f7..8f76c0eb094d0f5489e112008c1ac5909fc91780 100644 (file)
@@ -231,23 +231,32 @@ retry_connect:
 
        ads = ads_init(realm, c->opt_target_workgroup, c->opt_host);
 
+       if (!c->opt_user_name) {
+               c->opt_user_name = "administrator";
+       }
+
+       if (c->opt_user_specified) {
+               need_password = true;
+       }
+
 retry:
-       if (need_password) {
-               set_cmdline_auth_info_getpass(c->auth_info);
+       if (!c->opt_password && need_password && !c->opt_machine_pass) {
+               c->opt_password = net_prompt_pass(c, c->opt_user_name);
+               if (!c->opt_password) {
+                       ads_destroy(&ads);
+                       return ADS_ERROR(LDAP_NO_MEMORY);
+               }
        }
 
-       if (get_cmdline_auth_info_got_pass(c->auth_info) ||
-           !get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       if (c->opt_password) {
                use_in_memory_ccache();
                SAFE_FREE(ads->auth.password);
-               ads->auth.password = smb_xstrdup(
-                               get_cmdline_auth_info_password(c->auth_info));
+               ads->auth.password = smb_xstrdup(c->opt_password);
        }
 
        ads->auth.flags |= auth_flags;
        SAFE_FREE(ads->auth.user_name);
-       ads->auth.user_name = smb_xstrdup(
-                       get_cmdline_auth_info_username(c->auth_info));
+       ads->auth.user_name = smb_xstrdup(c->opt_user_name);
 
        /*
         * If the username is of the form "name@realm",
@@ -521,7 +530,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
                return net_ads_user_usage(c, argc, argv);
        }
 
-       escaped_user = escape_ldap_string_alloc(argv[0]);
+       escaped_user = escape_ldap_string(talloc_tos(), argv[0]);
 
        if (!escaped_user) {
                d_fprintf(stderr, "ads_user_info: failed to escape user %s\n", argv[0]);
@@ -529,12 +538,12 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
        }
 
        if (!ADS_ERR_OK(ads_startup(c, false, &ads))) {
-               SAFE_FREE(escaped_user);
+               TALLOC_FREE(escaped_user);
                return -1;
        }
 
        if (asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user) == -1) {
-               SAFE_FREE(escaped_user);
+               TALLOC_FREE(escaped_user);
                return -1;
        }
        rc = ads_search(ads, &res, searchstring, attrs);
@@ -543,7 +552,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
        if (!ADS_ERR_OK(rc)) {
                d_fprintf(stderr, "ads_search: %s\n", ads_errstr(rc));
                ads_destroy(&ads);
-               SAFE_FREE(escaped_user);
+               TALLOC_FREE(escaped_user);
                return -1;
        }
 
@@ -563,7 +572,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
 
        ads_msgfree(ads, res);
        ads_destroy(&ads);
-       SAFE_FREE(escaped_user);
+       TALLOC_FREE(escaped_user);
        return 0;
 }
 
@@ -866,7 +875,6 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
        TALLOC_CTX *ctx;
        struct libnet_UnjoinCtx *r = NULL;
        WERROR werr;
-       struct user_auth_info *ai = c->auth_info;
 
        if (c->display_usage) {
                d_printf("Usage:\n"
@@ -885,7 +893,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
                return -1;
        }
 
-       if (!get_cmdline_auth_info_use_kerberos(ai)) {
+       if (!c->opt_kerberos) {
                use_in_memory_ccache();
        }
 
@@ -895,14 +903,12 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
                return -1;
        }
 
-       set_cmdline_auth_info_getpass(ai);
-
        r->in.debug             = true;
-       r->in.use_kerberos      = get_cmdline_auth_info_use_kerberos(ai);
+       r->in.use_kerberos      = c->opt_kerberos;
        r->in.dc_name           = c->opt_host;
        r->in.domain_name       = lp_realm();
-       r->in.admin_account     = get_cmdline_auth_info_username(ai);
-       r->in.admin_password    = get_cmdline_auth_info_password(ai);
+       r->in.admin_account     = c->opt_user_name;
+       r->in.admin_password    = net_prompt_pass(c, c->opt_user_name);
        r->in.modify_config     = lp_config_backend_is_registry();
 
        /* Try to delete it, but if that fails, disable it.  The 
@@ -960,8 +966,7 @@ static NTSTATUS net_ads_join_ok(struct net_context *c)
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       set_cmdline_auth_info_use_machine_account(c->auth_info);
-       set_cmdline_auth_info_machine_account_creds(c->auth_info);
+       net_use_krb_machine_account(c);
 
        status = ads_startup(c, true, &ads);
        if (!ADS_ERR_OK(status)) {
@@ -1192,7 +1197,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
        const char *os_name = NULL;
        const char *os_version = NULL;
        bool modify_config = lp_config_backend_is_registry();
-       struct user_auth_info *ai = c->auth_info;;
 
        if (c->display_usage)
                return net_ads_join_usage(c, argc, argv);
@@ -1212,7 +1216,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
                goto fail;
        }
 
-       if (!get_cmdline_auth_info_use_kerberos(ai)) {
+       if (!c->opt_kerberos) {
                use_in_memory_ccache();
        }
 
@@ -1262,8 +1266,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
 
        /* Do the domain join here */
 
-       set_cmdline_auth_info_getpass(ai);
-
        r->in.domain_name       = domain;
        r->in.create_upn        = createupn;
        r->in.upn               = machineupn;
@@ -1271,10 +1273,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
        r->in.os_name           = os_name;
        r->in.os_version        = os_version;
        r->in.dc_name           = c->opt_host;
-       r->in.admin_account     = get_cmdline_auth_info_username(ai);
-       r->in.admin_password    = get_cmdline_auth_info_password(ai);
+       r->in.admin_account     = c->opt_user_name;
+       r->in.admin_password    = net_prompt_pass(c, c->opt_user_name);
        r->in.debug             = true;
-       r->in.use_kerberos      = get_cmdline_auth_info_use_kerberos(ai);
+       r->in.use_kerberos      = c->opt_kerberos;
        r->in.modify_config     = modify_config;
        r->in.join_flags        = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
                                  WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
@@ -1585,7 +1587,6 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
        char *prt_dn, *srv_dn, **srv_cn;
        char *srv_cn_escaped = NULL, *printername_escaped = NULL;
        LDAPMessage *res = NULL;
-       struct user_auth_info *ai = c->auth_info;
 
        if (argc < 1 || c->display_usage) {
                d_printf("Usage:\n"
@@ -1617,9 +1618,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
        nt_status = cli_full_connection(&cli, global_myname(), servername,
                                        &server_ss, 0,
                                        "IPC$", "IPC",
-                                       get_cmdline_auth_info_username(ai),
-                                       c->opt_workgroup,
-                                       get_cmdline_auth_info_password(ai),
+                                       c->opt_user_name, c->opt_workgroup,
+                                       c->opt_password ? c->opt_password : "",
                                        CLI_FULL_CONNECTION_USE_KERBEROS,
                                        Undefined, NULL);
 
@@ -1807,8 +1807,8 @@ static int net_ads_printer(struct net_context *c, int argc, const char **argv)
 static int net_ads_password(struct net_context *c, int argc, const char **argv)
 {
        ADS_STRUCT *ads;
-       const char *auth_principal;
-       const char *auth_password;
+       const char *auth_principal = c->opt_user_name;
+       const char *auth_password = c->opt_password;
        char *realm = NULL;
        char *new_password = NULL;
        char *chr, *prompt;
@@ -1823,9 +1823,10 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv)
                return 0;
        }
 
-       auth_principal = get_cmdline_auth_info_username(c->auth_info);
-       set_cmdline_auth_info_getpass(c->auth_info);
-       auth_password = get_cmdline_auth_info_password(c->auth_info);
+       if (c->opt_user_name == NULL || c->opt_password == NULL) {
+               d_fprintf(stderr, "You must supply an administrator username/password\n");
+               return -1;
+       }
 
        if (argc < 1) {
                d_fprintf(stderr, "ERROR: You must say which username to change password for\n");
@@ -1907,7 +1908,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
                return -1;
        }
 
-       set_cmdline_auth_info_use_machine_account(c->auth_info);
+       net_use_krb_machine_account(c);
 
        use_in_memory_ccache();
 
@@ -2289,7 +2290,6 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar
        TALLOC_CTX *mem_ctx = NULL;
        NTSTATUS status;
        int ret = -1;
-       struct user_auth_info *ai = c->auth_info;
 
        if (c->display_usage) {
                d_printf("Usage:\n"
@@ -2303,11 +2303,11 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar
                goto out;
        }
 
-       set_cmdline_auth_info_getpass(ai);
+       c->opt_password = net_prompt_pass(c, c->opt_user_name);
 
        status = kerberos_return_pac(mem_ctx,
-                                    get_cmdline_auth_info_username(ai),
-                                    get_cmdline_auth_info_password(ai),
+                                    c->opt_user_name,
+                                    c->opt_password,
                                     0,
                                     NULL,
                                     NULL,
@@ -2340,7 +2340,6 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char **
        TALLOC_CTX *mem_ctx = NULL;
        int ret = -1;
        NTSTATUS status;
-       struct user_auth_info *ai = c->auth_info;
 
        if (c->display_usage) {
                d_printf("Usage:\n"
@@ -2354,10 +2353,10 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char **
                goto out;
        }
 
-       set_cmdline_auth_info_getpass(ai);
+       c->opt_password = net_prompt_pass(c, c->opt_user_name);
 
-       ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai),
-                                         get_cmdline_auth_info_password(ai),
+       ret = kerberos_kinit_password_ext(c->opt_user_name,
+                                         c->opt_password,
                                          0,
                                          NULL,
                                          NULL,
index 5e7db385155b75b38d9bc7591f4a6efe523c932a..36cd12fb828badce2eb8d8edff296645ab2b8f02 100644 (file)
@@ -171,12 +171,10 @@ static int net_cache_add(struct net_context *c, int argc, const char **argv)
 
        if (gencache_set(keystr, datastr, timeout)) {
                d_printf("New cache entry stored successfully.\n");
-               gencache_shutdown();
                return 0;
        }
 
        d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n");
-       gencache_shutdown();
        return -1;
 }
 
@@ -275,7 +273,6 @@ static int net_cache_list(struct net_context *c, int argc, const char **argv)
                return 0;
        }
        gencache_iterate(print_cache_entry, NULL, pattern);
-       gencache_shutdown();
        return 0;
 }
 
@@ -297,10 +294,24 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv)
                return 0;
        }
        gencache_iterate(delete_cache_entry, NULL, pattern);
-       gencache_shutdown();
        return 0;
 }
 
+static int net_cache_stabilize(struct net_context *c, int argc,
+                              const char **argv)
+{
+       if (c->display_usage) {
+               d_printf("Usage:\n"
+                        "net cache flush\n"
+                        "    Delete all cache entries.\n");
+               return 0;
+       }
+
+       if (!gencache_stabilize()) {
+               return -1;
+       }
+       return 0;
+}
 /**
  * Entry point to 'net cache' subfunctionality
  *
@@ -366,6 +377,14 @@ int net_cache(struct net_context *c, int argc, const char **argv)
                        "net cache flush\n"
                        "  Delete all cache entries"
                },
+               {
+                       "stabilize",
+                       net_cache_stabilize,
+                       NET_TRANSPORT_LOCAL,
+                       "Move transient cache content to stable storage",
+                       "net cache stabilize\n"
+                       "  Move transient cache content to stable storage"
+               },
                {NULL, NULL, 0, NULL, NULL}
        };
 
index a13f52c519339edcfe0483061e0e273389269c8f..401079777f88b07702d65bb04580ed338b81604a 100644 (file)
@@ -368,11 +368,9 @@ int net_dom(struct net_context *c, int argc, const char **argv)
                return -1;
        }
 
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
index 5a170790c5b34e0ec40dfb544ae85d46ccade7b7..0502373aa2fe445bf0455ac3d21a26888280b8b6 100644 (file)
@@ -65,6 +65,5 @@ int net_help(struct net_context *c, int argc, const char **argv)
        }
 
        c->display_usage = true;
-       set_cmdline_auth_info_password(c->auth_info, "");
        return net_run_function(c, argc, argv, "net help", func);
 }
index 8a09147aad9c87d6ab9c4f35ec28a7ea7ec0a092..75ac032db92c8c6bf67f87201224c12ec9132f88 100644 (file)
@@ -459,6 +459,8 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
 NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
                          struct rpc_pipe_client **pp_pipe_hnd,
                          const struct ndr_syntax_id *interface);
+int net_use_krb_machine_account(struct net_context *c);
+int net_use_machine_account(struct net_context *c);
 bool net_find_server(struct net_context *c,
                        const char *domain,
                        unsigned flags,
@@ -473,6 +475,7 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
                                    const char *server,
                                    struct sockaddr_storage *pss,
                                    unsigned flags, struct cli_state **pcli);
+const char *net_prompt_pass(struct net_context *c, const char *user);
 int net_run_function(struct net_context *c, int argc, const char **argv,
                      const char *whoami, struct functable *table);
 void net_display_usage_from_functable(struct functable *table);
index 0118b4818a63f87381f0fdb1bc38cdd8acb9f623..f6f90030fe6f137d91df12c7f9e3353369c780a0 100644 (file)
@@ -25,8 +25,7 @@
 #include "../libcli/auth/libcli_auth.h"
 
 static int net_mode_share;
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
-                      const struct user_auth_info *auth_info);
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
 
 /**
  * @file net_rpc.c
@@ -123,7 +122,6 @@ int run_rpc_command(struct net_context *c,
        DOM_SID *domain_sid;
        const char *domain_name;
        int ret = -1;
-       struct user_auth_info *ai = c->auth_info;
 
        /* make use of cli_state handed over as an argument, if possible */
        if (!cli_arg) {
@@ -173,10 +171,8 @@ int run_rpc_command(struct net_context *c,
                                nt_status = cli_rpc_pipe_open_ntlmssp(
                                        cli, interface,
                                        PIPE_AUTH_LEVEL_PRIVACY,
-                                       lp_workgroup(),
-                                       get_cmdline_auth_info_username(ai),
-                                       get_cmdline_auth_info_password(ai),
-                                       &pipe_hnd);
+                                       lp_workgroup(), c->opt_user_name,
+                                       c->opt_password, &pipe_hnd);
                        } else {
                                nt_status = cli_rpc_pipe_open_noauth(
                                        cli, interface,
@@ -944,12 +940,9 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv)
        if (status != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
@@ -2763,12 +2756,9 @@ int net_rpc_group(struct net_context *c, int argc, const char **argv)
        if (status != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
@@ -3255,7 +3245,7 @@ static void copy_fn(const char *mnt, file_info *f,
 
                old_dir = local_state->cwd;
                local_state->cwd = dir;
-               if (!sync_files(local_state, new_mask, c->auth_info))
+               if (!sync_files(local_state, new_mask))
                        printf("could not handle files\n");
                local_state->cwd = old_dir;
 
@@ -3302,18 +3292,15 @@ static void copy_fn(const char *mnt, file_info *f,
  *
  * @return             Boolean result
  **/
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
-                      const struct user_auth_info *auth_info)
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
 {
        struct cli_state *targetcli;
        char *targetpath = NULL;
 
        DEBUG(3,("calling cli_list with mask: %s\n", mask));
 
-
-       if ( !cli_resolve_path(talloc_tos(), "", auth_info,
-                              cp_clistate->cli_share_src, mask, &targetcli,
-                              &targetpath ) ) {
+       if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
+                               mask, &targetcli, &targetpath ) ) {
                d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n", 
                        mask, cli_errstr(cp_clistate->cli_share_src));
                return false;
@@ -3476,7 +3463,7 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
                        goto done;
                }
 
-               if (!sync_files(&cp_clistate, mask, c->auth_info)) {
+               if (!sync_files(&cp_clistate, mask)) {
                        d_fprintf(stderr, "could not handle files for share: %s\n", info502.name);
                        nt_status = NT_STATUS_UNSUCCESSFUL;
                        goto done;
@@ -4577,12 +4564,9 @@ int net_rpc_share(struct net_context *c, int argc, const char **argv)
        if (status != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
@@ -4855,12 +4839,9 @@ int net_rpc_file(struct net_context *c, int argc, const char **argv)
        if (status != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
@@ -5550,7 +5531,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc,
                c->opt_workgroup = smb_xstrdup(domain_name);
        };
 
-       set_cmdline_auth_info_username(c->auth_info, acct_name);
+       c->opt_user_name = acct_name;
 
        /* find the domain controller */
        if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
@@ -5647,9 +5628,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc,
         * Store the password in secrets db
         */
 
-       if (!pdb_set_trusteddom_pw(domain_name,
-                                  get_cmdline_auth_info_password(c->auth_info),
-                                  domain_sid)) {
+       if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
                DEBUG(0, ("Storing password for trusted domain failed.\n"));
                cli_shutdown(cli);
                talloc_destroy(mem_ctx);
@@ -7211,12 +7190,9 @@ int net_rpc(struct net_context *c, int argc, const char **argv)
        if (status != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
index cae2491aed4d6414d016a052757249b6118949c2..ed0311317dcbacadef6703a88ff8e9b67305dcc5 100644 (file)
@@ -58,8 +58,7 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain,
        if (sec == SEC_ADS) {
                /* Connect to IPC$ using machine account's credentials. We don't use anonymous
                   connection here, as it may be denied by server's local policy. */
-               set_cmdline_auth_info_use_machine_account(c->auth_info);
-               set_cmdline_auth_info_machine_account_creds(c->auth_info);
+               net_use_machine_account(c);
 
        } else {
                /* some servers (e.g. WinNT) don't accept machine-authenticated
index bd5047c1ff057697c847a7f22568f92128fddb21..309be171ccf71fb21aae7599c78a96904bc38b89 100644 (file)
@@ -379,8 +379,8 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
        ctx->cli                = pipe_hnd;
        ctx->ops                = &libnet_samsync_keytab_ops;
        ctx->domain_name        = domain_name;
-       ctx->username           = get_cmdline_auth_info_username(c->auth_info);
-       ctx->password           = get_cmdline_auth_info_password(c->auth_info);
+       ctx->username           = c->opt_user_name;
+       ctx->password           = c->opt_password;
 
        ctx->force_full_replication = c->opt_force_full_repl ? true : false;
        ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
@@ -493,17 +493,20 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
 
        if (!dc_info.is_ad) {
                printf("DC is not running Active Directory\n");
-               return -1;
-       }
-
-       if (dc_info.is_mixed_mode) {
                ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
                                      0,
                                      rpc_vampire_keytab_internals, argc, argv);
+               return -1;
        } else {
                ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id,
                                      NET_FLAGS_SEAL,
                                      rpc_vampire_keytab_ds_internals, argc, argv);
+               if (ret != 0 && dc_info.is_mixed_mode) {
+                       printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n");
+                       ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
+                                             0,
+                                             rpc_vampire_keytab_internals, argc, argv);
+               }
        }
 
        return ret;
index dc13e91423881d6a7ccfe7822bd887bd29c822ff..3aaed1ed1814f239f87984f1c93c7da4f828e293 100644 (file)
@@ -220,12 +220,9 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv)
        if (libnetapi_init(&c->netapi_ctx) != 0) {
                return -1;
        }
-       set_cmdline_auth_info_getpass(c->auth_info);
-       libnetapi_set_username(c->netapi_ctx,
-                              get_cmdline_auth_info_username(c->auth_info));
-       libnetapi_set_password(c->netapi_ctx,
-                              get_cmdline_auth_info_password(c->auth_info));
-       if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
                libnetapi_set_use_kerberos(c->netapi_ctx);
        }
 
index 62abef000dc5757a7fc781171d9a1573d298fc51..41daa4180db28b2f3279bf2c2bbd477bdea4002a 100644 (file)
@@ -452,7 +452,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv
        const char *account_policy = NULL;
        uint32 value = 0;
        uint32 old_value = 0;
-       int field;
+       enum pdb_policy_type field;
        char *endptr;
 
         if (argc != 2 || c->display_usage) {
@@ -462,7 +462,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv
         }
 
        account_policy = argv[0];
-       field = account_policy_name_to_fieldnum(account_policy);
+       field = account_policy_name_to_typenum(account_policy);
 
        if (strequal(argv[1], "forever") || strequal(argv[1], "never")
            || strequal(argv[1], "off")) {
@@ -519,7 +519,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg
 {
        const char *account_policy = NULL;
         uint32 old_value;
-        int field;
+        enum pdb_policy_type field;
 
         if (argc != 1 || c->display_usage) {
                 d_fprintf(stderr, "usage: net sam policy show"
@@ -528,7 +528,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg
         }
 
        account_policy = argv[0];
-        field = account_policy_name_to_fieldnum(account_policy);
+        field = account_policy_name_to_typenum(account_policy);
 
         if (field == 0) {
                const char **names;
index 992a03d8137a0a5dc163de03f8c21d90baf733ad..6eacb1386c851d56748b4db8791423cf792f455e 100644 (file)
@@ -163,7 +163,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
                d_fprintf(stderr, "net usershare delete: share name %s contains "
                         "invalid characters (any of %s)\n",
                         sharename, INVALID_SHARENAME_CHARS);
-               SAFE_FREE(sharename);
+               TALLOC_FREE(sharename);
                return -1;
        }
 
@@ -172,7 +172,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
                                lp_usershare_path(),
                                sharename);
        if (!us_path) {
-               SAFE_FREE(sharename);
+               TALLOC_FREE(sharename);
                return -1;
        }
 
@@ -180,10 +180,10 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
                d_fprintf(stderr, "net usershare delete: unable to remove usershare %s. "
                        "Error was %s\n",
                         us_path, strerror(errno));
-               SAFE_FREE(sharename);
+               TALLOC_FREE(sharename);
                return -1;
        }
-       SAFE_FREE(sharename);
+       TALLOC_FREE(sharename);
        return 0;
 }
 
@@ -672,7 +672,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: maximum number of allowed usershares (%d) reached\n",
                        lp_usershare_max_shares() );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -681,7 +680,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                         "invalid characters (any of %s)\n",
                         sharename, INVALID_SHARENAME_CHARS);
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -690,7 +688,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: share name %s is already a valid system user name\n",
                        sharename );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -698,7 +695,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
        full_path = get_basepath(ctx);
        if (!full_path) {
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
        full_path_tmp = talloc_asprintf(ctx,
@@ -706,7 +702,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        full_path);
        if (!full_path_tmp) {
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -715,7 +710,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                                        sharename);
        if (!full_path) {
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -724,7 +718,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr,"net usershare add: path %s is not an absolute path.\n",
                        us_path);
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -734,7 +727,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        "this is a directory. Error was %s\n",
                        us_path, strerror(errno) );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -742,7 +734,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: path %s is not a directory.\n",
                        us_path );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -756,7 +747,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        "\tto the [global] section of the smb.conf to allow this.\n",
                        us_path );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -786,7 +776,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        d_fprintf(stderr, "net usershare add: malformed acl %s (missing ':').\n",
                                pacl );
                        TALLOC_FREE(ctx);
-                       SAFE_FREE(sharename);
                        return -1;
                }
 
@@ -802,7 +791,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                                        "(access control must be 'r', 'f', or 'd')\n",
                                        pacl );
                                TALLOC_FREE(ctx);
-                               SAFE_FREE(sharename);
                                return -1;
                }
 
@@ -810,7 +798,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        d_fprintf(stderr, "net usershare add: malformed terminating character for acl %s\n",
                                pacl );
                        TALLOC_FREE(ctx);
-                       SAFE_FREE(sharename);
                        return -1;
                }
 
@@ -818,7 +805,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                if ((name = talloc_strndup(ctx, pacl, pcolon - pacl)) == NULL) {
                        d_fprintf(stderr, "talloc_strndup failed\n");
                        TALLOC_FREE(ctx);
-                       SAFE_FREE(sharename);
                        return -1;
                }
                if (!string_to_sid(&sid, name)) {
@@ -833,7 +819,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                                        d_fprintf(stderr, "\n");
                                }
                                TALLOC_FREE(ctx);
-                               SAFE_FREE(sharename);
                                return -1;
                        }
                }
@@ -854,7 +839,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        "but the \"usershare allow guests\" parameter is not enabled "
                        "by this server.\n");
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -865,7 +849,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: cannot create tmp file %s\n",
                                full_path_tmp );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -874,7 +857,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: cannot lstat tmp file %s\n",
                                full_path_tmp );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -883,7 +865,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: cannot fstat tmp file %s\n",
                                full_path_tmp );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -891,7 +872,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n",
                                full_path_tmp );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -899,7 +879,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                d_fprintf(stderr, "net usershare add: failed to fchmod tmp file %s to 0644n",
                                full_path_tmp );
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -915,7 +894,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        (unsigned int)to_write, full_path_tmp, strerror(errno));
                unlink(full_path_tmp);
                TALLOC_FREE(ctx);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -926,7 +904,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                        sharename, strerror(errno));
                TALLOC_FREE(ctx);
                close(tmpfd);
-               SAFE_FREE(sharename);
                return -1;
        }
 
@@ -939,7 +916,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
                net_usershare_info(c, 1, my_argv);
        }
 
-       SAFE_FREE(sharename);
        TALLOC_FREE(ctx);
        return 0;
 }
@@ -998,6 +974,7 @@ static int net_usershare_list(struct net_context *c, int argc,
 
        pi.ctx = ctx;
        pi.op = US_LIST_OP;
+       pi.c = c;
 
        ret = process_share_list(info_fn, &pi);
        talloc_destroy(ctx);
index 50f3c1db01171090325f866e60d9e5ac967eb9e3..8bf9aac6f260b9a7662931813f0ea9653281fd6d 100644 (file)
@@ -96,22 +96,22 @@ NTSTATUS connect_to_service(struct net_context *c,
 {
        NTSTATUS nt_status;
        int flags = 0;
-       struct user_auth_info *ai = c->auth_info;
 
-       set_cmdline_auth_info_getpass(ai);
+       c->opt_password = net_prompt_pass(c, c->opt_user_name);
 
-       if (get_cmdline_auth_info_use_kerberos(ai)) {
-               flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
-                        CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+       if (c->opt_kerberos) {
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+       }
+
+       if (c->opt_kerberos && c->opt_password) {
+               flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
        }
 
        nt_status = cli_full_connection(cli_ctx, NULL, server_name,
                                        server_ss, c->opt_port,
                                        service_name, service_type,
-                                       get_cmdline_auth_info_username(ai),
-                                       c->opt_workgroup,
-                                       get_cmdline_auth_info_password(ai),
-                                       flags, Undefined, NULL);
+                                       c->opt_user_name, c->opt_workgroup,
+                                       c->opt_password, flags, Undefined, NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
                d_fprintf(stderr, "Could not connect to server %s\n", server_name);
 
@@ -131,10 +131,10 @@ NTSTATUS connect_to_service(struct net_context *c,
                return nt_status;
        }
 
-       if (get_cmdline_auth_info_smb_encrypt(ai)) {
+       if (c->smb_encrypt) {
                nt_status = cli_force_encryption(*cli_ctx,
-                                       get_cmdline_auth_info_username(ai),
-                                       get_cmdline_auth_info_password(ai),
+                                       c->opt_user_name,
+                                       c->opt_password,
                                        c->opt_workgroup);
 
                if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
@@ -234,12 +234,14 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
 {
        NTSTATUS nt_status;
        char *user_and_realm = NULL;
-       struct user_auth_info *ai = c->auth_info;
 
        /* FIXME: Should get existing kerberos ticket if possible. */
-       set_cmdline_auth_info_getpass(ai);
+       c->opt_password = net_prompt_pass(c, c->opt_user_name);
+       if (!c->opt_password) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
-       user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai));
+       user_and_realm = get_user_and_realm(c->opt_user_name);
        if (!user_and_realm) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -248,7 +250,7 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
                                        server_ss, c->opt_port,
                                        "IPC$", "IPC",
                                        user_and_realm, c->opt_workgroup,
-                                       get_cmdline_auth_info_password(ai),
+                                       c->opt_password,
                                        CLI_FULL_CONNECTION_USE_KERBEROS,
                                        Undefined, NULL);
 
@@ -259,10 +261,10 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
                return nt_status;
        }
 
-        if (get_cmdline_auth_info_smb_encrypt(ai)) {
+        if (c->smb_encrypt) {
                nt_status = cli_cm_force_encryption(*cli_ctx,
                                        user_and_realm,
-                                       get_cmdline_auth_info_password(ai),
+                                       c->opt_password,
                                        c->opt_workgroup,
                                         "IPC$");
                if (!NT_STATUS_IS_OK(nt_status)) {
@@ -326,6 +328,50 @@ NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
        return nt_status;
 }
 
+/****************************************************************************
+ Use the local machine account (krb) and password for this session.
+****************************************************************************/
+
+int net_use_krb_machine_account(struct net_context *c)
+{
+       char *user_name = NULL;
+
+       if (!secrets_init()) {
+               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+               exit(1);
+       }
+
+       c->opt_password = secrets_fetch_machine_password(
+                               c->opt_target_workgroup, NULL, NULL);
+       if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
+               return -1;
+       }
+       c->opt_user_name = user_name;
+       return 0;
+}
+
+/****************************************************************************
+ Use the machine account name and password for this session.
+****************************************************************************/
+
+int net_use_machine_account(struct net_context *c)
+{
+       char *user_name = NULL;
+
+       if (!secrets_init()) {
+               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+               exit(1);
+       }
+
+       c->opt_password = secrets_fetch_machine_password(
+                               c->opt_target_workgroup, NULL, NULL);
+       if (asprintf(&user_name, "%s$", global_myname()) == -1) {
+               return -1;
+       }
+       c->opt_user_name = user_name;
+       return 0;
+}
+
 bool net_find_server(struct net_context *c,
                        const char *domain,
                        unsigned flags,
@@ -489,6 +535,33 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
+const char *net_prompt_pass(struct net_context *c, const char *user)
+{
+       char *prompt = NULL;
+       const char *pass = NULL;
+
+       if (c->opt_password) {
+               return c->opt_password;
+       }
+
+       if (c->opt_machine_pass) {
+               return NULL;
+       }
+
+       if (c->opt_kerberos && !c->opt_user_specified) {
+               return NULL;
+       }
+
+       if (asprintf(&prompt, "Enter %s's password:", user) == -1) {
+               return NULL;
+       }
+
+       pass = getpass(prompt);
+       SAFE_FREE(prompt);
+
+       return pass;
+}
+
 int net_run_function(struct net_context *c, int argc, const char **argv,
                      const char *whoami, struct functable *table)
 {
index a4642994388d05dce50091928701f1d45ba9b205..dce2f05a834b51473cb0d56c7c4f7a3ce9eeae2f 100644 (file)
@@ -1109,7 +1109,7 @@ int main (int argc, char **argv)
        /* account policy operations */
        if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
                uint32 value;
-               int field = account_policy_name_to_fieldnum(account_policy);
+               enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
                if (field == 0) {
                        const char **names;
                        int count;
index d617fe1f0b5c0fa9d15ed96221a31a93a4d1e774..34eaeb2d79b32f39603288f991b32b1a05645e6f 100644 (file)
@@ -163,6 +163,8 @@ static void terminate(bool is_parent)
 
        trustdom_cache_shutdown();
 
+       gencache_stabilize();
+
 #if 0
        if (interactive) {
                TALLOC_CTX *mem_ctx = talloc_init("end_description");
index 0f40419a0ec44a599ab385ee53b949eb3cc83c07..08afb46674c48c595f4f024370a44c4672586fb9 100644 (file)
@@ -210,7 +210,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                gid_t primary_gid = (gid_t)-1;
 
                if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
-                   ads_atype_map(atype) != SID_NAME_USER) {
+                   ds_atype_map(atype) != SID_NAME_USER) {
                        DEBUG(1,("Not a user account? atype=0x%x\n", atype));
                        continue;
                }
@@ -608,7 +608,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
                goto done;
        }
 
-       if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) {
+       if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
@@ -620,12 +620,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
                GROUP_TYPE_SECURITY_ENABLED);
        if (!ldap_exp) {
                DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
-               SAFE_FREE(escaped_dn);
+               TALLOC_FREE(escaped_dn);
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       SAFE_FREE(escaped_dn);
+       TALLOC_FREE(escaped_dn);
 
        rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
        
index 92f0d60817e474725b0cfa6fcdac8e44304bbb7f..ab07c9767d5f0eb53184fa3e7c90c8ccb1e75a32 100644 (file)
@@ -179,10 +179,6 @@ int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
        if (tevent_req_is_unix_error(req, err)) {
                return -1;
        }
-       if (state->response->result != WINBINDD_OK) {
-               *err = EIO; /* EIO doesn't fit, but what would be better? */
-               return -1;
-       }
        *presponse = talloc_move(mem_ctx, &state->response);
        return 0;
 }
index b18f0ff5957472ef73b30e20c88686d0e63e3ada..9a43c6d6a22a7b37356bd28eba4cc93af9a99b19 100644 (file)
@@ -332,29 +332,29 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+       if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
                                    &account_policy_temp)) {
                return NT_STATUS_ACCESS_DENIED;
        }
        p->min_password_length = account_policy_temp;
 
-       if (!pdb_get_account_policy(AP_PASSWORD_HISTORY,
+       if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
                                    &account_policy_temp)) {
                return NT_STATUS_ACCESS_DENIED;
        }
        p->password_history_length = account_policy_temp;
 
-       if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+       if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
                                    &p->password_properties)) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
+       if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) {
                return NT_STATUS_ACCESS_DENIED;
        }
        u_expire = account_policy_temp;
 
-       if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
+       if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) {
                return NT_STATUS_ACCESS_DENIED;
        }
        u_min_age = account_policy_temp;
index c091cd7f53ac7c252973b5a9103522ced7ae9e82..f8cf7db920c411c3821384cf71529d65ccc2eff4 100644 (file)
@@ -93,6 +93,11 @@ void winbindd_lookupname(struct winbindd_cli_state *state)
                *p = 0;
                name_domain = state->request->data.name.name;
                name_user = p+1;
+       } else if ((p = strchr(state->request->data.name.name, '@')) != NULL) {
+               /* upn */
+               name_domain = p + 1;
+               *p = 0;
+               name_user = state->request->data.name.name;
        } else {
                name_domain = state->request->data.name.dom_name;
                name_user = state->request->data.name.name;
index 283eee09af4ae10a7fc078dff1e776cca2e736a4..44ae814ae913650e616934b47e95b91bc48a0fd4 100644 (file)
@@ -996,7 +996,8 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user)
                if ( assume_domain(lp_workgroup())) {
                        fstrcpy(domain, lp_workgroup());
                } else if ((p = strchr(domuser, '@')) != NULL) {
-                       fstrcpy(domain, "");
+                       fstrcpy(domain, p + 1);
+                       user[PTR_DIFF(p, domuser)] = 0;
                } else {
                        return False;
                }
index 6bad0178629f46bb749d0e8e3986d5069b2aa04d..8a0f12efd8aae39077d2ccdc51e16b70d340c91c 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "librpc/gen_ndr/ndr_krb5pac.h"
 
+extern const char *krbtgt_attrs[];
+extern const char *server_attrs[];
 extern const char *user_attrs[];
 
 union netr_Validation;
index 09bdec512d23bca9a9df7ac97d336a6b62a1ba22..f4ef36a24d87de5fa29e298260a97de70876af6d 100644 (file)
@@ -57,6 +57,7 @@ struct gensec_krb5_state {
        krb5_keyblock *keyblock;
        krb5_ticket *ticket;
        bool gssapi;
+       krb5_flags ap_req_options;
 };
 
 static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state)
@@ -88,7 +89,7 @@ static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state)
        return 0;
 }
 
-static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security, bool gssapi)
 {
        krb5_error_code ret;
        struct gensec_krb5_state *gensec_krb5_state;
@@ -114,7 +115,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
        gensec_krb5_state->keyblock = NULL;
        gensec_krb5_state->session_key = data_blob(NULL, 0);
        gensec_krb5_state->pac = data_blob(NULL, 0);
-       gensec_krb5_state->gssapi = false;
+       gensec_krb5_state->gssapi = gssapi;
 
        talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy); 
 
@@ -186,12 +187,12 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_server_start(struct gensec_security *gensec_security, bool gssapi)
 {
        NTSTATUS nt_status;
        struct gensec_krb5_state *gensec_krb5_state;
 
-       nt_status = gensec_krb5_start(gensec_security);
+       nt_status = gensec_krb5_start(gensec_security, gssapi);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -202,26 +203,23 @@ static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security
        return NT_STATUS_OK;
 }
 
-static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
 {
-       NTSTATUS nt_status = gensec_krb5_server_start(gensec_security);
+       return gensec_krb5_common_server_start(gensec_security, false);
+}
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               struct gensec_krb5_state *gensec_krb5_state;
-               gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
-               gensec_krb5_state->gssapi = true;
-       }
-       return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+{
+       return gensec_krb5_common_server_start(gensec_security, true);
 }
 
-static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi)
 {
        struct gensec_krb5_state *gensec_krb5_state;
        krb5_error_code ret;
        NTSTATUS nt_status;
        struct ccache_container *ccache_container;
        const char *hostname;
-       krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED;
 
        const char *principal;
        krb5_data in_data;
@@ -240,13 +238,26 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
                return NT_STATUS_INVALID_PARAMETER;
        }
                        
-       nt_status = gensec_krb5_start(gensec_security);
+       nt_status = gensec_krb5_start(gensec_security, gssapi);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
 
        gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
        gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START;
+       gensec_krb5_state->ap_req_options = AP_OPTS_USE_SUBKEY;
+
+       if (gensec_krb5_state->gssapi) {
+               /* The Fake GSSAPI modal emulates Samba3, which does not do mutual authentication */
+               if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) {
+                       gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+               }
+       } else {
+               /* The wrapping for KPASSWD (a user of the raw KRB5 API) should be mutually authenticated */
+               if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) {
+                       gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+               }
+       }
 
        principal = gensec_get_target_principal(gensec_security);
 
@@ -274,7 +285,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
                if (ret == 0) {
                        ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context, 
                                                &gensec_krb5_state->auth_context,
-                                               ap_req_options, 
+                                               gensec_krb5_state->ap_req_options, 
                                                target_principal,
                                                &in_data, ccache_container->ccache, 
                                                &gensec_krb5_state->enc_ticket);
@@ -284,7 +295,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
        } else {
                ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context, 
                                  &gensec_krb5_state->auth_context,
-                                 ap_req_options,
+                                 gensec_krb5_state->ap_req_options,
                                  gensec_get_target_service(gensec_security),
                                  hostname,
                                  &in_data, ccache_container->ccache, 
@@ -328,16 +339,14 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
        }
 }
 
-static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
 {
-       NTSTATUS nt_status = gensec_krb5_client_start(gensec_security);
+       return gensec_krb5_common_client_start(gensec_security, false);
+}
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               struct gensec_krb5_state *gensec_krb5_state;
-               gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
-               gensec_krb5_state->gssapi = true;
-       }
-       return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+{
+       return gensec_krb5_common_client_start(gensec_security, true);
 }
 
 /**
@@ -392,8 +401,13 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security,
                } else {
                        *out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length);
                }
-               gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
-               nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+               if (gensec_krb5_state->ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
+                       gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
+                       nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+               } else {
+                       gensec_krb5_state->state_position = GENSEC_KRB5_DONE;
+                       nt_status = NT_STATUS_OK;
+               }
                return nt_status;
        }
                
index c396662c127dd78aae6301c22eba4f979f5f8438..635d94242f6012643b8a21b153fddd82298a0402 100644 (file)
 #include "param/param.h"
 #include "auth/auth_sam.h"
 
-const char *user_attrs[] = {
-       /* required for the krb5 kdc */
-       "objectClass",
-       "sAMAccountName",
-       "userPrincipalName",
-       "servicePrincipalName",
-       "msDS-KeyVersionNumber",
-       "supplementalCredentials",
+#define KRBTGT_ATTRS \
+       /* required for the krb5 kdc */         \
+       "objectClass",                          \
+       "sAMAccountName",                       \
+       "userPrincipalName",                    \
+       "servicePrincipalName",                 \
+       "msDS-KeyVersionNumber",                \
+       "supplementalCredentials",              \
+                                               \
+       /* passwords */                         \
+       "dBCSPwd",                              \
+       "unicodePwd",                           \
+                                               \
+       "userAccountControl",                   \
+       "objectSid",                            \
+                                               \
+       "pwdLastSet",                           \
+       "accountExpires"                        
+
+const char *krbtgt_attrs[] = {
+       KRBTGT_ATTRS
+};
 
-       /* passwords */
-       "dBCSPwd", 
-       "unicodePwd",
+const char *server_attrs[] = {
+       KRBTGT_ATTRS
+};
 
-       "userAccountControl",
+const char *user_attrs[] = {
+       KRBTGT_ATTRS,
 
-       "pwdLastSet",
-       "accountExpires",
        "logonHours",
-       "objectSid",
 
        /* check 'allowed workstations' */
        "userWorkstations",
index 8a21ea55c9ad727a1a1ea79a108de0495a4456f3..b1a46c3c3127681bfe2ab135bfafd4812e8e2328 100644 (file)
@@ -189,7 +189,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                                         "(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
                                         "(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))", 
                                         ldb_binary_encode_string(mem_ctx, user),
-                                        UF_ACCOUNTDISABLE, samdb_acb2uf(acct_control));
+                                        UF_ACCOUNTDISABLE, ds_acb2uf(acct_control));
                if (ret != LDB_SUCCESS) {
                        DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n",
                                 user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
index 1930f4b6c75b2d694bbf20b91d666550a4c3caec..7c5f310aa93fa128f0b6944ab516f22c7707c432 100644 (file)
@@ -37,6 +37,7 @@ m4_include(client/config.m4)
 AC_CONFIG_FILES(lib/registry/registry.pc)
 AC_CONFIG_FILES(librpc/dcerpc.pc)
 AC_CONFIG_FILES(../librpc/ndr.pc)
+AC_CONFIG_FILES(../librpc/ndr_standard.pc)
 AC_CONFIG_FILES(../lib/torture/torture.pc)
 AC_CONFIG_FILES(auth/gensec/gensec.pc)
 AC_CONFIG_FILES(param/samba-hostconfig.pc)
index 5c20149384caf994b8aad38992a2b2caa24b7dec..3111a78e519770869a12ccd869a7315ab1f7a0b3 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "includes.h"
 #include "system/passwd.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
 #include "libcli/ldap/ldap_ndr.h"
@@ -583,7 +583,7 @@ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
                struct passwd *pwd;
                uid_t uid = rid - SIDMAP_LOCAL_USER_BASE;
                atype = ATYPE_NORMAL_ACCOUNT;
-               *rtype = samdb_atype_map(atype);
+               *rtype = ds_atype_map(atype);
 
                pwd = getpwuid(uid);
                if (pwd == NULL) {
@@ -595,7 +595,7 @@ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
                struct group *grp;
                gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE;
                atype = ATYPE_LOCAL_GROUP;
-               *rtype = samdb_atype_map(atype);
+               *rtype = ds_atype_map(atype);
                grp = getgrgid(gid);
                if (grp == NULL) {
                        *name = talloc_asprintf(mem_ctx, "gid%u", gid);
index cbae2ec24cb84e3c140f829bae216f1f738e951b..247aec703592bc6317ba9f60165fad2d12af21aa 100644 (file)
@@ -31,7 +31,7 @@
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "librpc/gen_ndr/ndr_misc.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "dsdb/common/proto.h"
 #include "libcli/ldap/ldap_ndr.h"
 #include "param/param.h"
@@ -640,7 +640,7 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
                                 struct ldb_message *msg, struct ldb_dn *domain_dn)
 {
        uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
-       uint32_t acct_flags = samdb_uf2acb(userAccountControl); 
+       uint32_t acct_flags = ds_uf2acb(userAccountControl);
        NTTIME must_change_time;
        NTTIME now;
 
@@ -902,7 +902,7 @@ int samdb_msg_add_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
 int samdb_msg_add_acct_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
                             const char *attr_name, uint32_t v)
 {
-       return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, samdb_acb2uf(v));
+       return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, ds_acb2uf(v));
 }
 
 /*
index 04386476983f7c686523ab4057fdd6aecb25a182..2a9f70fdb503eb269605680f2a064da5b263cedb 100644 (file)
@@ -26,8 +26,8 @@ PRIVATE_DEPENDENCIES = LIBLDB
 
 SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \
                sidmap.o \
-               flag_mapping.o \
-               util.o)
+               util.o) \
+               ../libds/common/flag_mapping.o
 $(eval $(call proto_header_template,$(dsdbsrcdir)/common/proto.h,$(SAMDB_COMMON_OBJ_FILES:.o=.c)))
 
 [SUBSYSTEM::SAMDB_SCHEMA]
index 8d648d6d82e1c3a1454669bf4b927d73f68f925d..f0d56ac62760526d6a42c4a4a4e8f24cff8657e6 100644 (file)
@@ -38,7 +38,7 @@
 #include "ldb_module.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 
 struct it_context {
        struct ldb_module *module;
index 4e28c8a1496b8d85846ffdcd67412caba845bda5..9ed06a91309cadf1d9ef16e09e651a18388ca247 100644 (file)
@@ -741,15 +741,15 @@ static int la_op_search_callback(struct ldb_request *req,
                        if (ret != LDB_SUCCESS) {
                                return ldb_module_done(ac->req, NULL, NULL, ret);
                        }
-                       break;
-               case LDB_RENAME:
-                       
+                       return ret;
+
+               case LDB_RENAME:        
+                       /* start the mod requests chain */
                        ret = la_do_mod_request(ac);
                        if (ret != LDB_SUCCESS) {
                                return ldb_module_done(ac->req, NULL, NULL,
                                                       ret);
-                       }
-       
+                       }       
                        return ret;
                        
                default:
@@ -759,7 +759,6 @@ static int la_op_search_callback(struct ldb_request *req,
                        return ldb_module_done(ac->req, NULL, NULL,
                                                LDB_ERR_OPERATIONS_ERROR);
                }
-               return LDB_SUCCESS;
        }
 
        talloc_free(ares);
index 44b7ef91e9f92b5aa5a3c83fdd783bcc31b87d59..c7fa636aa801e25f1cc667a96e5dbd8ae1dca3f3 100644 (file)
@@ -42,7 +42,7 @@
 #include "auth/kerberos/kerberos.h"
 #include "system/time.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "dsdb/samdb/ldb_modules/password_modules.h"
 #include "librpc/ndr/libndr.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
@@ -1026,6 +1026,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
        uint8_t zero16[16];
        bool do_newer_keys = false;
        bool do_cleartext = false;
+       int *domainFunctionality;
 
        ZERO_STRUCT(zero16);
        ZERO_STRUCT(names);
@@ -1064,10 +1065,10 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
                                               _old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
                }
        }
+       /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
+       domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
 
-       /* TODO: do the correct check for this, it maybe depends on the functional level? */
-       do_newer_keys = lp_parm_bool(ldb_get_opaque(ldb, "loadparm"),
-                                    NULL, "password_hash", "create_aes_key", false);
+       do_newer_keys = *domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008);
 
        if (io->domain->store_cleartext &&
            (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
@@ -1399,33 +1400,33 @@ static int setup_password_fields(struct setup_password_fields_io *io)
                }
 
                ret = setup_kerberos_keys(io);
-               if (ret != 0) {
+               if (ret != LDB_SUCCESS) {
                        return ret;
                }
        }
 
        ret = setup_nt_fields(io);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        ret = setup_lm_fields(io);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        ret = setup_supplemental_field(io);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        ret = setup_last_set_field(io);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        ret = setup_kvno_field(io);
-       if (ret != 0) {
+       if (ret != LDB_SUCCESS) {
                return ret;
        }
 
@@ -1648,6 +1649,7 @@ static int get_domain_data_callback(struct ldb_request *req,
                if (ret != LDB_SUCCESS) {
                        return ldb_module_done(ac->req, NULL, NULL, ret);
                }
+               break;
 
        case LDB_REPLY_REFERRAL:
                /* ignore */
index 41f4e8e7d50f0ffa3414e7d73e8bdc4ea6db1bba..53d6d0749ccab3477400759a789ee88519099784 100644 (file)
@@ -41,7 +41,7 @@
 #include "includes.h"
 #include "ldb_module.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
index 7080fb632f12172fb7528fb17ee6186acdfb15b4..59ea51dbce5d8a9e0a97fd6d4833d03ec92a62ce 100644 (file)
@@ -59,6 +59,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
        struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data);
        char **server_sasl;
        const struct dsdb_schema *schema;
+       int *val;
 
        ldb = ldb_module_get_ctx(module);
        schema = dsdb_get_schema(ldb);
@@ -77,7 +78,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
                }
        }
 
-       if (do_attribute(attrs, "supportedControl")) {
+       if (priv && do_attribute(attrs, "supportedControl")) {
                int i;
                for (i = 0; i < priv->num_controls; i++) {
                        char *control = talloc_strdup(msg, priv->controls[i]);
@@ -91,7 +92,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
                }
        }
 
-       if (do_attribute(attrs, "namingContexts")) {
+       if (priv && do_attribute(attrs, "namingContexts")) {
                int i;
                for (i = 0; i < priv->num_partitions; i++) {
                        struct ldb_dn *dn = priv->partitions[i];
@@ -201,13 +202,37 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
                }
        }
 
-       if (schema && do_attribute_explicit(attrs, "vendorVersion")) {
+       if (do_attribute_explicit(attrs, "vendorVersion")) {
                if (ldb_msg_add_fmt(msg, "vendorVersion", 
                                    "%s", SAMBA_VERSION_STRING) != 0) {
                        goto failed;
                }
        }
 
+       if (priv && do_attribute(attrs, "domainFunctionality")
+           && (val = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int))) {
+               if (ldb_msg_add_fmt(msg, "domainFunctionality", 
+                                   "%d", *val) != 0) {
+                       goto failed;
+               }
+       }
+
+       if (priv && do_attribute(attrs, "forestFunctionality")
+           && (val = talloc_get_type(ldb_get_opaque(ldb, "forestFunctionality"), int))) {
+               if (ldb_msg_add_fmt(msg, "forestFunctionality", 
+                                   "%d", *val) != 0) {
+                       goto failed;
+               }
+       }
+
+       if (priv && do_attribute(attrs, "domainControllerFunctionality")
+           && (val = talloc_get_type(ldb_get_opaque(ldb, "domainControllerFunctionality"), int))) {
+               if (ldb_msg_add_fmt(msg, "domainControllerFunctionality", 
+                                   "%d", *val) != 0) {
+                       goto failed;
+               }
+       }
+
        /* TODO: lots more dynamic attributes should be added here */
 
        return LDB_SUCCESS;
@@ -394,12 +419,17 @@ static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
 
 static int rootdse_init(struct ldb_module *module)
 {
+       int ret;
        struct ldb_context *ldb;
+       struct ldb_result *res;
        struct private_data *data;
+       const char *attrs[] = { "msDS-Behavior-Version", NULL };
+       const char *ds_attrs[] = { "dsServiceName", NULL };
+       TALLOC_CTX *mem_ctx;
 
        ldb = ldb_module_get_ctx(module);
 
-       data = talloc(module, struct private_data);
+       data = talloc_zero(module, struct private_data);
        if (data == NULL) {
                return -1;
        }
@@ -412,7 +442,107 @@ static int rootdse_init(struct ldb_module *module)
 
        ldb_set_default_dns(ldb);
 
-       return ldb_next_init(module);
+       ret = ldb_next_init(module);
+
+       if (ret) {
+               return ret;
+       }
+
+       mem_ctx = talloc_new(data);
+       if (!mem_ctx) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       /* Now that the partitions are set up, do a search for:
+          - domainControllerFunctionality
+          - domainFunctionality
+          - forestFunctionality
+
+          Then stuff these values into an opaque
+       */
+       ret = ldb_search(ldb, mem_ctx, &res,
+                        ldb_get_default_basedn(ldb),
+                        LDB_SCOPE_BASE, attrs, NULL);
+       if (ret == LDB_SUCCESS && res->count == 1) {
+               int domain_behaviour_version
+                       = ldb_msg_find_attr_as_int(res->msgs[0], 
+                                                  "msDS-Behavior-Version", -1);
+               if (domain_behaviour_version != -1) {
+                       int *val = talloc(ldb, int);
+                       if (!val) {
+                               ldb_oom(ldb);
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       *val = domain_behaviour_version;
+                       ret = ldb_set_opaque(ldb, "domainFunctionality", val);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+               }
+       }
+
+       ret = ldb_search(ldb, mem_ctx, &res,
+                        samdb_partitions_dn(ldb, mem_ctx),
+                        LDB_SCOPE_BASE, attrs, NULL);
+       if (ret == LDB_SUCCESS && res->count == 1) {
+               int forest_behaviour_version
+                       = ldb_msg_find_attr_as_int(res->msgs[0], 
+                                                  "msDS-Behavior-Version", -1);
+               if (forest_behaviour_version != -1) {
+                       int *val = talloc(ldb, int);
+                       if (!val) {
+                               ldb_oom(ldb);
+                               talloc_free(mem_ctx);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       *val = forest_behaviour_version;
+                       ret = ldb_set_opaque(ldb, "forestFunctionality", val);
+                       if (ret != LDB_SUCCESS) {
+                               talloc_free(mem_ctx);
+                               return ret;
+                       }
+               }
+       }
+
+       ret = ldb_search(ldb, mem_ctx, &res,
+                        ldb_dn_new(mem_ctx, ldb, ""),
+                        LDB_SCOPE_BASE, ds_attrs, NULL);
+       if (ret == LDB_SUCCESS && res->count == 1) {
+               struct ldb_dn *ds_dn
+                       = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0], 
+                                                 "dsServiceName");
+               if (ds_dn) {
+                       ret = ldb_search(ldb, mem_ctx, &res, ds_dn, 
+                                        LDB_SCOPE_BASE, attrs, NULL);
+                       if (ret == LDB_SUCCESS && res->count == 1) {
+                               int domain_controller_behaviour_version
+                                       = ldb_msg_find_attr_as_int(res->msgs[0], 
+                                                                  "msDS-Behavior-Version", -1);
+                               if (domain_controller_behaviour_version != -1) {
+                                       int *val = talloc(ldb, int);
+                                       if (!val) {
+                                               ldb_oom(ldb);
+                                               talloc_free(mem_ctx);
+                                       return LDB_ERR_OPERATIONS_ERROR;
+                                       }
+                                       *val = domain_controller_behaviour_version;
+                                       ret = ldb_set_opaque(ldb, 
+                                                            "domainControllerFunctionality", val);
+                                       if (ret != LDB_SUCCESS) {
+                                               talloc_free(mem_ctx);
+                                               return ret;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       talloc_free(mem_ctx);
+       
+       return LDB_SUCCESS;
 }
 
 static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
index 8e21e38139b87a1b22398d47997740a97facd047..544249cbe39990db5c09e728bd131b8bb7b14150 100644 (file)
@@ -572,7 +572,7 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac)
                                                "userAccountControl invalid");
                        return LDB_ERR_UNWILLING_TO_PERFORM;
                } else {
-                       account_type = samdb_uf2atype(uac);
+                       account_type = ds_uf2atype(uac);
                        ret = samdb_msg_add_uint(ldb,
                                                 ac->msg, ac->msg,
                                                 "sAMAccountType",
@@ -590,7 +590,7 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac)
                                                "groupType invalid");
                        return LDB_ERR_UNWILLING_TO_PERFORM;
                } else {
-                       account_type = samdb_gtype2atype(group_type);
+                       account_type = ds_gtype2atype(group_type);
                        ret = samdb_msg_add_uint(ldb,
                                                 ac->msg, ac->msg,
                                                 "sAMAccountType",
@@ -1280,7 +1280,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
                req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
 
                group_type = strtoul((const char *)el->values[0].data, NULL, 0);
-               account_type =  samdb_gtype2atype(group_type);
+               account_type =  ds_gtype2atype(group_type);
                ret = samdb_msg_add_uint(ldb, msg, msg,
                                         "sAMAccountType",
                                         account_type);
@@ -1296,7 +1296,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
                req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
 
                user_account_control = strtoul((const char *)el->values[0].data, NULL, 0);
-               account_type = samdb_uf2atype(user_account_control);
+               account_type = ds_uf2atype(user_account_control);
                ret = samdb_msg_add_uint(ldb, msg, msg,
                                         "sAMAccountType",
                                         account_type);
index 851187380b79f252f1bb6a48079c80f3a5e1d877..08e6e0d985781a1a29d5b817d68252751228176b 100644 (file)
@@ -36,7 +36,7 @@
 #include "ldb_wrap.h"
 #include "../lib/util/util_ldb.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "param/param.h"
 #include "lib/events/events.h"
 #include "auth/credentials/credentials.h"
index 49dc14d74c8c207e295429e27c36f7478cc17e4c..1493345b9d915c78d97cdac3e5d733415e6a568f 100644 (file)
@@ -38,7 +38,7 @@ struct tevent_context;
 #include "dsdb/schema/schema.h"
 #include "dsdb/samdb/samdb_proto.h"
 #include "dsdb/common/proto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 
 #define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2"
 struct dsdb_control_current_partition {
index 3702ab9281291836d18a78fa8bf31b6643edebd5..69b5bb1d6e9cfc7f030d48f63a3b3290276f7ce0 100644 (file)
@@ -493,10 +493,10 @@ do_authenticate (krb5_context context,
        goto out;
     }
 
-    ret = _kdc_check_flags (context, config,
-                           client_entry, client_name,
-                           server_entry, server_name,
-                           TRUE);
+    ret = kdc_check_flags (context, config,
+                          client_entry, client_name,
+                          server_entry, server_name,
+                          TRUE);
     if (ret) {
        make_error_reply (hdr, KAPWEXPIRED, reply);
        goto out;
@@ -790,10 +790,10 @@ do_getticket (krb5_context context,
        goto out;
     }
 
-    ret = _kdc_check_flags (context, config,
-                           client_entry, client_name,
-                           server_entry, server_name,
-                           FALSE);
+    ret = kdc_check_flags (context, config,
+                          client_entry, client_name,
+                          server_entry, server_name,
+                          FALSE);
     if (ret) {
        make_error_reply (hdr, KAPWEXPIRED, reply);
        goto out;
index e364dcc1d1f5dba8dc6c1a67d00aefdb38e873e3..43d54bf702540bf24178fb53c4bc169d160648bf 100644 (file)
@@ -678,6 +678,12 @@ kdc_check_flags(krb5_context context,
        hdb_entry *client = &client_ex->entry;
 
        /* check client */
+       if (client->flags.locked_out) {
+           kdc_log(context, config, 0,
+                   "Client (%s) is locked out", client_name);
+           return KRB5KDC_ERR_POLICY;
+       }
+
        if (client->flags.invalid) {
            kdc_log(context, config, 0,
                    "Client (%s) has invalid bit set", client_name);
@@ -727,6 +733,11 @@ kdc_check_flags(krb5_context context,
     if (server_ex != NULL) {
        hdb_entry *server = &server_ex->entry;
 
+       if (server->flags.locked_out) {
+           kdc_log(context, config, 0,
+                   "Client server locked out -- %s", server_name);
+           return KRB5KDC_ERR_POLICY;
+       }
        if (server->flags.invalid) {
            kdc_log(context, config, 0,
                    "Server has invalid flag set -- %s", server_name);
@@ -883,6 +894,7 @@ _kdc_as_rep(krb5_context context,
     AS_REP rep;
     KDCOptions f = b->kdc_options;
     hdb_entry_ex *client = NULL, *server = NULL;
+    HDB *clientdb;
     krb5_enctype cetype, setype, sessionetype;
     krb5_data e_data;
     EncTicketPart et;
@@ -966,7 +978,7 @@ _kdc_as_rep(krb5_context context,
      */
 
     ret = _kdc_db_fetch(context, config, client_princ,
-                       HDB_F_GET_CLIENT | flags, NULL, &client);
+                       HDB_F_GET_CLIENT | flags, &clientdb, &client);
     if(ret){
        kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
                krb5_get_err_text(context, ret));
@@ -1114,8 +1126,8 @@ _kdc_as_rep(krb5_context context,
                            "No client key matching pa-data (%s) -- %s",
                            estr, client_name);
                free(estr);
-               
                free_EncryptedData(&enc_data);
+
                continue;
            }
 
@@ -1159,6 +1171,10 @@ _kdc_as_rep(krb5_context context,
                e_text = "Failed to decrypt PA-DATA";
 
                free_EncryptedData(&enc_data);
+
+               if (clientdb->hdb_auth_status)
+                   (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD);
+
                ret = KRB5KDC_ERR_PREAUTH_FAILED;
                continue;
            }
@@ -1323,6 +1339,10 @@ _kdc_as_rep(krb5_context context,
        goto out;
     }
 
+    if (clientdb->hdb_auth_status)
+       (clientdb->hdb_auth_status)(context, clientdb, client, 
+                                   HDB_AUTH_SUCCESS);
+
     /*
      * Verify flags after the user been required to prove its identity
      * with in a preauth mech.
index 59104da3d60ec74657e332a91b86872b5fba107a..635eb27e75aa6cf8e14731c6d921f751a98f7360 100644 (file)
@@ -492,6 +492,7 @@ check_tgs_flags(krb5_context context,
 static krb5_error_code
 check_constrained_delegation(krb5_context context,
                             krb5_kdc_configuration *config,
+                            HDB *clientdb,
                             hdb_entry_ex *client,
                             krb5_const_principal server)
 {
@@ -499,21 +500,32 @@ check_constrained_delegation(krb5_context context,
     krb5_error_code ret;
     int i;
 
-    ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
-    if (ret) {
-       krb5_clear_error_message(context);
-       return ret;
-    }
+    /* if client delegates to itself, that ok */
+    if (krb5_principal_compare(context, client->entry.principal, server) == TRUE)
+       return 0;
 
-    if (acl) {
-       for (i = 0; i < acl->len; i++) {
-           if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
-               return 0;
+    if (clientdb->hdb_check_constrained_delegation) {
+       ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, server);
+       if (ret == 0)
+           return 0;
+    } else {
+       ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
+       if (ret) {
+           krb5_clear_error_message(context);
+           return ret;
+       }
+       
+       if (acl) {
+           for (i = 0; i < acl->len; i++) {
+               if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
+                   return 0;
+           }
        }
+       ret = KRB5KDC_ERR_BADOPTION;
     }
     kdc_log(context, config, 0,
            "Bad request for constrained delegation");
-    return KRB5KDC_ERR_BADOPTION;
+    return ret;
 }
 
 /*
@@ -793,17 +805,34 @@ tgs_make_reply(krb5_context context,
     et.flags.hw_authent  = tgt->flags.hw_authent;
     et.flags.anonymous   = tgt->flags.anonymous;
     et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
+
+    if(rspac->length) {
+       /*
+        * No not need to filter out the any PAC from the
+        * auth_data since it's signed by the KDC.
+        */
+       ret = _kdc_tkt_add_if_relevant_ad(context, &et,
+                                         KRB5_AUTHDATA_WIN2K_PAC, rspac);
+       if (ret)
+           goto out;
+    }
        
     if (auth_data) {
-       /* XXX Check enc-authorization-data */
-       et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+       unsigned int i = 0;
+
+       /* XXX check authdata */
        if (et.authorization_data == NULL) {
            ret = ENOMEM;
+           krb5_set_error_message(context, ret, "malloc: out of memory");
            goto out;
        }
-       ret = copy_AuthorizationData(auth_data, et.authorization_data);
-       if (ret)
-           goto out;
+       for(i = 0; i < auth_data->len ; i++) {
+           ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
+           if (ret) {
+               krb5_set_error_message(context, ret, "malloc: out of memory");
+               goto out;
+           }
+       }
 
        /* Filter out type KRB5SignedPath */
        ret = find_KRB5SignedPath(context, et.authorization_data, NULL);
@@ -820,18 +849,6 @@ tgs_make_reply(krb5_context context,
        }
     }
 
-    if(rspac->length) {
-       /*
-        * No not need to filter out the any PAC from the
-        * auth_data since it's signed by the KDC.
-        */
-       ret = _kdc_tkt_add_if_relevant_ad(context, &et,
-                                         KRB5_AUTHDATA_WIN2K_PAC,
-                                         rspac);
-       if (ret)
-           goto out;
-    }
-
     ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key);
     if (ret)
        goto out;
@@ -1369,6 +1386,7 @@ tgs_build_reply(krb5_context context,
     krb5_principal client_principal = NULL;
     char *spn = NULL, *cpn = NULL;
     hdb_entry_ex *server = NULL, *client = NULL;
+    HDB *clientdb;
     krb5_realm ref_realm = NULL;
     EncTicketPart *tgt = &ticket->ticket;
     krb5_principals spp = NULL;
@@ -1531,7 +1549,7 @@ server_lookup:
     }
 
     ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
-                       NULL, &client);
+                       &clientdb, &client);
     if(ret) {
        const char *krbtgt_realm;
 
@@ -1792,7 +1810,7 @@ server_lookup:
        if (ret) {
            kdc_log(context, config, 0,
                    "failed to decrypt ticket for "
-                   "constrained delegation from %s to %s ", spn, cpn);
+                   "constrained delegation from %s to %s ", cpn, spn);
            goto out;
        }
 
@@ -1800,16 +1818,17 @@ server_lookup:
        if (adtkt.flags.forwardable == 0) {
            kdc_log(context, config, 0,
                    "Missing forwardable flag on ticket for "
-                   "constrained delegation from %s to %s ", spn, cpn);
+                   "constrained delegation from %s to %s ", cpn, spn);
            ret = KRB5KDC_ERR_BADOPTION;
            goto out;
        }
 
-       ret = check_constrained_delegation(context, config, client, sp);
+       ret = check_constrained_delegation(context, config, clientdb, 
+                                          client, sp);
        if (ret) {
            kdc_log(context, config, 0,
                    "constrained delegation from %s to %s not allowed",
-                   spn, cpn);
+                   cpn, spn);
            goto out;
        }
 
index 9fe2bb8b46e182bc7ee2fbb18d2b2065e8ce000e..91141808f54426dde8c960763e6e4af23384a346 100644 (file)
 #endif
 
 #ifndef GSSAPI_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
 #define GSSAPI_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#define GSSAPI_DEPRECATED __declspec(deprecated)
+#else
+#define GSSAPI_DEPRECATED
+#endif
 #endif
 
 /*
@@ -768,42 +774,6 @@ gss_pseudo_random
         gss_buffer_t prf_out
        );
 
-/*
- * AEAD support
- */
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_wrap_iov(OM_uint32 * /* minor_status */,
-            gss_ctx_id_t /* context_handle */,
-            int /* conf_req_flag */,
-            gss_qop_t /* qop_req */,
-            int * /* conf_state */,
-            gss_iov_buffer_desc * /*iov */,
-            int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_unwrap_iov(OM_uint32 * /* minor_status */,
-              gss_ctx_id_t /* context_handle */,
-              int * /* conf_state */,
-              gss_qop_t * /* qop_state */,
-              gss_iov_buffer_desc * /* iov */,
-              int /* iov_count */);
-    
-OM_uint32  GSSAPI_LIB_FUNCTION
-gss_wrap_iov_length(OM_uint32 * /* minor_status */,
-                   gss_ctx_id_t /* context_handle */,
-                   int /* conf_req_flag */,
-                   gss_qop_t /* qop_req */,
-                   int * /* conf_state */,
-                   gss_iov_buffer_desc * /* iov */,
-                   int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_release_iov_buffer(OM_uint32 * /* minor_status */,
-                      gss_iov_buffer_desc * /* iov */,
-                      int /* iov_count */);
-
-
 OM_uint32
 gss_store_cred(OM_uint32         * /* minor_status */,
               gss_cred_id_t     /* input_cred_handle */,
@@ -899,6 +869,31 @@ gss_decapsulate_token(gss_buffer_t /* input_token */,
 
 
 
+/*
+ * AEAD support
+ */
+
+/*
+ * GSS_IOV
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+            gss_iov_buffer_desc *, int);
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *,
+              gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+                   gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
+
+
 #ifdef __cplusplus
 }
 #endif
index f5181cc311b877cd50ed9a666bcda8db0d6b414c..a6f0165e7247c3863dd3934dfef247a75b938b10 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 krb5_error_code
 _gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
 {
index e0944852a7ea1749441b85c2c5d72a1ce6537914..8d998ed0988f3ec3b5d033ccb761f0b006dcb913 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
 krb5_keytab _gsskrb5_keytab;
 
@@ -519,10 +517,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
            }
 
            /*
-            * Samba style get some flags (but not DCE-STYLE)
+            * Samba style get some flags (but not DCE-STYLE), use
+            * ap_options to guess the mutual flag.
             */
-           ctx->flags =
-               GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+           ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+           if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
+               ctx->flags |= GSS_C_MUTUAL_FLAG;
         }
     }
 
index bfab5667beb5cd6403b9a5cf39f5a3dfaac9b549..4f6f38e6743d8edba818a661d25c7d6affeea457 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
                          krb5_context context,
index aa96a45e451966da2d58690c7c1690adb9a44640..adc8a09fa44502d85455eb7edc31586a7a1459f0 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_add_cred (
      OM_uint32           *minor_status,
      const gss_cred_id_t input_cred_handle,
index 7dab7877d7f8aaa99222e0c010aff46be33aa2bf..38a5ac2dbe5200904eb3cb5ad35f3e0fcb4913ab 100644 (file)
 
 #include <roken.h>
 
-static OM_uint32
-iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count)
-{
-    unsigned int i;
-    
-    for (i = 0; i < iov_count; i++) {
-       if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){
-           void *ptr = malloc(iov[i].buffer.length);
-           if (ptr == NULL)
-               abort();
-           if (iov[i].buffer.value)
-               memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length);
-           iov[i].buffer.value = ptr;
-           iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
-       }
-    }
-    return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-iov_map(OM_uint32 *minor_status,
-       const gss_iov_buffer_desc *iov,
-       int iov_count,
-       krb5_crypto_iov *data)
-{
-    unsigned int i;
-
-    for (i = 0; i < iov_count; i++) {
-       switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
-       case GSS_IOV_BUFFER_TYPE_EMPTY:
-           data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
-           break;
-       case GSS_IOV_BUFFER_TYPE_DATA:
-           data[i].flags = KRB5_CRYPTO_TYPE_DATA;
-           break;
-       case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
-           data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
-           break;
-       case GSS_IOV_BUFFER_TYPE_HEADER:
-           data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
-           break;
-       case GSS_IOV_BUFFER_TYPE_TRAILER:
-           data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
-           break;
-       case GSS_IOV_BUFFER_TYPE_PADDING:
-           data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
-           break;
-       case GSS_IOV_BUFFER_TYPE_STREAM:
-           abort();
-           break;
-       default:
-           *minor_status = EINVAL;
-           return GSS_S_FAILURE;
-       }
-       data[i].data.data = iov[i].buffer.value;
-       data[i].data.length = iov[i].buffer.length;
-    }
-    return GSS_S_COMPLETE;
-}
-
 OM_uint32 GSSAPI_LIB_FUNCTION
 _gk_wrap_iov(OM_uint32 * minor_status,
             gss_ctx_id_t  context_handle,
@@ -104,50 +44,17 @@ _gk_wrap_iov(OM_uint32 * minor_status,
             gss_iov_buffer_desc *iov,
             int iov_count)
 {
-    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
-    krb5_context context;
-    OM_uint32 major_status, junk;
-    krb5_crypto_iov *data;
-    krb5_error_code ret;
-    unsigned usage;
-
-    GSSAPI_KRB5_INIT (&context);
-
-    major_status = iov_allocate(minor_status, iov, iov_count);
-    if (major_status != GSS_S_COMPLETE)
-       return major_status;
-
-    data = calloc(iov_count, sizeof(data[0]));
-    if (data == NULL) {
-       gss_release_iov_buffer(&junk, iov, iov_count);
-       *minor_status = ENOMEM;
-       return GSS_S_FAILURE;
-    }
-
-    major_status = iov_map(minor_status, iov, iov_count, data);
-    if (major_status != GSS_S_COMPLETE) {
-       gss_release_iov_buffer(&junk, iov, iov_count);
-       free(data);
-       return major_status;
-    }
+  const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+  krb5_context context;
 
-    if (ctx->more_flags & LOCAL) {
-       usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
-    } else {
-       usage = KRB5_KU_USAGE_INITIATOR_SIGN;
-    }
+  GSSAPI_KRB5_INIT (&context);
 
-    ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage,
-                               data, iov_count, NULL);
-    free(data);
-    if (ret) {
-       gss_release_iov_buffer(&junk, iov, iov_count);
-        *minor_status = ret;
-       return GSS_S_FAILURE;
-    }
+  if (ctx->more_flags & IS_CFX)
+      return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
+                                 conf_req_flag, conf_state,
+                                 iov, iov_count);
 
-    *minor_status = 0;
-    return GSS_S_COMPLETE;
+    return GSS_S_FAILURE;
 }
 
 OM_uint32 GSSAPI_LIB_FUNCTION
@@ -158,50 +65,16 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
               gss_iov_buffer_desc *iov,
               int iov_count)
 {
-    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+    const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
     krb5_context context;
-    krb5_error_code ret;
-    OM_uint32 major_status, junk;
-    krb5_crypto_iov *data;
-    unsigned usage;
 
     GSSAPI_KRB5_INIT (&context);
-
-    major_status = iov_allocate(minor_status, iov, iov_count);
-    if (major_status != GSS_S_COMPLETE)
-       return major_status;
-
-    data = calloc(iov_count, sizeof(data[0]));
-    if (data == NULL) {
-       gss_release_iov_buffer(&junk, iov, iov_count);
-       *minor_status = ENOMEM;
-       return GSS_S_FAILURE;
-    }
-
-    major_status = iov_map(minor_status, iov, iov_count, data);
-    if (major_status != GSS_S_COMPLETE) {
-       gss_release_iov_buffer(&junk, iov, iov_count);
-       free(data);
-       return major_status;
-    }
-
-    if (ctx->more_flags & LOCAL) {
-       usage = KRB5_KU_USAGE_INITIATOR_SIGN;
-    } else {
-       usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
-    }
-
-    ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage,
-                               data, iov_count, NULL);
-    free(data);
-    if (ret) {
-        *minor_status = ret;
-       gss_release_iov_buffer(&junk, iov, iov_count);
-       return GSS_S_FAILURE;
-    }
-
-    *minor_status = 0;
-    return GSS_S_COMPLETE;
+    
+    if (ctx->more_flags & IS_CFX)
+       return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
+                                     conf_state, qop_state, iov, iov_count);
+    
+    return GSS_S_FAILURE;
 }
 
 OM_uint32  GSSAPI_LIB_FUNCTION
@@ -213,59 +86,15 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
                    gss_iov_buffer_desc *iov,
                    int iov_count)
 {
-    gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+    const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
     krb5_context context;
-    unsigned int i;
-    size_t size;
-    size_t *padding = NULL;
-
+    
     GSSAPI_KRB5_INIT (&context);
-    *minor_status = 0;
-
-    for (size = 0, i = 0; i < iov_count; i++) {
-       switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
-       case GSS_IOV_BUFFER_TYPE_EMPTY:
-           break;
-       case GSS_IOV_BUFFER_TYPE_DATA:
-           size += iov[i].buffer.length;
-           break;
-       case GSS_IOV_BUFFER_TYPE_HEADER:
-           iov[i].buffer.length =
-             krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER);
-           size += iov[i].buffer.length;
-           break;
-       case GSS_IOV_BUFFER_TYPE_TRAILER:
-           iov[i].buffer.length =
-             krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER);
-           size += iov[i].buffer.length;
-           break;
-       case GSS_IOV_BUFFER_TYPE_PADDING:
-           if (padding != NULL) {
-               *minor_status = 0;
-               return GSS_S_FAILURE;
-           }
-           padding = &iov[i].buffer.length;
-           break;
-       case GSS_IOV_BUFFER_TYPE_STREAM:
-           size += iov[i].buffer.length;
-           break;
-       case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
-           break;
-       default:
-           *minor_status = EINVAL;
-           return GSS_S_FAILURE;
-       }
-    }
-    if (padding) {
-       size_t pad = krb5_crypto_length(context, ctx->crypto,
-                                       KRB5_CRYPTO_TYPE_PADDING);
-       if (pad > 1) {
-           *padding = pad - (size % pad);
-           if (*padding == pad)
-               *padding = 0;
-       } else
-           *padding = 0;
-    }
-
-    return GSS_S_COMPLETE;
+    
+    if (ctx->more_flags & IS_CFX)
+       return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context,
+                                          conf_req_flag, qop_req, conf_state,
+                                          iov, iov_count);
+    
+    return GSS_S_FAILURE;
 }
index b48cfebcf1b13b3d82864f6fc67d2df14b844264..e7331b0119c4988f92f9db12bebbc16d2c8115dc 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
  *
index 3a206b1be1b036195ba25e6cfb59ea54942d5d29..7e0c3fe72703b17f8b99267e58e580720f184d96 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_canonicalize_name (
             OM_uint32 * minor_status,
             const gss_name_t input_name,
index 7ae26e2e7a556ac6b1775afb4b5d1c5b5cf20ab8..35e5a9e45a8787b1f8927a66e05646f281d156f8 100755 (executable)
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /*
- * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
+ * Implementation of RFC 4121
  */
 
 #define CFXSentByAcceptor      (1 << 0)
@@ -101,13 +99,14 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle,
     return 0;
 }
 
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
-                               const gsskrb5_ctx ctx,
-                               krb5_context context,
-                               int conf_req_flag,
-                               gss_qop_t qop_req,
-                               OM_uint32 req_output_size,
-                               OM_uint32 *max_input_size)
+OM_uint32
+_gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+                     const gsskrb5_ctx ctx,
+                     krb5_context context,
+                     int conf_req_flag,
+                     gss_qop_t qop_req,
+                     OM_uint32 req_output_size,
+                     OM_uint32 *max_input_size)
 {
     krb5_error_code ret;
 
@@ -203,11 +202,763 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
     return 0;
 }
 
+gss_iov_buffer_desc *
+_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
+{
+    int i;
+
+    for (i = 0; i < iov_count; i++)
+       if (type == GSS_IOV_BUFFER_TYPE(iov[i].type))
+           return &iov[i];
+    return NULL;
+}
+
+static OM_uint32
+allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
+{
+    if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) {
+       if (buffer->buffer.length == size)
+           return GSS_S_COMPLETE;
+       free(buffer->buffer.value);
+    }
+
+    buffer->buffer.value = malloc(size);
+    buffer->buffer.length = size;
+    if (buffer->buffer.value == NULL) {
+       *minor_status = ENOMEM;
+       return GSS_S_FAILURE;
+    }
+    buffer->type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
+
+    return GSS_S_COMPLETE;
+}
+
+
+
+OM_uint32
+_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
+                    gsskrb5_ctx ctx,
+                    krb5_context context,
+                    int conf_req_flag,
+                    int *conf_state,
+                    gss_iov_buffer_desc *iov,
+                    int iov_count)
+{
+    OM_uint32 major_status, junk;
+    gss_iov_buffer_desc *header, *trailer, *padding;
+    size_t gsshsize, k5hsize;
+    size_t gsstsize, k5tsize;
+    size_t i, padlength, rrc = 0, ec = 0;
+    gss_cfx_wrap_token token;
+    krb5_error_code ret;
+    int32_t seq_number;
+    unsigned usage;
+    krb5_crypto_iov *data = NULL;
+    int paddingoffset = 0;
+       
+    header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+    if (header == NULL) {
+       *minor_status = EINVAL;
+       return GSS_S_FAILURE;
+    }
+
+    krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength);
+
+    padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+    if (padlength != 0 && padding == NULL) {
+       *minor_status = EINVAL;
+       return GSS_S_FAILURE;
+    }
+
+    trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+    if (conf_req_flag) {
+       ec = padlength;
+
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+
+       gsshsize = k5hsize + sizeof(*token);
+       gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */
+
+    } else {
+
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize);
+
+       gsshsize = sizeof(*token);
+       gsstsize = k5tsize;
+    }
+
+    /*
+     *
+     */
+
+    if (trailer == NULL) {
+       /* conf_req_flag=0 doesn't support DCE_STYLE */
+       if (conf_req_flag == 0) {
+           *minor_status = EINVAL;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }           
+       rrc = gsstsize;
+       if (IS_DCE_STYLE(ctx))
+           rrc -= ec;
+       gsshsize += gsstsize;
+       gsstsize = 0;
+    } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+       major_status = allocate_buffer(minor_status, trailer, gsstsize);
+       if (major_status)
+           goto failure;
+    } else if (trailer->buffer.length < gsstsize) {
+       *minor_status = KRB5_BAD_MSIZE;
+       major_status = GSS_S_FAILURE;
+       goto failure;
+    } else
+       trailer->buffer.length = gsstsize;
+
+    /*
+     *
+     */
+
+    if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+       major_status = allocate_buffer(minor_status, header, gsshsize);
+       if (major_status != GSS_S_COMPLETE)
+           goto failure;
+    } else if (header->buffer.length < gsshsize) {
+       *minor_status = KRB5_BAD_MSIZE;
+       major_status = GSS_S_FAILURE;
+       goto failure;
+    } else
+       header->buffer.length = gsshsize;
+
+    token = (gss_cfx_wrap_token)header->buffer.value;
+
+    token->TOK_ID[0] = 0x05;
+    token->TOK_ID[1] = 0x04;
+    token->Flags     = 0;
+    token->Filler    = 0xFF;
+
+    if (ctx->more_flags & ACCEPTOR_SUBKEY)
+       token->Flags |= CFXAcceptorSubkey;
+
+    if (ctx->more_flags & LOCAL)
+       usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+    else
+       usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+
+    if (conf_req_flag) {
+       /*
+        * In Wrap tokens with confidentiality, the EC field is
+        * used to encode the size (in bytes) of the random filler.
+        */
+       token->Flags |= CFXSealed;
+       token->EC[0] = (padlength >> 8) & 0xFF;
+       token->EC[1] = (padlength >> 0) & 0xFF;
+
+    } else {
+       /*
+        * In Wrap tokens without confidentiality, the EC field is
+        * used to encode the size (in bytes) of the trailing
+        * checksum.
+        *
+        * This is not used in the checksum calcuation itself,
+        * because the checksum length could potentially vary
+        * depending on the data length.
+        */
+       token->EC[0] = 0;
+       token->EC[1] = 0;
+    }
+
+    /*
+     * In Wrap tokens that provide for confidentiality, the RRC
+     * field in the header contains the hex value 00 00 before
+     * encryption.
+     *
+     * In Wrap tokens that do not provide for confidentiality,
+     * both the EC and RRC fields in the appended checksum
+     * contain the hex value 00 00 for the purpose of calculating
+     * the checksum.
+     */
+    token->RRC[0] = 0;
+    token->RRC[1] = 0;
+
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+    krb5_auth_con_getlocalseqnumber(context,
+                                   ctx->auth_context,
+                                   &seq_number);
+    _gsskrb5_encode_be_om_uint32(0,          &token->SND_SEQ[0]);
+    _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+    krb5_auth_con_setlocalseqnumber(context,
+                                   ctx->auth_context,
+                                   ++seq_number);
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+    data = calloc(iov_count + 3, sizeof(data[0]));
+    if (data == NULL) {
+       *minor_status = ENOMEM;
+       major_status = GSS_S_FAILURE;
+       goto failure;
+    }
+
+    if (conf_req_flag) {
+       /*
+         plain packet:
+
+         {"header" | encrypt(plaintext-data | padding | E"header")}
+
+         Expanded, this is with with RRC = 0:
+
+         {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer }
+
+         In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer)
+
+         {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data  }
+        */
+
+       i = 0;
+       data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+       data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+       data[i].data.length = k5hsize;
+
+       for (i = 1; i < iov_count + 1; i++) {
+           switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) {
+           case GSS_IOV_BUFFER_TYPE_DATA:
+               data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+               break;
+           case GSS_IOV_BUFFER_TYPE_PADDING:
+               data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
+               paddingoffset = i;
+               break;
+           case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+               data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+               break;
+           default:
+               data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+               break;
+           }
+           data[i].data.length = iov[i - 1].buffer.length;
+           data[i].data.data = iov[i - 1].buffer.value;
+       }
+
+       /*
+        * Any necessary padding is added here to ensure that the
+        * encrypted token header is always at the end of the
+        * ciphertext.
+        */
+
+       /* XXX KRB5_CRYPTO_TYPE_PADDING */
+
+       /* encrypted CFX header in trailer (or after the header if in
+          DCE mode). Copy in header into E"header"
+       */
+       data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+       if (trailer)
+           data[i].data.data = trailer->buffer.value;
+       else
+           data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+
+       data[i].data.length = sizeof(*token);
+       memcpy(data[i].data.data, token, sizeof(*token));
+       i++;
+
+       /* Kerberos trailer comes after the gss trailer */
+       data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+       data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+       data[i].data.length = k5tsize;
+       i++;
+
+       ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+       if (ret != 0) {
+           *minor_status = ret;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       if (rrc) {
+           token->RRC[0] = (rrc >> 8) & 0xFF;
+           token->RRC[1] = (rrc >> 0) & 0xFF;
+       }
+
+       if (paddingoffset)
+           padding->buffer.length = data[paddingoffset].data.length;
+
+    } else {
+       /*
+         plain packet:
+
+         {data | "header" | gss-trailer (krb5 checksum)
+         
+         don't do RRC != 0
+
+        */
+
+       for (i = 0; i < iov_count; i++) {
+           switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+           case GSS_IOV_BUFFER_TYPE_DATA:
+           case GSS_IOV_BUFFER_TYPE_PADDING:
+               data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+               break;
+           case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+               data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+               break;
+           default:
+               data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+               break;
+           }
+           data[i].data.length = iov[i].buffer.length;
+           data[i].data.data = iov[i].buffer.value;
+       }
+
+       data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+       data[i].data.data = header->buffer.value;
+       data[i].data.length = header->buffer.length;
+       i++;
+
+       data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+       data[i].data.data = trailer->buffer.value;
+       data[i].data.length = trailer->buffer.length;
+       i++;
+
+       ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+       if (ret) {
+           *minor_status = ret;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       token->EC[0] =  (trailer->buffer.length >> 8) & 0xFF;
+       token->EC[1] =  (trailer->buffer.length >> 0) & 0xFF;
+    }
+
+    if (conf_state != NULL)
+       *conf_state = conf_req_flag;
+
+    free(data);
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+
+ failure:
+    if (data)
+       free(data);
+
+    gss_release_iov_buffer(&junk, iov, iov_count);
+
+    return major_status;
+}
+
+/* This is slowpath */
+static OM_uint32
+unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count)
+{
+    uint8_t *p, *q;
+    size_t len = 0, skip;
+    int i;
+
+    for (i = 0; i < iov_count; i++)
+       if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+           len += iov[i].buffer.length;
+    
+    p = malloc(len);
+    if (p == NULL) {
+       *minor_status = ENOMEM;
+       return GSS_S_FAILURE;
+    }
+    q = p;
+
+    /* copy up */
+
+    for (i = 0; i < iov_count; i++) {
+       if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+       {
+           memcpy(q, iov[i].buffer.value, iov[i].buffer.length);
+           q += iov[i].buffer.length;
+       }
+    }
+    assert((q - p) == len);
+
+    /* unrotate first part */
+    q = p + rrc;
+    skip = rrc;
+    for (i = 0; i < iov_count; i++) {
+       if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+       {
+           if (iov[i].buffer.length <= skip) {
+               skip -= iov[i].buffer.length;
+           } else {
+               memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip);
+               q += iov[i].buffer.length - skip;
+               skip = 0;
+           }
+       }
+    }
+    /* copy trailer */
+    q = p;
+    skip = rrc;
+    for (i = 0; i < iov_count; i++) {
+       if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+           GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+       {
+           memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip));
+           if (iov[i].buffer.length > skip)
+               break;
+           skip -= iov[i].buffer.length;
+           q += iov[i].buffer.length;
+       }
+    }
+    return GSS_S_COMPLETE;
+}
+
+
+OM_uint32
+_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
+                      gsskrb5_ctx ctx,
+                      krb5_context context,
+                      int *conf_state,
+                      gss_qop_t *qop_state,
+                      gss_iov_buffer_desc *iov,
+                      int iov_count)
+{
+    OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
+    gss_iov_buffer_desc *header, *trailer;
+    gss_cfx_wrap_token token, ttoken;
+    u_char token_flags;
+    krb5_error_code ret;
+    unsigned usage;
+    uint16_t ec, rrc;
+    krb5_crypto_iov *data = NULL;
+    int i, j;
+
+    *minor_status = 0;
+
+    header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+    if (header == NULL) {
+       *minor_status = EINVAL;
+       return GSS_S_FAILURE;
+    }
+
+    if (header->buffer.length < sizeof(*token)) /* we check exact below */
+       return GSS_S_DEFECTIVE_TOKEN;
+
+    trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+    token = (gss_cfx_wrap_token)header->buffer.value;
+
+    if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
+       return GSS_S_DEFECTIVE_TOKEN;
+
+    /* Ignore unknown flags */
+    token_flags = token->Flags &
+       (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
+
+    if (token_flags & CFXSentByAcceptor) {
+       if ((ctx->more_flags & LOCAL) == 0)
+           return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+       if ((token_flags & CFXAcceptorSubkey) == 0)
+           return GSS_S_DEFECTIVE_TOKEN;
+    } else {
+       if (token_flags & CFXAcceptorSubkey)
+           return GSS_S_DEFECTIVE_TOKEN;
+    }
+
+    if (token->Filler != 0xFF)
+       return GSS_S_DEFECTIVE_TOKEN;
+
+    if (conf_state != NULL)
+       *conf_state = (token_flags & CFXSealed) ? 1 : 0;
+
+    ec  = (token->EC[0]  << 8) | token->EC[1];
+    rrc = (token->RRC[0] << 8) | token->RRC[1];
+
+    /*
+     * Check sequence number
+     */
+    _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+    _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+    if (seq_number_hi) {
+       /* no support for 64-bit sequence numbers */
+       *minor_status = ERANGE;
+       return GSS_S_UNSEQ_TOKEN;
+    }
+
+    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+    if (ret != 0) {
+       *minor_status = 0;
+       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+       return ret;
+    }
+    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+    /*
+     * Decrypt and/or verify checksum
+     */
+
+    if (ctx->more_flags & LOCAL) {
+       usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+    } else {
+       usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+    }
+
+    data = calloc(iov_count + 3, sizeof(data[0]));
+    if (data == NULL) {
+       *minor_status = ENOMEM;
+       major_status = GSS_S_FAILURE;
+       goto failure;
+    }
+
+    if (token_flags & CFXSealed) {
+       size_t k5tsize, k5hsize;
+
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+
+       /* Rotate by RRC; bogus to do this in-place XXX */
+       /* Check RRC */
+
+       if (trailer == NULL) {
+           size_t gsstsize = k5tsize + sizeof(*token);
+           size_t gsshsize = k5hsize + sizeof(*token);
+
+           if (IS_DCE_STYLE(ctx))
+               gsstsize += ec;
+           gsshsize += gsstsize;
+
+           if (rrc != gsstsize) {
+               major_status = GSS_S_DEFECTIVE_TOKEN;
+               goto failure;
+           }
+           if (header->buffer.length != gsshsize) {
+               major_status = GSS_S_DEFECTIVE_TOKEN;
+               goto failure;
+           }
+       } else if (trailer->buffer.length != sizeof(*token) + k5tsize) {
+           major_status = GSS_S_DEFECTIVE_TOKEN;
+           goto failure;
+       } else if (header->buffer.length != sizeof(*token) + k5hsize) {
+           major_status = GSS_S_DEFECTIVE_TOKEN;
+           goto failure;
+       } else if (rrc != 0) {
+           /* go though slowpath */
+           major_status = unrotate_iov(minor_status, rrc, iov, iov_count);
+           if (major_status)
+               goto failure;
+       }
+
+       i = 0;
+       data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+       data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+       data[i].data.length = k5hsize;
+       i++;
+
+       for (j = 0; j < iov_count; i++, j++) {
+           switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
+           case GSS_IOV_BUFFER_TYPE_DATA:
+           case GSS_IOV_BUFFER_TYPE_PADDING:
+               data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+               break;
+           case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+               data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+               break;
+           default:
+               data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+               break;
+           }
+           data[i].data.length = iov[j].buffer.length;
+           data[i].data.data = iov[j].buffer.value;
+       }
+
+       /* encrypted CFX header in trailer (or after the header if in
+          DCE mode). Copy in header into E"header"
+       */
+       data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+       if (trailer)
+           data[i].data.data = trailer->buffer.value;
+       else
+           data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+       data[i].data.length = sizeof(*token);
+       ttoken = (gss_cfx_wrap_token)data[i].data.data;
+       i++;
+
+       /* Kerberos trailer comes after the gss trailer */
+       data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+       data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+       data[i].data.length = k5tsize;
+       i++;
+
+       ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+       if (ret != 0) {
+           *minor_status = ret;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       ttoken->RRC[0] = token->RRC[0];
+       ttoken->RRC[1] = token->RRC[1];
+
+       /* Check the integrity of the header */
+       if (memcmp(ttoken, token, sizeof(*token)) != 0) {
+           major_status = GSS_S_BAD_MIC;
+           goto failure;
+       }
+    } else {
+       /* Check RRC */
+       if (rrc != 0) {
+           *minor_status = EINVAL;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       if (trailer == NULL) {
+           *minor_status = EINVAL;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       if (trailer->buffer.length != ec) {
+           *minor_status = EINVAL;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+
+       for (i = 0; i < iov_count; i++) {
+           switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+           case GSS_IOV_BUFFER_TYPE_DATA:
+           case GSS_IOV_BUFFER_TYPE_PADDING:
+               data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+               break;
+           case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+               data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+               break;
+           default:
+               data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+               break;
+           }
+           data[i].data.length = iov[i].buffer.length;
+           data[i].data.data = iov[i].buffer.value;
+       }
+
+       data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+       data[i].data.data = header->buffer.value;
+       data[i].data.length = header->buffer.length;
+       i++;
+
+       data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+       data[i].data.data = trailer->buffer.value;
+       data[i].data.length = trailer->buffer.length;
+       i++;
+
+       token = (gss_cfx_wrap_token)header->buffer.value;
+       token->EC[0]  = 0;
+       token->EC[1]  = 0;
+       token->RRC[0] = 0;
+       token->RRC[1] = 0;
+
+       ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+       if (ret) {
+           *minor_status = ret;
+           major_status = GSS_S_FAILURE;
+           goto failure;
+       }
+    }
+
+    if (qop_state != NULL) {
+       *qop_state = GSS_C_QOP_DEFAULT;
+    }
+
+    free(data);
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+
+ failure:
+    if (data)
+       free(data);
+
+    gss_release_iov_buffer(&junk, iov, iov_count);
+
+    return major_status;
+}
+
+OM_uint32
+_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
+                           gsskrb5_ctx ctx,
+                           krb5_context context,
+                           int conf_req_flag,
+                           gss_qop_t qop_req,
+                           int *conf_state,
+                           gss_iov_buffer_desc *iov,
+                           int iov_count)
+{
+    size_t size;
+    int i;
+    size_t *padding = NULL;
+
+    GSSAPI_KRB5_INIT (&context);
+    *minor_status = 0;
+
+    for (size = 0, i = 0; i < iov_count; i++) {
+       switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+       case GSS_IOV_BUFFER_TYPE_EMPTY:
+           break;
+       case GSS_IOV_BUFFER_TYPE_DATA:
+           size += iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_HEADER:
+           *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
+           if (*minor_status)
+               return GSS_S_FAILURE;
+           break;
+       case GSS_IOV_BUFFER_TYPE_TRAILER:
+           *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
+           if (*minor_status)
+               return GSS_S_FAILURE;
+           break;
+       case GSS_IOV_BUFFER_TYPE_PADDING:
+           if (padding != NULL) {
+               *minor_status = 0;
+               return GSS_S_FAILURE;
+           }
+           padding = &iov[i].buffer.length;
+           break;
+       case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+           break;
+       default:
+           *minor_status = EINVAL;
+           return GSS_S_FAILURE;
+       }
+    }
+    if (padding) {
+       size_t pad;
+       krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
+       if (pad > 1) {
+           *padding = pad - (size % pad);
+           if (*padding == pad)
+               *padding = 0;
+       } else
+           *padding = 0;
+    }
+
+    return GSS_S_COMPLETE;
+}
+
+
+
+
 OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
                           const gsskrb5_ctx ctx,
                           krb5_context context,
                           int conf_req_flag,
-                          gss_qop_t qop_req,
                           const gss_buffer_t input_message_buffer,
                           int *conf_state,
                           gss_buffer_t output_message_buffer)
index fbb0f0218e7e1d15f27f63dc0fb641be73f67cb3..f45e4df3e2059306821433738b4e91ad12daf0c2 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_compare_name
            (OM_uint32 * minor_status,
             const gss_name_t name1,
index 012602c07441623b6841156f5331f4d9634b06f8..221d219c69fa3739ead198f9fdc38f3fe360163e 100644 (file)
@@ -33,9 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
-
 static krb5_error_code
 check_compat(OM_uint32 *minor_status,
             krb5_context context, krb5_const_principal name,
index 323038993880670aa5b59d812d3bf93c3850c97e..987ceea4aa99717d9c09e17f0e2d02a088df97d0 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 _gsskrb5_lifetime_left(OM_uint32 *minor_status,
                       krb5_context context,
index 40a8fab1b7b42a3fde291b00a97018c105832945..a4b28f91ed04b22c156d444e7db2ac788d70543c 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 #if 0
 OM_uint32
 gss_krb5_copy_ccache(OM_uint32 *minor_status,
index a2a5de9fe75b87b286bceb04e5610308977619fc..7ccf0b0f79c154113cbc2078634c55390ffa0a66 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * return the length of the mechanism in token or -1
  * (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
index ea0831815a27f50ec1167590651914972005229f..b3d436ea019c681b3ff450936cda78639625d1bd 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 _gsskrb5_delete_sec_context(OM_uint32 * minor_status,
                            gss_ctx_id_t * context_handle,
index 0b377315108ab3782be025c29cddd894b49b5278..6487d8488033c707ba49e30f9e6d07c6347af4a1 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_display_name
            (OM_uint32 * minor_status,
             const gss_name_t input_name,
index 4136c25e533c31a76be8ee73f5e99ad5846d6be0..f9d84fc762843eee5fe21bbcb01e0b2ec50beb23 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static const char *
 calling_error(OM_uint32 v)
 {
index 2b5e5c0ef48a781ec10ec379627040fb46f3da36..b0188acd517671b9b1a4b0de21d45fa195477694 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_duplicate_name (
             OM_uint32 * minor_status,
             const gss_name_t src_name,
index 838a34d7db9a20f6d1c43d4222ec03e198edd6c4..79cd9232e19dc4cc761af66e78b541d565710286 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 void
 _gssapi_encap_length (size_t data_len,
                      size_t *len,
index bad73611dc84a277854cc83bfb615c667e3a3aa3..705bb70d91cb8decb8a88e9b68043268b10d4099 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_export_name
            (OM_uint32  * minor_status,
             const gss_name_t input_name,
index 305d5c334e64312ceaab52276fb57d06ab0f996c..3d3870a6b45de0c4487a2037e4aa787433f451eb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 _gsskrb5_export_sec_context (
     OM_uint32 * minor_status,
index 1c28f7c141d8f47ab54c83d9d8b51c4265466fde..df23776a63c35da9c82b7fe6450d0c2083a4cb4f 100644 (file)
@@ -34,8 +34,6 @@
 #include "gsskrb5_locl.h"
 #include <gssapi_mech.h>
 
-RCSID("$Id$");
-
 /*
  * The implementation must reserve static storage for a
  * gss_OID_desc object containing the value
index 66aaba44d67827dff7578f1179b3303b5934d7f0..ad3009c73e09adbd80eab3bb84adf3b27fe50d2e 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static OM_uint32
 mic_des
            (OM_uint32 * minor_status,
index 8f5387fe2b56b32fc8eea7b05ca1bb7cfd1a689a..d488ce754b893e75a91ccaf493d81b23c4a86e1b 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static OM_uint32
 parse_krb5_name (OM_uint32 *minor_status,
                 krb5_context context,
index ba1a977d2dc6ee8aa7a2b3717d92fa64dbaf2d57..2af942338fb0f8ab2c5f2868900f9ed960609579 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 _gsskrb5_import_sec_context (
     OM_uint32 * minor_status,
index 3702106e7903cbda61b4a14e0c2c825a7cf22140..b1d18bd244c9c5df0915526ec0ead588f16e4c7b 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_indicate_mechs
            (OM_uint32 * minor_status,
             gss_OID_set * mech_set
index b28e6a4c12b536e997a47895fd5b8d23ca0da8d2..3a22c33ed69f3d7a43588405a50e297e0da938b7 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
 static int created_key;
 static HEIMDAL_thread_key context_key;
index 4b632bd95ac768852df380b9951eca4ace827468..35ab9dd88d3abbfb353dbe6030a02e12a3b93d53 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * copy the addresses from `input_chan_bindings' (if any) to
  * the auth context `ac'
@@ -697,7 +695,7 @@ repl_mutual
     if (actual_mech_type)
        *actual_mech_type = GSS_KRB5_MECHANISM;
 
-    if (ctx->flags & GSS_C_DCE_STYLE) {
+    if (IS_DCE_STYLE(ctx)) {
        /* There is no OID wrapping. */
        indata.length   = input_token->length;
        indata.data     = input_token->value;
index 188a6135a4b1cd14793c6a8a1e54d4a9663e0398..381ffc9e6f6bdb9572b7e8be68b737f7574df184 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_inquire_context (
     OM_uint32 * minor_status,
        const gss_ctx_id_t context_handle,
index 27e3014923602ac1ebda43479267dea25db67869..518736d78e4142a90763dc064c548b3121075635 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_inquire_cred
 (OM_uint32 * minor_status,
  const gss_cred_id_t cred_handle,
index 1fd973394093638af1758247941574f5af84073b..9da1ac43f181a13e21f73ffd40fbd899921af2eb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_inquire_cred_by_mech (
     OM_uint32 * minor_status,
        const gss_cred_id_t cred_handle,
index 5a35202a6a04d9a26c037f4327e01f2ed23df9dc..f32342f1d860993846c6e8fa699688249b14ed48 100644 (file)
@@ -32,8 +32,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_inquire_cred_by_oid
           (OM_uint32 * minor_status,
            const gss_cred_id_t cred_handle,
index 5d54bd65086792eeef84a524809c5cd1c931e5f5..5fa3c302a28004209f6209ff8832caff3dc8edf6 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_inquire_mechs_for_name (
             OM_uint32 * minor_status,
             const gss_name_t input_name,
index 9eba7b7f4ddc8586f9f5ac6df70bbd03a89b09ed..591343307e48d5c60764184053daf569fa67a4a5 100644 (file)
@@ -33,9 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
-
 static gss_OID *name_list[] = {
     &GSS_C_NT_HOSTBASED_SERVICE,
     &GSS_C_NT_USER_NAME,
index f8ef2a3aa4e0719dde8b1a21c4bdcdf15d352be9..ce01e666fa028316b27fc96e9da0750306ec1a22 100644 (file)
@@ -32,8 +32,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static int
 oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
 {
index 9fd13f51bd27b7318417fb6e3af9aa1d593e0b38..76ae3b78ed33301280f49733935d249bd1503021 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32
 _gsskrb5_pseudo_random(OM_uint32 *minor_status,
                       gss_ctx_id_t context_handle,
index 3229b36292b1007175ed5c8aaddc6c3c55b0ef99..1c9d44588fdea93e5af509c9e71f51bcbee0fe43 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_process_context_token (
        OM_uint32          *minor_status,
        const gss_ctx_id_t context_handle,
index 18e0279939730f958701f3889dffaf09414e0aba..b704e001ebd1c5127b184bdb527a284087914f20 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_release_buffer
            (OM_uint32 * minor_status,
             gss_buffer_t buffer
index 62674a1d530870c23d334cf0806009efad2c0a99..5eec3c48cbd89065b3d3950e5a4be0ea4d2ce55c 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_release_cred
            (OM_uint32 * minor_status,
             gss_cred_id_t * cred_handle
index 5491052c59378b9b7608833db13fc1ec5d570490..0fafc275d0675aa57b472e49c605b2edab618973 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 OM_uint32 _gsskrb5_release_name
            (OM_uint32 * minor_status,
             gss_name_t * input_name
index 6391d44429d46be458003a0c04805dd6f2993aa9..fbbc5b6c7037ca0d5d1b859b08976db0a6e632c8 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 #define DEFAULT_JITTER_WINDOW 20
 
 struct gss_msg_order {
index 2a2390f8d1f3a86870c4d4a69ea2ac44a1eb2e53..15d7632e4c99bc2c83da9410b02e973fb1f0990d 100644 (file)
@@ -32,8 +32,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /* 1.2.752.43.13.17 */
 static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
 {6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
index 460cfe942ad2736e16dd4696b7c9730b7a70c222..096e83504530aedc2aeffb705d1cec2b0ce592df 100644 (file)
@@ -36,8 +36,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static OM_uint32
 get_bool(OM_uint32 *minor_status,
         const gss_buffer_t value,
index 0e87cb88b73d8682f897cbbb22239cca8551bf10..20cf952b4eb4a96092ad64dfe6fa5364436bb9eb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static OM_uint32
 unwrap_des
            (OM_uint32 * minor_status,
index 6eb7ae4b089fee2f3aabc3b626ef1b5ebfda4753..c7e16e81f77f28fac2e83f9f404d52a8fe5c801e 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 static OM_uint32
 verify_mic_des
            (OM_uint32 * minor_status,
index b9f4c237c767d540e124abb2c3e34aaa0593eb31..3de13f908f1621e1c7e4fc873aa20ac6cfc55196 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "gsskrb5_locl.h"
 
-RCSID("$Id$");
-
 /*
  * Return initiator subkey, or if that doesn't exists, the subkey.
  */
@@ -540,7 +538,7 @@ OM_uint32 _gsskrb5_wrap
 
   if (ctx->more_flags & IS_CFX)
       return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
-                              qop_req, input_message_buffer, conf_state,
+                              input_message_buffer, conf_state,
                               output_message_buffer);
 
   HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
index a8ebe644ab239c88d18e3b76f610e233e2bbe43c..b1bc7dd98132faa4cd1f2a29de33d116f5827f7c 100644 (file)
@@ -50,7 +50,7 @@ gss_acquire_cred(OM_uint32 *minor_status,
        int i;
 
        *minor_status = 0;
-       if (output_cred_handle)
+       if (output_cred_handle == NULL)
            return GSS_S_CALL_INACCESSIBLE_READ;
        if (actual_mechs)
            *actual_mechs = GSS_C_NO_OID_SET;
index cbe0cd146093399237b7fa5fc1e8e8c81fada39f..9c784f42de108f42a37d84decc8beeaeaf663cdd 100644 (file)
@@ -3,27 +3,39 @@
  */ 
 
 #include "mech_locl.h"
-RCSID("$Id$");
 
 /**
  * Encrypts or sign the data.
  *
+ * This is a more complicated version of gss_wrap(), it allows the
+ * caller to use AEAD data (signed header/trailer) and allow greater
+ * controll over where the encrypted data is placed.
+ *
  * The maximum packet size is gss_context_stream_sizes.max_msg_size.
  *
- * The caller needs provide the folloing buffers:
+ * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:
  *
  * - HEADER (of size gss_context_stream_sizes.header)
- *   SIGN_ONLY (optional, zero or more)
- *   DATA
- *   SIGN_ONLY (optional, zero or more)
- *   PADDING (of size gss_context_stream_sizes.blocksize)
+ *   { DATA or SIGN_ONLY } (optional, zero or more)
+ *   PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
  *   TRAILER (of size gss_context_stream_sizes.trailer)
  *
  * - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
- *   DATA elements is padded to a block bountry.
+ *   DATA elements is padded to a block bountry and header is of at
+ *   least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.
+ *
+ * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.
  *
  * To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
  *
+ * When used in conf_req_flag=0,
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ *   { DATA or SIGN_ONLY } (optional, zero or more)
+ *   PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
+ *   TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ *
  * The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
  * gss_context_query_attributes().
  *
@@ -65,6 +77,13 @@ gss_wrap_iov(OM_uint32 * minor_status,
                                iov, iov_count);
 }
 
+/**
+ * Decrypt or verifies the signature on the data.
+ *
+ *
+ * @ingroup gssapi
+ */
+
 OM_uint32 GSSAPI_LIB_FUNCTION
 gss_unwrap_iov(OM_uint32 *minor_status,
               gss_ctx_id_t context_handle,
@@ -99,7 +118,18 @@ gss_unwrap_iov(OM_uint32 *minor_status,
                                  iov, iov_count);
 }
 
-OM_uint32  GSSAPI_LIB_FUNCTION
+/**
+ * Update the length fields in iov buffer for the types:
+ * - GSS_IOV_BUFFER_TYPE_HEADER
+ * - GSS_IOV_BUFFER_TYPE_PADDING
+ * - GSS_IOV_BUFFER_TYPE_TRAILER
+ *
+ * Consider using gss_context_query_attributes() to fetch the data instead.
+ *
+ * @ingroup gssapi
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
 gss_wrap_iov_length(OM_uint32 * minor_status,
                    gss_ctx_id_t context_handle,
                    int conf_req_flag,
@@ -132,6 +162,13 @@ gss_wrap_iov_length(OM_uint32 * minor_status,
                                       iov, iov_count);
 }
 
+/**
+ * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by
+ * looking at the GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED flag.
+ *
+ * @ingroup gssapi
+ */
+
 OM_uint32 GSSAPI_LIB_FUNCTION
 gss_release_iov_buffer(OM_uint32 *minor_status,
                       gss_iov_buffer_desc *iov,
@@ -146,9 +183,10 @@ gss_release_iov_buffer(OM_uint32 *minor_status,
        return GSS_S_CALL_INACCESSIBLE_READ;
 
     for (i = 0; i < iov_count; i++) {
-       if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED)
+       if ((iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) == 0)
            continue;
        gss_release_buffer(&junk, &iov[i].buffer);
+       iov[i].type &= ~GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
     }
     return GSS_S_COMPLETE;
 }
@@ -159,6 +197,8 @@ gss_release_iov_buffer(OM_uint32 *minor_status,
  * SSPI equivalent if this function is QueryContextAttributes.
  *
  * - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ *
+ * @ingroup gssapi
  */
 
 static gss_OID_desc gss_c_attr_stream_sizes_desc =
index 158126d99f96cd1c7876121cf0e42d1ececbc774..2bdfc28ebf9582f7d11296a9df48be456183a3c8 100644 (file)
@@ -92,12 +92,6 @@ send_supported_mechs (OM_uint32 *minor_status,
                      gss_buffer_t output_token)
 {
     NegotiationTokenWin nt;
-    char hostname[MAXHOSTNAMELEN + 1], *p;
-    gss_buffer_desc name_buf;
-    gss_OID name_type;
-    gss_name_t target_princ;
-    gss_name_t canon_princ;
-    OM_uint32 minor;
     size_t buf_len;
     gss_buffer_desc data;
     OM_uint32 ret;
@@ -116,62 +110,9 @@ send_supported_mechs (OM_uint32 *minor_status,
        return ret;
     }
 
-    memset(&target_princ, 0, sizeof(target_princ));
-    if (gethostname(hostname, sizeof(hostname) - 2) != 0) {
-       *minor_status = errno;
-       free_NegotiationTokenWin(&nt);
-       return GSS_S_FAILURE;
-    }
-    hostname[sizeof(hostname) - 1] = '\0';
-
-    /* Send the constructed SAM name for this host */
-    for (p = hostname; *p != '\0' && *p != '.'; p++) {
-       *p = toupper((unsigned char)*p);
-    }
-    *p++ = '$';
-    *p = '\0';
-
-    name_buf.length = strlen(hostname);
-    name_buf.value = hostname;
-
-    ret = gss_import_name(minor_status, &name_buf,
-                         GSS_C_NO_OID,
-                         &target_princ);
-    if (ret != GSS_S_COMPLETE) {
-       free_NegotiationTokenWin(&nt);
-       return ret;
-    }
-
-    name_buf.length = 0;
-    name_buf.value = NULL;
-
-    /* Canonicalize the name using the preferred mechanism */
-    ret = gss_canonicalize_name(minor_status,
-                               target_princ,
-                               GSS_C_NO_OID,
-                               &canon_princ);
-    if (ret != GSS_S_COMPLETE) {
-       free_NegotiationTokenWin(&nt);
-       gss_release_name(&minor, &target_princ);
-       return ret;
-    }
-
-    ret = gss_display_name(minor_status, canon_princ,
-                          &name_buf, &name_type);
-    if (ret != GSS_S_COMPLETE) {
-       free_NegotiationTokenWin(&nt);
-       gss_release_name(&minor, &canon_princ);
-       gss_release_name(&minor, &target_princ);
-       return ret;
-    }
-
-    gss_release_name(&minor, &canon_princ);
-    gss_release_name(&minor, &target_princ);
-
     ALLOC(nt.u.negTokenInit.negHints, 1);
     if (nt.u.negTokenInit.negHints == NULL) {
        *minor_status = ENOMEM;
-       gss_release_buffer(&minor, &name_buf);
        free_NegotiationTokenWin(&nt);
        return GSS_S_FAILURE;
     }
@@ -179,20 +120,19 @@ send_supported_mechs (OM_uint32 *minor_status,
     ALLOC(nt.u.negTokenInit.negHints->hintName, 1);
     if (nt.u.negTokenInit.negHints->hintName == NULL) {
        *minor_status = ENOMEM;
-       gss_release_buffer(&minor, &name_buf);
        free_NegotiationTokenWin(&nt);
        return GSS_S_FAILURE;
     }
 
-    *(nt.u.negTokenInit.negHints->hintName) = name_buf.value;
-    name_buf.value = NULL;
+    *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore");
     nt.u.negTokenInit.negHints->hintAddress = NULL;
 
     ASN1_MALLOC_ENCODE(NegotiationTokenWin,
                       data.value, data.length, &nt, &buf_len, ret);
     free_NegotiationTokenWin(&nt);
     if (ret) {
-       return ret;
+       *minor_status = ret;
+       return GSS_S_FAILURE;
     }
     if (data.length != buf_len)
        abort();
index 14402d4b1c5c5fe7afcf4fc81c4ede8855700503..99eb76c818e78ea3eb8f9b1945a6e42f198874ea 100644 (file)
@@ -84,12 +84,14 @@ typedef struct DES_key_schedule
  *
  */
 
-#if !defined(__GNUC__) && !defined(__attribute__)
-#define __attribute__(x)
-#endif
-
 #ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
 #define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200) 
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
+#endif
 #endif
 
 #ifdef __cplusplus
index a7c8fac900c06df5c0627a4683532b239efa869f..0086a069602e22309e5903897fa082e6b934525c 100644 (file)
@@ -190,10 +190,17 @@ struct hc_evp_md {
 #endif
 
 #ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
 #define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200) 
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
 #endif
+#endif
+
 #ifndef HC_DEPRECATED_CRYPTO
-#define HC_DEPRECATED_CRYPTO __attribute__((deprecated))
+#define HC_DEPRECATED_CRYPTO HC_DEPRECATED
 #endif
 
 
index 556833d1c452a5429098053ed11a1dda89d81ad8..9de0a04a1fadf881f71e408414c0d9c855315b15 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id$");
-
 #if HAVE_DB1
 
 #if defined(HAVE_DB_185_H)
@@ -317,6 +315,7 @@ hdb_db_create(krb5_context context, HDB **db,
     }
     (*db)->hdb_master_key_set = 0;
     (*db)->hdb_openp = 0;
+    (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
     (*db)->hdb_open = DB_open;
     (*db)->hdb_close = DB_close;
     (*db)->hdb_fetch = _hdb_fetch;
index 7e2961c61438610c62d1f1b2d6e61603fc701989..a399ab0a5cac5d35fafd1a10331e6fd15f85c9eb 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id$");
-
 struct hdb_dbinfo {
     char *label;
     char *realm;
index 9053fd66335c1d56e7516b0ebdac2c66a4b9b0fa..faf0b6bdf29149227bb5dfc4afb50ad074e923d6 100644 (file)
@@ -34,8 +34,6 @@
 #include "hdb_locl.h"
 #include <der.h>
 
-RCSID("$Id$");
-
 krb5_error_code
 hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
 {
index c2abd4af73ee78b71984f33d75ba5899e12c9f77..a72851c9f2011b65895aa46ba2c33aabbc2da192 100644 (file)
@@ -45,7 +45,9 @@ HDBFlags ::= BIT STRING {
        immutable(13),                  -- may not be deleted
        trusted-for-delegation(14),     -- Trusted to print forwardabled tickets
        allow-kerberos4(15),            -- Allow Kerberos 4 requests
-       allow-digest(16)                -- Allow digest requests
+       allow-digest(16),               -- Allow digest requests
+       locked-out(17)                  -- Account is locked out,
+                                       -- authentication will be denied
 }
 
 GENERATION ::= SEQUENCE {
index e55b0bed03ce286d51f8ed1f66db1c3bcf142217..9795f8b255b75b885c6d1da8f69e936816c2f34d 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "krb5_locl.h"
 #include "hdb_locl.h"
-RCSID("$Id$");
 
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
index a5e6514e6c836bdd375052cb1b09e0ec70341c90..f490dbf2f0f1a5807013ef452741f41d47f11508 100644 (file)
@@ -54,7 +54,15 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 #define HDB_F_GET_ANY          28      /* fetch any of client,server,krbtgt */
 #define HDB_F_CANON            32      /* want canonicalition */
 
+/* hdb_capability_flags */
 #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
+#define HDB_CAP_F_HANDLE_PASSWORDS     2
+#define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4
+
+/* auth status values */
+#define HDB_AUTH_SUCCESS               0
+#define HDB_AUTH_WRONG_PASSWORD                1
+#define HDB_AUTH_INVALID_SIGNATURE     2
 
 /* key usage for master key */
 #define HDB_KU_MKEY    0x484442
@@ -184,6 +192,34 @@ typedef struct HDB{
      * point for the module.
      */
     krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
+    /**
+     * Change password.
+     *
+     * Will update keys for the entry when given password.  The new
+     * keys must be written into the entry and and will then later be
+     * ->hdb_store() into the database. The backend will still perform
+     * all other operations, increasing the kvno, and update
+     * modification timestamp.
+     * 
+     * The backen need to call _kadm5_set_keys() and perform password
+     * quality checks.
+     */
+    krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int);
+
+    /**
+     * Auth feedback
+     *
+     * This is a feedback call that allows backends that provides
+     * lockout functionality to register failure and/or successes.
+     *
+     * In case the entry is locked out, the backend should set the
+     * hdb_entry.flags.locked-out flag.
+     */
+    krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int);
+    /**
+     * Check is delegation is allowed.
+     */
+    krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
 }HDB;
 
 #define HDB_INTERFACE_VERSION  5
index 50fe7d7fda531b69b945a67d9f89521f2c3affe0..63f254d0022ae95c267a81c147713c402e3207bd 100644 (file)
@@ -34,8 +34,6 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id$");
-
 /*
  * free all the memory used by (len, keys)
  */
index 97989a97641a1f3e6d0c5357d25ec602aad792dc..9b36a268cfd7b34feddf9134c1a334b0bb68382b 100644 (file)
@@ -35,8 +35,6 @@
 
 /* keytab backend for HDB databases */
 
-RCSID("$Id$");
-
 struct hdb_data {
     char *dbname;
     char *mkey;
@@ -123,61 +121,43 @@ hdb_get_name(krb5_context context,
     return 0;
 }
 
-static void
-set_config (krb5_context context,
-           const krb5_config_binding *binding,
-           const char **dbname,
-           const char **mkey)
-{
-    *dbname = krb5_config_get_string(context, binding, "dbname", NULL);
-    *mkey   = krb5_config_get_string(context, binding, "mkey_file", NULL);
-}
-
 /*
  * try to figure out the database (`dbname') and master-key (`mkey')
  * that should be used for `principal'.
  */
 
-static void
+static krb5_error_code
 find_db (krb5_context context,
-        const char **dbname,
-        const char **mkey,
+        char **dbname,
+        char **mkey,
         krb5_const_principal principal)
 {
-    const krb5_config_binding *top_bind = NULL;
-    const krb5_config_binding *default_binding = NULL;
-    const krb5_config_binding *db;
     krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+    krb5_error_code ret;
+    struct hdb_dbinfo *head, *dbinfo = NULL;
 
     *dbname = *mkey = NULL;
 
-    while ((db =
-           krb5_config_get_next(context,
-                                NULL,
-                                &top_bind,
-                                krb5_config_list,
-                                "kdc",
-                                "database",
-                                NULL)) != NULL) {
-       const char *p;
-       
-       p = krb5_config_get_string (context, db, "realm", NULL);
-       if (p == NULL) {
-           if(default_binding) {
-               krb5_warnx(context, "WARNING: more than one realm-less "
-                          "database specification");
-               krb5_warnx(context, "WARNING: using the first encountered");
-           } else
-               default_binding = db;
-       } else if (strcmp (realm, p) == 0) {
-           set_config (context, db, dbname, mkey);
+    ret = hdb_get_dbinfo(context, &head);
+    if (ret)
+       return ret;
+
+    while ((dbinfo = hdb_dbinfo_get_next(head, dbinfo)) != NULL) {
+       const char *p = hdb_dbinfo_get_realm(context, dbinfo);
+       if (p && strcmp (realm, p) == 0) {
+           p = hdb_dbinfo_get_dbname(context, dbinfo);
+           if (p)
+               *dbname = strdup(p);
+           p = hdb_dbinfo_get_mkey_file(context, dbinfo);
+           if (p)
+               *mkey = strdup(p);
            break;
        }
     }
-    if (*dbname == NULL && default_binding != NULL)
-       set_config (context, default_binding, dbname, mkey);
+    hdb_free_dbinfo(context, &head);
     if (*dbname == NULL)
-       *dbname = HDB_DEFAULT_DB;
+       *dbname = strdup(HDB_DEFAULT_DB);
+    return 0;
 }
 
 /*
@@ -196,29 +176,35 @@ hdb_get_entry(krb5_context context,
     hdb_entry_ex ent;
     krb5_error_code ret;
     struct hdb_data *d = id->data;
-    int i;
-    HDB *db;
     const char *dbname = d->dbname;
     const char *mkey   = d->mkey;
+    char *fdbname = NULL, *fmkey = NULL;
+    HDB *db;
+    int i;
 
     memset(&ent, 0, sizeof(ent));
 
-    if (dbname == NULL)
-       find_db (context, &dbname, &mkey, principal);
+    if (dbname == NULL) {
+       ret = find_db(context, &fdbname, &fmkey, principal);
+       if (ret)
+           return ret;
+       dbname = fdbname;
+       mkey = fmkey;
+    }
 
     ret = hdb_create (context, &db, dbname);
     if (ret)
-       return ret;
+       goto out2;
     ret = hdb_set_master_keyfile (context, db, mkey);
     if (ret) {
        (*db->hdb_destroy)(context, db);
-       return ret;
+       goto out2;
     }
        
     ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
     if (ret) {
        (*db->hdb_destroy)(context, db);
-       return ret;
+       goto out2;
     }
     ret = (*db->hdb_fetch)(context, db, principal,
                           HDB_F_DECRYPT|
@@ -252,9 +238,12 @@ hdb_get_entry(krb5_context context,
        }
     }
     hdb_free_entry(context, &ent);
-out:
+ out:
     (*db->hdb_close)(context, db);
     (*db->hdb_destroy)(context, db);
+ out2:
+    free(fdbname);
+    free(fmkey);
     return ret;
 }
 
index 1520c4f7e9a06641afcb71da5ab5a58035e03e91..35323cf10038804501c3422e9489c0e4f8e12f89 100644 (file)
@@ -36,8 +36,6 @@
 #define O_BINARY 0
 #endif
 
-RCSID("$Id$");
-
 struct hdb_master_key_data {
     krb5_keytab_entry keytab;
     krb5_crypto crypto;
index 1e9df8165202b2cd85a693d5d50349c9b40517c2..d97a98ed6b5a1261aa3e5cc10bb464fafdc6b0da 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id$");
-
 #if HAVE_NDBM
 
 #if defined(HAVE_GDBM_NDBM_H)
@@ -348,6 +346,7 @@ hdb_ndbm_create(krb5_context context, HDB **db,
     }
     (*db)->hdb_master_key_set = 0;
     (*db)->hdb_openp = 0;
+    (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
     (*db)->hdb_open = NDBM_open;
     (*db)->hdb_close = NDBM_close;
     (*db)->hdb_fetch = _hdb_fetch;
index 80631007173dc76463f3cd1347e18cfdffd296ca..f4667c6e31596d3a61ba2de4b22fe47700a239b7 100644 (file)
@@ -37,10 +37,6 @@ struct hx509_crypto;
 
 struct signature_alg;
 
-enum crypto_op_type {
-    COT_SIGN
-};
-
 struct hx509_generate_private_context {
     const heim_oid *key_oid;
     int isCA;
index 9fd21173454db2389e284599720f60dab645d2c2..a30780d1edcfc0b665b8688b0bfde436e37b2072 100644 (file)
@@ -3182,7 +3182,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
     krb5_error_code ret;
     struct key_data *dkey;
     const struct encryption_type *et = crypto->et;
-    krb5_crypto_iov *tiv, *piv, *hiv, *div;
+    krb5_crypto_iov *tiv, *piv, *hiv;
 
     if (num_data < 0) {
         krb5_clear_error_message(context);
@@ -3197,11 +3197,11 @@ krb5_encrypt_iov_ivec(krb5_context context,
     headersz = et->confoundersize;
     trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
-    div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
-    if (div == NULL)
-       return KRB5_CRYPTO_INTERNAL;
-    
-    len = div->data.length;
+    for (len = 0, i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+           continue;
+       len += data[i].data.length;
+    }
 
     sz = headersz + len;
     block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
@@ -3217,7 +3217,6 @@ krb5_encrypt_iov_ivec(krb5_context context,
     krb5_generate_random_block(hiv->data.data, hiv->data.length);
 
     /* padding */
-
     piv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
     /* its ok to have no TYPE_PADDING if there is no padding */
     if (piv == NULL && pad_sz != 0)
@@ -3226,26 +3225,26 @@ krb5_encrypt_iov_ivec(krb5_context context,
        if (piv->data.length < pad_sz)
            return KRB5_BAD_MSIZE;
        piv->data.length = pad_sz;
+       if (pad_sz)
+           memset(piv->data.data, pad_sz, pad_sz);
+       else
+           piv = NULL;
     }
 
-
     /* trailer */
-
     tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
     if (tiv == NULL || tiv->data.length != trailersz)
        return KRB5_BAD_MSIZE;
 
-
     /*
      * XXX replace with EVP_Sign? at least make create_checksum an iov
      * function.
      * XXX CTS EVP is broken, can't handle multi buffers :(
      */
 
-    len = hiv->data.length;
+    len = block_sz;
     for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
-           data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+       if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
            continue;
        len += data[i].data.length;
     }
@@ -3261,6 +3260,10 @@ krb5_encrypt_iov_ivec(krb5_context context,
        memcpy(q, data[i].data.data, data[i].data.length);
        q += data[i].data.length;
     }
+    if (piv) {
+       memset(q, 0, piv->data.length);
+       q += piv->data.length;
+    }
 
     ret = create_checksum(context,
                          et->keyed_checksum,
@@ -3282,30 +3285,24 @@ krb5_encrypt_iov_ivec(krb5_context context,
     memcpy(tiv->data.data, cksum.checksum.data, cksum.checksum.length);
     free_Checksum (&cksum);
 
-    /* now encrypt data */
-
-    ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
-    if(ret)
-       return ret;
-    ret = _key_schedule(context, dkey);
-    if(ret)
-       return ret;
-
     /* XXX replace with EVP_Cipher */
-
-    len = hiv->data.length + div->data.length;
-    if (piv)
-       len += piv->data.length;
-
-    p = q = malloc(len);
+    p = q = malloc(block_sz);
     if(p == NULL)
        return ENOMEM;
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
-    memcpy(q, div->data.data, div->data.length);
-    q += div->data.length;
-    memset(q, 0, pad_sz);
+
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+           continue;
+       memcpy(q, data[i].data.data, data[i].data.length);
+       q += data[i].data.length;
+    }
+    if (piv) {
+       memset(q, 0, piv->data.length);
+       q += piv->data.length;
+    }
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
@@ -3318,7 +3315,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
        return ret;
     }
 
-    ret = (*et->encrypt)(context, dkey, p, len, 1, usage, ivec);
+    ret = (*et->encrypt)(context, dkey, p, block_sz, 1, usage, ivec);
     if (ret) {
        free(p);
        return ret;
@@ -3330,11 +3327,17 @@ krb5_encrypt_iov_ivec(krb5_context context,
     memcpy(hiv->data.data, q, hiv->data.length);
     q += hiv->data.length;
 
-    memcpy(div->data.data, q, div->data.length);
-    q += div->data.length;
-
-    if (piv)
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+           continue;
+       memcpy(data[i].data.data, q, data[i].data.length);
+       q += data[i].data.length;
+    }
+    if (piv) {
        memcpy(piv->data.data, q, pad_sz);
+       q += pad_sz;
+    }
+
     free(p);
 
     return ret;
@@ -3371,13 +3374,12 @@ krb5_decrypt_iov_ivec(krb5_context context,
 {
     unsigned int i;
     size_t headersz, trailersz, len;
-    size_t sz, block_sz, pad_sz;
     Checksum cksum;
     unsigned char *p, *q;
     krb5_error_code ret;
     struct key_data *dkey;
     struct encryption_type *et = crypto->et;
-    krb5_crypto_iov *tiv, *hiv, *div;
+    krb5_crypto_iov *tiv, *hiv;
 
     if (num_data < 0) {
         krb5_clear_error_message(context);
@@ -3390,56 +3392,47 @@ krb5_decrypt_iov_ivec(krb5_context context,
     }
 
     headersz = et->confoundersize;
-    trailersz = CHECKSUMSIZE(et->keyed_checksum);
-
-    for (len = 0, i = 0; i < num_data; i++) {
-       if (data[i].flags == KRB5_CRYPTO_TYPE_DATA) {
-           if (len != 0) 
-               return KRB5_CRYPTO_INTERNAL;
-           len += data[i].data.length;
-       }
-    }
-
-    sz = headersz + len;
-    block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
-
-    pad_sz = block_sz - sz;
-    trailersz += pad_sz;
-
-    /* header */
 
     hiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
-    if (hiv == NULL || hiv->data.length < headersz)
+    if (hiv == NULL || hiv->data.length != headersz)
        return KRB5_BAD_MSIZE;
-    hiv->data.length = headersz;
 
     /* trailer */
+    trailersz = CHECKSUMSIZE(et->keyed_checksum);
 
     tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
-    if (tiv == NULL || tiv->data.length < trailersz)
+    if (tiv->data.length != trailersz)
        return KRB5_BAD_MSIZE;
-    tiv->data.length = trailersz;
-
-    div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
-    if (div == NULL)
-       return KRB5_CRYPTO_INTERNAL;
 
-    /* XXX replace with EVP_Cipher */
+    /* Find length of data we will decrypt */
 
-    for (len = 0, i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_HEADER &&
-           data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+    len = headersz;
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
            continue;
        len += data[i].data.length;
     }
 
+    if ((len % et->padsize) != 0) {
+       krb5_clear_error_message(context);
+       return KRB5_BAD_MSIZE;
+    }
+
+    /* XXX replace with EVP_Cipher */
+
     p = q = malloc(len);
     if (p == NULL)
        return ENOMEM;
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
-    memcpy(q, div->data.data, div->data.length);
+
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+           continue;
+       memcpy(q, data[i].data.data, data[i].data.length);
+       q += data[i].data.length;
+    }
 
     ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
     if(ret) {
@@ -3460,20 +3453,26 @@ krb5_decrypt_iov_ivec(krb5_context context,
 
     /* copy data back to buffers */
     memcpy(hiv->data.data, p, hiv->data.length);
-    memcpy(div->data.data, p + hiv->data.length, len - hiv->data.length);
+    q = p + hiv->data.length;
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+           continue;
+       memcpy(data[i].data.data, q, data[i].data.length);
+       q += data[i].data.length;
+    }
+
     free(p);
 
     /* check signature */
-
-    len = hiv->data.length;
     for (i = 0; i < num_data; i++) {
-       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
-           data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+       if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
            continue;
        len += data[i].data.length;
     }
 
     p = q = malloc(len);
+    if (p == NULL)
+       return ENOMEM;
 
     memcpy(q, hiv->data.data, hiv->data.length);
     q += hiv->data.length;
@@ -3582,33 +3581,145 @@ krb5_create_checksum_iov(krb5_context context,
     return 0;
 }
 
+/**
+ * Verify a Kerberos message checksum.
+ *
+ * @param context Kerberos context
+ * @param crypto Kerberos crypto context
+ * @param usage Key usage for this buffer
+ * @param data array of buffers to process
+ * @param num_data length of array
+ *
+ * @return Return an error code or 0.
+ * @ingroup krb5_crypto
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_verify_checksum_iov(krb5_context context,
+                        krb5_crypto crypto,
+                        unsigned usage,
+                        krb5_crypto_iov *data,
+                        unsigned int num_data,
+                        krb5_cksumtype *type)
+{
+    struct encryption_type *et = crypto->et;
+    Checksum cksum;
+    krb5_crypto_iov *civ;
+    krb5_error_code ret;
+    int i;
+    size_t len;
+    char *p, *q;
+
+    if (num_data < 0) {
+        krb5_clear_error_message(context);
+       return KRB5_CRYPTO_INTERNAL;
+    }
+
+    if(!derived_crypto(context, crypto)) {
+       krb5_clear_error_message(context);
+       return KRB5_CRYPTO_INTERNAL;
+    }
+
+    civ = find_iv(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
+    if (civ == NULL)
+       return KRB5_BAD_MSIZE;
+
+    len = 0;
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+           data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+           continue;
+       len += data[i].data.length;
+    }
+
+    p = q = malloc(len);
+
+    for (i = 0; i < num_data; i++) {
+       if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+           data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+           continue;
+       memcpy(q, data[i].data.data, data[i].data.length);
+       q += data[i].data.length;
+    }
+
+    cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
+    cksum.checksum.length = civ->data.length;
+    cksum.checksum.data = civ->data.data;
+
+    ret = krb5_verify_checksum(context, crypto, usage, p, len, &cksum);
+    free(p);
+
+    if (ret == 0 && type)
+       *type = cksum.cksumtype;
+
+    return ret;
+}
+
 
-size_t KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
 krb5_crypto_length(krb5_context context,
                   krb5_crypto crypto,
-                  int type)
+                  int type,
+                  size_t *len)
 {
-    if (!derived_crypto(context, crypto))
-       return (size_t)-1;
+    if (!derived_crypto(context, crypto)) {
+       krb5_set_error_message(context, EINVAL, "not a derived crypto");
+       return EINVAL;
+    }
+       
     switch(type) {
     case KRB5_CRYPTO_TYPE_EMPTY:
+       *len = 0;
        return 0;
     case KRB5_CRYPTO_TYPE_HEADER:
-       return crypto->et->blocksize;
+       *len = crypto->et->blocksize;
+       return 0;
+    case KRB5_CRYPTO_TYPE_DATA:
+    case KRB5_CRYPTO_TYPE_SIGN_ONLY:
+       /* len must already been filled in */
+       return 0;
     case KRB5_CRYPTO_TYPE_PADDING:
        if (crypto->et->padsize > 1)
-           return crypto->et->padsize;
+           *len = crypto->et->padsize;
+       else
+           *len = 0;
        return 0;
     case KRB5_CRYPTO_TYPE_TRAILER:
-       return CHECKSUMSIZE(crypto->et->keyed_checksum);
+       *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+       return 0;
     case KRB5_CRYPTO_TYPE_CHECKSUM:
        if (crypto->et->keyed_checksum)
-           return CHECKSUMSIZE(crypto->et->keyed_checksum);
-       return CHECKSUMSIZE(crypto->et->checksum);
+           *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+       else
+           *len = CHECKSUMSIZE(crypto->et->checksum);
+       return 0;
+    }
+    krb5_set_error_message(context, EINVAL,
+                          "%d not a supported type", type);
+    return EINVAL;
+}
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_crypto_length_iov(krb5_context context,
+                      krb5_crypto crypto,
+                      krb5_crypto_iov *data,
+                      unsigned int num_data)
+{
+    krb5_error_code ret;
+    int i;
+
+    for (i = 0; i < num_data; i++) {
+       ret = krb5_crypto_length(context, crypto,
+                                data[i].flags,
+                                &data[i].data.length);
+       if (ret)
+           return ret;
     }
-    return (size_t)-1;
+    return 0;
 }
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_encrypt_ivec(krb5_context context,
                  krb5_crypto crypto,
index 96571af531a9f5ac577264dda5f118fcd2eaf015..8f366fa1487dc7d9ea3eebb5be5936c88c54cdff 100644 (file)
@@ -41,9 +41,7 @@ struct mbuf;
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
-#ifdef HAVE_IFADDR_H
 #include <ifaddrs.h>
-#endif
 
 static krb5_error_code
 gethostname_fallback (krb5_context context, krb5_addresses *res)
index 0435ab5d3b825210f2421bf6bf40f309409218d0..ff89a90d55a89afb45cd07d5248c8b4023194ce4 100644 (file)
@@ -1601,7 +1601,7 @@ krb5_init_creds_step(krb5_context context,
                    ret = 0; 
            } else if (ret == KRB5_KDC_ERR_WRONG_REALM && ctx->flags.canonicalize) {
                /* client referal to a new realm */
-               if (ctx->error.crealm) {
+               if (ctx->error.crealm == NULL) {
                    krb5_set_error_message(context, ret,
                                           N_("Got a client referral, not but no realm", ""));
                    goto out;
index 13dafacf21bd2227d8a20a118b7d36fbfb255a1b..1f2e76972898446112916aa6e8d7ae1b108ceec6 100644 (file)
 #endif
 
 #ifndef KRB5_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
 #define KRB5_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200) 
+#define KRB5_DEPRECATED __declspec(deprecated)
+#else
+#define KRB5_DEPRECATED
+#endif
 #endif
 
 /* simple constants */
index 31d267320f112aed770de496f08f419acec4f191..ee5c1159b138baa91e430cd0c0ef02dea84191a8 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include "krb5_locl.h"
+#include <vis.h>
 
 struct facility {
     int min;
@@ -218,11 +219,21 @@ log_file(const char *timestr,
         void *data)
 {
     struct file_data *f = data;
+    char *msgclean;
+    size_t len = strlen(msg) + 1;
     if(f->keep_open == 0)
        f->fd = fopen(f->filename, f->mode);
     if(f->fd == NULL)
        return;
-    fprintf(f->fd, "%s %s\n", timestr, msg);
+    /* make sure the log doesn't contain special chars */
+    len *= 4;
+    msgclean = malloc(len);
+    if (msgclean == NULL)
+       goto out;
+    strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL);
+    fprintf(f->fd, "%s %s\n", timestr, msgclean);
+    free(msgclean);
+ out:
     if(f->keep_open == 0) {
        fclose(f->fd);
        f->fd = NULL;
index 4be89b6564bcfeb20a61f008a87d4ccb90386716..acf984280ee1a16bae20680afb93c35d21f2d106 100644 (file)
@@ -110,7 +110,12 @@ emem_trunc(krb5_storage *sp, off_t offset)
      * If offset is larget then current size, or current size is
      * shrunk more then half of the current size, adjust buffer.
      */
-    if (offset > s->size || (s->size / 2) > offset) {
+    if (offset == 0) {
+       free(s->base);
+       s->size = 0;
+       s->base = NULL;
+       s->ptr = NULL;
+    } else if (offset > s->size || (s->size / 2) > offset) {
        void *base;
        size_t off;
        off = s->ptr - s->base;
diff --git a/source4/heimdal_build/ifaddrs.hin b/source4/heimdal_build/ifaddrs.hin
new file mode 100644 (file)
index 0000000..a50b033
--- /dev/null
@@ -0,0 +1 @@
+#include "system/network.h"
index 5c8d78e56d0346f7b486636924656b5abcfddaa7..e7e7ae184273079db3d430bafb8a7bfaf71bd40e 100644 (file)
@@ -46,6 +46,15 @@ dnl declarations will be correct). Phew!
 AC_CHECK_HEADERS([err.h], [],
        [ cp heimdal/lib/roken/err.hin heimdal_build/err.h ])
 
+dnl Not all systems have ifaddrs.h, so we provide a replacement. Heimdal
+dnl unconditionally #includes <ifaddrs.h>, so we need to create an ifaddrs.h,
+dnl but we can't just have a static one because we don't want to use
+dnl it on systems that have a real ifaddrs.h. If the system has a real
+dnl ifaddrs.h. We don't use heimdal's lib/roken/ifaddrs.hin because
+dnl our libreplace would conflict with it.
+AC_CHECK_HEADERS([ifaddrs.h], [],
+       [ cp heimdal_build/ifaddrs.hin heimdal_build/ifaddrs.h ])
+
 AC_CHECK_HEADERS([                             \
        crypt.h                                 \
        curses.h                                \
index ba43dd94952737ef6fd0c67d95194336e9d526ce..8c3def7dcac67c7b98a0edc7d71725c82e4b5f47 100644 (file)
 */
 
 #include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include "err.h"
 #include "roken.h"
+#include "system/filesys.h"
 
 #ifndef HAVE_ERR
  void err(int eval, const char *format, ...)
@@ -63,6 +61,7 @@
 #ifndef HAVE_FLOCK
  int flock(int fd, int op)
 {
+#undef flock
        struct flock lock;
        lock.l_whence = 0;
        lock.l_start = 0;
index 4eabbe2af4e4e314c47c6dec9cdef4054cbeb2dc..87060cff17b274966427e6eb380d3d2aa78bdbe5 100644 (file)
 #define HAVE_SETEUID 1
 #endif
 
+#ifndef HAVE_STRNLEN
+#define HAVE_STRNLEN
+#endif
+
 #ifndef HAVE_STRNDUP
 #define HAVE_STRNDUP
 #endif
 #define HAVE_STRCASECMP
 #endif
 
+#ifndef HAVE_ASPRINTF
+#define HAVE_ASPRINTF
+#endif
+
+#ifndef HAVE_VASPRINTF
+#define HAVE_VASPRINTF
+#endif
+
 #ifndef HAVE_MKSTEMP
 #define HAVE_MKSTEMP
 #endif
 #define HAVE_INNETGR
 #endif
 
+#ifndef HAVE_INET_ATON
+#define HAVE_INET_ATON
+#endif
+
 /* we lie about having pidfile() so that NetBSD5 can compile. Nothing
    in the parts of heimdal we use actually uses pidfile(), and we
    don't use it in Samba, so this works, although its ugly */
index 7d731ab13d993e4b15fb8a3d8669309229250f6d..cadbe33af612b6967a60c52775c61c97bd5ac8ce 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "includes.h"
 #include "system/time.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
 #include "librpc/gen_ndr/netlogon.h"
@@ -154,7 +154,7 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h
                flags.invalid = 1;
        }
 
-/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */
+/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in hdb_samba4_message2entry() */
 
 /*
        if (userAccountControl & UF_MNS_LOGON_ACCOUNT) {
@@ -193,7 +193,7 @@ static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex)
        talloc_free(entry_ex->ctx);
 }
 
-static krb5_error_code LDB_message2entry_keys(krb5_context context,
+static krb5_error_code hdb_samba4_message2entry_keys(krb5_context context,
                                              struct smb_iconv_convenience *iconv_convenience,
                                              TALLOC_CTX *mem_ctx,
                                              struct ldb_message *msg,
@@ -283,22 +283,22 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                                               (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        ret = EINVAL;
-                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
-                       krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+                       krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+                       krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
                        goto out;
                }
 
                if (newer_keys && _pkb.version != 4) {
                        ret = EINVAL;
-                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
-                       krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+                       krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+                       krb5_warnx(context, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
                        goto out;
                }
 
                if (!newer_keys && _pkb.version != 3) {
                        ret = EINVAL;
-                       krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
-                       krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
+                       krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
+                       krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
                        goto out;
                }
 
@@ -484,7 +484,7 @@ out:
 /*
  * Construct an hdb_entry from a directory entry.
  */
-static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, 
+static krb5_error_code hdb_samba4_message2entry(krb5_context context, HDB *db, 
                                         struct loadparm_context *lp_ctx, 
                                         TALLOC_CTX *mem_ctx, krb5_const_principal principal,
                                         enum hdb_ldb_ent_type ent_type,
@@ -511,7 +511,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        
        if (!samAccountName) {
                ret = ENOENT;
-               krb5_set_error_message(context, ret, "LDB_message2entry: no samAccountName present");
+               krb5_set_error_message(context, ret, "hdb_samba4_message2entry: no samAccountName present");
                goto out;
        }
 
@@ -690,7 +690,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
        entry_ex->entry.generation = NULL;
 
        /* Get keys from the db */
-       ret = LDB_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
+       ret = hdb_samba4_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
        if (ret) {
                /* Could be bougus data in the entry, or out of memory */
                goto out;
@@ -731,7 +731,7 @@ out:
 /*
  * Construct an hdb_entry from a directory entry.
  */
-static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db, 
+static krb5_error_code hdb_samba4_trust_message2entry(krb5_context context, HDB *db, 
                                               struct loadparm_context *lp_ctx,
                                               TALLOC_CTX *mem_ctx, krb5_const_principal principal,
                                               enum trust_direction direction,
@@ -909,7 +909,7 @@ out:
 
 }
 
-static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,                                     
+static krb5_error_code hdb_samba4_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,                                      
                                        TALLOC_CTX *mem_ctx,
                                        const char *realm,
                                        struct ldb_dn *realm_dn,
@@ -946,39 +946,39 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
        return 0;
 }
 
-static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
+static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode)
 {
        if (db->hdb_master_key_set) {
                krb5_error_code ret = HDB_ERR_NOENTRY;
-               krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");
-               krb5_set_error_message(context, ret, "LDB_open: use of a master key incompatible with LDB\n");
+               krb5_warnx(context, "hdb_samba4_open: use of a master key incompatible with LDB\n");
+               krb5_set_error_message(context, ret, "hdb_samba4_open: use of a master key incompatible with LDB\n");
                return ret;
        }               
 
        return 0;
 }
 
-static krb5_error_code LDB_close(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_close(krb5_context context, HDB *db)
 {
        return 0;
 }
 
-static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation)
+static krb5_error_code hdb_samba4_lock(krb5_context context, HDB *db, int operation)
 {
        return 0;
 }
 
-static krb5_error_code LDB_unlock(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_unlock(krb5_context context, HDB *db)
 {
        return 0;
 }
 
-static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name)
+static krb5_error_code hdb_samba4_rename(krb5_context context, HDB *db, const char *new_name)
 {
        return HDB_ERR_DB_INUSE;
 }
 
-static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db, 
+static krb5_error_code hdb_samba4_fetch_client(krb5_context context, HDB *db, 
                                        struct loadparm_context *lp_ctx, 
                                        TALLOC_CTX *mem_ctx, 
                                        krb5_const_principal principal,
@@ -1008,13 +1008,13 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
                return EINVAL;
        }
        
-       ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, 
+       ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, 
                                principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
                                realm_dn, msg, entry_ex);
        return ret;
 }
 
-static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db, 
+static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db, 
                                        struct loadparm_context *lp_ctx, 
                                        TALLOC_CTX *mem_ctx, 
                                        krb5_const_principal principal,
@@ -1044,19 +1044,18 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
 
                int lret;
                char *realm_fixed;
-               const char * const *princ_attrs = user_attrs;
                
                lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx, 
                                                       realm_dn, LDB_SCOPE_SUBTREE,
-                                                      &msg, princ_attrs, 
+                                                      &msg, krbtgt_attrs, 
                                                       "(&(objectClass=user)(samAccountName=krbtgt))"); 
                if (lret == LDB_ERR_NO_SUCH_OBJECT) {
-                       krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB!");
-                       krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB!");
+                       krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
+                       krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
                        return HDB_ERR_NOENTRY;
                } else if (lret != LDB_SUCCESS) {
-                       krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
-                       krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+                       krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+                       krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
                        return HDB_ERR_NOENTRY;
                }
                
@@ -1077,16 +1076,16 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
                talloc_free(realm_fixed);
                if (!alloc_principal->name.name_string.val[1]) {
                        ret = ENOMEM;
-                       krb5_set_error_message(context, ret, "LDB_fetch: strdup() failed!");
+                       krb5_set_error_message(context, ret, "hdb_samba4_fetch: strdup() failed!");
                        return ret;
                }
                principal = alloc_principal;
 
-               ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, 
+               ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, 
                                        principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, 
                                        realm_dn, msg, entry_ex);
                if (ret != 0) {
-                       krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");     
+                       krb5_warnx(context, "hdb_samba4_fetch: self krbtgt message2entry failed");      
                }
                return ret;
 
@@ -1109,21 +1108,21 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
 
                /* Trusted domains are under CN=system */
                
-               ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db, 
+               ret = hdb_samba4_lookup_trust(context, (struct ldb_context *)db->hdb_db, 
                                       mem_ctx, 
                                       realm, realm_dn, &msg);
                
                if (ret != 0) {
-                       krb5_warnx(context, "LDB_fetch: could not find principal in DB");
-                       krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB");
+                       krb5_warnx(context, "hdb_samba4_fetch: could not find principal in DB");
+                       krb5_set_error_message(context, ret, "hdb_samba4_fetch: could not find principal in DB");
                        return ret;
                }
                
-               ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx, 
+               ret = hdb_samba4_trust_message2entry(context, db, lp_ctx, mem_ctx, 
                                              principal, direction, 
                                              realm_dn, msg, entry_ex);
                if (ret != 0) {
-                       krb5_warnx(context, "LDB_fetch: trust_message2entry failed");   
+                       krb5_warnx(context, "hdb_samba4_fetch: trust_message2entry failed");    
                }
                return ret;
 
@@ -1134,17 +1133,16 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
 
 }
 
-static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db, 
-                                       struct loadparm_context *lp_ctx,
-                                       TALLOC_CTX *mem_ctx, 
-                                       krb5_const_principal principal,
-                                       unsigned flags,
-                                       hdb_entry_ex *entry_ex)
+static krb5_error_code hdb_samba4_lookup_server(krb5_context context, HDB *db, 
+                                               struct loadparm_context *lp_ctx,
+                                               TALLOC_CTX *mem_ctx, 
+                                               krb5_const_principal principal,
+                                               const char **attrs,
+                                               struct ldb_dn **realm_dn,
+                                               struct ldb_message **msg)
 {
        krb5_error_code ret;
        const char *realm;
-       struct ldb_message *msg = NULL;
-       struct ldb_dn *realm_dn;
        if (principal->name.name_string.len >= 2) {
                /* 'normal server' case */
                int ldb_ret;
@@ -1164,7 +1162,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                 * referral instead */
                nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,
                                                         mem_ctx, principal_string, 
-                                                        &user_dn, &realm_dn);
+                                                        &user_dn, realm_dn);
                free(principal_string);
                
                if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1174,7 +1172,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                ldb_ret = gendb_search_single_extended_dn((struct ldb_context *)db->hdb_db,
                                                          mem_ctx, 
                                                          user_dn, LDB_SCOPE_BASE,
-                                                         &msg, user_attrs,
+                                                         msg, attrs,
                                                          "(objectClass=*)");
                if (ldb_ret != LDB_SUCCESS) {
                        return HDB_ERR_NOENTRY;
@@ -1183,10 +1181,9 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
        } else {
                int lret;
                char *filter = NULL;
-               const char * const *princ_attrs = user_attrs;
                char *short_princ;
                /* server as client principal case, but we must not lookup userPrincipalNames */
-               realm_dn = ldb_get_default_basedn(db->hdb_db);
+               *realm_dn = ldb_get_default_basedn(db->hdb_db);
                realm = krb5_principal_get_realm(context, principal);
                
                /* TODO: Check if it is our realm, otherwise give referall */
@@ -1194,14 +1191,14 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                ret = krb5_unparse_name_flags(context, principal,  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
                
                if (ret != 0) {
-                       krb5_set_error_message(context, ret, "LDB_lookup_principal: could not parse principal");
-                       krb5_warnx(context, "LDB_lookup_principal: could not parse principal");
+                       krb5_set_error_message(context, ret, "hdb_samba4_lookup_principal: could not parse principal");
+                       krb5_warnx(context, "hdb_samba4_lookup_principal: could not parse principal");
                        return ret;
                }
                
                lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx, 
-                                                      realm_dn, LDB_SCOPE_SUBTREE,
-                                                      &msg, princ_attrs, "(&(objectClass=user)(samAccountName=%s))", 
+                                                      *realm_dn, LDB_SCOPE_SUBTREE,
+                                                      msg, attrs, "(&(objectClass=user)(samAccountName=%s))", 
                                                       ldb_binary_encode_string(mem_ctx, short_princ));
                free(short_princ);
                if (lret == LDB_ERR_NO_SUCH_OBJECT) {
@@ -1215,46 +1212,66 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
                }
        }
 
-       ret = LDB_message2entry(context, db, lp_ctx, mem_ctx, 
+       return 0;
+}
+
+static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db, 
+                                              struct loadparm_context *lp_ctx,
+                                              TALLOC_CTX *mem_ctx, 
+                                              krb5_const_principal principal,
+                                              unsigned flags,
+                                              hdb_entry_ex *entry_ex)
+{
+       krb5_error_code ret;
+       struct ldb_dn *realm_dn;
+       struct ldb_message *msg;
+
+       ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, principal, 
+                                      server_attrs, &realm_dn, &msg);
+       if (ret != 0) {
+               return ret;
+       }
+
+       ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx, 
                                principal, HDB_SAMBA4_ENT_TYPE_SERVER,
                                realm_dn, msg, entry_ex);
        if (ret != 0) {
-               krb5_warnx(context, "LDB_fetch: message2entry failed"); 
+               krb5_warnx(context, "hdb_samba4_fetch: message2entry failed");  
        }
 
        return ret;
 }
                        
-static krb5_error_code LDB_fetch(krb5_context context, HDB *db, 
+static krb5_error_code hdb_samba4_fetch(krb5_context context, HDB *db, 
                                 krb5_const_principal principal,
                                 unsigned flags,
                                 hdb_entry_ex *entry_ex)
 {
        krb5_error_code ret = HDB_ERR_NOENTRY;
-       TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");
+       TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_fetch context");
        struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
 
        if (!mem_ctx) {
                ret = ENOMEM;
-               krb5_set_error_message(context, ret, "LDB_fetch: talloc_named() failed!");
+               krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
                return ret;
        }
 
        if (flags & HDB_F_GET_CLIENT) {
-               ret = LDB_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+               ret = hdb_samba4_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
                if (ret != HDB_ERR_NOENTRY) goto done;
        }
        if (flags & HDB_F_GET_SERVER) {
                /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
-               ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+               ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
                if (ret != HDB_ERR_NOENTRY) goto done;
 
                /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
-               ret = LDB_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+               ret = hdb_samba4_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
                if (ret != HDB_ERR_NOENTRY) goto done;
        }
        if (flags & HDB_F_GET_KRBTGT) {
-               ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+               ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
                if (ret != HDB_ERR_NOENTRY) goto done;
        }
 
@@ -1263,12 +1280,12 @@ done:
        return ret;
 }
 
-static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
 {
        return HDB_ERR_DB_INUSE;
 }
 
-static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal)
+static krb5_error_code hdb_samba4_remove(krb5_context context, HDB *db, krb5_const_principal principal)
 {
        return HDB_ERR_DB_INUSE;
 }
@@ -1282,7 +1299,7 @@ struct hdb_ldb_seq {
        struct ldb_dn *realm_dn;
 };
 
-static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
 {
        krb5_error_code ret;
        struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;
@@ -1294,16 +1311,16 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
                return HDB_ERR_NOENTRY;
        }
 
-       mem_ctx = talloc_named(priv, 0, "LDB_seq context");
+       mem_ctx = talloc_named(priv, 0, "hdb_samba4_seq context");
 
        if (!mem_ctx) {
                ret = ENOMEM;
-               krb5_set_error_message(context, ret, "LDB_seq: talloc_named() failed!");
+               krb5_set_error_message(context, ret, "hdb_samba4_seq: talloc_named() failed!");
                return ret;
        }
 
        if (priv->index < priv->count) {
-               ret = LDB_message2entry(context, db, priv->lp_ctx, 
+               ret = hdb_samba4_message2entry(context, db, priv->lp_ctx, 
                                        mem_ctx, 
                                        NULL, HDB_SAMBA4_ENT_TYPE_ANY, 
                                        priv->realm_dn, priv->msgs[priv->index++], entry);
@@ -1321,7 +1338,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
        return ret;
 }
 
-static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
                                        hdb_entry_ex *entry)
 {
        struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
@@ -1353,11 +1370,11 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
        priv->realm_dn = ldb_get_default_basedn(ldb_ctx);
        priv->count = 0;
 
-       mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
+       mem_ctx = talloc_named(priv, 0, "hdb_samba4_firstkey context");
 
        if (!mem_ctx) {
                ret = ENOMEM;
-               krb5_set_error_message(context, ret, "LDB_firstkey: talloc_named() failed!");
+               krb5_set_error_message(context, ret, "hdb_samba4_firstkey: talloc_named() failed!");
                return ret;
        }
 
@@ -1382,7 +1399,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
 
        db->hdb_dbc = priv;
 
-       ret = LDB_seq(context, db, flags, entry);
+       ret = hdb_samba4_seq(context, db, flags, entry);
 
        if (ret != 0) {
                talloc_free(priv);
@@ -1393,18 +1410,87 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
        return ret;
 }
 
-static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigned flags,
                                   hdb_entry_ex *entry)
 {
-       return LDB_seq(context, db, flags, entry);
+       return hdb_samba4_seq(context, db, flags, entry);
 }
 
-static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
 {
        talloc_free(db);
        return 0;
 }
 
+krb5_error_code hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db, 
+                                                       hdb_entry_ex *entry,
+                                                       krb5_const_principal target_principal)
+{
+       struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
+       struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb_ctx, "loadparm"), 
+                                                         struct loadparm_context);
+       krb5_error_code ret;
+       krb5_principal enterprise_prinicpal = NULL;
+       struct ldb_dn *realm_dn;
+       struct ldb_message *msg;
+       struct dom_sid *orig_sid;
+       struct dom_sid *target_sid;
+       struct hdb_ldb_private *p = talloc_get_type(entry->ctx, struct hdb_ldb_private);
+       const char *delegation_check_attrs[] = {
+               "objectSid", NULL
+       };
+       
+       TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_check_constrained_delegation");
+
+       if (!mem_ctx) {
+               ret = ENOMEM;
+               krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
+               return ret;
+       }
+
+       if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+               /* Need to reparse the enterprise principal to find the real target */
+               if (target_principal->name.name_string.len != 1) {
+                       ret = KRB5_PARSE_MALFORMED;
+                       krb5_set_error_message(context, ret, "hdb_samba4_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components", 
+                                              target_principal->name.name_string.len);   
+                       talloc_free(mem_ctx);
+                       return ret;
+               }
+               ret = krb5_parse_name(context, target_principal->name.name_string.val[0], 
+                                     &enterprise_prinicpal);
+               if (ret) {
+                       talloc_free(mem_ctx);
+                       return ret;
+               }
+               target_principal = enterprise_prinicpal;
+       }
+
+       ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, target_principal, 
+                                      delegation_check_attrs, &realm_dn, &msg);
+
+       krb5_free_principal(context, enterprise_prinicpal);
+
+       if (ret != 0) {
+               talloc_free(mem_ctx);
+               return ret;
+       }
+
+       orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
+       target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
+
+       /* Allow delegation to the same principal, even if by a different
+        * name.  The easy and safe way to prove this is by SID
+        * comparison */
+       if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) {
+               talloc_free(mem_ctx);
+               return KRB5KDC_ERR_BADOPTION;
+       }
+
+       talloc_free(mem_ctx);
+       return ret;
+}
+
 /* This interface is to be called by the KDC, which is expecting Samba
  * calling conventions.  It is also called by a wrapper
  * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
@@ -1451,22 +1537,25 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx,
        }
 
        (*db)->hdb_dbc = NULL;
-       (*db)->hdb_open = LDB_open;
-       (*db)->hdb_close = LDB_close;
-       (*db)->hdb_fetch = LDB_fetch;
-       (*db)->hdb_store = LDB_store;
-       (*db)->hdb_remove = LDB_remove;
-       (*db)->hdb_firstkey = LDB_firstkey;
-       (*db)->hdb_nextkey = LDB_nextkey;
-       (*db)->hdb_lock = LDB_lock;
-       (*db)->hdb_unlock = LDB_unlock;
-       (*db)->hdb_rename = LDB_rename;
+       (*db)->hdb_open = hdb_samba4_open;
+       (*db)->hdb_close = hdb_samba4_close;
+       (*db)->hdb_fetch = hdb_samba4_fetch;
+       (*db)->hdb_store = hdb_samba4_store;
+       (*db)->hdb_remove = hdb_samba4_remove;
+       (*db)->hdb_firstkey = hdb_samba4_firstkey;
+       (*db)->hdb_nextkey = hdb_samba4_nextkey;
+       (*db)->hdb_lock = hdb_samba4_lock;
+       (*db)->hdb_unlock = hdb_samba4_unlock;
+       (*db)->hdb_rename = hdb_samba4_rename;
        /* we don't implement these, as we are not a lockable database */
        (*db)->hdb__get = NULL;
        (*db)->hdb__put = NULL;
        /* kadmin should not be used for deletes - use other tools instead */
        (*db)->hdb__del = NULL;
-       (*db)->hdb_destroy = LDB_destroy;
+       (*db)->hdb_destroy = hdb_samba4_destroy;
+
+       (*db)->hdb_auth_status = NULL;
+       (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation;
 
        return NT_STATUS_OK;
 }
index 5bd4cb10c7345ce05982f71dcb7447d8f9816b0f..21ae7091a691700e09fbd1db34c90e69916d3177 100644 (file)
@@ -21,7 +21,7 @@
 */
 
 #include "includes.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "lib/ldb/include/ldb.h"
 #include "librpc/gen_ndr/ndr_krb5pac.h"
 #include "librpc/gen_ndr/krb5pac.h"
index 64ad6832dbb050c32b44db583f7548fa4df4a615..164e5a95a045c6f98c26f616846a11629a455232 100644 (file)
@@ -240,7 +240,7 @@ int ldb_connect(struct ldb_context *ldb, const char *url,
 
        if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
                ldb_debug(ldb, LDB_DEBUG_FATAL,
-                         "Unable to load modules for %s: %s\n",
+                         "Unable to load modules for %s: %s",
                          url, ldb_errstring(ldb));
                return LDB_ERR_OTHER;
        }
index f8009eb8a345403b64f85fe7985e45b5d22efe4b..7680862c2cd9485ba1470b8b71e27e54adc91f99 100644 (file)
@@ -56,6 +56,7 @@ static void ldb_debug_stderr(void *context, enum ldb_debug_level level,
 {
        if (level <= LDB_DEBUG_WARNING) {
                vfprintf(stderr, fmt, ap);
+               fprintf(stderr, "\n");
        }
 }
 
index d64a9f1c3a813e07c584c854a99fc19b0cc4d50e..d890ff83006215373243057508f5f897e39c12c7 100644 (file)
@@ -296,7 +296,7 @@ int ldb_ldif_write(struct ldb_context *ldb,
                        }
                }
                if (!ldb_changetypes[i].name) {
-                       ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n",
+                       ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d",
                                  ldif->changetype);
                        talloc_free(mem_ctx);
                        return -1;
@@ -561,7 +561,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
        
        /* first line must be a dn */
        if (ldb_attr_cmp(attr, "dn") != 0) {
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n", 
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'",
                          attr);
                goto failed;
        }
@@ -569,7 +569,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
        msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value);
 
        if ( ! ldb_dn_validate(msg->dn)) {
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", 
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'",
                          (char *)value.data);
                goto failed;
        }
@@ -588,8 +588,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                                }
                        }
                        if (!ldb_changetypes[i].name) {
-                               ldb_debug(ldb, LDB_DEBUG_ERROR, 
-                                         "Error: Bad ldif changetype '%s'\n",(char *)value.data);
+                               ldb_debug(ldb, LDB_DEBUG_ERROR,
+                                         "Error: Bad ldif changetype '%s'",(char *)value.data);
                        }
                        flags = 0;
                        continue;
@@ -638,7 +638,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
                        }
                        if (value.length == 0) {
                                ldb_debug(ldb, LDB_DEBUG_ERROR,
-                                         "Error: Attribute value cannot be empty for attribute '%s'\n", el->name);
+                                         "Error: Attribute value cannot be empty for attribute '%s'", el->name);
                                goto failed;
                        }
                        if (value.data != el->values[el->num_values].data) {
index c622701d308c1c2807ab0c8e5a30085399343bb4..e6ee0de0274e9b5e6f85b39687552bd47d6204d5 100644 (file)
@@ -335,7 +335,7 @@ static int ldb_match_extended(struct ldb_context *ldb,
                }
        }
        if (comp == NULL) {
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n",
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
                          tree->u.extended.rule_id);
                return -1;
        }
index ae97ef4cced4db84ed7490aee01167165f32abb4..05dffd005a09b8b10d29cc71a80ed996d2976ddb 100644 (file)
@@ -84,13 +84,13 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
        /* spaces not admitted */
        modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
        if ( ! modstr) {
-               ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n");
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()");
                return NULL;
        }
 
        modules = talloc_realloc(mem_ctx, modules, char *, 2);
        if ( ! modules ) {
-               ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
                talloc_free(modstr);
                return NULL;
        }
@@ -106,7 +106,7 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
                i++;
                modules = talloc_realloc(mem_ctx, modules, char *, i + 2);
                if ( ! modules ) {
-                       ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+                       ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
                        return NULL;
                }
 
@@ -239,7 +239,7 @@ int ldb_connect_backend(struct ldb_context *ldb,
 
        if (fn == NULL) {
                ldb_debug(ldb, LDB_DEBUG_FATAL,
-                         "Unable to find backend for '%s'\n", url);
+                         "Unable to find backend for '%s'", url);
                return LDB_ERR_OTHER;
        }
 
@@ -247,7 +247,7 @@ int ldb_connect_backend(struct ldb_context *ldb,
 
        if (ret != LDB_SUCCESS) {
                ldb_debug(ldb, LDB_DEBUG_ERROR,
-                         "Failed to connect to '%s'\n", url);
+                         "Failed to connect to '%s'", url);
                return ret;
        }
        return ret;
@@ -304,18 +304,18 @@ static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
        path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name, 
                               SHLIBEXT);
 
-       ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
+       ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path);
 
        handle = dlopen(path, RTLD_NOW);
        if (handle == NULL) {
-               ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
+               ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror());
                return NULL;
        }
 
        sym = (int (*)(void))dlsym(handle, symbol);
 
        if (sym == NULL) {
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s\n", symbol, path, dlerror());
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror());
                return NULL;
        }
 
@@ -351,7 +351,7 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
                }
                
                if (ops == NULL) {
-                       ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", 
+                       ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found",
                                  module_list[i]);
                        continue;
                }
@@ -382,7 +382,7 @@ int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
        if (module) {
                int ret = module->ops->init_context(module);
                if (ret != LDB_SUCCESS) {
-                       ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed\n", module->ops->name);
+                       ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name);
                        return ret;
                }
        }
@@ -428,7 +428,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                        ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
                } else if (ret != LDB_SUCCESS) {
-                       ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
+                       ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb));
                        talloc_free(mem_ctx);
                        return ret;
                } else {
@@ -436,7 +436,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
                        if (res->count == 0) {
                                ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
                        } else if (res->count > 1) {
-                               ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
+                               ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out", res->count);
                                talloc_free(mem_ctx);
                                return -1;
                        } else {
index a9a6dad46d5aeb5b0a93d33397fa4830fc4deec9..4234fcc31154af825650ed4e81032ea01c631ffc 100644 (file)
@@ -67,11 +67,8 @@ build-python:: ldb.$(SHLIBEXT)
 pyldb.o: $(ldbdir)/pyldb.c
        $(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
 
-pyldb_util.o: $(ldbdir)/pyldb_util.c
-       $(CC) $(PICFLAG) -c $(ldbdir)/pyldb_util.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-
-ldb.$(SHLIBEXT): pyldb.o pyldb_util.o
-       $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o pyldb_util.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
+ldb.$(SHLIBEXT): pyldb.o 
+       $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
 
 install-python:: build-python
        mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
index b7e4c8584461fdb92bfca0cbea27f1ae581b4edb..01482f6bfbcceb4fafac434be6a0fa7491533728 100644 (file)
@@ -2,7 +2,7 @@ prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
 includedir=@includedir@
-modulesdir=@modulesdir@
+modulesdir=@LDB_MODULESDIR@
 
 Name: ldb
 Description: An LDAP-like embedded database
index 4447d0e09a473b8af1ca6983d73ff8d5f3394f0a..ffde048223f318a12583ff02aa6f286d65110c43 100644 (file)
@@ -790,7 +790,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
 
        status = ldap_connect(ildb->ldap, url);
        if (!NT_STATUS_IS_OK(status)) {
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n",
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s",
                          url, ldap_errstr(ildb->ldap, module, status));
                goto failed;
        }
@@ -810,14 +810,14 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
                        const char *password = cli_credentials_get_password(creds);
                        status = ldap_bind_simple(ildb->ldap, bind_dn, password);
                        if (!NT_STATUS_IS_OK(status)) {
-                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
                                          ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }
                } else {
                        status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx);
                        if (!NT_STATUS_IS_OK(status)) {
-                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
                                          ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }
index 43a01f75a73baa5f7c3805c745bd6c0ddac07bdb..52c16101bb4ec280dbfd8bd3ae6dbdcdadd563a3 100644 (file)
@@ -219,7 +219,7 @@ static int lldb_search(struct lldb_context *lldb_ac)
        }
 
        if (req->controls != NULL) {
-               ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n");
+               ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!");
        }
 
        ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -871,7 +871,7 @@ static int lldb_connect(struct ldb_context *ldb,
 
        ret = ldap_initialize(&lldb->ldap, url);
        if (ret != LDAP_SUCCESS) {
-               ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n",
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s",
                          url, ldap_err2string(ret));
                goto failed;
        }
@@ -880,7 +880,7 @@ static int lldb_connect(struct ldb_context *ldb,
 
        ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
        if (ret != LDAP_SUCCESS) {
-               ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n",
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s",
                          ldap_err2string(ret));
                goto failed;
        }
index 5b4ea7910a75137c8ddea361620d64491e71162d..68e9d3f392987cd78608e7faf276687edd7be561 100644 (file)
@@ -242,7 +242,7 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque
 
        default:
                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
-                         "Invalid remote request!\n");
+                         "Invalid remote request!");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
@@ -503,14 +503,14 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
                case MAP_GENERATE:
                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                  "MAP_IGNORE/MAP_GENERATE attribute '%s' "
-                                 "used in DN!\n", ldb_dn_get_component_name(dn, i));
+                                 "used in DN!", ldb_dn_get_component_name(dn, i));
                        goto failed;
 
                case MAP_CONVERT:
                        if (map->u.convert.convert_local == NULL) {
                                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                          "'convert_local' not set for attribute '%s' "
-                                         "used in DN!\n", ldb_dn_get_component_name(dn, i));
+                                         "used in DN!", ldb_dn_get_component_name(dn, i));
                                goto failed;
                        }
                        /* fall through */
@@ -578,14 +578,14 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
                case MAP_GENERATE:
                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                  "MAP_IGNORE/MAP_GENERATE attribute '%s' "
-                                 "used in DN!\n", ldb_dn_get_component_name(dn, i));
+                                 "used in DN!", ldb_dn_get_component_name(dn, i));
                        goto failed;
 
                case MAP_CONVERT:
                        if (map->u.convert.convert_remote == NULL) {
                                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                          "'convert_remote' not set for attribute '%s' "
-                                         "used in DN!\n", ldb_dn_get_component_name(dn, i));
+                                         "used in DN!", ldb_dn_get_component_name(dn, i));
                                goto failed;
                        }
                        /* fall through */
@@ -1007,7 +1007,7 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
        dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name);
        if ( ! ldb_dn_validate(dn)) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
-                         "Failed to construct '%s' DN!\n", MAP_DN_NAME);
+                         "Failed to construct '%s' DN!", MAP_DN_NAME);
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
@@ -1018,13 +1018,13 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
        }
        if (res->count == 0) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
-                         "No results for '%s=%s'!\n", MAP_DN_NAME, name);
+                         "No results for '%s=%s'!", MAP_DN_NAME, name);
                talloc_free(res);
                return LDB_ERR_CONSTRAINT_VIOLATION;
        }
        if (res->count > 1) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
-                         "Too many results for '%s=%s'!\n", MAP_DN_NAME, name);
+                         "Too many results for '%s=%s'!", MAP_DN_NAME, name);
                talloc_free(res);
                return LDB_ERR_CONSTRAINT_VIOLATION;
        }
index 455740ce590ee27dc0f54a8af5a0072c5da77daa..89037419fbca71fcbf1f34386c0620bc0eb2f7fc 100644 (file)
@@ -73,7 +73,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
        /* Unknown attribute: ignore */
        if (map == NULL) {
                ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
-                         "Not mapping attribute '%s': no mapping found\n",
+                         "Not mapping attribute '%s': no mapping found",
                          old->name);
                goto local;
        }
@@ -86,7 +86,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
                if (map->u.convert.convert_local == NULL) {
                        ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
                                  "Not mapping attribute '%s': "
-                                 "'convert_local' not set\n",
+                                 "'convert_local' not set",
                                  map->local_name);
                        goto local;
                }
@@ -100,7 +100,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
                if (map->u.generate.generate_remote == NULL) {
                        ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
                                  "Not mapping attribute '%s': "
-                                 "'generate_remote' not set\n",
+                                 "'generate_remote' not set",
                                  map->local_name);
                        goto local;
                }
@@ -167,7 +167,7 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca
                /* Skip 'IS_MAPPED' */
                if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) {
                        ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
-                                 "Skipping attribute '%s'\n",
+                                 "Skipping attribute '%s'",
                                  msg->elements[i].name);
                        continue;
                }
index ffcefad6be6fdf066cb4b3552f11d5d4e75d6ff5..4487d7e763dd4118f987c49cd7a2c2b75a4f7b92 100644 (file)
@@ -304,7 +304,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
                if (map->u.convert.convert_remote == NULL) {
                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                  "Skipping attribute '%s': "
-                                 "'convert_remote' not set\n",
+                                 "'convert_remote' not set",
                                  attr_name);
                        return LDB_SUCCESS;
                }
@@ -323,7 +323,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
                if (map->u.generate.generate_local == NULL) {
                        ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
                                  "Skipping attribute '%s': "
-                                 "'generate_local' not set\n",
+                                 "'generate_local' not set",
                                  attr_name);
                        return LDB_SUCCESS;
                }
@@ -900,7 +900,7 @@ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx,
        if (map->type == MAP_GENERATE) {
                ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
                          "Skipping attribute '%s': "
-                         "'convert_operator' not set\n",
+                         "'convert_operator' not set",
                          tree->u.equality.attr);
                *new = NULL;
                return 0;
@@ -1062,7 +1062,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares)
                           ac->req->op.search.scope)) {
                ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "
                          "Skipping record '%s': "
-                         "doesn't match original search\n",
+                         "doesn't match original search",
                          ldb_dn_get_linearized(ares->message->dn));
                return LDB_SUCCESS;
        }
index 042c1c928292efd9647b54197f086a0edf27fce0..2c399686eafce1fd563ebf3809603e6d868599d2 100644 (file)
@@ -141,7 +141,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
                const struct ldb_schema_syntax *s;
 
                if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) {
-                       ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name);
+                       ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name);
                        goto failed;
                }
                switch (flags & ~LTDB_FLAG_HIDDEN) {
@@ -156,7 +156,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
                        break;
                default:
                        ldb_debug(ldb, LDB_DEBUG_ERROR, 
-                                 "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n",
+                                 "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES",
                                  flags, msg->elements[i].name);
                        goto failed;
                }
@@ -164,7 +164,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
                s = ldb_standard_syntax_by_name(ldb, syntax);
                if (s == NULL) {
                        ldb_debug(ldb, LDB_DEBUG_ERROR, 
-                                 "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n",
+                                 "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES",
                                  syntax, msg->elements[i].name);
                        goto failed;
                }
index fab60cb1253677a5daf96371a3160864f1c2992b..1daa4500f89b0c6859232d06f27005c0c41104a5 100644 (file)
@@ -1409,7 +1409,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
                struct ldb_ldif ldif;
 
                ldb_debug(ldb, LDB_DEBUG_ERROR,
-                               "ERROR: dn %s not found in %s\n", dn,
+                               "ERROR: dn %s not found in %s", dn,
                                ldb_dn_get_linearized(dn_key));
                ldif.changetype = LDB_CHANGETYPE_NONE;
                ldif.msg = msg;
@@ -1587,7 +1587,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
        key2 = ltdb_key(module, msg->dn);
        if (key2.dptr == NULL) {
                /* probably a corrupt record ... darn */
-               ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n",
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
                                                        ldb_dn_get_linearized(msg->dn));
                talloc_free(msg);
                return 0;
@@ -1609,7 +1609,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
                ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
        } else {
                ldb_debug(ldb, LDB_DEBUG_ERROR,
-                       "Adding special ONE LEVEL index failed (%s)!\n",
+                       "Adding special ONE LEVEL index failed (%s)!",
                        ldb_dn_get_linearized(msg->dn));
        }
 
index 1995606f88042a0595db1ba89e59c0a7b9731f7c..5640e7053c8f493ca9e1157d4b51d38aa50d659b 100644 (file)
@@ -280,7 +280,7 @@ int ltdb_unpack_data(struct ldb_module *module,
 
        if (remaining != 0) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, 
-                         "Error: %d bytes unread in ltdb_unpack_data\n", remaining);
+                         "Error: %d bytes unread in ltdb_unpack_data", remaining);
        }
 
        return 0;
index 4a452761b8332de4431c46da1cf01ece145a8f02..d4f7b452cb4c22a1743d103be5b053051d2cd9b3 100644 (file)
@@ -1276,7 +1276,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
                                   ldb_get_create_perms(ldb), ldb);
        if (!ltdb->tdb) {
                ldb_debug(ldb, LDB_DEBUG_ERROR,
-                         "Unable to open tdb '%s'\n", path);
+                         "Unable to open tdb '%s'", path);
                talloc_free(ltdb);
                return -1;
        }
index dd5afd868cd3fa144b9908f31bae4065a9b46603..271cf5262506d47583996eccfe06062a147dc68e 100644 (file)
@@ -393,7 +393,7 @@ static int asq_init(struct ldb_module *module)
 
        ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID);
        if (ret != LDB_SUCCESS) {
-               ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n");
+               ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!");
        }
 
        return ldb_next_init(module);
index 43b223b52e19f078a5adaf483a5123d8352a3e32..77b0014afac35739b91ab46cc19e60672ef59887 100644 (file)
@@ -169,8 +169,8 @@ static int operational_search_post_process(struct ldb_module *module,
        return 0;
 
 failed:
-       ldb_debug_set(ldb, LDB_DEBUG_WARNING, 
-                     "operational_search_post_process failed for attribute '%s'\n", 
+       ldb_debug_set(ldb, LDB_DEBUG_WARNING,
+                     "operational_search_post_process failed for attribute '%s'",
                      attrs[a]);
        return -1;
 }
index f2692305d55918a810626d06117ee8c9599c5cd4..b712f84872154327aeda6bd5a8749fd80d0144d6 100644 (file)
@@ -409,7 +409,7 @@ static int paged_request_init(struct ldb_module *module)
        if (ret != LDB_SUCCESS) {
                ldb_debug(ldb, LDB_DEBUG_WARNING,
                        "paged_results:"
-                       "Unable to register control with rootdse!\n");
+                       "Unable to register control with rootdse!");
        }
 
        return ldb_next_init(module);
index 880678d89de4f576dd808573babdffca2e456724..e9f873f0732e8dfc3124182f6f3945dbc2a3c363 100644 (file)
@@ -98,7 +98,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
        int i, ret;
 
        ldb = ldb_module_get_ctx(module);
-       ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n");
+       ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");
 
        /* do not manipulate our control entries */
        if (ldb_dn_is_special(req->op.add.message->dn)) {
@@ -288,7 +288,7 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
        int ret;
 
        ldb = ldb_module_get_ctx(module);
-       ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n");
+       ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");
 
        /* do not manipulate our control entries */
        if (ldb_dn_is_special(req->op.rename.newdn)) {
index a95a86140c4df5071c22436b99266bfbad1f6df3..b4ea017b3269947e70c11ce756f049ba1d933ea7 100644 (file)
@@ -339,7 +339,7 @@ static int server_sort_init(struct ldb_module *module)
        if (ret != LDB_SUCCESS) {
                ldb_debug(ldb, LDB_DEBUG_WARNING,
                        "server_sort:"
-                       "Unable to register control with rootdse!\n");
+                       "Unable to register control with rootdse!");
        }
 
        return ldb_next_init(module);
index 2e0f4fdf3606b88576b905d8949aa8417171825e..bcca70eb82bb81e997b72f9d7e5655c2fc4e4243 100644 (file)
@@ -41,6 +41,16 @@ typedef intargfunc ssizeargfunc;
 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
 #endif
 
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+       if (ret == LDB_ERR_PYTHON_EXCEPTION)
+               return; /* Python exception should already be set, just keep that */
+
+       PyErr_SetObject(error, 
+                                       Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 
+                                 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
+
 static PyObject *PyExc_LdbError;
 
 PyAPI_DATA(PyTypeObject) PyLdbMessage;
index e0e0d2af69ec5385b5fb85ac5b1069f9dbdf4d51..a0954158bd63b2b1d8189be372231a0edbe651ab 100644 (file)
@@ -85,7 +85,6 @@ typedef struct {
 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
 #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
 
-void PyErr_SetLdbError(PyObject *exctype, int ret, struct ldb_context *ldb_ctx);
 #define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \
        if (ret != LDB_SUCCESS) { \
                PyErr_SetLdbError(err, ret, ldb); \
diff --git a/source4/lib/ldb/pyldb_util.c b/source4/lib/ldb/pyldb_util.c
deleted file mode 100644 (file)
index 84183e8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   interface to ldb.
-
-   Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
-
-        ** NOTE! The following LGPL license applies to the ldb
-        ** library. This does NOT imply that all of Samba is released
-        ** under the LGPL
-   
-   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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "replace.h"
-#include <Python.h>
-#include "pyldb.h"
-#include <ldb.h>
-
-void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
-{
-       if (ret == LDB_ERR_PYTHON_EXCEPTION)
-               return; /* Python exception should already be set, just keep that */
-
-       PyErr_SetObject(error, 
-                                       Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 
-                                 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
-}
index e08c150aafac1909ee04264d3679fb9e1fb7523b..dbc2eb27eb20712fbb704142f7a2d8386e9e36a0 100644 (file)
@@ -1,14 +1,6 @@
 [PYTHON::pyldb]
 LIBRARY_REALNAME = ldb.$(SHLIBEXT)
 PUBLIC_DEPENDENCIES = LIBLDB PYTALLOC
-PRIVATE_DEPENDENCIES = pyldb_util
 
 pyldb_OBJ_FILES = $(ldbsrcdir)/pyldb.o 
 $(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
-
-[SUBSYSTEM::pyldb_util]
-PUBLIC_DEPENDENCIES = LIBPYTHON
-PRIVATE_DEPENDENCIES = LIBLDB
-
-pyldb_util_OBJ_FILES = $(ldbsrcdir)/pyldb_util.o
-$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
index 639271b76df8af76e7876123b72db54d76c3ac22..0598f8039bf4a2448a259d96c9f3ef0391fc5f4d 100644 (file)
@@ -19,6 +19,7 @@ ctags:
 showflags::
        @echo 'ldb will be compiled with flags:'
        @echo '  CFLAGS = $(CFLAGS)'
+       @echo '  SHLD_FLAGS = $(SHLD_FLAGS)'
        @echo '  LIBS = $(LIBS)'
 
 distclean::
index 925806985e1bab27acf316b0a316f29a0cdab921..24d86abf4850e6f1411ab218914be2d414b462d3 100644 (file)
@@ -316,6 +316,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename,
        if (read(fd, &hdr, 4) != 4) {
                DEBUG(0, ("Error reading registry patch file `%s'\n",
                        filename));
+               close(fd);
                return WERR_GENERAL_FAILURE;
        }
 
index 83520f673d2000333cb89ada040da9301ebd8224..3f6553f7e8a4e671bd84a762ad03df3bd2c4b6a9 100644 (file)
@@ -3,6 +3,3 @@ Samba3 import, migration and compatibility.
 
 For example, the first file in this directory (smbpasswd.c) handles
 portions of the smbpasswd file format.
-
-The other files in this directory support reading the various 
-TDB databases from Samba3.
diff --git a/source4/lib/samba3/STATUS b/source4/lib/samba3/STATUS
deleted file mode 100644 (file)
index e464452..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
---- Samba3 -> Samba4 Upgrade ---
-(C) 2005 Jelmer Vernooij <jelmer@samba.org>
-Published under the GNU GPL
-
-Sponsored by the Google Summer of Code program (http://code.google.com/summerofcode.html)
-Mentored by Andrew Bartlett <abartlet@samba.org>
-Thanks!
-
-Done:
- - Reading wins.dat
- - Reading registry.tdb
- - Reading passdb.tdb
- - Reading account_policy.tdb
- - Reading group_mappings.tdb
- - Reading winbindd_idmap.tdb
- - Reading share_info.tdb
- - Reading secrets.tdb
- - Reading smbpasswd
- - Reading + writing (generic) smb.conf files
- - Testsuite for read support mentioned above
- - Console utility for dumping Samba information
- - Import user accounts in Samba4
- - Import groups in Samba4
- - Import secrets in Samba4
- - Import WINS data in Samba4
- - Dump idmap data to LDB
- - Import registry keys/values in Samba4
- - Import account policies in Samba4
- - Testsuite for upgrade
- - Console utility from upgrading from Samba3 -> Samba4
- - SWAT (Web interface) support for upgrading from Samba3 -> Samba4
- - LDB generic mapping module
- - (Experimental) Samba4 LDB <-> Samba3 LDAP mapping module based on LDB generic mapping module
- - Testsuite for Samba4 LDB <-> Samba3 LDAP mapping module
-
-Source files:
-source/lib/ldb/modules/ldb_map.c
-source/lib/ldb/modules/ldb_map.h
-source/lib/samba3/group.c
-source/lib/samba3/idmap.c
-source/lib/samba3/policy.c
-source/lib/samba3/registry.c
-source/lib/samba3/samba3.c
-source/lib/samba3/secrets.c
-source/lib/samba3/share_info.c
-source/lib/samba3/smbpasswd.c
-source/lib/samba3/tdbsam.c
-source/lib/samba3/winsdb.c
-source/lib/samba3/samba3.h
-source/scripting/libjs/upgrade.js
-source/scripting/ejs/smbcalls_param.c
-source/scripting/ejs/smbcalls_samba3.c
-source/param/generic.c
-source/param/generic.h
-testdata/samba3/verify
-testprogs/ejs/samba3sam
-source/setup/upgrade
-source/scripting/bin/samba3dump
-source/dsdb/samdb/ldb_modules/samba3sam.c
-source/script/tests/test_s3upgrade.sh
-swat/install/samba3.esp
-
-Known remaining issues:
- - [upgrade] Conversion from the smbpasswd/TDB passwords to ntPwdHash / lmPwdHash is broken. Couldn't find out why.
- - [ldb_map] Conversion of attribute names in DN's is still a bit dodgy
- - [ldb_map] mapped objectClass names may be mentioned multiple times in returned records
- - [ldb_map] add/modify support not tested very well with LDAP yet (only LDB+TDB)
- - [ldb_map] group membership is not yet mapped (only primaryGroupID / sambaPrimaryGroupSID)
index 1a0ce041436699f31b4923ee31f4e4f031f3d774..87de13f8f89bf3a69235526b85dfd9510ee29e29 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "librpc/gen_ndr/security.h"
 #include "librpc/gen_ndr/samr.h"
-#include "param/param.h"
 
 struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, const char *p);
 char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info);
index e1349e06f840970025df78297f9a1f56eac0c17c..0764dfeb8fa8b07a159b05812ef7e67c08830651 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
 
-   security descriptror utility functions
+   security descriptor utility functions
 
    Copyright (C) Andrew Tridgell               2004
    Copyright (C) Stefan Metzmacher             2005
index f3684ed280aa8dcabc34bd9eed9a1676e40129b2..5d09a5083a4ebbf2ff044f0c3ea4244aa1216e7f 100644 (file)
@@ -78,9 +78,11 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
        req = talloc(transport, struct smb2_request);
        if (req == NULL) return NULL;
 
-       seqnum = transport->seqnum++;
-       if (seqnum == UINT64_MAX) {
-               seqnum = transport->seqnum++;
+       seqnum = transport->seqnum;
+       if (transport->credits.charge > 0) {
+               transport->seqnum += transport->credits.charge;
+       } else {
+               transport->seqnum += 1;
        }
 
        req->state     = SMB2_REQUEST_INIT;
@@ -131,7 +133,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
 
        SIVAL(req->out.hdr, 0,                          SMB2_MAGIC);
        SSVAL(req->out.hdr, SMB2_HDR_LENGTH,            SMB2_HDR_BODY);
-       SSVAL(req->out.hdr, SMB2_HDR_EPOCH,             0);
+       SSVAL(req->out.hdr, SMB2_HDR_EPOCH,             transport->credits.charge);
        SIVAL(req->out.hdr, SMB2_HDR_STATUS,            0);
        SSVAL(req->out.hdr, SMB2_HDR_OPCODE,            opcode);
        SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            transport->credits.ask_num);
index eb231984dfa516e4d2d726fc45d6678f1f02a19a..6372cd805b4bd391f731a2639a777e4214ac2171 100644 (file)
@@ -87,6 +87,7 @@ struct smb2_transport {
        } compound;
 
        struct {
+               uint16_t charge;
                uint16_t ask_num;
        } credits;
 
index 60522370b7ab3ec5edf35c201fbd48c5d8baf53a..dffd1acd2b503ec5a0d85ea091909618ba70f759 100644 (file)
@@ -84,6 +84,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
 
        transport->socket = talloc_steal(transport, sock);
        transport->options = *options;
+       transport->credits.charge = 0;
        transport->credits.ask_num = 1;
 
        /* setup the stream -> packet parser */
@@ -552,6 +553,12 @@ void smb2_transport_credits_ask_num(struct smb2_transport *transport,
        transport->credits.ask_num = ask_num;
 }
 
+void smb2_transport_credits_set_charge(struct smb2_transport *transport,
+                                      uint16_t charge)
+{
+       transport->credits.charge = charge;
+}
+
 static void idle_handler(struct tevent_context *ev, 
                         struct tevent_timer *te, struct timeval t, void *private_data)
 {
index dbbabd6a6da636f8b9e97bf17d6d101aec5c4f34..b89e238a1cb3e4899a6cc91a63143ba15c2423a8 100644 (file)
@@ -25,7 +25,7 @@
 #include "lib/ldb/include/ldb_errors.h"
 #include "lib/ldb_wrap.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_misc.h"
index b0669640f3085f3c9bf92207d50d7406bc119525..9e7abe81b1a7cebde7f21cbc58d0241f477e02bf 100644 (file)
@@ -484,7 +484,7 @@ struct composite_context *libnet_GroupList_send(struct libnet_context *ctx,
        /* store the arguments in the state structure */
        s->ctx          = ctx;
        s->page_size    = io->in.page_size;
-       s->resume_index = (uint32_t)io->in.resume_index;
+       s->resume_index = io->in.resume_index;
        s->domain_name  = talloc_strdup(c, io->in.domain_name);
        s->monitor_fn   = monitor;
 
index b80d3449c8ed9473ae76ef128a9ebf69f50bf9c3..8ac47437fd275d1e2d941b78bd26968fa27ea152 100644 (file)
@@ -58,11 +58,11 @@ struct libnet_GroupList {
        struct {
                const char *domain_name;
                int page_size;
-               uint resume_index;
+               uint32_t resume_index;
        } in;
        struct {
                int count;
-               uint resume_index;
+               uint32_t resume_index;
                
                struct grouplist {
                        const char *sid;
index 08a2295169b74119c6bb2b121603c9434b941d5f..8092260515b97e0da47b35d21ea5a1576b8b0c27 100644 (file)
@@ -25,6 +25,7 @@
 #include "../lib/util/dlinklist.h"
 #include "samba3/samba3.h"
 #include "libcli/security/security.h"
+#include "param/param.h"
 
 
 struct samdump_secret {
index e0e5e421151a87b56f8506403b9af47703fdd022..3bd7a4e28723f1aff89fb7a66fc600132a16fc74 100644 (file)
@@ -25,7 +25,7 @@
 #include "lib/ldb/include/ldb_errors.h"
 #include "lib/ldb_wrap.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
 #include "param/param.h"
 
index 8606d0856e20cc73fc29faa7d79078a48db04d88..dd4d501c176f22a71f70276d5cbc2dca71c34dee 100644 (file)
@@ -945,7 +945,7 @@ struct composite_context* libnet_UserList_send(struct libnet_context *ctx,
        /* store the arguments in the state structure */
        s->ctx          = ctx;
        s->page_size    = r->in.page_size;
-       s->resume_index = (uint32_t)r->in.resume_index;
+       s->resume_index = r->in.resume_index;
        s->domain_name  = talloc_strdup(c, r->in.domain_name);
        s->monitor_fn   = monitor;
 
index 4aad654b3bf9b64bd261a23c2028f4b5934220d8..8203d14c337995f87e90aa23f69b6accdb7db117 100644 (file)
@@ -140,11 +140,11 @@ struct libnet_UserList {
        struct {
                const char *domain_name;
                int page_size;
-               uint resume_index;
+               uint32_t resume_index;
        } in;
        struct {
                int count;
-               uint resume_index;
+               uint32_t resume_index;
 
                struct userlist {
                        const char *sid;
index 52c7f3e2d1d131b2e5ed472ebfd7b88a98e0baa8..9cb2d7faf609f3460da3d6fc38e8d3b4eabb3d06 100644 (file)
@@ -79,11 +79,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
 
 NDR_WINSTATION_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winstation.o
 
-[SUBSYSTEM::NDR_ECHO]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o
-
 [SUBSYSTEM::NDR_IRPC]
 PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT
 
@@ -114,30 +109,23 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
 
 NDR_ROT_OBJ_FILES = ../librpc/gen_ndr/ndr_rot.o
 
-[SUBSYSTEM::NDR_LSA]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
-
-NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/lsa.h
-
-[SUBSYSTEM::NDR_DFS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs.o
-
 [SUBSYSTEM::NDR_FRSRPC]
 PUBLIC_DEPENDENCIES = LIBNDR
 
-NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o
+NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o ../librpc/ndr/ndr_frsrpc.o
 
 [SUBSYSTEM::NDR_FRSAPI]
 PUBLIC_DEPENDENCIES = LIBNDR
 
 NDR_FRSAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_frsapi.o
 
+[SUBSYSTEM::NDR_FRSTRANS]
+PUBLIC_DEPENDENCIES = LIBNDR
+
+NDR_FRSTRANS_OBJ_FILES = ../librpc/gen_ndr/ndr_frstrans.o
+
 [SUBSYSTEM::NDR_DRSUAPI]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
+PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_STANDARD ASN1_UTIL
 
 NDR_DRSUAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o
 
@@ -161,13 +149,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
 
 NDR_UNIXINFO_OBJ_FILES = ../librpc/gen_ndr/ndr_unixinfo.o
 
-[SUBSYSTEM::NDR_SAMR]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
-
-NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h ndr_samr_c.h)
-
 [SUBSYSTEM::NDR_NFS4ACL]
 PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
 
@@ -182,35 +163,6 @@ NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss.o
 
 NDR_SPOOLSS_BUF_OBJ_FILES = ../librpc/ndr/ndr_spoolss_buf.o
 
-[SUBSYSTEM::NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY
-
-NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc.o
-
-[SUBSYSTEM::NDR_SRVSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY
-
-NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc.o
-
-[SUBSYSTEM::NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl.o ../librpc/ndr/ndr_svcctl.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, ndr_svcctl.h svcctl.h)
-
-[SUBSYSTEM::NDR_ATSVC]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h)
-
-[SUBSYSTEM::NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
-
-NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog.o
-
 [SUBSYSTEM::NDR_EPMAPPER]
 PUBLIC_DEPENDENCIES = LIBNDR
 
@@ -236,16 +188,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
 
 NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o
 
-[SUBSYSTEM::NDR_WINREG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY
-
-NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg.o
-
-[SUBSYSTEM::NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown.o
-
 [SUBSYSTEM::NDR_MGMT]
 PUBLIC_DEPENDENCIES = LIBNDR 
 
@@ -291,18 +233,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
 
 NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc.o
 
-[SUBSYSTEM::NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o
-
-[SUBSYSTEM::NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY
-
-NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/netlogon.h
-
 [SUBSYSTEM::NDR_TRKWKS]
 PUBLIC_DEPENDENCIES = LIBNDR
 
@@ -314,7 +244,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
 NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc.o
 
 [SUBSYSTEM::NDR_KRB5PAC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_SECURITY
 
 NDR_KRB5PAC_OBJ_FILES = ../librpc/gen_ndr/ndr_krb5pac.o ../librpc/ndr/ndr_krb5pac.o
 
@@ -339,7 +269,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
 NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
 
 [SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON
 
 NDR_NBT_OBJ_FILES = ../librpc/gen_ndr/ndr_nbt.o
 
@@ -356,7 +286,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
 NDR_WINSREPL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winsrepl.o
 
 [SUBSYSTEM::NDR_WINBIND]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD
 
 NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o
 #PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h
@@ -374,18 +304,48 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES)
        @$(PERL) ../librpc/tables.pl --output=$@ $^ > $(gen_ndrsrcdir)/tables.x
        @mv $(gen_ndrsrcdir)/tables.x $@
 
+[LIBRARY::NDR_STANDARD]
+PUBLIC_DEPENDENCIES = LIBNDR
+PRIVATE_DEPENDENCIES = NDR_SECURITY
+
+NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \
+                                                ../librpc/gen_ndr/ndr_lsa.o \
+                                                ../librpc/gen_ndr/ndr_samr.o \
+                                                ../librpc/gen_ndr/ndr_netlogon.o \
+                                                ../librpc/ndr/ndr_netlogon.o \
+                                                ../librpc/gen_ndr/ndr_dfs.o \
+                                                ../librpc/gen_ndr/ndr_atsvc.o \
+                                                ../librpc/gen_ndr/ndr_wkssvc.o \
+                                                ../librpc/gen_ndr/ndr_srvsvc.o \
+                                                ../librpc/gen_ndr/ndr_svcctl.o \
+                                                ../librpc/ndr/ndr_svcctl.o \
+                                                ../librpc/gen_ndr/ndr_winreg.o \
+                                                ../librpc/gen_ndr/ndr_initshutdown.o \
+                                                ../librpc/gen_ndr/ndr_eventlog.o \
+                                                ../librpc/gen_ndr/ndr_ntsvcs.o
+
+PC_FILES += $(librpcsrcdir)/ndr_standard.pc
+
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h atsvc.h ndr_atsvc.h ndr_svcctl.h svcctl.h)
+
+NDR_STANDARD_VERSION = 0.0.1
+NDR_STANDARD_SOVERSION = 0
+
 [SUBSYSTEM::NDR_TABLE]
 PUBLIC_DEPENDENCIES = \
-       NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \
-       NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \
-       NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \
-       NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
-       NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
-       NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \
-       NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
-       NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \
-       NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
-       NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \
+       NDR_STANDARD \
+       NDR_AUDIOSRV \
+       NDR_DSBACKUP NDR_EFS NDR_DRSUAPI \
+       NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS \
+       NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
+       NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
+       NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC \
+       NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
+       NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \
+       NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
+       NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND \
+       NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS \
+       NDR_NFS4ACL NDR_NTP_SIGND \
        NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH
 
 NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
@@ -401,7 +361,7 @@ PUBLIC_DEPENDENCIES = NDR_AUDIOSRV dcerpc
 RPC_NDR_AUDIOSRV_OBJ_FILES = ../librpc/gen_ndr/ndr_audiosrv_c.o
 
 [SUBSYSTEM::RPC_NDR_ECHO]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ECHO
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo_c.o
 
@@ -416,12 +376,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_EFS
 RPC_NDR_EFS_OBJ_FILES = ../librpc/gen_ndr/ndr_efs_c.o
 
 [SUBSYSTEM::RPC_NDR_LSA]
-PUBLIC_DEPENDENCIES = dcerpc NDR_LSA
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa_c.o
 
 [SUBSYSTEM::RPC_NDR_DFS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_DFS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs_c.o
 
@@ -456,7 +416,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_IRPC
 RPC_NDR_IRPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_irpc_c.o
 
 [LIBRARY::dcerpc_samr]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SAMR 
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 PC_FILES += $(librpcsrcdir)/dcerpc_samr.pc
 
@@ -464,13 +424,15 @@ dcerpc_samr_VERSION = 0.0.1
 dcerpc_samr_SOVERSION = 0
 dcerpc_samr_OBJ_FILES = ../librpc/gen_ndr/ndr_samr_c.o
 
+PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_samr_c.h
+
 [SUBSYSTEM::RPC_NDR_SPOOLSS]
 PUBLIC_DEPENDENCIES = dcerpc NDR_SPOOLSS
 
 RPC_NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss_c.o
 
 [SUBSYSTEM::RPC_NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WKSSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc_c.o
 
@@ -480,14 +442,14 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SRVSVC
 RPC_NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc_c.o
 
 [SUBSYSTEM::RPC_NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SVCCTL
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl_c.o
 
 PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_svcctl_c.h
 
 [LIBRARY::dcerpc_atsvc]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ATSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 dcerpc_atsvc_VERSION = 0.0.1
 dcerpc_atsvc_SOVERSION = 0
@@ -498,7 +460,7 @@ PC_FILES += $(librpcsrcdir)/dcerpc_atsvc.pc
 PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_atsvc_c.h
 
 [SUBSYSTEM::RPC_NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_EVENTLOG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog_c.o
 
@@ -528,12 +490,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_WINS
 RPC_NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins_c.o
 
 [SUBSYSTEM::RPC_NDR_WINREG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WINREG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg_c.o
 
 [SUBSYSTEM::RPC_NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = dcerpc NDR_INITSHUTDOWN
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown_c.o
 
@@ -573,12 +535,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SCERPC
 RPC_NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc_c.o
 
 [SUBSYSTEM::RPC_NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_NTSVCS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
 
 RPC_NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs_c.o
 
 [SUBSYSTEM::RPC_NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = NDR_NETLOGON
+PUBLIC_DEPENDENCIES = NDR_STANDARD
 
 RPC_NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon_c.o
 
index 4ebbaaeffc68d0cd7f1a75c8e0e3f818f98ed00e..601f7902df639ae077296cfc198678717ba059cb 100644 (file)
@@ -192,9 +192,12 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC
                os_ex.major             = server_info->version_major;
                os_ex.minor             = server_info->version_minor;
                os_ex.build             = server_info->version_build;
-               os_ex.extra_string              = "";
-               os_ex.unknown2          = 0;
-               os_ex.unknown3          = 0;
+               os_ex.extra_string      = "";
+               os_ex.service_pack_major= 0;
+               os_ex.service_pack_minor= 0;
+               os_ex.suite_mask        = 0;
+               os_ex.product_type      = 0;
+               os_ex.reserved          = 0;
 
                ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
index 20b00f24e3b42db817a7a9c72f6ca68ba5d287ab..95ad1c51fb33bafd5030abbbe13c7dce826e4f4c 100644 (file)
@@ -258,7 +258,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
          one of the interfaces attached to this pipe endpoint.
        */
        ep_description->transport = NCACN_NP;
-       ep_description->endpoint = talloc_reference(ep_description, p->pipe_name);
+       ep_description->endpoint = talloc_strdup(ep_description, p->pipe_name);
+       NT_STATUS_HAVE_NO_MEMORY(ep_description->endpoint);
 
        /* The session info is refcount-increased in the 
         * dcesrv_endpoint_search_connect() function
index c33323350e0d2b755be8e74838f8af2b93410567..8e8da72e1f63cf588d4e1df1cd1dc85e4c1bfc67 100644 (file)
@@ -796,7 +796,10 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        (*name)->has_wildcard = false;
        /* we can't get the correct 'original_name', but for the purposes
           of this call this is close enough */
-       (*name)->original_name = talloc_reference(*name, child->original_name);
+       (*name)->original_name = talloc_strdup(*name, child->original_name);
+       if ((*name)->original_name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
        (*name)->stream_name = NULL;
        (*name)->stream_id = 0;
 
index 3ef341d61ad64798b319ac9d985e06d7475666fe..97c306f7c3542e291a0814cb0d80d6fa4ce145c4 100644 (file)
@@ -310,9 +310,9 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_INTERNAL_ERROR;
        }
 
-       ntvfs->private_data = priv;
        priv->last_sec_ctx = NULL;
        priv->last_token = NULL;
+       ntvfs->private_data = priv;
 
        tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx, 
                                     unixuid_event_nesting_hook,
index f3dc0741253a4213ed2e8e252100d33a5c3961fb..32669db37ad698229c488d2f875bd1f896f84ec2 100644 (file)
@@ -19,7 +19,7 @@ PUBLIC_HEADERS += $(rpc_serversrcdir)/common/common.h
 [MODULE::dcerpc_rpcecho]
 INIT_FUNCTION = dcerpc_server_rpcecho_init
 SUBSYSTEM = dcerpc_server
-PRIVATE_DEPENDENCIES = NDR_ECHO LIBEVENTS
+PRIVATE_DEPENDENCIES = NDR_STANDARD LIBEVENTS
 # End MODULE dcerpc_rpcecho
 ################################################
 
@@ -69,7 +69,7 @@ $(eval $(call proto_header_template,$(rpc_serversrcdir)/srvsvc/proto.h,$(dcerpc_
 INIT_FUNCTION = dcerpc_server_wkssvc_init
 SUBSYSTEM = dcerpc_server
 PRIVATE_DEPENDENCIES = \
-               DCERPC_COMMON NDR_WKSSVC
+               DCERPC_COMMON NDR_STANDARD
 # End MODULE dcerpc_wkssvc
 ################################################
 
@@ -99,7 +99,7 @@ SUBSYSTEM = dcerpc_server
 PRIVATE_DEPENDENCIES = \
                SAMDB \
                DCERPC_COMMON \
-               NDR_SAMR
+               NDR_STANDARD
 # End MODULE dcesrv_samr
 ################################################
 
@@ -114,7 +114,7 @@ INIT_FUNCTION = dcerpc_server_winreg_init
 SUBSYSTEM = dcerpc_server
 OUTPUT_TYPE = MERGED_OBJ
 PRIVATE_DEPENDENCIES = \
-               registry NDR_WINREG
+               registry NDR_STANDARD
 # End MODULE dcerpc_winreg
 ################################################
 
@@ -128,7 +128,7 @@ SUBSYSTEM = dcerpc_server
 PRIVATE_DEPENDENCIES = \
                DCERPC_COMMON \
                SCHANNELDB \
-               NDR_NETLOGON \
+               NDR_STANDARD \
                auth_sam \
                LIBSAMBA-HOSTCONFIG
 # End MODULE dcerpc_netlogon
@@ -144,7 +144,7 @@ SUBSYSTEM = dcerpc_server
 PRIVATE_DEPENDENCIES = \
                SAMDB \
                DCERPC_COMMON \
-               NDR_LSA \
+               NDR_STANDARD \
                LIBCLI_AUTH \
                NDR_DSSETUP
 # End MODULE dcerpc_lsa
index cbadf654fbdadceac3bb49322baa8312f5dc5bbc..2b4a8915563fd24983ae97043915d204a4668b98 100644 (file)
@@ -1378,7 +1378,7 @@ static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_
                        = samdb_result_uint(msg, "posixOffset", 0);                                        
                return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
                
-       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+       case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
                info->enc_types.enc_types
                        = samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
                break;
index dc47d3783aeb0a95ee91514272f20366182cf310..005c7d4f06b5b1b7cbca42a98c098704f48ebc78 100644 (file)
@@ -394,7 +394,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx,
 
                atype = samdb_result_uint(res[i], "sAMAccountType", 0);
                        
-               *rtype = samdb_atype_map(atype);
+               *rtype = ds_atype_map(atype);
                if (*rtype == SID_NAME_UNKNOWN) {
                        return STATUS_SOME_UNMAPPED;
                }
@@ -503,7 +503,7 @@ static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX
 
                atype = samdb_result_uint(res[0], "sAMAccountType", 0);
 
-               *rtype = samdb_atype_map(atype);
+               *rtype = ds_atype_map(atype);
 
                return NT_STATUS_OK;
        }
index dc2d078d6bd460158be0f7b2b2a198a541bbd5aa..2095bf6fa5e47814a4d82943fd301cd4d439b752 100644 (file)
@@ -27,7 +27,7 @@
 #include "auth/auth.h"
 #include "auth/auth_sam_reply.h"
 #include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "rpc_server/samr/proto.h"
 #include "../lib/util/util_ldb.h"
 #include "libcli/auth/libcli_auth.h"
@@ -151,8 +151,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
                }
 
                /* pull the user attributes */
-               num_records = gendb_search((struct ldb_context *)sam_ctx,
-                                          mem_ctx, NULL, &msgs,
+               num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
                                           trust_dom_attrs,
                                           "(&(trustPartner=%s)(objectclass=trustedDomain))", 
                                           encoded_account);
@@ -184,8 +183,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
        }
        
        /* pull the user attributes */
-       num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
-                                  NULL, &msgs, attrs,
+       num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
                                   "(&(sAMAccountName=%s)(objectclass=user))", 
                                   ldb_binary_encode_string(mem_ctx, account_name));
 
@@ -852,7 +850,7 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
                       struct netr_GetDcName *r)
 {
        const char * const attrs[] = { NULL };
-       void *sam_ctx;
+       struct ldb_context *sam_ctx;
        struct ldb_message **res;
        struct ldb_dn *domain_dn;
        int ret;
@@ -865,13 +863,13 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
                return WERR_DS_SERVICE_UNAVAILABLE;
        }
 
-       domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
+       domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
                                       r->in.domainname);
        if (domain_dn == NULL) {
                return WERR_DS_SERVICE_UNAVAILABLE;
        }
 
-       ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+       ret = gendb_search_dn(sam_ctx, mem_ctx,
                              domain_dn, &res, attrs);
        if (ret != 1) {
                return WERR_NO_SUCH_DOMAIN;
@@ -1401,7 +1399,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
                                              struct netr_DsrEnumerateDomainTrusts *r)
 {
        struct netr_DomainTrustList *trusts;
-       void *sam_ctx;
+       struct ldb_context *sam_ctx;
        int ret;
        struct ldb_message **dom_res;
        const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
@@ -1413,7 +1411,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
                return WERR_GENERAL_FAILURE;
        }
 
-       ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
+       ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
                              &dom_res, dom_attrs);
        if (ret == -1) {
                return WERR_GENERAL_FAILURE;            
index 03acf97cab700cc817bad19bc187a7b8a3172771..c75560123044c02f0ba7b328ed5eee42230cd4c2 100644 (file)
@@ -29,7 +29,7 @@
 #include "system/time.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "dsdb/samdb/samdb.h"
 #include "libcli/ldap/ldap_ndr.h"
 #include "libcli/security/security.h"
@@ -1360,7 +1360,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
                                  UF_INTERDOMAIN_TRUST_ACCOUNT | 
                                  UF_WORKSTATION_TRUST_ACCOUNT | 
                                  UF_SERVER_TRUST_ACCOUNT));
-       user_account_control |= samdb_acb2uf(r->in.acct_flags);
+       user_account_control |= ds_acb2uf(r->in.acct_flags);
 
        talloc_free(msg);
        msg = ldb_msg_new(mem_ctx);
@@ -1876,7 +1876,7 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
                        continue;
                }
 
-               rtype = samdb_atype_map(atype);
+               rtype = ds_atype_map(atype);
                
                if (rtype == SID_NAME_UNKNOWN) {
                        status = STATUS_SOME_UNMAPPED;
@@ -1962,7 +1962,7 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
                        continue;
                }
 
-               ids[i] = samdb_atype_map(atype);
+               ids[i] = ds_atype_map(atype);
                
                if (ids[i] == SID_NAME_UNKNOWN) {
                        status = STATUS_SOME_UNMAPPED;
index ec83cbfdc93e1773c630639c64d2b6f2612a7f4f..6f12d2f119d17898e91c2db81fd52d0aad159c40 100644 (file)
@@ -26,7 +26,7 @@
 #include "rpc_server/samr/dcesrv_samr.h"
 #include "system/time.h"
 #include "../lib/crypto/crypto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
 #include "libcli/ldap/ldap.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
index 2bd34b119f34483929616da1f68be2cfe2f1723a..0666ae1adefb4d9b5e73caa5904f2eada34f8933 100755 (executable)
@@ -8,11 +8,15 @@ cd $SRCDIR || exit 1
 
 echo "Installing setup templates"
 mkdir -p $SETUPDIR || exit 1
+mkdir -p $SETUPDIR/ad-schema || exit 1
+cp setup/ad-schema/*.txt $SETUPDIR/ad-schema || exit 1
+for p in enableaccount newuser provision provision-backend setexpiry setpassword
+do
+       chmod 0555 setup/$p
+       cp setup/$p $SETUPDIR || exit 1
+done
 cp setup/schema-map-* $SETUPDIR || exit 1
 cp setup/DB_CONFIG $SETUPDIR || exit 1
-cp setup/provision-backend $SETUPDIR || exit 1
-cp setup/provision $SETUPDIR || exit 1
-cp setup/newuser $SETUPDIR || exit 1
 cp setup/*.inf $SETUPDIR || exit 1
 cp setup/*.ldif $SETUPDIR || exit 1
 cp setup/*.reg $SETUPDIR || exit 1
index 5816d9637d8e3a973474c4e4ad91da86f01f5859..0869d2feac24d59b331f4618cd89672c858bc9e6 100644 (file)
        } */\
        ldb = PyLdb_AsLdbContext(py_ldb);
 
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+       if (ret == LDB_ERR_PYTHON_EXCEPTION)
+               return; /* Python exception should already be set, just keep that */
+
+       PyErr_SetObject(error, 
+                                       Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 
+                                 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
 
 static PyObject *py_ldb_get_exception(void)
 {
@@ -204,6 +213,63 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
+static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
+{
+       PyObject *py_ldb;
+       int value;
+       int *old_val, *new_val;
+       char *py_opaque_name, *opaque_name_talloc;
+       struct ldb_context *ldb;
+       TALLOC_CTX *tmp_ctx;
+
+       if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
+               return NULL;
+
+       PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+       /* see if we have a cached copy */
+       old_val = (int *)ldb_get_opaque(ldb, 
+                                       py_opaque_name);
+
+       if (old_val) {
+               *old_val = value;
+               Py_RETURN_NONE;
+       } 
+
+       tmp_ctx = talloc_new(ldb);
+       if (tmp_ctx == NULL) {
+               goto failed;
+       }
+       
+       new_val = talloc(tmp_ctx, int);
+       if (!new_val) {
+               goto failed;
+       }
+       
+       opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
+       if (!opaque_name_talloc) {
+               goto failed;
+       }
+       
+       *new_val = value;
+
+       /* cache the domain_sid in the ldb */
+       if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
+               goto failed;
+       }
+
+       talloc_steal(ldb, new_val);
+       talloc_steal(ldb, opaque_name_talloc);
+       talloc_free(tmp_ctx);
+
+       Py_RETURN_NONE;
+
+failed:
+       talloc_free(tmp_ctx);
+       PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
+       return NULL;
+}
+
 static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
 {
        PyObject *py_ldb;
@@ -284,6 +350,8 @@ static PyMethodDef py_misc_methods[] = {
                "Register Samba-specific LDB modules and schemas." },
        { "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
                NULL },
+       { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
+               NULL },
        { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
                NULL },
        { "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS,
@@ -303,5 +371,11 @@ void initglue(void)
                return;
 
        PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
+
+       PyModule_AddObject(m, "DS_BEHAVIOR_WIN2000", PyInt_FromLong(DS_BEHAVIOR_WIN2000));
+       PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003_INTERIM", PyInt_FromLong(DS_BEHAVIOR_WIN2003_INTERIM));
+       PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003", PyInt_FromLong(DS_BEHAVIOR_WIN2003));
+       PyModule_AddObject(m, "DS_BEHAVIOR_WIN2008", PyInt_FromLong(DS_BEHAVIOR_WIN2008));
+
 }
 
index 60a7919136548dc967a1ef44d98581b69cdd7cc1..164803bb65d692369bd73e6745db40a034b1b18b 100644 (file)
@@ -42,7 +42,6 @@ else:
 
 
 import ldb
-import credentials
 import glue
 
 class Ldb(ldb.Ldb):
@@ -73,6 +72,8 @@ class Ldb(ldb.Ldb):
             self.set_modules_dir(modules_dir)
         elif default_ldb_modules_dir is not None:
             self.set_modules_dir(default_ldb_modules_dir)
+        elif lp is not None:
+            self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb"))
 
         if credentials is not None:
             self.set_credentials(credentials)
@@ -242,3 +243,8 @@ def valid_netbios_name(name):
     return True
 
 version = glue.version
+
+DS_BEHAVIOR_WIN2000 = glue.DS_BEHAVIOR_WIN2000
+DS_BEHAVIOR_WIN2003_INTERIM = glue.DS_BEHAVIOR_WIN2003_INTERIM
+DS_BEHAVIOR_WIN2003 = glue.DS_BEHAVIOR_WIN2003
+DS_BEHAVIOR_WIN2008 = glue.DS_BEHAVIOR_WIN2008
index c12245f6c5706a6eae36bc04a5ce8afdd0181498..8b756b2d6fcf26225bd28e78aff721e12d16da67 100644 (file)
@@ -20,7 +20,7 @@
 """Support for parsing Samba-related command-line options."""
 
 import optparse
-from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS
+from credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS
 from hostconfig import Hostconfig
 
 __docformat__ = "restructuredText"
index f8eeb1892569a4b68b3b85577467f96c156cd604..ee79be1af9d2f0969ad77dc303c4f953f164c8c3 100644 (file)
@@ -23,8 +23,6 @@
 __docformat__ = "restructuredText"
 
 import samba
-import glue
-import ldb
 
 class IDmapDB(samba.Ldb):
     """The IDmap database."""
index 2e8050e5038a1690dc9e184914767cd4f44c215e..a0abc337ce45cb54de851533f3ef78cfe7b4a4f7 100644 (file)
@@ -226,6 +226,7 @@ def __transform_entry(entry, objectClass):
     assert(cn)
     entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn])
     entry.insert(1, ["objectClass", ["top", objectClass]])
+    entry.insert(2, ["cn", cn])
     
     for l in entry:
         key = l[0].lower()
index 189c93a1fcfd31fec65dba5d4e074e5a6b2d2484..8a7ed6a86e5531b0d52b7191a77b108cb69302bd 100644 (file)
@@ -37,13 +37,13 @@ import param
 import registry
 import samba
 from auth import system_session
-from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
+from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \
+  DS_BEHAVIOR_WIN2008
 from samba.samdb import SamDB
 from samba.idmap import IDmapDB
 from samba.dcerpc import security
 import urllib
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
-        timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
+from ldb import SCOPE_SUBTREE, LdbError, timestring
 from ms_schema import read_ms_schema
 
 __docformat__ = "restructuredText"
@@ -729,7 +729,7 @@ def setup_samdb_rootdse(samdb, setup_path, names):
 def setup_self_join(samdb, names,
                     machinepass, dnspass, 
                     domainsid, invocationid, setup_path,
-                    policyguid):
+                    policyguid, domainControllerFunctionality):
     """Join a host to its own domain."""
     assert isinstance(invocationid, str)
     setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { 
@@ -745,7 +745,9 @@ def setup_self_join(samdb, names,
               "DNSPASS_B64": b64encode(dnspass),
               "REALM": names.realm,
               "DOMAIN": names.domain,
-              "DNSDOMAIN": names.dnsdomain})
+              "DNSDOMAIN": names.dnsdomain,
+              "SAMBA_VERSION_STRING": version,
+              "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)})
     setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { 
               "POLICYGUID": policyguid,
               "DNSDOMAIN": names.dnsdomain,
@@ -765,6 +767,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
     :note: This will wipe the main SAM database file!
     """
 
+    domainFunctionality = DS_BEHAVIOR_WIN2008
+    forestFunctionality = DS_BEHAVIOR_WIN2008
+    domainControllerFunctionality = DS_BEHAVIOR_WIN2008
+
     erase = (fill != FILL_DRS)
 
     # Also wipes the database
@@ -780,6 +786,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
         return samdb
 
     message("Pre-loading the Samba 4 and AD schema")
+
+    samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
+    samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
+    samdb.set_opaque_integer("domainControllerFunctionality", domainControllerFunctionality)
+
     samdb.set_domain_sid(str(domainsid))
     if serverrole == "domain controller":
         samdb.set_invocation_id(invocationid)
@@ -818,6 +829,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
             "POLICYGUID": policyguid,
             "DOMAINDN": names.domaindn,
             "DOMAINGUID_MOD": domainguid_mod,
+            "DOMAIN_FUNCTIONALITY": str(domainFunctionality)
             })
 
         message("Adding configuration container (permitted to fail)")
@@ -864,7 +876,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
             "DOMAIN": names.domain,
             "SCHEMADN": names.schemadn,
             "DOMAINDN": names.domaindn,
-            "SERVERDN": names.serverdn
+            "SERVERDN": names.serverdn,
+            "FOREST_FUNCTIONALALITY": str(forestFunctionality)
             })
 
         message("Setting up display specifiers")
@@ -908,7 +921,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
                                 dnspass=dnspass,  
                                 machinepass=machinepass, 
                                 domainsid=domainsid, policyguid=policyguid,
-                                setup_path=setup_path)
+                                setup_path=setup_path, domainControllerFunctionality=domainControllerFunctionality)
 
     except:
         samdb.transaction_cancel()
index c8ddbc8864d3be23bac79035140d592dd36692de..179efa2700aaeba8bc661ed3e385e2ab1c15628e 100644 (file)
@@ -502,7 +502,7 @@ TDBSAM_USER_PREFIX = "USER_"
 class LdapSam(object):
     """Samba 3 LDAP passdb backend reader."""
     def __init__(self, url):
-        self.ldap_url = ldap_url
+        self.ldap_url = url
 
 
 class TdbSam(TdbDatabase):
@@ -692,7 +692,7 @@ class ParamFile(object):
                (k, v) = l.split("=", 1) 
                self._sections[section][self._sanitize_name(k)] = v
             else:
-                raise Error("Unable to parser line %d: %r" % (i+1,l))
+                raise Exception("Unable to parser line %d: %r" % (i+1,l))
 
     def get(self, param, section=None):
         """Return the value of a parameter.
index bc76cd3c5fdbbf576c590234cb880fa336112af1..6cb24698462de17c3e4acc5e1e311a506556e287 100644 (file)
@@ -231,6 +231,14 @@ userPassword:: %s
         """
         glue.dsdb_set_ntds_invocation_id(self, invocation_id)
 
+    def set_opaque_integer(self, name, value):
+        """Set an integer as an opaque (a flag or other value) value on the database
+        
+        :param name: The name for the opaque value
+        :param value: The integer value
+        """
+        glue.dsdb_set_opaque_integer(self, name, value)
+
     def setexpiry(self, user, expiry_seconds, noexpiry):
         """Set the account expiry for a user
         
diff --git a/source4/scripting/python/samba/tests/shares.py b/source4/scripting/python/samba/tests/shares.py
new file mode 100644 (file)
index 0000000..9130c36
--- /dev/null
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation. Tests for shares
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009
+#   
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#   
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#   
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+from samba.shares import SharesContainer
+from unittest import TestCase
+
+
+class MockService(object):
+
+    def __init__(self, data):
+        self.data = data
+
+    def __getitem__(self, name):
+        return self.data[name]
+
+
+class MockLoadParm(object):
+
+    def __init__(self, data):
+        self.data = data
+
+    def __getitem__(self, name):
+        return MockService(self.data[name])
+
+    def __contains__(self, name):
+        return name in self.data
+
+    def __len__(self):
+        return len(self.data)
+
+    def services(self):
+        return self.data.keys()
+
+
+class ShareTests(TestCase):
+
+    def _get_shares(self, conf):
+        return SharesContainer(MockLoadParm(conf))
+
+    def test_len_no_global(self):
+        shares = self._get_shares({})
+        self.assertEquals(0, len(shares))
+
+    def test_iter(self):
+        self.assertEquals([], list(self._get_shares({})))
+        self.assertEquals([], list(self._get_shares({"global":{}})))
+        self.assertEquals(["bla"], list(self._get_shares({"global":{}, "bla":{}})))
+
+    def test_len(self):
+        shares = self._get_shares({"global": {}})
+        self.assertEquals(0, len(shares))
+
+    def test_getitem_nonexistant(self):
+        shares = self._get_shares({"global": {}})
+        self.assertRaises(KeyError, shares.__getitem__, "bla")
+
+    def test_getitem_global(self):
+        shares = self._get_shares({"global": {}})
+        self.assertRaises(KeyError, shares.__getitem__, "global")
index 0c83604e827503dc5abbdd82f9ab64b53bd0fed2..81945525e6a4ad717c95d191b7a33a3f14ce6b78 100644 (file)
@@ -9,17 +9,16 @@
 
 __docformat__ = "restructuredText"
 
-from provision import findnss, provision, FILL_DRS
+from provision import provision, FILL_DRS
 import grp
 import ldb
 import time
 import pwd
-import uuid
 import registry
 from samba import Ldb
-from samba.samdb import SamDB
+from samba.param import LoadParm
 
-def import_sam_policy(samldb, samba3_policy, domaindn):
+def import_sam_policy(samldb, policy, dn):
     """Import a Samba 3 policy database."""
     samldb.modify_ldif("""
 dn: %s
@@ -394,7 +393,7 @@ def upgrade_smbconf(oldconf,mark):
         kept in the new configuration as "samba3:<name>"
     """
     data = oldconf.data()
-    newconf = param_init()
+    newconf = LoadParm()
 
     for s in data:
         for p in data[s]:
index 91180418b84f6d6b2fb5ab828fc3e5ec2839ed66..68d406ab9bea1db3f1cf4a56f4cba5f7abb3fc03 100644 (file)
@@ -40,6 +40,7 @@ rpc.netlogon.*.DatabaseRedo
 rpc.netlogon.*.ServerGetTrustInfo
 samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet
 samba4.rpc.samr.users.privileges
+samba4.rpc.spoolss.printer # Not provided by Samba 4 yet
 base.charset.*.Testing partial surrogate
 .*net.api.delshare.*                           # DelShare isn't implemented yet
 rap.*netservergetinfo
index 5cb851ceb79879214ab85a10f16466b4a31ada5d..d7fa6aa54f90d0eeef6dc877871976d1211e8174 100755 (executable)
@@ -22,9 +22,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
-import getopt
 import optparse
-import os
 import sys
 
 # Find right directory when running from source tree
@@ -34,7 +32,6 @@ import samba
 from samba.credentials import DONT_USE_KERBEROS
 from samba.auth import system_session
 import samba.getopt as options
-from samba import param
 from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir
 
 # how do we make this case insensitive??
@@ -121,7 +118,6 @@ if not opts.interactive and (opts.realm is None or opts.domain is None):
 
 if opts.interactive:
        from getpass import getpass
-       import readline
        import socket
        def ask(prompt, default=None):
                if default is not None:
index e5b20d03e11d93a5243d2d8c12e70489172bfac5..9f50b45dffda3cfd21d84bfbdae13187c9f077ea 100644 (file)
@@ -1,7 +1,28 @@
+dn: CN=Builtin,${DOMAINDN}
+objectClass: top
+objectClass: builtinDomain
+forceLogoff: -9223372036854775808
+lockoutDuration: -18000000000
+lockOutObservationWindow: -18000000000
+lockoutThreshold: 0
+maxPwdAge: -37108517437440
+minPwdAge: 0
+minPwdLength: 0
+modifiedCountAtLastProm: 0
+nextRid: 1000
+pwdProperties: 0
+pwdHistoryLength: 0
+objectSid: S-1-5-32
+serverState: 1
+uASCompat: 1
+modifiedCount: 1
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
+
 dn: OU=Domain Controllers,${DOMAINDN}
 objectClass: top
 objectClass: organizationalUnit
-cn: Domain Controllers
 description: Default container for domain controllers
 systemFlags: -1946157056
 isCriticalSystemObject: TRUE
@@ -10,82 +31,171 @@ showInAdvancedViewOnly: FALSE
 dn: CN=ForeignSecurityPrincipals,${DOMAINDN}
 objectClass: top
 objectClass: container
-cn: ForeignSecurityPrincipals
 description: Default container for security identifiers (SIDs) associated with objects from external, trusted domains
 systemFlags: -1946157056
 isCriticalSystemObject: TRUE
 showInAdvancedViewOnly: FALSE
 
+dn: CN=Infrastructure,${DOMAINDN}
+objectClass: top
+objectClass: infrastructureUpdate
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+isCriticalSystemObject: TRUE
+
+dn: CN=LostAndFound,${DOMAINDN}
+objectClass: top
+objectClass: lostAndFound
+description: Default container for orphaned objects
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=NTDS Quotas,${DOMAINDN}
+objectClass: top
+objectClass: msDS-QuotaContainer
+description: Quota specifications container
+msDS-TombstoneQuotaFactor: 100
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of application data.
+
+dn: CN=Microsoft,CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of Microsoft application data.
+
 dn: CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
-cn: System
 description: Builtin system settings
 systemFlags: -1946157056
 isCriticalSystemObject: TRUE
 
-dn: CN=RID Manager$,CN=System,${DOMAINDN}
-objectclass: top
-objectclass: rIDManager
-cn: RID Manager$
+dn: CN=AdminSDHolder,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
 systemFlags: -1946157056
 isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-rIDAvailablePool: 4611686014132423217
+
+dn: CN=ComPartitions,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: leaf
+objectClass: domainPolicy
+isCriticalSystemObject: TRUE
+
+dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: classStore
+isCriticalSystemObject: TRUE
+
+dn: CN=Dfs-Configuration,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: dfsConfiguration
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
 
 dn: CN=DomainUpdates,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
-cn: DomainUpdates
+
+dn: CN=Operations,CN=DomainUpdates,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
 
 dn: CN=Windows2003Update,CN=DomainUpdates,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
-cn: Windows2003Update
 revision: 8
 
-dn: CN=Infrastructure,${DOMAINDN}
-objectclass: top
-objectclass: infrastructureUpdate
-cn: Infrastructure
+dn: CN=File Replication Service,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: applicationSettings
+objectClass: nTFRSSettings
 systemFlags: -1946157056
 isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
 
-dn: CN=Builtin,${DOMAINDN}
+dn: CN=FileLinks,CN=System,${DOMAINDN}
 objectClass: top
-objectClass: builtinDomain
-cn: Builtin
-forceLogoff: -9223372036854775808
-lockoutDuration: -18000000000
-lockOutObservationWindow: -18000000000
-lockoutThreshold: 0
-maxPwdAge: -37108517437440
-minPwdAge: 0
-minPwdLength: 0
-modifiedCountAtLastProm: 0
-nextRid: 1000
-pwdProperties: 0
-pwdHistoryLength: 0
-objectSid: S-1-5-32
-serverState: 1
-uASCompat: 1
-modifiedCount: 1
+objectClass: fileLinkTracking
+systemFlags: -1946157056
 isCriticalSystemObject: TRUE
-showInAdvancedViewOnly: FALSE
+
+dn: CN=ObjectMoveTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackObjectMoveTable
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=VolumeTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackVolumeTable
 systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=IP Security,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
+
+dn: CN=Meetings,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
 
 dn: CN=Policies,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
 systemFlags: -1946157056
+isCriticalSystemObject: TRUE
 
-dn: CN=IP Security,CN=System,${DOMAINDN}
+dn: CN=RAS and IAS Servers Access Check,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
 
-dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+dn: CN=RID Manager$,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: rIDManager
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+rIDAvailablePool: 4611686014132423217
+isCriticalSystemObject: TRUE
+
+dn: CN=RpcServices,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
+objectClass: rpcContainer
 systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Server,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: securityObject
+objectClass: samServer
+systemFlags: -1946157056
+revision: 65543
+isCriticalSystemObject: TRUE
 
+dn: CN=WinsockServices,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
index a7f3ce985c54a8b4c55a6ca90f149024537f570a..29ba75be98a95542b37689a8c07a362dc98e8151 100644 (file)
@@ -47,10 +47,10 @@ replace: serverState
 serverState: 1
 -
 replace: nTMixedDomain
-nTMixedDomain: 1
+nTMixedDomain: 0
 -
 replace: msDS-Behavior-Version
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${DOMAIN_FUNCTIONALITY}
 -
 replace: ridManagerReference
 ridManagerReference: CN=RID Manager$,CN=System,${DOMAINDN}
@@ -67,9 +67,6 @@ fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
 replace: systemFlags
 systemFlags: -1946157056
 -
-replace: isCriticalSystemObject
-isCriticalSystemObject: TRUE
--
 replace: subRefs
 subRefs: ${CONFIGDN}
 -
@@ -84,4 +81,7 @@ wellKnownObjects: B:32:a361b2ffffd211d1aa4b00c04fd7d83a:OU=Domain Controllers,${
 wellKnownObjects: B:32:aa312825768811d1aded00c04fd8d5cd:CN=Computers,${DOMAINDN}
 wellKnownObjects: B:32:a9d1ca15768811d1aded00c04fd8d5cd:CN=Users,${DOMAINDN}
 -
+replace: isCriticalSystemObject
+isCriticalSystemObject: TRUE
+-
 ${DOMAINGUID_MOD}
index 110c44c3564bfbc267da1ff108a4802391825913..b3d9dc1fa80b66ba68c0e4ef85a8c52d0b7c0d60 100644 (file)
@@ -3,11 +3,11 @@ changetype: modify
 replace: description
 description: Default container for upgraded computer accounts
 -
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
 replace: systemFlags
 systemFlags: -1946157056
 -
 replace: isCriticalSystemObject
 isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
index e84ac8517eb4486cb1ba38d7b6a9a5ed775c76aa..4109c2236c12eb668ae998ddfbc83e3b0d6cc12f 100644 (file)
@@ -6,8 +6,9 @@ objectClass: top
 objectClass: crossRefContainer
 cn: Partitions
 systemFlags: -2147483648
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${FOREST_FUNCTIONALALITY}
 fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+showInAdvancedViewOnly: TRUE
 
 dn: CN=Enterprise Configuration,CN=Partitions,${CONFIGDN}
 objectClass: top
index d6a46592508afc681a1bf53d276e9c6394f18d10..65ab1eaf5f77e3b9964d1d2cd0a7fec7f1a1a0aa 100644 (file)
@@ -1,14 +1,3 @@
-dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: leaf
-objectClass: domainPolicy
-isCriticalSystemObject: TRUE
-
-dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: classStore
-isCriticalSystemObject: TRUE
-
 dn: CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN}
 objectClass: top
 objectClass: container
index e4e4309a90acd4de4d0cabe68d05174e9e7a6c72..f9ee4e5904687f02d9e867a251c14350ef190f23 100644 (file)
@@ -11,9 +11,6 @@ supportedLDAPVersion: 2
 dnsHostName: ${DNSNAME}
 ldapServiceName: ${DNSDOMAIN}:${NETBIOSNAME}$@${REALM}
 serverName: ${SERVERDN}
-domainFunctionality: 0
-forestFunctionality: 0
-domainControllerFunctionality: 2
 isSynchronized: FALSE
 vendorName: Samba Team (http://samba.org)
 supportedCapabilities: 1.2.840.113556.1.4.800
index b7ca8723190408fa20f84c6fb8a4b390be5df95d..da8c5b9e1dee83b718610d1f10bf7f75d20bc9a7 100644 (file)
@@ -13,9 +13,8 @@ primaryGroupID: 516
 accountExpires: 9223372036854775807
 sAMAccountName: ${NETBIOSNAME}$
 operatingSystem: Samba
-operatingSystemVersion: 4.0
+operatingSystemVersion: ${SAMBA_VERSION_STRING}
 dNSHostName: ${DNSNAME}
-isCriticalSystemObject: TRUE
 userPassword:: ${MACHINEPASS_B64}
 servicePrincipalName: HOST/${DNSNAME}
 servicePrincipalName: HOST/${NETBIOSNAME}
@@ -23,6 +22,7 @@ servicePrincipalName: HOST/${DNSNAME}/${REALM}
 servicePrincipalName: HOST/${NETBIOSNAME}/${REALM}
 servicePrincipalName: HOST/${DNSNAME}/${DOMAIN}
 servicePrincipalName: HOST/${NETBIOSNAME}/${DOMAIN}
+isCriticalSystemObject: TRUE
 
 #Provide a account for DNS keytab export
 dn: CN=dns,CN=Users,${DOMAINDN}
@@ -36,9 +36,8 @@ userAccountControl: 514
 accountExpires: 9223372036854775807
 sAMAccountName: dns
 servicePrincipalName: DNS/${DNSDOMAIN}
-isCriticalSystemObject: TRUE
 userPassword:: ${DNSPASS_B64}
-showInAdvancedViewOnly: TRUE
+isCriticalSystemObject: TRUE
 
 dn: ${SERVERDN}
 objectClass: top
@@ -57,7 +56,7 @@ options: 1
 systemFlags: 33554432
 dMDLocation: ${SCHEMADN}
 invocationId: ${INVOCATIONID}
-msDS-Behavior-Version: 2
+msDS-Behavior-Version: ${DOMAIN_CONTROLLER_FUNCTIONALITY}
 msDS-hasMasterNCs: ${CONFIGDN}
 msDS-hasMasterNCs: ${SCHEMADN}
 msDS-hasMasterNCs: ${DOMAINDN}
index 88146d8cac7947f8a5ac3c06e7cbe773915b6ce0..47240a9d0789da75e8c8603a8690ba0ad47f25bb 100644 (file)
@@ -7,8 +7,8 @@ objectSid: ${DOMAINSID}-500
 adminCount: 1
 accountExpires: 9223372036854775807
 sAMAccountName: Administrator
-isCriticalSystemObject: TRUE
 userPassword:: ${ADMINPASS_B64}
+isCriticalSystemObject: TRUE
 
 dn: CN=Guest,CN=Users,${DOMAINDN}
 objectClass: user
@@ -45,8 +45,8 @@ adminCount: 1
 accountExpires: 9223372036854775807
 sAMAccountName: krbtgt
 servicePrincipalName: kadmin/changepw
-isCriticalSystemObject: TRUE
 userPassword:: ${KRBTGTPASS_B64}
+isCriticalSystemObject: TRUE
 
 dn: CN=Domain Computers,CN=Users,${DOMAINDN}
 objectClass: top
@@ -187,16 +187,6 @@ sAMAccountName: Event Log Readers
 groupType: -2147483644
 isCriticalSystemObject: TRUE
 
-dn: CN=IIS_IUSRS,CN=Users,${DOMAINDN}
-objectClass: top
-objectClass: group
-cn: IIS_IUSRS
-description: IIS_IUSRS
-objectSid: ${DOMAINSID}-568
-sAMAccountName: IIS_IUSRS
-groupType: -2147483644
-isCriticalSystemObject: TRUE
-
 dn: CN=Administrators,CN=Builtin,${DOMAINDN}
 objectClass: top
 objectClass: group
@@ -210,7 +200,6 @@ adminCount: 1
 sAMAccountName: Administrators
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeSecurityPrivilege
 privilege: SeBackupPrivilege
 privilege: SeRestorePrivilege
@@ -235,6 +224,7 @@ privilege: SeEnableDelegationPrivilege
 privilege: SeInteractiveLogonRight
 privilege: SeNetworkLogonRight
 privilege: SeRemoteInteractiveLogonRight
+isCriticalSystemObject: TRUE
 
 dn: CN=Users,CN=Builtin,${DOMAINDN}
 objectClass: top
@@ -271,10 +261,10 @@ adminCount: 1
 sAMAccountName: Print Operators
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeLoadDriverPrivilege
 privilege: SeShutdownPrivilege
 privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
 
 dn: CN=Backup Operators,CN=Builtin,${DOMAINDN}
 objectClass: top
@@ -286,11 +276,11 @@ adminCount: 1
 sAMAccountName: Backup Operators
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeBackupPrivilege
 privilege: SeRestorePrivilege
 privilege: SeShutdownPrivilege
 privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
 
 dn: CN=Replicator,CN=Builtin,${DOMAINDN}
 objectClass: top
@@ -358,13 +348,13 @@ adminCount: 1
 sAMAccountName: Server Operators
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeBackupPrivilege
 privilege: SeSystemtimePrivilege
 privilege: SeRemoteShutdownPrivilege
 privilege: SeRestorePrivilege
 privilege: SeShutdownPrivilege
 privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
 
 dn: CN=Account Operators,CN=Builtin,${DOMAINDN}
 objectClass: top
@@ -376,8 +366,8 @@ adminCount: 1
 sAMAccountName: Account Operators
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
 
 dn: CN=Pre-Windows 2000 Compatible Access,CN=Builtin,${DOMAINDN}
 objectClass: top
@@ -388,9 +378,9 @@ objectSid: S-1-5-32-554
 sAMAccountName: Pre-Windows 2000 Compatible Access
 systemFlags: -1946157056
 groupType: -2147483643
-isCriticalSystemObject: TRUE
 privilege: SeRemoteInteractiveLogonRight
 privilege: SeChangeNotifyPrivilege
+isCriticalSystemObject: TRUE
 
 dn: CN=Incoming Forest Trust Builders,CN=Builtin,${DOMAINDN}
 objectClass: top
index a7e8a4336aeea2e9c62a07061b6038105bb5d0a5..6a2e180b15e811f4cab8c8c9a72dd216308d2988 100644 (file)
@@ -3,11 +3,11 @@ changetype: modify
 replace: description
 description: Default container for upgraded user accounts
 -
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
 replace: systemFlags
 systemFlags: -1946157056
 -
 replace: isCriticalSystemObject
 isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
index c11e65e465b517ba8ca1d557463d0715d7fbf50f..591aefbb752a59eb8bdff07d0ccbb49539345739 100644 (file)
@@ -220,7 +220,6 @@ objectClass: classSchema
 subClassOf: top
 governsID: 1.3.6.1.4.1.7165.4.2.2
 rDNAttID: cn
-showInAdvancedViewOnly: TRUE
 adminDisplayName: Samba4-Local-Domain
 adminDescription: Samba4-Local-Domain
 systemMayContain: msDS-Behavior-Version
@@ -243,7 +242,6 @@ subClassOf: top
 governsID: 1.3.6.1.4.1.7165.4.2.1
 mayContain: msDS-ObjectReferenceBL
 rDNAttID: cn
-showInAdvancedViewOnly: TRUE
 adminDisplayName: Samba4TopTop
 adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
 objectClassCategory: 3
@@ -344,7 +342,6 @@ objectClass: classSchema
 subClassOf: top
 governsID: 1.3.6.1.4.1.7165.4.2.3
 rDNAttID: cn
-showInAdvancedViewOnly: TRUE
 adminDisplayName: Samba4TopExtra
 adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
 objectClassCategory: 2
index fd54863686ca323d4b774e6d9e74bfe7d30aac0e..076120bfeeea839a4c7b613acddb384729a70e8f 100644 (file)
@@ -29,6 +29,7 @@
 #include "libcli/security/security.h"
 #include "torture/torture.h"
 #include "auth/auth_sam_reply.h"
+#include "param/param.h"
 
 static bool torture_pac_self_check(struct torture_context *tctx)
 {
index c8e421a674980201bd45a6b8835fc9e0d5c77bf8..e9a19bcf96d21a85f2d1cff15649583d8c540e25 100644 (file)
@@ -114,15 +114,15 @@ static bool test_IsPathReplicated_err(struct torture_context *tctx,
 {
        struct frsapi_IsPathReplicated r;
        struct GUID guid;
-       uint32_t unknown1, unknown2, unknown3 = 0;
+       uint32_t replicated, primary, root;
 
        ZERO_STRUCT(r);
 
        r.in.path = path;
        r.in.replica_set_type = type;
-       r.out.unknown1 = &unknown1;
-       r.out.unknown2 = &unknown2;
-       r.out.unknown3 = &unknown3;
+       r.out.replicated = &replicated;
+       r.out.primary = &primary;
+       r.out.root = &root;
        r.out.replica_set_guid = &guid;
 
        torture_assert_ntstatus_ok(tctx,
@@ -191,11 +191,11 @@ static bool test_ForceReplication(struct torture_context *tctx,
 
        ZERO_STRUCT(r);
 
-       r.in.guid1 = NULL;
-       r.in.guid2 = NULL;
-       r.in.replica_set = talloc_asprintf(tctx, "%s",
-                                          lp_realm(tctx->lp_ctx));
-       r.in.partner_name = dcerpc_server_name(p);
+       r.in.replica_set_guid = NULL;
+       r.in.connection_guid = NULL;
+       r.in.replica_set_name = talloc_asprintf(tctx, "%s",
+                                               lp_realm(tctx->lp_ctx));
+       r.in.partner_dns_name = dcerpc_server_name(p);
 
        torture_assert_ntstatus_ok(tctx,
                dcerpc_frsapi_ForceReplication(p, tctx, &r),
index 7d03e7ef9ebbd6c76b7e8d6576ad80f34c61895a..b45b56545251214ffcb2f069a0df60af031a1ed7 100644 (file)
@@ -47,7 +47,7 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p,
        NTSTATUS status;
        uint16_t system_name = '\\';
 
-       printf("\nTesting OpenPolicy\n");
+       torture_comment(tctx, "\nTesting OpenPolicy\n");
 
        qos.len = 0;
        qos.impersonation_level = 2;
@@ -70,10 +70,10 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p,
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
-                       printf("not considering %s to be an error\n", nt_errstr(status));
+                       torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
                        return true;
                }
-               printf("OpenPolicy failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -90,7 +90,7 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p,
        struct lsa_OpenPolicy2 r;
        NTSTATUS status;
 
-       printf("\nTesting OpenPolicy2\n");
+       torture_comment(tctx, "\nTesting OpenPolicy2\n");
 
        *handle = talloc(tctx, struct policy_handle);
        if (!*handle) {
@@ -118,12 +118,12 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p,
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
-                       printf("not considering %s to be an error\n", nt_errstr(status));
+                       torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
                        talloc_free(*handle);
                        *handle = NULL;
                        return true;
                }
-               printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -161,7 +161,7 @@ static bool test_LookupNames(struct dcerpc_pipe *p,
        NTSTATUS status;
        int i;
 
-       printf("\nTesting LookupNames with %d names\n", tnames->count);
+       torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
 
        sids.count = 0;
        sids.sids = NULL;
@@ -187,30 +187,30 @@ static bool test_LookupNames(struct dcerpc_pipe *p,
            NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
                for (i=0;i< tnames->count;i++) {
                        if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
-                               printf("LookupName of %s was unmapped\n",
+                               torture_comment(tctx, "LookupName of %s was unmapped\n",
                                       tnames->names[i].name.string);
                        } else if (i >=count) {
-                               printf("LookupName of %s failed to return a result\n",
+                               torture_comment(tctx, "LookupName of %s failed to return a result\n",
                                       tnames->names[i].name.string);
                        }
                }
-               printf("LookupNames failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
                return false;
        } else if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupNames failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
                return false;
        }
 
        for (i=0;i< tnames->count;i++) {
                if (i < count && sids.sids[i].sid_type != tnames->names[i].sid_type) {
-                       printf("LookupName of %s got unexpected name type: %s\n",
+                       torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n",
                               tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type));
                } else if (i >=count) {
-                       printf("LookupName of %s failed to return a result\n",
+                       torture_comment(tctx, "LookupName of %s failed to return a result\n",
                               tnames->names[i].name.string);
                }
        }
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -235,7 +235,7 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
        name[0].name.string = "NT AUTHORITY\\BOGUS";
        name[1].name.string = NULL;
 
-       printf("\nTesting LookupNames with bogus names\n");
+       torture_comment(tctx, "\nTesting LookupNames with bogus names\n");
 
        sids.count = 0;
        sids.sids = NULL;
@@ -257,11 +257,11 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupNames(p, tctx, &r);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
-               printf("LookupNames failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
                return false;
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -274,7 +274,7 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p,
        struct lsa_TransNameArray tnames;
        bool ret = true;
 
-       printf("Testing LookupNames with well known names\n");
+       torture_comment(tctx, "Testing LookupNames with well known names\n");
 
        tnames.names = &name;
        tnames.count = 1;
@@ -330,7 +330,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
        NTSTATUS status;
        int i;
 
-       printf("\nTesting LookupNames2 with %d names\n", tnames->count);
+       torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
 
        sids.count = 0;
        sids.sids = NULL;
@@ -354,7 +354,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupNames2(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupNames2 failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -366,7 +366,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
                }
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -386,7 +386,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
        NTSTATUS status;
        int i;
 
-       printf("\nTesting LookupNames3 with %d names\n", tnames->count);
+       torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
 
        sids.count = 0;
        sids.sids = NULL;
@@ -410,7 +410,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupNames3(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupNames3 failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -422,7 +422,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
                }
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -440,7 +440,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
        NTSTATUS status;
        int i;
 
-       printf("\nTesting LookupNames4 with %d names\n", tnames->count);
+       torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
 
        sids.count = 0;
        sids.sids = NULL;
@@ -463,7 +463,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupNames4(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupNames4 failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -475,7 +475,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
                }
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -492,7 +492,7 @@ static bool test_LookupSids(struct dcerpc_pipe *p,
        uint32_t count = sids->num_sids;
        NTSTATUS status;
 
-       printf("\nTesting LookupSids\n");
+       torture_comment(tctx, "\nTesting LookupSids\n");
 
        names.count = 0;
        names.names = NULL;
@@ -508,11 +508,11 @@ static bool test_LookupSids(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupSids(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupSids failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
                return false;
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        if (!test_LookupNames(p, tctx, handle, &names)) {
                return false;
@@ -533,7 +533,7 @@ static bool test_LookupSids2(struct dcerpc_pipe *p,
        uint32_t count = sids->num_sids;
        NTSTATUS status;
 
-       printf("\nTesting LookupSids2\n");
+       torture_comment(tctx, "\nTesting LookupSids2\n");
 
        names.count = 0;
        names.names = NULL;
@@ -551,11 +551,11 @@ static bool test_LookupSids2(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupSids2(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupSids2 failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status));
                return false;
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        if (!test_LookupNames2(p, tctx, handle, &names, false)) {
                return false;
@@ -578,7 +578,7 @@ static bool test_LookupSids3(struct dcerpc_pipe *p,
        uint32_t count = sids->num_sids;
        NTSTATUS status;
 
-       printf("\nTesting LookupSids3\n");
+       torture_comment(tctx, "\nTesting LookupSids3\n");
 
        names.count = 0;
        names.names = NULL;
@@ -597,15 +597,15 @@ static bool test_LookupSids3(struct dcerpc_pipe *p,
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
-                       printf("not considering %s to be an error\n", nt_errstr(status));
+                       torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
                        return true;
                }
-               printf("LookupSids3 failed - %s - not considered an error\n",
+               torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n",
                       nt_errstr(status));
                return false;
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        if (!test_LookupNames4(p, tctx, &names, false)) {
                return false;
@@ -623,7 +623,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
        struct lsa_SidArray sids;
        int i;
 
-       printf("\nTesting LookupSids with lots of SIDs\n");
+       torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
 
        sids.num_sids = 100;
 
@@ -654,11 +654,11 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_LookupSids(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("LookupSids failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
                        return false;
                }
 
-               printf("\n");
+               torture_comment(tctx, "\n");
 
                if (!test_LookupNames(p, tctx, handle, &names)) {
                        return false;
@@ -672,7 +672,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
                names.count = 0;
                names.names = NULL;
 
-               printf("\nTesting LookupSids3\n");
+               torture_comment(tctx, "\nTesting LookupSids3\n");
 
                r.in.sids = &sids;
                r.in.names = &names;
@@ -688,10 +688,10 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
                            NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
-                               printf("not considering %s to be an error\n", nt_errstr(status));
+                               torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
                                return true;
                        }
-                       printf("LookupSids3 failed - %s\n",
+                       torture_comment(tctx, "LookupSids3 failed - %s\n",
                               nt_errstr(status));
                        return false;
                }
@@ -700,7 +700,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
                }
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
 
 
@@ -742,7 +742,7 @@ static bool test_LookupSids_async(struct dcerpc_pipe *p,
        names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
        r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
 
-       printf("\nTesting %d async lookupsids request\n", num_async_requests);
+       torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
 
        req = talloc_array(tctx, struct rpc_request *, num_async_requests);
 
@@ -804,7 +804,7 @@ static bool test_LookupPrivValue(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupPrivValue(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -826,7 +826,7 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupPrivName(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -844,7 +844,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
        struct lsa_PrivilegeSet privs;
        bool ret = true;
 
-       printf("\nTesting RemovePrivilegesFromAccount\n");
+       torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
 
        r.in.handle = acct_handle;
        r.in.remove_all = 0;
@@ -868,7 +868,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
                        return false;
                }
                /* Windows 2008 does not allow this to be removed */
@@ -876,7 +876,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
                        return ret;
                }
 
-               printf("RemovePrivilegesFromAccount failed to remove %s - %s\n",
+               torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
                       name->string,
                       nt_errstr(status));
                return false;
@@ -895,7 +895,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
        struct lsa_PrivilegeSet privs;
        bool ret = true;
 
-       printf("\nTesting AddPrivilegesToAccount\n");
+       torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
 
        r.in.handle = acct_handle;
        r.in.privs = &privs;
@@ -908,7 +908,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -925,14 +925,14 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p,
        struct lsa_PrivilegeSet *privs = NULL;
        bool ret = true;
 
-       printf("\nTesting EnumPrivsAccount\n");
+       torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
 
        r.in.handle = acct_handle;
        r.out.privs = &privs;
 
        status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -961,46 +961,46 @@ static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p,
        uint32_t access_mask;
        struct lsa_GetSystemAccessAccount r;
 
-       printf("\nTesting GetSystemAccessAccount\n");
+       torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
 
        r.in.handle = acct_handle;
        r.out.access_mask = &access_mask;
 
        status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status));
                return false;
        }
 
        if (r.out.access_mask != NULL) {
-               printf("Rights:");
+               torture_comment(tctx, "Rights:");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
-                       printf(" LSA_POLICY_MODE_INTERACTIVE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
-                       printf(" LSA_POLICY_MODE_NETWORK");
+                       torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
-                       printf(" LSA_POLICY_MODE_BATCH");
+                       torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
-                       printf(" LSA_POLICY_MODE_SERVICE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
-                       printf(" LSA_POLICY_MODE_PROXY");
+                       torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
-                       printf(" LSA_POLICY_MODE_DENY_INTERACTIVE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
-                       printf(" LSA_POLICY_MODE_DENY_NETWORK");
+                       torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
-                       printf(" LSA_POLICY_MODE_DENY_BATCH");
+                       torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
-                       printf(" LSA_POLICY_MODE_DENY_SERVICE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
-                       printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
-                       printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
+                       torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
-                       printf(" LSA_POLICY_MODE_ALL");
+                       torture_comment(tctx, " LSA_POLICY_MODE_ALL");
                if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
-                       printf(" LSA_POLICY_MODE_ALL_NT4");
-               printf("\n");
+                       torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
+               torture_comment(tctx, "\n");
        }
 
        return true;
@@ -1013,12 +1013,12 @@ static bool test_Delete(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct lsa_Delete r;
 
-       printf("\nTesting Delete\n");
+       torture_comment(tctx, "\nTesting Delete\n");
 
        r.in.handle = handle;
        status = dcerpc_lsa_Delete(p, tctx, &r);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
-               printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
+               torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1032,13 +1032,13 @@ static bool test_DeleteObject(struct dcerpc_pipe *p,
        NTSTATUS status;
        struct lsa_DeleteObject r;
 
-       printf("\nTesting DeleteObject\n");
+       torture_comment(tctx, "\nTesting DeleteObject\n");
 
        r.in.handle = handle;
        r.out.handle = handle;
        status = dcerpc_lsa_DeleteObject(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("DeleteObject failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1057,7 +1057,7 @@ static bool test_CreateAccount(struct dcerpc_pipe *p,
 
        newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
 
-       printf("\nTesting CreateAccount\n");
+       torture_comment(tctx, "\nTesting CreateAccount\n");
 
        r.in.handle = handle;
        r.in.sid = newsid;
@@ -1074,11 +1074,11 @@ static bool test_CreateAccount(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_OpenAccount(p, tctx, &r_o);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("OpenAccount failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
                        return false;
                }
        } else if (!NT_STATUS_IS_OK(status)) {
-               printf("CreateAccount failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1109,7 +1109,7 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1137,7 +1137,7 @@ static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1183,7 +1183,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
        secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random());
 
        for (i=0; i< 2; i++) {
-               printf("\nTesting CreateSecret of %s\n", secname[i]);
+               torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
 
                init_lsa_String(&r.in.name, secname[i]);
 
@@ -1193,7 +1193,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_CreateSecret(p, tctx, &r);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("CreateSecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1203,7 +1203,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_CreateSecret(p, tctx, &r);
                if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
-                       printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1212,17 +1212,17 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                r2.in.name = r.in.name;
                r2.out.sec_handle = &sec_handle2;
 
-               printf("Testing OpenSecret\n");
+               torture_comment(tctx, "Testing OpenSecret\n");
 
                status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("OpenSecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status));
                        return false;
                }
 
                status = dcerpc_fetch_session_key(p, &session_key);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1235,11 +1235,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                r3.in.new_val->length = enc_key.length;
                r3.in.new_val->size = enc_key.length;
 
-               printf("Testing SetSecret\n");
+               torture_comment(tctx, "Testing SetSecret\n");
 
                status = dcerpc_lsa_SetSecret(p, tctx, &r3);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("SetSecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1253,11 +1253,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                /* break the encrypted data */
                enc_key.data[0]++;
 
-               printf("Testing SetSecret with broken key\n");
+               torture_comment(tctx, "Testing SetSecret with broken key\n");
 
                status = dcerpc_lsa_SetSecret(p, tctx, &r3);
                if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
-                       printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
                        ret = false;
                }
 
@@ -1275,14 +1275,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
                bufp1.buf = NULL;
 
-               printf("Testing QuerySecret\n");
+               torture_comment(tctx, "Testing QuerySecret\n");
                status = dcerpc_lsa_QuerySecret(p, tctx, &r4);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("QuerySecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
                        ret = false;
                } else {
                        if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
-                               printf("No secret buffer returned\n");
+                               torture_comment(tctx, "No secret buffer returned\n");
                                ret = false;
                        } else {
                                blob1.data = r4.out.new_val->buf->data;
@@ -1294,7 +1294,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                                                              &blob1, &session_key);
 
                                if (strcmp(secret1, secret2) != 0) {
-                                       printf("Returned secret (r4) '%s' doesn't match '%s'\n",
+                                       torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
                                               secret2, secret1);
                                        ret = false;
                                }
@@ -1312,11 +1312,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
 
                msleep(200);
-               printf("Testing SetSecret (existing value should move to old)\n");
+               torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
 
                status = dcerpc_lsa_SetSecret(p, tctx, &r5);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("SetSecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
                        ret = false;
                }
 
@@ -1337,14 +1337,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_QuerySecret(p, tctx, &r6);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("QuerySecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
                        ret = false;
                        secret4 = NULL;
                } else {
 
                        if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
                                || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
-                               printf("Both secret buffers and both times not returned\n");
+                               torture_comment(tctx, "Both secret buffers and both times not returned\n");
                                ret = false;
                                secret4 = NULL;
                        } else {
@@ -1357,7 +1357,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                                                              &blob1, &session_key);
 
                                if (strcmp(secret3, secret4) != 0) {
-                                       printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
+                                       torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
                                        ret = false;
                                }
 
@@ -1370,12 +1370,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                                                              &blob1, &session_key);
 
                                if (strcmp(secret1, secret2) != 0) {
-                                       printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1);
+                                       torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
                                        ret = false;
                                }
 
                                if (*r6.out.new_mtime == *r6.out.old_mtime) {
-                                       printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
+                                       torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
                                               i,
                                               secname[i],
                                               nt_time_string(tctx, *r6.out.old_mtime),
@@ -1394,11 +1394,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                r7.in.old_val->size = enc_key.length;
                r7.in.new_val = NULL;
 
-               printf("Testing SetSecret of old Secret only\n");
+               torture_comment(tctx, "Testing SetSecret of old Secret only\n");
 
                status = dcerpc_lsa_SetSecret(p, tctx, &r7);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("SetSecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
                        ret = false;
                }
 
@@ -1416,20 +1416,20 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_QuerySecret(p, tctx, &r8);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("QuerySecret failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
                        ret = false;
                } else {
                        if (!r8.out.new_val || !r8.out.old_val) {
-                               printf("in/out pointers not returned, despite being set on in for QuerySecret\n");
+                               torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
                                ret = false;
                        } else if (r8.out.new_val->buf != NULL) {
-                               printf("NEW secret buffer must not be returned after OLD set\n");
+                               torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
                                ret = false;
                        } else if (r8.out.old_val->buf == NULL) {
-                               printf("OLD secret buffer was not returned after OLD set\n");
+                               torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
                                ret = false;
                        } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
-                               printf("Both times not returned after OLD set\n");
+                               torture_comment(tctx, "Both times not returned after OLD set\n");
                                ret = false;
                        } else {
                                blob1.data = r8.out.old_val->buf->data;
@@ -1441,12 +1441,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                                                              &blob1, &session_key);
 
                                if (strcmp(secret5, secret6) != 0) {
-                                       printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6);
+                                       torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
                                        ret = false;
                                }
 
                                if (*r8.out.new_mtime != *r8.out.old_mtime) {
-                                       printf("Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
+                                       torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
                                               secname[i],
                                               nt_time_string(tctx, *r8.out.old_mtime),
                                               nt_time_string(tctx, *r8.out.new_mtime));
@@ -1467,15 +1467,15 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
                d_o.out.handle = &sec_handle2;
                status = dcerpc_lsa_DeleteObject(p, tctx, &d_o);
                if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
-                       printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
                        ret = false;
                } else {
 
-                       printf("Testing OpenSecret of just-deleted secret\n");
+                       torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
 
                        status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
                        if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-                               printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
                                ret = false;
                        }
                }
@@ -1495,7 +1495,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p,
        struct lsa_EnumAccountRights r;
        struct lsa_RightSet rights;
 
-       printf("\nTesting EnumAccountRights\n");
+       torture_comment(tctx, "\nTesting EnumAccountRights\n");
 
        r.in.handle = acct_handle;
        r.in.sid = sid;
@@ -1503,7 +1503,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_EnumAccountRights(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumAccountRights of %s failed - %s\n",
+               torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
                       dom_sid_string(tctx, sid), nt_errstr(status));
                return false;
        }
@@ -1522,19 +1522,21 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
        struct sec_desc_buf *sdbuf = NULL;
 
        if (torture_setting_bool(tctx, "samba4", false)) {
-               printf("\nskipping QuerySecurity test against Samba4\n");
+               torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
                return true;
        }
 
-       printf("\nTesting QuerySecurity\n");
+       torture_comment(tctx, "\nTesting QuerySecurity\n");
 
        r.in.handle = acct_handle;
-       r.in.sec_info = 7;
+       r.in.sec_info = SECINFO_OWNER |
+                       SECINFO_GROUP |
+                       SECINFO_DACL;
        r.out.sdbuf = &sdbuf;
 
        status = dcerpc_lsa_QuerySecurity(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("QuerySecurity failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1550,7 +1552,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
        struct lsa_OpenAccount r;
        struct policy_handle acct_handle;
 
-       printf("\nTesting OpenAccount\n");
+       torture_comment(tctx, "\nTesting OpenAccount\n");
 
        r.in.handle = handle;
        r.in.sid = sid;
@@ -1559,7 +1561,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_OpenAccount(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("OpenAccount failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1589,7 +1591,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
        int i;
        bool ret = true;
 
-       printf("\nTesting EnumAccounts\n");
+       torture_comment(tctx, "\nTesting EnumAccounts\n");
 
        r.in.handle = handle;
        r.in.resume_handle = &resume_handle;
@@ -1604,7 +1606,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
                        break;
                }
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("EnumAccounts failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1620,31 +1622,31 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
                 * be on schannel, or we would not be able to do the
                 * rest */
 
-               printf("Testing all accounts\n");
+               torture_comment(tctx, "Testing all accounts\n");
                for (i=0;i<sids1.num_sids;i++) {
                        ret &= test_OpenAccount(p, tctx, handle, sids1.sids[i].sid);
                        ret &= test_EnumAccountRights(p, tctx, handle, sids1.sids[i].sid);
                }
-               printf("\n");
+               torture_comment(tctx, "\n");
        }
 
        if (sids1.num_sids < 3) {
                return ret;
        }
 
-       printf("Trying EnumAccounts partial listing (asking for 1 at 2)\n");
+       torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
        resume_handle = 2;
        r.in.num_entries = 1;
        r.out.sids = &sids2;
 
        status = dcerpc_lsa_EnumAccounts(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumAccounts failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
                return false;
        }
 
        if (sids2.num_sids != 1) {
-               printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
+               torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
                return false;
        }
 
@@ -1664,7 +1666,7 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
        uint16_t returned_language_id = 0;
        struct lsa_StringLarge *disp_name = NULL;
 
-       printf("\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
+       torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
 
        r.in.handle = handle;
        r.in.name = priv_name;
@@ -1675,10 +1677,10 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
 
        status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status));
                return false;
        }
-       printf("%s -> \"%s\"  (language 0x%x/0x%x)\n",
+       torture_comment(tctx, "%s -> \"%s\"  (language 0x%x/0x%x)\n",
               priv_name->string, disp_name->string,
               r.in.language_id, *r.out.returned_language_id);
 
@@ -1696,7 +1698,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
 
        ZERO_STRUCT(sids);
 
-       printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
+       torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
 
        r.in.handle = handle;
        r.in.name = priv_name;
@@ -1710,7 +1712,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
        }
 
        if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1729,7 +1731,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p,
        int i;
        bool ret = true;
 
-       printf("\nTesting EnumPrivs\n");
+       torture_comment(tctx, "\nTesting EnumPrivs\n");
 
        r.in.handle = handle;
        r.in.resume_handle = &resume_handle;
@@ -1740,7 +1742,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p,
        resume_handle = 0;
        status = dcerpc_lsa_EnumPrivs(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumPrivs failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -1766,10 +1768,10 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p,
        struct lsa_String string;
        struct lsa_ForestTrustInformation info, *info_ptr;
 
-       printf("\nTesting lsaRQueryForestTrustInformation\n");
+       torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
 
        if (torture_setting_bool(tctx, "samba4", false)) {
-               printf("skipping QueryForestTrustInformation against Samba4\n");
+               torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
                return true;
        }
 
@@ -1789,7 +1791,7 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p,
        status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r);
 
        if (!NT_STATUS_IS_OK(status)) {
-               printf("lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
+               torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
                ret = false;
        }
 
@@ -1824,7 +1826,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
        int i,j;
        bool ret = true;
 
-       printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
+       torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
        for (i=0; i< domains->count; i++) {
                struct lsa_OpenTrustedDomain trust;
                struct lsa_OpenTrustedDomainByName trust_by_name;
@@ -1844,7 +1846,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
                        status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust);
 
                        if (!NT_STATUS_IS_OK(status)) {
-                               printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status));
                                return false;
                        }
 
@@ -1862,11 +1864,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
                                q.out.info = &info;
                                status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
                                if (!NT_STATUS_IS_OK(status) && ok[j]) {
-                                       printf("QueryTrustedDomainInfo level %d failed - %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
                                               levels[j], nt_errstr(status));
                                        ret = false;
                                } else if (NT_STATUS_IS_OK(status) && !ok[j]) {
-                                       printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
                                               levels[j], nt_errstr(status));
                                        ret = false;
                                }
@@ -1874,7 +1876,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
 
                        status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust);
                        if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-                               printf("Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
                                return false;
                        }
 
@@ -1883,7 +1885,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
 
                        status = dcerpc_lsa_Close(p, tctx, &c);
                        if (!NT_STATUS_IS_OK(status)) {
-                               printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
                                return false;
                        }
 
@@ -1902,11 +1904,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
 
                                status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
                                if (!NT_STATUS_IS_OK(status) && ok[j]) {
-                                       printf("QueryTrustedDomainInfoBySid level %d failed - %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
                                               levels[j], nt_errstr(status));
                                        ret = false;
                                } else if (NT_STATUS_IS_OK(status) && !ok[j]) {
-                                       printf("QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
                                               levels[j], nt_errstr(status));
                                        ret = false;
                                }
@@ -1921,7 +1923,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
                status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name);
 
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1933,11 +1935,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
                        q.out.info = &info;
                        status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
                        if (!NT_STATUS_IS_OK(status) && ok[j]) {
-                               printf("QueryTrustedDomainInfo level %d failed - %s\n",
+                               torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
                                       levels[j], nt_errstr(status));
                                ret = false;
                        } else if (NT_STATUS_IS_OK(status) && !ok[j]) {
-                               printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+                               torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
                                       levels[j], nt_errstr(status));
                                ret = false;
                        }
@@ -1948,7 +1950,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
 
                status = dcerpc_lsa_Close(p, tctx, &c);
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
                        return false;
                }
 
@@ -1965,11 +1967,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
                        q.out.info          = &info;
                        status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q);
                        if (!NT_STATUS_IS_OK(status) && ok[j]) {
-                               printf("QueryTrustedDomainInfoByName level %d failed - %s\n",
+                               torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
                                       levels[j], nt_errstr(status));
                                ret = false;
                        } else if (NT_STATUS_IS_OK(status) && !ok[j]) {
-                               printf("QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
+                               torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
                                       levels[j], nt_errstr(status));
                                ret = false;
                        }
@@ -1990,7 +1992,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
        struct lsa_DomainListEx domains_ex;
        bool ret = true;
 
-       printf("\nTesting EnumTrustDom\n");
+       torture_comment(tctx, "\nTesting EnumTrustDom\n");
 
        r.in.handle = handle;
        r.in.resume_handle = &resume_handle;
@@ -2002,11 +2004,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
 
        if (NT_STATUS_IS_OK(enum_status)) {
                if (domains.count == 0) {
-                       printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+                       torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
                        return false;
                }
        } else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
-               printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
+               torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
                return false;
        }
 
@@ -2027,24 +2029,24 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
                        if (domains.count == 0) {
                                return true;
                        }
-                       printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+                       torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
                        return false;
                } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
                        /* Windows 2003 gets this off by one on the first run */
                        if (r.out.domains->count < 3 || r.out.domains->count > 4) {
-                               printf("EnumTrustDom didn't fill the buffer we "
+                               torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
                                       "asked it to (got %d, expected %d / %d == %d entries)\n",
                                       r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
                                       LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
                                ret = false;
                        }
                } else if (!NT_STATUS_IS_OK(enum_status)) {
-                       printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
+                       torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status));
                        return false;
                }
 
                if (domains.count == 0) {
-                       printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+                       torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
                        return false;
                }
 
@@ -2052,7 +2054,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
 
        } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
 
-       printf("\nTesting EnumTrustedDomainsEx\n");
+       torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
 
        r_ex.in.handle = handle;
        r_ex.in.resume_handle = &resume_handle;
@@ -2063,7 +2065,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
        enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex);
 
        if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
-               printf("EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
+               torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
                return false;
        }
 
@@ -2082,12 +2084,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
                        if (domains_ex.count == 0) {
                                return true;
                        }
-                       printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+                       torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
                        return false;
                } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
                        /* Windows 2003 gets this off by one on the first run */
                        if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
-                               printf("EnumTrustDom didn't fill the buffer we "
+                               torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
                                       "asked it to (got %d, expected %d / %d == %d entries)\n",
                                       r_ex.out.domains->count,
                                       r_ex.in.max_size,
@@ -2095,12 +2097,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
                                       r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
                        }
                } else if (!NT_STATUS_IS_OK(enum_status)) {
-                       printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
+                       torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
                        return false;
                }
 
                if (domains_ex.count == 0) {
-                       printf("EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+                       torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
                        return false;
                }
 
@@ -2125,7 +2127,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
        union lsa_TrustedDomainInfo *info = NULL;
        int i;
 
-       printf("\nTesting CreateTrustedDomain for 12 domains\n");
+       torture_comment(tctx, "\nTesting CreateTrustedDomain for 12 domains\n");
 
        if (!test_EnumTrustDom(p, tctx, handle)) {
                ret = false;
@@ -2151,7 +2153,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
                        status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r);
                }
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status));
                        ret = false;
                } else {
 
@@ -2160,28 +2162,28 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
                        q.out.info = &info;
                        status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
                        if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
                                ret = false;
                        } else if (!q.out.info) {
                                ret = false;
                        } else {
                                if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
-                                       printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
                                               info->info_ex.netbios_name.string, trustinfo.name.string);
                                        ret = false;
                                }
                                if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
                                               trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
                                        ret = false;
                                }
                                if (info->info_ex.trust_attributes != 0) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
                                               trust_name, info->info_ex.trust_attributes, 0);
                                        ret = false;
                                }
                                if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
                                               trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
                                        ret = false;
                                }
@@ -2222,11 +2224,11 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
        enum ndr_err_code ndr_err;
        int i;
 
-       printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n");
+       torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for 12 domains\n");
 
        status = dcerpc_fetch_session_key(p, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
                return false;
        }
 
@@ -2263,7 +2265,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
                ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct,
                                               (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       printf("ndr_push_struct_blob of trustDomainPasswords structure failed");
+                       torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed");
                        ret = false;
                }
 
@@ -2284,7 +2286,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
                        status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r);
                }
                if (!NT_STATUS_IS_OK(status)) {
-                       printf("CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
                        ret = false;
                } else {
 
@@ -2293,29 +2295,29 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
                        q.out.info = &info;
                        status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
                        if (!NT_STATUS_IS_OK(status)) {
-                               printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+                               torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
                                ret = false;
                        } else if (!q.out.info) {
-                               printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
+                               torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
                                ret = false;
                        } else {
                                if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
-                                       printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
                                               info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
                                        ret = false;
                                }
                                if (info->info_ex.trust_type != trustinfo.trust_type) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
                                               trust_name, info->info_ex.trust_type, trustinfo.trust_type);
                                        ret = false;
                                }
                                if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
                                               trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
                                        ret = false;
                                }
                                if (info->info_ex.trust_direction != trustinfo.trust_direction) {
-                                       printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+                                       torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
                                               trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
                                        ret = false;
                                }
@@ -2325,13 +2327,13 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
 
        /* now that we have some domains to look over, we can test the enum calls */
        if (!test_EnumTrustDom(p, tctx, handle)) {
-               printf("test_EnumTrustDom failed\n");
+               torture_comment(tctx, "test_EnumTrustDom failed\n");
                ret = false;
        }
 
        for (i=0; i<12; i++) {
                if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) {
-                       printf("test_DeleteTrustedDomainBySid failed\n");
+                       torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
                        ret = false;
                }
        }
@@ -2349,14 +2351,14 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
        int i;
        bool ret = true;
 
-       printf("\nTesting QueryDomainInformationPolicy\n");
+       torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
 
        for (i=2;i<4;i++) {
                r.in.handle = handle;
                r.in.level = i;
                r.out.info = &info;
 
-               printf("\nTrying QueryDomainInformationPolicy level %d\n", i);
+               torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
 
                status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r);
 
@@ -2364,7 +2366,7 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
                if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                        continue;
                } else if (!NT_STATUS_IS_OK(status)) {
-                       printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
+                       torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
                        ret = false;
                        continue;
                }
@@ -2386,9 +2388,9 @@ static bool test_QueryInfoPolicyCalls(    bool version2,
        bool ret = true;
 
        if (version2)
-               printf("\nTesting QueryInfoPolicy2\n");
+               torture_comment(tctx, "\nTesting QueryInfoPolicy2\n");
        else
-               printf("\nTesting QueryInfoPolicy\n");
+               torture_comment(tctx, "\nTesting QueryInfoPolicy\n");
 
        for (i=1;i<=14;i++) {
                r.in.handle = handle;
@@ -2396,9 +2398,9 @@ static bool test_QueryInfoPolicyCalls(    bool version2,
                r.out.info = &info;
 
                if (version2)
-                       printf("\nTrying QueryInfoPolicy2 level %d\n", i);
+                       torture_comment(tctx, "\nTrying QueryInfoPolicy2 level %d\n", i);
                else
-                       printf("\nTrying QueryInfoPolicy level %d\n", i);
+                       torture_comment(tctx, "\nTrying QueryInfoPolicy level %d\n", i);
 
                if (version2)
                        /* We can perform the cast, because both types are
@@ -2413,7 +2415,7 @@ static bool test_QueryInfoPolicyCalls(    bool version2,
                case LSA_POLICY_INFO_AUDIT_FULL_SET:
                case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
                        if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
-                               printf("Server should have failed level %u: %s\n", i, nt_errstr(status));
+                               torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status));
                                ret = false;
                        }
                        break;
@@ -2430,9 +2432,9 @@ static bool test_QueryInfoPolicyCalls(    bool version2,
                case LSA_POLICY_INFO_PD:
                        if (!NT_STATUS_IS_OK(status)) {
                                if (version2)
-                                       printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                                       torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
                                else
-                                       printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                                       torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                ret = false;
                        }
                        break;
@@ -2441,16 +2443,16 @@ static bool test_QueryInfoPolicyCalls(  bool version2,
                                /* Other levels not implemented yet */
                                if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
                                        if (version2)
-                                               printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                                               torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
                                        else
-                                               printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                                               torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                        ret = false;
                                }
                        } else if (!NT_STATUS_IS_OK(status)) {
                                if (version2)
-                                       printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+                                       torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
                                else
-                                       printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+                                       torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
                                ret = false;
                        }
                        break;
@@ -2522,7 +2524,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
        struct lsa_String *authority_name_p = NULL;
        struct lsa_String *account_name_p = NULL;
 
-       printf("\nTesting GetUserName\n");
+       torture_comment(tctx, "\nTesting GetUserName\n");
 
        r.in.system_name        = "\\";
        r.in.account_name       = &account_name_p;
@@ -2532,7 +2534,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
        status = dcerpc_lsa_GetUserName(p, tctx, &r);
 
        if (!NT_STATUS_IS_OK(status)) {
-               printf("GetUserName failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
                ret = false;
        }
 
@@ -2544,7 +2546,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
        status = dcerpc_lsa_GetUserName(p, tctx, &r);
 
        if (!NT_STATUS_IS_OK(status)) {
-               printf("GetUserName failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
                ret = false;
        }
 
@@ -2559,25 +2561,25 @@ bool test_lsa_Close(struct dcerpc_pipe *p,
        struct lsa_Close r;
        struct policy_handle handle2;
 
-       printf("\nTesting Close\n");
+       torture_comment(tctx, "\nTesting Close\n");
 
        r.in.handle = handle;
        r.out.handle = &handle2;
 
        status = dcerpc_lsa_Close(p, tctx, &r);
        if (!NT_STATUS_IS_OK(status)) {
-               printf("Close failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
                return false;
        }
 
        status = dcerpc_lsa_Close(p, tctx, &r);
        /* its really a fault - we need a status code for rpc fault */
        if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
-               printf("Close failed - %s\n", nt_errstr(status));
+               torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
                return false;
        }
 
-       printf("\n");
+       torture_comment(tctx, "\n");
 
        return true;
 }
@@ -2625,28 +2627,9 @@ bool torture_rpc_lsa(struct torture_context *tctx)
                        ret = false;
                }
 
-               if (!test_CreateAccount(p, tctx, handle)) {
-                       ret = false;
-               }
-
                if (!test_CreateSecret(p, tctx, handle)) {
                        ret = false;
                }
-               if (!test_CreateTrustedDomain(p, tctx, handle)) {
-                       ret = false;
-               }
-
-               if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
-                       ret = false;
-               }
-
-               if (!test_EnumAccounts(p, tctx, handle)) {
-                       ret = false;
-               }
-
-               if (!test_EnumPrivs(p, tctx, handle)) {
-                       ret = false;
-               }
 
                if (!test_QueryInfoPolicy(p, tctx, handle)) {
                        ret = false;
@@ -2766,3 +2749,104 @@ struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
 
        return suite;
 }
+
+static bool testcase_TrustedDomains(struct torture_context *tctx,
+                                   struct dcerpc_pipe *p)
+{
+       bool ret = true;
+       struct policy_handle *handle;
+
+       if (!test_OpenPolicy(p, tctx)) {
+               ret = false;
+       }
+
+       if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+               ret = false;
+       }
+
+       if (!handle) {
+               ret = false;
+       }
+
+       if (!test_CreateTrustedDomain(p, tctx, handle)) {
+               ret = false;
+       }
+
+       if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
+               ret = false;
+       }
+
+       if (!test_lsa_Close(p, tctx, handle)) {
+               ret = false;
+       }
+
+       return ret;
+}
+
+struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite;
+       struct torture_rpc_tcase *tcase;
+
+       suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS");
+
+       tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+                                                 &ndr_table_lsarpc);
+       torture_rpc_tcase_add_test(tcase, "TrustedDomains",
+                                  testcase_TrustedDomains);
+
+       return suite;
+}
+
+static bool testcase_Privileges(struct torture_context *tctx,
+                               struct dcerpc_pipe *p)
+{
+       bool ret = true;
+       struct policy_handle *handle;
+
+       if (!test_OpenPolicy(p, tctx)) {
+               ret = false;
+       }
+
+       if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+               ret = false;
+       }
+
+       if (!handle) {
+               ret = false;
+       }
+
+       if (!test_CreateAccount(p, tctx, handle)) {
+               ret = false;
+       }
+
+       if (!test_EnumAccounts(p, tctx, handle)) {
+               ret = false;
+       }
+
+       if (!test_EnumPrivs(p, tctx, handle)) {
+               ret = false;
+       }
+
+       if (!test_lsa_Close(p, tctx, handle)) {
+               ret = false;
+       }
+
+       return ret;
+}
+
+
+struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite;
+       struct torture_rpc_tcase *tcase;
+
+       suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES");
+
+       tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+                                                 &ndr_table_lsarpc);
+       torture_rpc_tcase_add_test(tcase, "Privileges",
+                                  testcase_Privileges);
+
+       return suite;
+}
index a70266697e0bcbdf26e8cc9d673a4a4bc809eda2..53d03a3ce9c52ff931e716ca9d3790a35f336ba2 100644 (file)
@@ -35,7 +35,6 @@ static bool test_random_uuid(struct torture_context *torture)
 {
        NTSTATUS status;
        struct dcerpc_pipe *p1, *p2;
-       struct rpc_request *req;
        struct GUID uuid;
        struct dssetup_DsRoleGetPrimaryDomainInformation r1;
        struct lsa_GetUserName r2;
index 4043562ab506a78c363035660aa3531fc4fec64b..ffdd7484708b7e99d5f7d52872539c252094267a 100644 (file)
@@ -431,6 +431,8 @@ NTSTATUS torture_rpc_init(void)
        torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite));
        torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite));
        torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite));
+       torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite));
+       torture_suite_add_suite(suite, torture_rpc_lsa_privileges(suite));
        torture_suite_add_suite(suite, torture_rpc_echo(suite));
        torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs);
        torture_suite_add_suite(suite, torture_rpc_frsapi(suite));
@@ -444,6 +446,7 @@ NTSTATUS torture_rpc_init(void)
        torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss);
        torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
        torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
+       torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
        torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
        torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users);
        torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords);
index 10e18e1531fb6f2b260d5ec7b9e79726b530e804..ddc14f33a2c347c6079e770354238150b25e3f76 100644 (file)
 #include "torture/rpc/rpc.h"
 #include "librpc/gen_ndr/ndr_spoolss_c.h"
 
+#define TORTURE_WELLKNOWN_PRINTER      "torture_wkn_printer"
+#define TORTURE_PRINTER                        "torture_printer"
+#define TORTURE_WELLKNOWN_PRINTER_EX   "torture_wkn_printer_ex"
+#define TORTURE_PRINTER_EX             "torture_printer_ex"
+
 struct test_spoolss_context {
        /* print server handle */
        struct policy_handle server_handle;
@@ -75,20 +80,22 @@ struct test_spoolss_context {
 
 #define COMPARE_STRING_ARRAY(tctx, c,r,e)
 
-static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx)
+static bool test_OpenPrinter_server(struct torture_context *tctx,
+                                   struct dcerpc_pipe *p,
+                                   struct policy_handle *server_handle)
 {
        NTSTATUS status;
        struct spoolss_OpenPrinter op;
 
-       op.in.printername       = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
+       op.in.printername       = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
        op.in.datatype          = NULL;
        op.in.devmode_ctr.devmode= NULL;
        op.in.access_mask       = 0;
-       op.out.handle           = &ctx->server_handle;
+       op.out.handle           = server_handle;
 
        torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
 
-       status = dcerpc_spoolss_OpenPrinter(p, ctx, &op);
+       status = dcerpc_spoolss_OpenPrinter(p, tctx, &op);
        torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
        torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
 
@@ -810,6 +817,564 @@ static bool test_GetPrinter(struct torture_context *tctx,
        return true;
 }
 
+static bool test_SetPrinter_errors(struct torture_context *tctx,
+                                  struct dcerpc_pipe *p,
+                                  struct policy_handle *handle)
+{
+       struct spoolss_SetPrinter r;
+       uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+       int i;
+
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+
+       info_ctr.level = 0;
+       info_ctr.info.info0 = NULL;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+
+       r.in.handle = handle;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.in.command = 0;
+
+       torture_comment(tctx, "Testing SetPrinter all zero\n");
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+               "failed to call SetPrinter");
+       torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+               "failed to call SetPrinter");
+
+ again:
+       for (i=0; i < ARRAY_SIZE(levels); i++) {
+
+               struct spoolss_SetPrinterInfo0 info0;
+               struct spoolss_SetPrinterInfo1 info1;
+               struct spoolss_SetPrinterInfo2 info2;
+               struct spoolss_SetPrinterInfo3 info3;
+               struct spoolss_SetPrinterInfo4 info4;
+               struct spoolss_SetPrinterInfo5 info5;
+               struct spoolss_SetPrinterInfo6 info6;
+               struct spoolss_SetPrinterInfo7 info7;
+               struct spoolss_DeviceModeInfo info8;
+               struct spoolss_DeviceModeInfo info9;
+
+
+               info_ctr.level = levels[i];
+               switch (levels[i]) {
+               case 0:
+                       ZERO_STRUCT(info0);
+                       info_ctr.info.info0 = &info0;
+                       break;
+               case 1:
+                       ZERO_STRUCT(info1);
+                       info_ctr.info.info1 = &info1;
+                       break;
+               case 2:
+                       ZERO_STRUCT(info2);
+                       info_ctr.info.info2 = &info2;
+                       break;
+               case 3:
+                       ZERO_STRUCT(info3);
+                       info_ctr.info.info3 = &info3;
+                       break;
+               case 4:
+                       ZERO_STRUCT(info4);
+                       info_ctr.info.info4 = &info4;
+                       break;
+               case 5:
+                       ZERO_STRUCT(info5);
+                       info_ctr.info.info5 = &info5;
+                       break;
+               case 6:
+                       ZERO_STRUCT(info6);
+                       info_ctr.info.info6 = &info6;
+                       break;
+               case 7:
+                       ZERO_STRUCT(info7);
+                       info_ctr.info.info7 = &info7;
+                       break;
+               case 8:
+                       ZERO_STRUCT(info8);
+                       info_ctr.info.info8 = &info8;
+                       break;
+               case 9:
+                       ZERO_STRUCT(info9);
+                       info_ctr.info.info9 = &info9;
+                       break;
+               }
+
+               torture_comment(tctx, "Testing SetPrinter level %d, command %d\n",
+                       info_ctr.level, r.in.command);
+
+               torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+                       "failed to call SetPrinter");
+
+               switch (r.in.command) {
+               case SPOOLSS_PRINTER_CONTROL_UNPAUSE: /* 0 */
+                       /* is ignored for all levels other then 0 */
+                       if (info_ctr.level > 0) {
+                               /* ignored then */
+                               break;
+                       }
+               case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */
+               case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */
+               case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */
+                       if (info_ctr.level > 0) {
+                               /* is invalid for all levels other then 0 */
+                               torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+                                       "unexpected error code returned");
+                               continue;
+                       } else {
+                               torture_assert_werr_ok(tctx, r.out.result,
+                                       "failed to call SetPrinter with non 0 command");
+                               continue;
+                       }
+                       break;
+
+               case SPOOLSS_PRINTER_CONTROL_SET_STATUS: /* 4 */
+                       /* FIXME: gd needs further investigation */
+               default:
+                       torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+                               "unexpected error code returned");
+                       continue;
+               }
+
+               switch (info_ctr.level) {
+               case 1:
+                       torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
+                               "unexpected error code returned");
+                       break;
+               case 2:
+                       torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_PRINTER_DRIVER,
+                               "unexpected error code returned");
+                       break;
+               case 3:
+               case 4:
+               case 5:
+               case 7:
+                       torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+                               "unexpected error code returned");
+                       break;
+               case 9:
+                       torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
+                               "unexpected error code returned");
+                       break;
+               default:
+                       torture_assert_werr_ok(tctx, r.out.result,
+                               "failed to call SetPrinter");
+                       break;
+               }
+       }
+
+       if (r.in.command < 5) {
+               r.in.command++;
+               goto again;
+       }
+
+       return true;
+}
+
+static void clear_info2(struct spoolss_SetPrinterInfoCtr *r)
+{
+       if ((r->level == 2) && (r->info.info2)) {
+               r->info.info2->secdesc = NULL;
+               r->info.info2->devmode = NULL;
+       }
+}
+
+static bool test_PrinterInfo(struct torture_context *tctx,
+                            struct dcerpc_pipe *p,
+                            struct policy_handle *handle)
+{
+       NTSTATUS status;
+       struct spoolss_SetPrinter s;
+       struct spoolss_GetPrinter q;
+       struct spoolss_GetPrinter q0;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       union spoolss_PrinterInfo info;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       uint32_t needed;
+       bool ret = true;
+       int i;
+
+       uint32_t status_list[] = {
+               /* these do not stick
+               PRINTER_STATUS_PAUSED,
+               PRINTER_STATUS_ERROR,
+               PRINTER_STATUS_PENDING_DELETION, */
+               PRINTER_STATUS_PAPER_JAM,
+               PRINTER_STATUS_PAPER_OUT,
+               PRINTER_STATUS_MANUAL_FEED,
+               PRINTER_STATUS_PAPER_PROBLEM,
+               PRINTER_STATUS_OFFLINE,
+               PRINTER_STATUS_IO_ACTIVE,
+               PRINTER_STATUS_BUSY,
+               PRINTER_STATUS_PRINTING,
+               PRINTER_STATUS_OUTPUT_BIN_FULL,
+               PRINTER_STATUS_NOT_AVAILABLE,
+               PRINTER_STATUS_WAITING,
+               PRINTER_STATUS_PROCESSING,
+               PRINTER_STATUS_INITIALIZING,
+               PRINTER_STATUS_WARMING_UP,
+               PRINTER_STATUS_TONER_LOW,
+               PRINTER_STATUS_NO_TONER,
+               PRINTER_STATUS_PAGE_PUNT,
+               PRINTER_STATUS_USER_INTERVENTION,
+               PRINTER_STATUS_OUT_OF_MEMORY,
+               PRINTER_STATUS_DOOR_OPEN,
+               PRINTER_STATUS_SERVER_UNKNOWN,
+               PRINTER_STATUS_POWER_SAVE,
+               /* these do not stick
+               0x02000000,
+               0x04000000,
+               0x08000000,
+               0x10000000,
+               0x20000000,
+               0x40000000,
+               0x80000000 */
+       };
+       uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL;
+       uint32_t attribute_list[] = {
+               PRINTER_ATTRIBUTE_QUEUED,
+               /* fails with WERR_INVALID_DATATYPE:
+               PRINTER_ATTRIBUTE_DIRECT, */
+               /* does not stick
+               PRINTER_ATTRIBUTE_DEFAULT, */
+               PRINTER_ATTRIBUTE_SHARED,
+               /* does not stick
+               PRINTER_ATTRIBUTE_NETWORK, */
+               PRINTER_ATTRIBUTE_HIDDEN,
+               PRINTER_ATTRIBUTE_LOCAL,
+               PRINTER_ATTRIBUTE_ENABLE_DEVQ,
+               PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS,
+               PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST,
+               PRINTER_ATTRIBUTE_WORK_OFFLINE,
+               /* does not stick
+               PRINTER_ATTRIBUTE_ENABLE_BIDI, */
+               /* fails with WERR_INVALID_DATATYPE:
+               PRINTER_ATTRIBUTE_RAW_ONLY, */
+               /* these do not stick
+               PRINTER_ATTRIBUTE_PUBLISHED,
+               PRINTER_ATTRIBUTE_FAX,
+               PRINTER_ATTRIBUTE_TS,
+               0x00010000,
+               0x00020000,
+               0x00040000,
+               0x00080000,
+               0x00100000,
+               0x00200000,
+               0x00400000,
+               0x00800000,
+               0x01000000,
+               0x02000000,
+               0x04000000,
+               0x08000000,
+               0x10000000,
+               0x20000000,
+               0x40000000,
+               0x80000000 */
+       };
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+
+       s.in.handle = handle;
+       s.in.command = 0;
+       s.in.info_ctr = &info_ctr;
+       s.in.devmode_ctr = &devmode_ctr;
+       s.in.secdesc_ctr = &secdesc_ctr;
+
+       q.in.handle = handle;
+       q.out.info = &info;
+       q0 = q;
+
+#define TESTGETCALL(call, r) \
+               r.in.buffer = NULL; \
+               r.in.offered = 0;\
+               r.out.needed = &needed; \
+               status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+               if (!NT_STATUS_IS_OK(status)) { \
+                       torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+                              r.in.level, nt_errstr(status), __location__); \
+                       ret = false; \
+                       break; \
+               }\
+               if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
+                       DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); \
+                       data_blob_clear(&blob); \
+                       r.in.buffer = &blob; \
+                       r.in.offered = needed; \
+               }\
+               status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+               if (!NT_STATUS_IS_OK(status)) { \
+                       torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+                              r.in.level, nt_errstr(status), __location__); \
+                       ret = false; \
+                       break; \
+               } \
+               if (!W_ERROR_IS_OK(r.out.result)) { \
+                       torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+                              r.in.level, win_errstr(r.out.result), __location__); \
+                       ret = false; \
+                       break; \
+               }
+
+
+#define TESTSETCALL_EXP(call, r, err) \
+               clear_info2(&info_ctr);\
+               status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+               if (!NT_STATUS_IS_OK(status)) { \
+                       torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+                              r.in.info_ctr->level, nt_errstr(status), __location__); \
+                       ret = false; \
+                       break; \
+               } \
+               if (!W_ERROR_IS_OK(err)) { \
+                       if (!W_ERROR_EQUAL(err, r.out.result)) { \
+                               torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
+                                      r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
+                               ret = false; \
+                       } \
+                       break; \
+               } \
+               if (!W_ERROR_IS_OK(r.out.result)) { \
+                       torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+                              r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
+                       ret = false; \
+                       break; \
+               }
+
+#define TESTSETCALL(call, r) \
+       TESTSETCALL_EXP(call, r, WERR_OK)
+
+#define STRING_EQUAL(s1, s2, field) \
+               if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
+                       torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+                              #field, s2, __location__); \
+                       ret = false; \
+                       break; \
+               }
+
+#define MEM_EQUAL(s1, s2, length, field) \
+               if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+                       torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+                              #field, (const char *)s2, __location__); \
+                       ret = false; \
+                       break; \
+               }
+
+#define INT_EQUAL(i1, i2, field) \
+               if (i1 != i2) { \
+                       torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
+                              #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
+                       ret = false; \
+                       break; \
+               }
+
+#define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
+               torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+               q.in.level = lvl1; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.level = lvl1; \
+               info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+               info_ctr.info.info ## lvl1->field1 = value;\
+               TESTSETCALL_EXP(SetPrinter, s, err) \
+               info_ctr.info.info ## lvl1->field1 = ""; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.info.info ## lvl1->field1 = value; \
+               STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
+               q.in.level = lvl2; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+               STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
+       } while (0)
+
+#define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
+       TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
+       } while (0);
+
+#define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
+               torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+               q.in.level = lvl1; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.level = lvl1; \
+               info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+               info_ctr.info.info ## lvl1->field1 = value; \
+               TESTSETCALL(SetPrinter, s) \
+               info_ctr.info.info ## lvl1->field1 = 0; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+               INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
+               q.in.level = lvl2; \
+               TESTGETCALL(GetPrinter, q) \
+               info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+               INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
+       } while (0)
+
+#define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
+        TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
+        } while (0)
+
+       q0.in.level = 0;
+       do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+       TEST_PRINTERINFO_STRING(2, comment,  1, comment, "xx2-1 comment");
+       TEST_PRINTERINFO_STRING(2, comment,  2, comment, "xx2-2 comment");
+
+       /* level 0 printername does not stick */
+/*     TEST_PRINTERINFO_STRING(2, printername,  0, printername, "xx2-0 printer"); */
+       TEST_PRINTERINFO_STRING(2, printername,  1, name,        "xx2-1 printer");
+       TEST_PRINTERINFO_STRING(2, printername,  2, printername, "xx2-2 printer");
+       TEST_PRINTERINFO_STRING(2, printername,  4, printername, "xx2-4 printer");
+       TEST_PRINTERINFO_STRING(2, printername,  5, printername, "xx2-5 printer");
+/*     TEST_PRINTERINFO_STRING(4, printername,  0, printername, "xx4-0 printer"); */
+       TEST_PRINTERINFO_STRING(4, printername,  1, name,        "xx4-1 printer");
+       TEST_PRINTERINFO_STRING(4, printername,  2, printername, "xx4-2 printer");
+       TEST_PRINTERINFO_STRING(4, printername,  4, printername, "xx4-4 printer");
+       TEST_PRINTERINFO_STRING(4, printername,  5, printername, "xx4-5 printer");
+/*     TEST_PRINTERINFO_STRING(5, printername,  0, printername, "xx5-0 printer"); */
+       TEST_PRINTERINFO_STRING(5, printername,  1, name,        "xx5-1 printer");
+       TEST_PRINTERINFO_STRING(5, printername,  2, printername, "xx5-2 printer");
+       TEST_PRINTERINFO_STRING(5, printername,  4, printername, "xx5-4 printer");
+       TEST_PRINTERINFO_STRING(5, printername,  5, printername, "xx5-5 printer");
+
+       /* servername can be set but does not stick
+       TEST_PRINTERINFO_STRING(2, servername,  0, servername, "xx2-0 servername");
+       TEST_PRINTERINFO_STRING(2, servername,  2, servername, "xx2-2 servername");
+       TEST_PRINTERINFO_STRING(2, servername,  4, servername, "xx2-4 servername");
+       */
+
+       /* passing an invalid port will result in WERR_UNKNOWN_PORT */
+       TEST_PRINTERINFO_STRING_EXP_ERR(2, portname,  2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT);
+       TEST_PRINTERINFO_STRING_EXP_ERR(2, portname,  5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT);
+       TEST_PRINTERINFO_STRING_EXP_ERR(5, portname,  2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT);
+       TEST_PRINTERINFO_STRING_EXP_ERR(5, portname,  5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT);
+
+       TEST_PRINTERINFO_STRING(2, sharename,   2, sharename,   "xx2-2 sharename");
+       /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
+       TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername,  2, drivername,  "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER);
+       TEST_PRINTERINFO_STRING(2, location,    2, location,    "xx2-2 location");
+       /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
+       TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile,     2, sepfile,     "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE);
+       /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
+       TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR);
+       TEST_PRINTERINFO_STRING(2, datatype,    2, datatype,    "xx2-2 datatype");
+       TEST_PRINTERINFO_STRING(2, parameters,  2, parameters,  "xx2-2 parameters");
+
+       for (i=0; i < ARRAY_SIZE(attribute_list); i++) {
+/*             TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       ); */
+               TEST_PRINTERINFO_INT_EXP(2, attributes, 2, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(2, attributes, 4, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(2, attributes, 5, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+/*             TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       ); */
+               TEST_PRINTERINFO_INT_EXP(4, attributes, 2, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(4, attributes, 4, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(4, attributes, 5, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+/*             TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       ); */
+               TEST_PRINTERINFO_INT_EXP(5, attributes, 2, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(5, attributes, 4, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+               TEST_PRINTERINFO_INT_EXP(5, attributes, 5, attributes,
+                       attribute_list[i],
+                       (attribute_list[i] | default_attribute)
+                       );
+       }
+
+       for (i=0; i < ARRAY_SIZE(status_list); i++) {
+               /* level 2 sets do not stick
+               TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
+               TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
+               TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
+               TEST_PRINTERINFO_INT(6, status, 0, status, status_list[i]);
+               TEST_PRINTERINFO_INT(6, status, 2, status, status_list[i]);
+               TEST_PRINTERINFO_INT(6, status, 6, status, status_list[i]);
+       }
+
+       /* priorities need to be between 0 and 99
+          passing an invalid priority will result in WERR_INVALID_PRIORITY */
+       TEST_PRINTERINFO_INT(2, priority,       2, priority, 0);
+       TEST_PRINTERINFO_INT(2, priority,       2, priority, 1);
+       TEST_PRINTERINFO_INT(2, priority,       2, priority, 99);
+       /* TEST_PRINTERINFO_INT(2, priority,    2, priority, 100); */
+       TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 0);
+       TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 1);
+       TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 99);
+       /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
+
+       TEST_PRINTERINFO_INT(2, starttime,      2, starttime, __LINE__);
+       TEST_PRINTERINFO_INT(2, untiltime,      2, untiltime, __LINE__);
+
+       /* does not stick
+       TEST_PRINTERINFO_INT(2, cjobs,          2, cjobs, __LINE__);
+       TEST_PRINTERINFO_INT(2, averageppm,     2, averageppm, __LINE__); */
+
+       /* does not stick
+       TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
+       TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
+
+       /* FIXME: gd also test devmode and secdesc behavior */
+
+       {
+               /* verify composition of level 1 description field */
+               const char *description;
+               const char *tmp;
+
+               q0.in.level = 1;
+               do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+               description = talloc_strdup(tctx, q0.out.info->info1.description);
+
+               q0.in.level = 2;
+               do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+               tmp = talloc_asprintf(tctx, "%s,%s,%s",
+                       q0.out.info->info2.printername,
+                       q0.out.info->info2.drivername,
+                       q0.out.info->info2.location);
+
+               do { STRING_EQUAL(description, tmp, "description")} while (0);
+       }
+
+       return ret;
+}
+
 
 static bool test_ClosePrinter(struct torture_context *tctx,
                              struct dcerpc_pipe *p,
@@ -1972,12 +2537,45 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
        return ret;
 }
 
-#if 0
-static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
+static bool test_GetPrinterDriver(struct torture_context *tctx,
+                                 struct dcerpc_pipe *p,
+                                 struct policy_handle *handle,
+                                 const char *driver_name)
+{
+       struct spoolss_GetPrinterDriver r;
+       uint32_t needed;
+
+       r.in.handle = handle;
+       r.in.architecture = "W32X86";
+       r.in.level = 1;
+       r.in.buffer = NULL;
+       r.in.offered = 0;
+       r.out.needed = &needed;
+
+       torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+               "failed to call GetPrinterDriver");
+       if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+               DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+               data_blob_clear(&blob);
+               r.in.buffer = &blob;
+               r.in.offered = needed;
+               torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+                       "failed to call GetPrinterDriver");
+       }
+
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to call GetPrinterDriver");
+
+       return true;
+}
+
+static bool test_GetPrinterDriver2(struct torture_context *tctx,
+                                  struct dcerpc_pipe *p,
                                   struct policy_handle *handle,
                                   const char *driver_name)
 {
-       NTSTATUS status;
        struct spoolss_GetPrinterDriver2 r;
        uint32_t needed;
        uint32_t server_major_version;
@@ -1994,34 +2592,24 @@ static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
        r.out.server_major_version = &server_major_version;
        r.out.server_minor_version = &server_minor_version;
 
-       printf("Testing GetPrinterDriver2\n");
-
-       status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
-               return false;
-       }
+       torture_comment(tctx, "Testing GetPrinterDriver2 level %d\n", r.in.level);
 
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+               "failed to call GetPrinterDriver2");
        if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+               DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+               data_blob_clear(&blob);
+               r.in.buffer = &blob;
                r.in.offered = needed;
-               status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("GetPrinterDriver2 failed - %s\n",
-                      nt_errstr(status));
-               return false;
+               torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+                       "failed to call GetPrinterDriver2");
        }
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("GetPrinterDriver2 failed - %s\n",
-                      win_errstr(r.out.result));
-               return false;
-       }
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to call GetPrinterDriver2");
 
        return true;
 }
-#endif
 
 static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
                                        struct dcerpc_pipe *p)
@@ -2073,6 +2661,432 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
        return true;
 }
 
+static bool test_DeletePrinter(struct torture_context *tctx,
+                              struct dcerpc_pipe *p,
+                              struct policy_handle *handle)
+{
+       struct spoolss_DeletePrinter r;
+
+       torture_comment(tctx, "Testing DeletePrinter\n");
+
+       r.in.handle = handle;
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter(p, tctx, &r),
+               "failed to delete printer");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to delete printer");
+
+       return true;
+}
+
+static bool test_EnumPrinters_findname(struct torture_context *tctx,
+                                      struct dcerpc_pipe *p,
+                                      uint32_t flags,
+                                      uint32_t level,
+                                      const char *name,
+                                      bool *found)
+{
+       struct spoolss_EnumPrinters e;
+       uint32_t count;
+       union spoolss_PrinterInfo *info;
+       uint32_t needed;
+       int i;
+
+       *found = false;
+
+       e.in.flags = flags;
+       e.in.server = NULL;
+       e.in.level = level;
+       e.in.buffer = NULL;
+       e.in.offered = 0;
+       e.out.count = &count;
+       e.out.info = &info;
+       e.out.needed = &needed;
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+               "failed to enum printers");
+
+       if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
+               DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+               data_blob_clear(&blob);
+               e.in.buffer = &blob;
+               e.in.offered = needed;
+
+               torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+                       "failed to enum printers");
+       }
+
+       torture_assert_werr_ok(tctx, e.out.result,
+               "failed to enum printers");
+
+       for (i=0; i < count; i++) {
+
+               const char *current = NULL;
+
+               switch (level) {
+               case 1:
+                       current = info[i].info1.name;
+                       break;
+               }
+
+               if (strequal(current, name)) {
+                       *found = true;
+                       break;
+               }
+       }
+
+       return true;
+}
+
+static bool test_AddPrinter_wellknown(struct torture_context *tctx,
+                                     struct dcerpc_pipe *p,
+                                     const char *printername,
+                                     bool ex)
+{
+       WERROR result;
+       struct spoolss_AddPrinter r;
+       struct spoolss_AddPrinterEx rex;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_SetPrinterInfo1 info1;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct spoolss_UserLevelCtr userlevel_ctr;
+       struct policy_handle handle;
+       bool found = false;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+       ZERO_STRUCT(userlevel_ctr);
+       ZERO_STRUCT(info1);
+
+       torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":"");
+
+       /* try to add printer to wellknown printer list (level 1) */
+
+       userlevel_ctr.level = 1;
+
+       info_ctr.info.info1 = &info1;
+       info_ctr.level = 1;
+
+       rex.in.server = NULL;
+       rex.in.info_ctr = &info_ctr;
+       rex.in.devmode_ctr = &devmode_ctr;
+       rex.in.secdesc_ctr = &secdesc_ctr;
+       rex.in.userlevel_ctr = &userlevel_ctr;
+       rex.out.handle = &handle;
+
+       r.in.server = NULL;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.out.handle = &handle;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+               "unexpected result code");
+
+       info1.name = printername;
+       info1.flags = PRINTER_ATTRIBUTE_SHARED;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+          better do a real check to see the printer is really there */
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_NETWORK, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+
+       torture_assert(tctx, found, "failed to find newly added printer");
+
+       info1.flags = 0;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+          better do a real check to see the printer has really been removed
+          from the well known printer list */
+
+       found = false;
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_NETWORK, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+#if 0
+       torture_assert(tctx, !found, "printer still in well known printer list");
+#endif
+       return true;
+}
+
+static bool test_AddPrinter_normal(struct torture_context *tctx,
+                                  struct dcerpc_pipe *p,
+                                  struct policy_handle *handle_p,
+                                  const char *printername,
+                                  const char *drivername,
+                                  const char *portname,
+                                  bool ex)
+{
+       WERROR result;
+       struct spoolss_AddPrinter r;
+       struct spoolss_AddPrinterEx rex;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_SetPrinterInfo2 info2;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct spoolss_UserLevelCtr userlevel_ctr;
+       struct policy_handle handle;
+       bool found = false;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+       ZERO_STRUCT(userlevel_ctr);
+
+       torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":"");
+
+       userlevel_ctr.level = 1;
+
+       rex.in.server = NULL;
+       rex.in.info_ctr = &info_ctr;
+       rex.in.devmode_ctr = &devmode_ctr;
+       rex.in.secdesc_ctr = &secdesc_ctr;
+       rex.in.userlevel_ctr = &userlevel_ctr;
+       rex.out.handle = &handle;
+
+       r.in.server = NULL;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.out.handle = &handle;
+
+ again:
+
+       /* try to add printer to printer list (level 2) */
+
+       ZERO_STRUCT(info2);
+
+       info_ctr.info.info2 = &info2;
+       info_ctr.level = 2;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+               "unexpected result code");
+
+       info2.printername = printername;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+
+       if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
+               struct policy_handle printer_handle;
+
+               torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, &printer_handle),
+                       "failed to open printer handle");
+
+               torture_assert(tctx, test_DeletePrinter(tctx, p, &printer_handle),
+                       "failed to delete printer");
+
+               torture_assert(tctx, test_ClosePrinter(tctx, p, &printer_handle),
+                       "failed to close server handle");
+
+               goto again;
+       }
+
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
+               "unexpected result code");
+
+       info2.portname = portname;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
+               "unexpected result code");
+
+       info2.drivername = drivername;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
+               "unexpected result code");
+
+       info2.printprocessor = "winprint";
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_ok(tctx, result,
+               "failed to add printer");
+
+       *handle_p = handle;
+
+       /* we are paranoid, really check if the printer is there now */
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_LOCAL, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+       torture_assert(tctx, found, "failed to find newly added printer");
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       return true;
+}
+
+static bool test_AddPrinterEx(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle_p,
+                             const char *printername,
+                             const char *drivername,
+                             const char *portname)
+{
+       bool ret = true;
+
+       if (!torture_setting_bool(tctx, "samba3", false)) {
+               if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER_EX, true)) {
+                       torture_comment(tctx, "failed to add printer to well known list\n");
+                       ret = false;
+               }
+       }
+
+       if (!test_AddPrinter_normal(tctx, p, handle_p,
+                                   printername, drivername, portname,
+                                   true)) {
+               torture_comment(tctx, "failed to add printer to printer list\n");
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_AddPrinter(struct torture_context *tctx,
+                           struct dcerpc_pipe *p,
+                           struct policy_handle *handle_p,
+                           const char *printername,
+                           const char *drivername,
+                           const char *portname)
+{
+       bool ret = true;
+
+       if (!torture_setting_bool(tctx, "samba3", false)) {
+               if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER, false)) {
+                       torture_comment(tctx, "failed to add printer to well known list\n");
+                       ret = false;
+               }
+       }
+
+       if (!test_AddPrinter_normal(tctx, p, handle_p,
+                                   printername, drivername, portname,
+                                   false)) {
+               torture_comment(tctx, "failed to add printer to printer list\n");
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_printer_info(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle)
+{
+       bool ret = true;
+
+       if (!test_PrinterInfo(tctx, p, handle)) {
+               ret = false;
+       }
+
+       if (!test_SetPrinter_errors(tctx, p, handle)) {
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_printer(struct torture_context *tctx,
+                        struct dcerpc_pipe *p)
+{
+       bool ret = true;
+       struct policy_handle handle[2];
+       bool found = false;
+       const char *drivername = "Microsoft XPS Document Writer";
+       const char *portname = "LPT1:";
+
+       /* test printer created via AddPrinter */
+
+       if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, portname)) {
+               return false;
+       }
+
+       if (!test_printer_info(tctx, p, &handle[0])) {
+               ret = false;
+       }
+
+       if (!test_DeletePrinter(tctx, p, &handle[0])) {
+               ret = false;
+       }
+
+       if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+                                       TORTURE_PRINTER, &found)) {
+               ret = false;
+       }
+
+       torture_assert(tctx, !found, "deleted printer still there");
+
+       /* test printer created via AddPrinterEx */
+
+       if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, portname)) {
+               return false;
+       }
+
+       if (!test_printer_info(tctx, p, &handle[1])) {
+               ret = false;
+       }
+
+       if (!test_DeletePrinter(tctx, p, &handle[1])) {
+               ret = false;
+       }
+
+       if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+                                       TORTURE_PRINTER_EX, &found)) {
+               ret = false;
+       }
+
+       torture_assert(tctx, !found, "deleted printer still there");
+
+       return ret;
+}
+
 bool torture_rpc_spoolss(struct torture_context *torture)
 {
        NTSTATUS status;
@@ -2087,7 +3101,7 @@ bool torture_rpc_spoolss(struct torture_context *torture)
 
        ctx = talloc_zero(torture, struct test_spoolss_context);
 
-       ret &= test_OpenPrinter_server(torture, p, ctx);
+       ret &= test_OpenPrinter_server(torture, p, &ctx->server_handle);
 
        ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled");
        ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled");
@@ -2129,3 +3143,15 @@ bool torture_rpc_spoolss(struct torture_context *torture)
 
        return ret;
 }
+
+struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-PRINTER");
+
+       struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
+                                                       "printer", &ndr_table_spoolss);
+
+       torture_rpc_tcase_add_test(tcase, "printer", test_printer);
+
+       return suite;
+}
index bc4fc15e07b671579479c4afebe8888436ca1871..b321b41bdd9228467a4569226eb66e4f3fb9b170 100644 (file)
@@ -22,6 +22,7 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix $(torturesrcdir)/smb2/, \
                smb2.o \
                durable_open.o \
                oplocks.o \
+               dir.o \
                lease.o \
                create.o \
                read.o \
index bd1abce82788b7311f242103234bbf175bf2fba7..fd32b52111b3f6c44f3343989a55fa4225a78cbd 100644 (file)
@@ -200,6 +200,8 @@ bool torture_smb2_connect(struct torture_context *torture)
                return false;
        }
 
+       smb2_util_unlink(tree, "test9.dat");
+
        h1 = torture_smb2_createfile(tree, "test9.dat");
        h2 = torture_smb2_createfile(tree, "test9.dat");
        status = torture_smb2_write(torture, tree, h1);
index 58cf2229bc70008a71490d9ac77a3d918031b51d..4b44a50bbdf7ab875eb8859281bd6ac4f748a71f 100644 (file)
@@ -1,20 +1,22 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    SMB2 dir list test suite
 
    Copyright (C) Andrew Tridgell 2005
-   
+   Copyright (C) Zachary Loafman 2009
+   Copyright (C) Aravind Srinivasan 2009
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "includes.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/libcli.h"
 
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
+#include "torture/util.h"
+
+#include "system/filesys.h"
+
+#define CHECK_STATUS(status, correct) do { \
+       if (!NT_STATUS_EQUAL(status, correct)) { \
+               torture_result(tctx, TORTURE_FAIL, __location__": \
+                      Incorrect status %s - should be %s", \
+                      nt_errstr(status), nt_errstr(correct)); \
+               ret = false; \
+               goto done; \
+       }} while (0)
+
+#define CHECK_VALUE(v, correct) torture_assert_int_equal(tctx, (v), \
+                               (correct), "incorrect value");
+
+#define DNAME  "smb2_dir"
+#define NFILES 100
+
+struct file_elem {
+       char *name;
+       bool found;
+};
+
+static NTSTATUS populate_tree(struct torture_context *tctx,
+                             TALLOC_CTX *mem_ctx,
+                             struct smb2_tree *tree,
+                             struct file_elem *files,
+                             int nfiles,
+                             struct smb2_handle *h_out)
+{
+       struct smb2_create create;
+       NTSTATUS status;
+       bool ret;
+       int i;
+
+       smb2_deltree(tree, DNAME);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+       create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+       create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+                                NTCREATEX_SHARE_ACCESS_WRITE |
+                                NTCREATEX_SHARE_ACCESS_DELETE;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+       create.in.fname = DNAME;
+
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       *h_out = create.out.file.handle;
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       for (i = 0; i < nfiles; i++) {
+               files[i].name = generate_random_str(tctx, 8);
+               create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+                   DNAME, files[i].name);
+               status = smb2_create(tree, mem_ctx, &create);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               smb2_util_close(tree, create.out.file.handle);
+       }
+ done:
+       return status;
+}
 
 /*
   test find continue
 */
-static bool torture_smb2_find_dir(struct smb2_tree *tree)
+
+static bool test_find(struct torture_context *tctx,
+                     struct smb2_tree *tree)
 {
-       struct smb2_handle handle;
-       NTSTATUS status;
-       int i;
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       struct smb2_handle h;
        struct smb2_find f;
-       bool ret = true;
        union smb_search_data *d;
+       struct file_elem files[NFILES] = {};
+       NTSTATUS status;
+       bool ret = true;
        uint_t count;
+       int i, j, file_count = 0;
 
-       status = smb2_util_roothandle(tree, &handle);
-       if (!NT_STATUS_IS_OK(status)) {
-               return false;
+       status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = h;
+       f.in.pattern            = "*";
+       f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
+       f.in.max_response_size  = 0x100;
+       f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+
+               for (i = 0; i < count; i++) {
+                       bool expected;
+                       const char *found = d[i].both_directory_info.name.s;
+
+                       if (!strcmp(found, ".") || !strcmp(found, ".."))
+                               continue;
+
+                       expected = false;
+                       for (j = 0; j < NFILES; j++) {
+                               if (!strcmp(files[j].name, found)) {
+                                       files[j].found = true;
+                                       expected = true;
+                                       break;
+                               }
+                       }
+
+                       if (expected)
+                               continue;
+
+                       torture_result(tctx, TORTURE_FAIL,
+                           "(%s): didn't expect %s\n",
+                           __location__, found);
+                       ret = false;
+                       goto done;
+               }
+
+               file_count = file_count + i;
+               f.in.continue_flags = 0;
+               f.in.max_response_size  = 4096;
+       } while (count != 0);
+
+       CHECK_VALUE(file_count, NFILES + 2);
+
+       for (i = 0; i < NFILES; i++) {
+               if (files[j].found)
+                       continue;
+
+               torture_result(tctx, TORTURE_FAIL,
+                   "(%s): expected to find %s, but didn't\n",
+                   __location__, files[j].name);
+               ret = false;
+               goto done;
        }
 
+ done:
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+/*
+  test fixed enumeration
+*/
+
+static bool test_fixed(struct torture_context *tctx,
+                      struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       struct smb2_create create;
+       struct smb2_handle h, h2;
+       struct smb2_find f;
+       union smb_search_data *d;
+       struct file_elem files[NFILES] = {};
+       NTSTATUS status;
+       bool ret = true;
+       uint_t count;
+       int i;
+
+       status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+       create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+       create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+                                NTCREATEX_SHARE_ACCESS_WRITE |
+                                NTCREATEX_SHARE_ACCESS_DELETE;
+       create.in.create_disposition = NTCREATEX_DISP_OPEN;
+       create.in.fname = DNAME;
+
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       h2 = create.out.file.handle;
+
        ZERO_STRUCT(f);
-       f.in.file.handle        = handle;
+       f.in.file.handle        = h;
        f.in.pattern            = "*";
        f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
        f.in.max_response_size  = 0x100;
        f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;
 
+       /* Start enumeration on h, then delete all from h2 */
+       status = smb2_find_level(tree, tree, &f, &count, &d);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       f.in.file.handle        = h2;
+
        do {
                status = smb2_find_level(tree, tree, &f, &count, &d);
-               if (!NT_STATUS_IS_OK(status)) {
-                       printf("SMB2_FIND_ID_BOTH_DIRECTORY_INFO failed - %s\n", nt_errstr(status));
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
                        break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+
+               for (i = 0; i < count; i++) {
+                       const char *found = d[i].both_directory_info.name.s;
+                       char *path = talloc_asprintf(mem_ctx, "%s\\%s",
+                           DNAME, found);
+
+                       if (!strcmp(found, ".") || !strcmp(found, ".."))
+                               continue;
+
+                       status = smb2_util_unlink(tree, path);
+                       CHECK_STATUS(status, NT_STATUS_OK);
+
+                       talloc_free(path);
                }
 
-               printf("Got %d files\n", count);
-               for (i=0;i<count;i++) {
-                       printf("\t'%s'\n", 
-                              d[i].both_directory_info.name.s);
+               f.in.continue_flags = 0;
+               f.in.max_response_size  = 4096;
+       } while (count != 0);
+
+       /* Now finish h enumeration. */
+       f.in.file.handle = h;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+
+               for (i = 0; i < count; i++) {
+                       const char *found = d[i].both_directory_info.name.s;
+
+                       if (!strcmp(found, ".") || !strcmp(found, ".."))
+                               continue;
+
+                       torture_result(tctx, TORTURE_FAIL,
+                           "(%s): didn't expect %s\n",
+                           __location__, found);
+                       ret = false;
+                       goto done;
                }
+
                f.in.continue_flags = 0;
                f.in.max_response_size  = 4096;
        } while (count != 0);
 
+ done:
+       smb2_util_close(tree, h);
+       smb2_util_close(tree, h2);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
 
        return ret;
 }
 
+static struct {
+       const char *name;
+       uint8_t level;
+       enum smb_search_data_level data_level;
+       int name_offset;
+       int resume_key_offset;
+       uint32_t capability_mask;
+       NTSTATUS status;
+       union smb_search_data data;
+} levels[] = {
+       {"SMB2_FIND_DIRECTORY_INFO",
+        SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
+        offsetof(union smb_search_data, directory_info.name.s),
+        offsetof(union smb_search_data, directory_info.file_index),
+       },
+       {"SMB2_FIND_FULL_DIRECTORY_INFO",
+        SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
+        offsetof(union smb_search_data, full_directory_info.name.s),
+        offsetof(union smb_search_data, full_directory_info.file_index),
+       },
+       {"SMB2_FIND_NAME_INFO",
+        SMB2_FIND_NAME_INFO, RAW_SEARCH_DATA_NAME_INFO,
+        offsetof(union smb_search_data, name_info.name.s),
+        offsetof(union smb_search_data, name_info.file_index),
+       },
+       {"SMB2_FIND_BOTH_DIRECTORY_INFO",
+        SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+        offsetof(union smb_search_data, both_directory_info.name.s),
+        offsetof(union smb_search_data, both_directory_info.file_index),
+       },
+       {"SMB2_FIND_ID_FULL_DIRECTORY_INFO",
+        SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
+        offsetof(union smb_search_data, id_full_directory_info.name.s),
+        offsetof(union smb_search_data, id_full_directory_info.file_index),
+       },
+       {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO",
+        SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
+        offsetof(union smb_search_data, id_both_directory_info.name.s),
+        offsetof(union smb_search_data, id_both_directory_info.file_index),
+       }
+};
+
+/*
+  extract the name from a smb_data structure and level
+*/
+static const char *extract_name(union smb_search_data *data,
+                               uint8_t level,
+                               enum smb_search_data_level data_level)
+{
+       int i;
+       for (i=0;i<ARRAY_SIZE(levels);i++) {
+               if (level == levels[i].level &&
+                   data_level == levels[i].data_level) {
+                       return *(const char **)(levels[i].name_offset + (char *)data);
+               }
+       }
+       return NULL;
+}
+
+/* find a level in the table by name */
+static union smb_search_data *find(const char *name)
+{
+       int i;
+       for (i=0;i<ARRAY_SIZE(levels);i++) {
+               if (NT_STATUS_IS_OK(levels[i].status) &&
+                   strcmp(levels[i].name, name) == 0) {
+                       return &levels[i].data;
+               }
+       }
+       return NULL;
+}
+
+static bool fill_level_data(TALLOC_CTX *mem_ctx,
+                           union smb_search_data *data,
+                           union smb_search_data *d,
+                           uint_t count,
+                           uint8_t level,
+                           enum smb_search_data_level data_level)
+{
+       int i;
+       const char *sname = NULL;
+       for (i=0; i < count ; i++) {
+               sname = extract_name(&d[i], level, data_level);
+               if (sname == NULL)
+                       return false;
+               if (!strcmp(sname, ".") || !strcmp(sname, ".."))
+                       continue;
+               *data = d[i];
+       }
+       return true;
+}
+
+
+NTSTATUS torture_single_file_search(struct smb2_tree *tree,
+                                   TALLOC_CTX *mem_ctx,
+                                   const char *pattern,
+                                   uint8_t level,
+                                   enum smb_search_data_level data_level,
+                                   int index,
+                                   union smb_search_data *d,
+                                   uint_t *count,
+                                   struct smb2_handle *h)
+{
+       struct smb2_find f;
+       NTSTATUS status;
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = *h;
+       f.in.pattern            = pattern;
+       f.in.continue_flags     = SMB2_CONTINUE_FLAG_RESTART;
+       f.in.max_response_size  = 0x100;
+       f.in.level              = level;
+
+       status = smb2_find_level(tree, tree, &f, count, &d);
+       if (NT_STATUS_IS_OK(status))
+               fill_level_data(mem_ctx, &levels[index].data, d, *count, level,
+                               data_level);
+       return status;
+}
+
+/*
+   basic testing of all File Information Classes using a single file
+*/
+static bool test_one_file(struct torture_context *tctx,
+                         struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       bool ret = true;
+       const char *fname =  "torture_search.txt";
+       NTSTATUS status;
+       int i;
+       uint_t count;
+       union smb_fileinfo all_info2, alt_info, internal_info;
+       union smb_search_data *s;
+       union smb_search_data d;
+       struct smb2_handle h, h2;
+
+       status = torture_smb2_testdir(tree, DNAME, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       status = smb2_create_complex_file(tree, DNAME "\\torture_search.txt",
+                                         &h2);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /* call all the File Information Classes */
+       for (i=0;i<ARRAY_SIZE(levels);i++) {
+               torture_comment(tctx, "testing %s %d\n", levels[i].name,
+                               levels[i].level);
+
+               levels[i].status = torture_single_file_search(tree, mem_ctx,
+                                  fname, levels[i].level, levels[i].data_level,
+                                  i, &d, &count, &h);
+               CHECK_STATUS(levels[i].status, NT_STATUS_OK);
+       }
+
+       /* get the all_info file into to check against */
+       all_info2.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+       all_info2.generic.in.file.handle = h2;
+       status = smb2_getinfo_file(tree, tctx, &all_info2);
+       torture_assert_ntstatus_ok(tctx, status,
+                                  "RAW_FILEINFO_ALL_INFO failed");
+
+       alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
+       alt_info.generic.in.file.handle = h2;
+       status = smb2_getinfo_file(tree, tctx, &alt_info);
+       torture_assert_ntstatus_ok(tctx, status,
+                                  "RAW_FILEINFO_ALT_NAME_INFO failed");
+
+       internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
+       internal_info.generic.in.file.handle = h2;
+       status = smb2_getinfo_file(tree, tctx, &internal_info);
+       torture_assert_ntstatus_ok(tctx, status,
+                                  "RAW_FILEINFO_INTERNAL_INFORMATION failed");
+
+#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
+       s = find(name); \
+       if (s) { \
+               if ((s->sname1.field1) != (v.sname2.out.field2)) { \
+                       printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \
+                               __location__, \
+                               #sname1, #field1, (int)s->sname1.field1, \
+                               #sname2, #field2, (int)v.sname2.out.field2); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
+       s = find(name); \
+       if (s) { \
+               if (s->sname1.field1 != \
+                   (~1 & nt_time_to_unix(v.sname2.out.field2))) { \
+                       printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+                               __location__, \
+                               #sname1, #field1, \
+                               timestring(tctx, s->sname1.field1), \
+                               #sname2, #field2, \
+                               nt_time_string(tctx, v.sname2.out.field2)); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
+       s = find(name); \
+       if (s) { \
+               if (s->sname1.field1 != v.sname2.out.field2) { \
+                       printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+                               __location__, \
+                               #sname1, #field1, \
+                               nt_time_string(tctx, s->sname1.field1), \
+                               #sname2, #field2, \
+                               nt_time_string(tctx, v.sname2.out.field2)); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
+       s = find(name); \
+       if (s) { \
+               if (!s->sname1.field1 || \
+                   strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \
+                       printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+                               __location__, \
+                               #sname1, #field1, s->sname1.field1, \
+                               #sname2, #field2, v.sname2.out.field2.s); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
+       s = find(name); \
+       if (s) { \
+               if (!s->sname1.field1.s || \
+                   strcmp(s->sname1.field1.s, v.sname2.out.field2.s)) { \
+                       printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+                               __location__, \
+                               #sname1, #field1, s->sname1.field1.s, \
+                               #sname2, #field2, v.sname2.out.field2.s); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_NAME(name, sname1, field1, fname, flags) do { \
+       s = find(name); \
+       if (s) { \
+               if (!s->sname1.field1.s || \
+                   strcmp(s->sname1.field1.s, fname)) { \
+                       printf("(%s) %s/%s [%s] != %s\n", \
+                               __location__, \
+                               #sname1, #field1, s->sname1.field1.s, \
+                               fname); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
+       s = find(name); \
+       if (s) { \
+               if (!s->sname1.field1 || \
+                   strcmp(s->sname1.field1, fname)) { \
+                       printf("(%s) %s/%s [%s] != %s\n", \
+                               __location__, \
+                               #sname1, #field1, s->sname1.field1, \
+                               fname); \
+                       ret = false; \
+               } \
+       }} while (0)
+
+       /* check that all the results are as expected */
+       CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         attrib, all_info2, all_info2, attrib);
+       CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    attrib, all_info2, all_info2, attrib);
+       CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    attrib, all_info2, all_info2, attrib);
+       CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, attrib, all_info2, all_info2, attrib);
+       CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, attrib, all_info2, all_info2, attrib);
+
+       CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         write_time, all_info2, all_info2, write_time);
+       CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    write_time, all_info2, all_info2, write_time);
+       CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    write_time, all_info2, all_info2, write_time);
+       CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time);
+       CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time);
+
+       CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         create_time, all_info2, all_info2, create_time);
+       CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    create_time, all_info2, all_info2, create_time);
+       CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    create_time, all_info2, all_info2, create_time);
+       CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time);
+       CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time);
+       CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         access_time, all_info2, all_info2, access_time);
+       CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    access_time, all_info2, all_info2, access_time);
+       CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    access_time, all_info2, all_info2, access_time);
+       CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time);
+       CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time);
+
+       CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         change_time, all_info2, all_info2, change_time);
+       CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    change_time, all_info2, all_info2, change_time);
+       CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    change_time, all_info2, all_info2, change_time);
+       CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time);
+       CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time);
+
+       CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         size, all_info2, all_info2, size);
+       CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    size, all_info2, all_info2, size);
+       CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    size, all_info2, all_info2, size);
+       CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, size, all_info2, all_info2, size);
+       CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, size, all_info2, all_info2, size);
+
+       CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         alloc_size, all_info2, all_info2, alloc_size);
+       CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
+       CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
+       CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+       CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+
+       CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    ea_size, all_info2, all_info2, ea_size);
+       CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    ea_size, all_info2, all_info2, ea_size);
+       CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, ea_size, all_info2, all_info2, ea_size);
+       CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, ea_size, all_info2, all_info2, ea_size);
+
+       CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    short_name, alt_info, alt_name_info, fname, STR_UNICODE);
+
+       CHECK_NAME("SMB2_FIND_DIRECTORY_INFO",           directory_info,         name, fname, STR_TERMINATE_ASCII);
+       CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO",      full_directory_info,    name, fname, STR_TERMINATE_ASCII);
+       CHECK_NAME("SMB2_FIND_NAME_INFO",                name_info,              name, fname, STR_TERMINATE_ASCII);
+       CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    name, fname, STR_TERMINATE_ASCII);
+       CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO",   id_full_directory_info, name, fname, STR_TERMINATE_ASCII);
+       CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",   id_both_directory_info, name, fname, STR_TERMINATE_ASCII);
+       CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, file_id, internal_info, internal_information, file_id);
+
+       CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, file_id, internal_info, internal_information, file_id);
+
+done:
+       smb2_util_close(tree, h);
+       smb2_util_unlink(tree, fname);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+
+struct multiple_result {
+       TALLOC_CTX *tctx;
+       int count;
+       union smb_search_data *list;
+};
+
+bool fill_result(void *private_data,
+                union smb_search_data *file,
+                int count,
+                uint8_t level,
+                enum smb_search_data_level data_level)
+{
+       int i;
+       const char *sname;
+       struct multiple_result *data = (struct multiple_result *)private_data;
+
+       for (i=0; i<count; i++) {
+               sname = extract_name(&file[i], level, data_level);
+               if (!strcmp(sname, ".") || !(strcmp(sname, "..")))
+                       continue;
+               data->count++;
+               data->list = talloc_realloc(data->tctx,
+                                           data->list,
+                                           union smb_search_data,
+                                           data->count);
+               data->list[data->count-1] = file[i];
+       }
+       return true;
+}
+
+enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART};
+
+static NTSTATUS multiple_smb2_search(struct smb2_tree *tree,
+                                    TALLOC_CTX *tctx,
+                                    const char *pattern,
+                                    uint8_t level,
+                                    enum smb_search_data_level data_level,
+                                    enum continue_type cont_type,
+                                    void *data,
+                                    struct smb2_handle *h)
+{
+       struct smb2_find f;
+       bool ret = true;
+       uint_t count = 0;
+       union smb_search_data *d;
+       NTSTATUS status;
+       struct multiple_result *result = (struct multiple_result *)data;
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = *h;
+       f.in.pattern            = pattern;
+       f.in.max_response_size  = 0x1000;
+       f.in.level              = level;
+
+       /* The search should start from the beginning everytime */
+       f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+               if (!fill_result(result, d, count, level, data_level)) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+
+               /*
+                * After the first iteration is complete set the CONTINUE
+                * FLAGS appropriately
+                */
+               switch (cont_type) {
+                       case CONT_INDEX:
+                               f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+                               break;
+                       case CONT_SINGLE:
+                               f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+                               break;
+                       case CONT_RESTART:
+                       default:
+                               /* we should prevent staying in the loop forever */
+                               f.in.continue_flags = 0;
+                               break;
+               }
+       } while (count != 0);
+done:
+       return status;
+}
+
+
+static enum smb_search_data_level compare_data_level;
+uint8_t level_sort;
 
-/* 
-   basic testing of directory listing with continue
+static int search_compare(union smb_search_data *d1,
+                         union smb_search_data *d2)
+{
+       const char *s1, *s2;
+
+       s1 = extract_name(d1, level_sort, compare_data_level);
+       s2 = extract_name(d2, level_sort, compare_data_level);
+       return strcmp_safe(s1, s2);
+}
+
+/*
+   basic testing of search calls using many files
 */
-bool torture_smb2_dir(struct torture_context *torture)
+static bool test_many_files(struct torture_context *tctx,
+                           struct smb2_tree *tree)
 {
-       TALLOC_CTX *mem_ctx = talloc_new(NULL);
-       struct smb2_tree *tree;
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       const int num_files = 700;
+       int i, t;
+       char *fname;
        bool ret = true;
+       NTSTATUS status;
+       struct multiple_result result;
+       struct smb2_create create;
+       struct smb2_handle h;
+       struct {
+               const char *name;
+               const char *cont_name;
+               uint8_t level;
+               enum smb_search_data_level data_level;
+               enum continue_type cont_type;
+       } search_types[] = {
+               {"SMB2_FIND_BOTH_DIRECTORY_INFO",    "SINGLE",  SMB2_FIND_BOTH_DIRECTORY_INFO,    RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,    CONT_SINGLE},
+               {"SMB2_FIND_BOTH_DIRECTORY_INFO",    "INDEX",   SMB2_FIND_BOTH_DIRECTORY_INFO,    RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,    CONT_INDEX},
+               {"SMB2_FIND_BOTH_DIRECTORY_INFO",    "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO,    RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,    CONT_RESTART},
+               {"SMB2_FIND_DIRECTORY_INFO",         "SINGLE",  SMB2_FIND_DIRECTORY_INFO,         RAW_SEARCH_DATA_DIRECTORY_INFO,         CONT_SINGLE},
+               {"SMB2_FIND_DIRECTORY_INFO",         "INDEX",   SMB2_FIND_DIRECTORY_INFO,         RAW_SEARCH_DATA_DIRECTORY_INFO,         CONT_INDEX},
+               {"SMB2_FIND_DIRECTORY_INFO",         "RESTART", SMB2_FIND_DIRECTORY_INFO,         RAW_SEARCH_DATA_DIRECTORY_INFO,         CONT_RESTART},
+               {"SMB2_FIND_FULL_DIRECTORY_INFO",    "SINGLE",  SMB2_FIND_FULL_DIRECTORY_INFO,    RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_SINGLE},
+               {"SMB2_FIND_FULL_DIRECTORY_INFO",    "INDEX",   SMB2_FIND_FULL_DIRECTORY_INFO,    RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_INDEX},
+               {"SMB2_FIND_FULL_DIRECTORY_INFO",    "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO,    RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_RESTART},
+               {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE",  SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE},
+               {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX",   SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX},
+               {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART},
+               {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE",  SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE},
+               {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX",   SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX},
+               {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART}
+       };
 
-       if (!torture_smb2_connection(torture, &tree)) {
+       smb2_deltree(tree, DNAME);
+       status = torture_smb2_testdir(tree, DNAME, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       torture_comment(tctx, "Testing with %d files\n", num_files);
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       for (i=num_files-1;i>=0;i--) {
+               fname = talloc_asprintf(mem_ctx, DNAME "\\t%03d-%d.txt", i, i);
+               create.in.fname = talloc_asprintf(mem_ctx, "%s", fname);
+               status = smb2_create(tree, mem_ctx, &create);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               smb2_util_close(tree, create.out.file.handle);
+               talloc_free(fname);
+       }
+
+       for (t=0;t<ARRAY_SIZE(search_types);t++) {
+               ZERO_STRUCT(result);
+               result.tctx = talloc_new(tctx);
+
+               torture_comment(tctx,
+                               "Continue %s via %s\n", search_types[t].name,
+                               search_types[t].cont_name);
+               status = multiple_smb2_search(tree, tctx, "*",
+                                             search_types[t].level,
+                                             search_types[t].data_level,
+                                             search_types[t].cont_type,
+                                             &result, &h);
+
+               CHECK_VALUE(result.count, num_files);
+
+               compare_data_level = search_types[t].data_level;
+               level_sort = search_types[t].level;
+
+               qsort(result.list, result.count, sizeof(result.list[0]),
+                     QSORT_CAST  search_compare);
+
+               for (i=0;i<result.count;i++) {
+                       const char *s;
+                       enum smb_search_level level;
+                       level = RAW_SEARCH_SMB2;
+                       s = extract_name(&result.list[i],
+                                        search_types[t].level,
+                                        compare_data_level);
+                       fname = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+                       torture_assert_str_equal(tctx, fname, s,
+                                                "Incorrect name");
+                       talloc_free(fname);
+               }
+               talloc_free(result.tctx);
+       }
+
+done:
+       smb2_util_close(tree, h);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+/*
+  check a individual file result
+*/
+static bool check_result(struct multiple_result *result,
+                        const char *name,
+                        bool exist,
+                        uint32_t attrib)
+{
+       int i;
+       for (i=0;i<result->count;i++) {
+               if (strcmp(name,
+                          result->list[i].both_directory_info.name.s) == 0) {
+                       break;
+               }
+       }
+       if (i == result->count) {
+               if (exist) {
+                       printf("failed: '%s' should exist with attribute %s\n",
+                              name, attrib_string(result->list, attrib));
+                       return false;
+               }
+               return true;
+       }
+
+       if (!exist) {
+               printf("failed: '%s' should NOT exist (has attribute %s)\n",
+                      name, attrib_string(result->list,
+                      result->list[i].both_directory_info.attrib));
                return false;
        }
 
-       ret &= torture_smb2_find_dir(tree);
+       if ((result->list[i].both_directory_info.attrib&0xFFF) != attrib) {
+               printf("failed: '%s' should have attribute 0x%x (has 0x%x)\n",
+                      name,
+                      attrib, result->list[i].both_directory_info.attrib);
+               return false;
+       }
+       return true;
+}
+
+/*
+   test what happens when the directory is modified during a search
+*/
+static bool test_modify_search(struct torture_context *tctx,
+                              struct smb2_tree *tree)
+{
+       int num_files = 700;
+       struct multiple_result result;
+       union smb_setfileinfo sfinfo;
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       struct smb2_create create;
+       struct smb2_handle h;
+       struct smb2_find f;
+       union smb_search_data *d;
+       struct file_elem files[700] = {};
+       NTSTATUS status;
+       bool ret = true;
+       int i;
+       uint_t count;
+
+       smb2_deltree(tree, DNAME);
+
+       status = torture_smb2_testdir(tree, DNAME, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       printf("Creating %d files\n", num_files);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       for (i = num_files-1; i >= 0; i--) {
+               files[i].name = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+               create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+                                                 DNAME, files[i].name);
+               status = smb2_create(tree, mem_ctx, &create);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               smb2_util_close(tree, create.out.file.handle);
+       }
+
+       printf("pulling the first two files\n");
+       ZERO_STRUCT(result);
+       result.tctx = talloc_new(tctx);
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = h;
+       f.in.pattern            = "*";
+       f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
+       f.in.max_response_size  = 0x100;
+       f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+               if (!fill_result(&result, d, count, f.in.level,
+                                RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+                       ret = false;
+                       goto done;
+               }
+       }while(result.count < 2);
+
+       printf("Changing attributes and deleting\n");
 
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       files[num_files].name = talloc_asprintf(mem_ctx, "T003-03.txt.2");
+       create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+                                         files[num_files].name);
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smb2_util_close(tree, create.out.file.handle);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       files[num_files + 1].name = talloc_asprintf(mem_ctx, "T013-13.txt.2");
+       create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+                                         files[num_files + 1].name);
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       smb2_util_close(tree, create.out.file.handle);
+
+       files[num_files + 2].name = talloc_asprintf(mem_ctx, "T013-13.txt.3");
+       status = smb2_create_complex_file(tree, DNAME "\\T013-13.txt.3", &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       smb2_util_unlink(tree, DNAME "\\T014-14.txt");
+       smb2_util_setatr(tree, DNAME "\\T015-15.txt", FILE_ATTRIBUTE_HIDDEN);
+       smb2_util_setatr(tree, DNAME "\\T016-16.txt", FILE_ATTRIBUTE_NORMAL);
+       smb2_util_setatr(tree, DNAME "\\T017-17.txt", FILE_ATTRIBUTE_SYSTEM);
+       smb2_util_setatr(tree, DNAME "\\T018-18.txt", 0);
+       smb2_util_setatr(tree, DNAME "\\T039-39.txt", FILE_ATTRIBUTE_HIDDEN);
+       smb2_util_setatr(tree, DNAME "\\T000-0.txt", FILE_ATTRIBUTE_HIDDEN);
+       sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
+       sfinfo.generic.in.file.path = DNAME "\\T013-13.txt.3";
+       sfinfo.disposition_info.in.delete_on_close = 1;
+       status = smb2_composite_setpathinfo(tree, &sfinfo);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /* Reset the numfiles to include the new files and start the
+        * search from the beginning */
+       num_files = num_files + 2;
+       f.in.pattern = "*";
+       f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+       result.count = 0;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+               if (!fill_result(&result, d, count, f.in.level,
+                                RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+                       ret = false;
+                       goto done;
+               }
+               f.in.continue_flags = 0;
+               f.in.max_response_size  = 4096;
+       } while (count != 0);
+
+
+       ret &= check_result(&result, "t039-39.txt", true, FILE_ATTRIBUTE_HIDDEN);
+       ret &= check_result(&result, "t000-0.txt", true, FILE_ATTRIBUTE_HIDDEN);
+       ret &= check_result(&result, "t014-14.txt", false, 0);
+       ret &= check_result(&result, "t015-15.txt", true, FILE_ATTRIBUTE_HIDDEN);
+       ret &= check_result(&result, "t016-16.txt", true, FILE_ATTRIBUTE_NORMAL);
+       ret &= check_result(&result, "t017-17.txt", true, FILE_ATTRIBUTE_SYSTEM);
+       ret &= check_result(&result, "t018-18.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+       ret &= check_result(&result, "t019-19.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+       ret &= check_result(&result, "T013-13.txt.2", true, FILE_ATTRIBUTE_ARCHIVE);
+       ret &= check_result(&result, "T003-3.txt.2", false, 0);
+       ret &= check_result(&result, "T013-13.txt.3", true, FILE_ATTRIBUTE_NORMAL);
+
+       if (!ret) {
+               for (i=0;i<result.count;i++) {
+                       printf("%s %s (0x%x)\n",
+                              result.list[i].both_directory_info.name.s,
+                              attrib_string(tctx,
+                              result.list[i].both_directory_info.attrib),
+                              result.list[i].both_directory_info.attrib);
+               }
+       }
+ done:
+       smb2_util_close(tree, h);
+       smb2_deltree(tree, DNAME);
        talloc_free(mem_ctx);
 
        return ret;
 }
+
+/*
+   testing if directories always come back sorted
+*/
+static bool test_sorted(struct torture_context *tctx,
+                       struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       const int num_files = 700;
+       int i;
+       struct file_elem files[700] = {};
+       bool ret = true;
+       NTSTATUS status;
+       struct multiple_result result;
+       struct smb2_handle h;
+
+       printf("Testing if directories always come back sorted\n");
+       status = populate_tree(tctx, mem_ctx, tree, files, num_files, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       ZERO_STRUCT(result);
+       result.tctx = tctx;
+
+       status = multiple_smb2_search(tree, tctx, "*",
+                                     SMB2_FIND_BOTH_DIRECTORY_INFO,
+                                     RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+                                     SMB2_CONTINUE_FLAG_SINGLE,
+                                     &result, &h);
+
+       CHECK_VALUE(result.count, num_files);
+
+       for (i=0;i<num_files-1;i++) {
+               const char *name1, *name2;
+               name1 = result.list[i].both_directory_info.name.s;
+               name2 = result.list[i+1].both_directory_info.name.s;
+               if (strcasecmp_m(name1, name2) > 0) {
+                       printf("non-alphabetical order at entry %d  '%s' '%s'"
+                              "\n", i, name1, name2);
+                       torture_comment(tctx,
+                       "Server does not produce sorted directory listings"
+                       "(not an error)\n");
+                       goto done;
+               }
+       }
+       talloc_free(result.list);
+done:
+       smb2_util_close(tree, h);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+/* test the behavior of file_index field in the SMB2_FIND struct */
+
+static bool test_file_index(struct torture_context *tctx,
+                           struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       const int num_files = 100;
+       int resume_index = 4;
+       int i;
+       char *fname;
+       bool ret = true;
+       NTSTATUS status;
+       struct multiple_result result;
+       struct smb2_create create;
+       struct smb2_find f;
+       struct smb2_handle h;
+       union smb_search_data *d;
+       int count;
+
+       smb2_deltree(tree, DNAME);
+
+       status = torture_smb2_testdir(tree, DNAME, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       printf("Testing the behavior of file_index flag\n");
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+       for (i = num_files-1; i >= 0; i--) {
+               fname = talloc_asprintf(mem_ctx, DNAME "\\file%u.txt", i);
+               create.in.fname = fname;
+               status = smb2_create(tree, mem_ctx, &create);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               talloc_free(fname);
+               smb2_util_close(tree, create.out.file.handle);
+       }
+
+       ZERO_STRUCT(result);
+       result.tctx = tctx;
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = h;
+       f.in.pattern            = "*";
+       f.in.continue_flags     = SMB2_CONTINUE_FLAG_SINGLE;
+       f.in.max_response_size  = 0x1000;
+       f.in.level              = SMB2_FIND_FULL_DIRECTORY_INFO;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+               if (!fill_result(&result, d, count, f.in.level,
+                                RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+                       ret = false;
+                       goto done;
+               }
+       } while(result.count < 10);
+
+       if (result.list[0].full_directory_info.file_index == 0) {
+               torture_comment(tctx,
+                               "Talking to a server that doesn't provide a "
+                               "file index.\nWindows servers using NTFS do "
+                               "not provide a file_index. Skipping test\n");
+               goto done;
+       } else {
+               /* We are not talking to a Windows based server.  Windows
+                * servers using NTFS do not provide a file_index.  Windows
+                * server using FAT do provide a file index, however in both
+                * cases they do not honor a file index on a resume request.
+                * See MS-FSCC <62> and MS-SMB2 <54> for more information. */
+
+               /* Set the file_index flag to point to the fifth file from the
+                * previous enumeration and try to start the subsequent
+                * searches from that point */
+               f.in.file_index =
+                   result.list[resume_index].full_directory_info.file_index;
+               f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+
+               /* get the name of the next expected file */
+               fname = talloc_asprintf(mem_ctx, DNAME "\\%s",
+                       result.list[resume_index].full_directory_info.name.s);
+
+               ZERO_STRUCT(result);
+               result.tctx = tctx;
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       goto done;
+               CHECK_STATUS(status, NT_STATUS_OK);
+               if (!fill_result(&result, d, count, f.in.level,
+                                RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+                       ret = false;
+                       goto done;
+               }
+               if (strcmp(fname,
+                       result.list[0].full_directory_info.name.s)) {
+                       printf("next expected file: %s but the server "
+                              "returned %s\n", fname,
+                              result.list[0].full_directory_info.name.s);
+                       torture_comment(tctx,
+                                       "Not an error. Resuming using a file "
+                                       "index is an optional feature of the "
+                                       "protocol.\n");
+                       goto done;
+               }
+       }
+done:
+       smb2_util_close(tree, h);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+/*
+ * Tests directory enumeration in a directory containing >1000 files with
+ * names of varying lengths.
+ */
+static bool test_large_files(struct torture_context *tctx,
+                            struct smb2_tree *tree)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       const int num_files = 2000;
+       int i, j = 1, retry_count = 0;
+       struct file_elem files[2000] = {};
+       bool ret = true;
+       NTSTATUS status;
+       struct smb2_create create;
+       struct smb2_find f;
+       struct smb2_handle h;
+       union smb_search_data *d;
+       int count, file_count = 0;
+
+       torture_comment(tctx,
+       "Testing directory enumeration in a directory with >1000 files\n");
+
+       smb2_deltree(tree, DNAME);
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+       create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+       create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+       create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+                                NTCREATEX_SHARE_ACCESS_WRITE |
+                                NTCREATEX_SHARE_ACCESS_DELETE;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+       create.in.fname = DNAME;
+
+       status = smb2_create(tree, mem_ctx, &create);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       h = create.out.file.handle;
+
+       ZERO_STRUCT(create);
+       create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+       create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+       create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+       for (i = 0; i < num_files; i++) {
+               files[i].name = generate_random_str(tctx, j);
+               create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+                   DNAME, files[i].name);
+               status = smb2_create(tree, mem_ctx, &create);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               smb2_util_close(tree, create.out.file.handle);
+               retry_count = 0;
+               if (i%9 == 0)
+                       j = j + 1;
+       }
+
+       ZERO_STRUCT(f);
+       f.in.file.handle        = h;
+       f.in.pattern            = "*";
+       f.in.max_response_size  = 0x100;
+       f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+       do {
+               status = smb2_find_level(tree, tree, &f, &count, &d);
+               if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+                       break;
+               CHECK_STATUS(status, NT_STATUS_OK);
+
+               for (i = 0; i < count; i++) {
+                       bool expected;
+                       const char *found = d[i].both_directory_info.name.s;
+
+                       if (!strcmp(found, ".") || !strcmp(found, ".."))
+                               continue;
+
+                       expected = false;
+                       for (j = 0; j < 2000; j++) {
+                               if (!strcmp(files[j].name, found)) {
+                                       files[j].found = true;
+                                       expected = true;
+                                       break;
+                               }
+                       }
+
+                       if (expected)
+                               continue;
+
+                       torture_result(tctx, TORTURE_FAIL,
+                           "(%s): didn't expect %s\n",
+                           __location__, found);
+                       ret = false;
+                       goto done;
+               }
+               file_count = file_count + i;
+               f.in.continue_flags = 0;
+               f.in.max_response_size  = 4096;
+       } while (count != 0);
+
+       CHECK_VALUE(file_count, num_files + 2);
+
+       for (i = 0; i < num_files; i++) {
+               if (files[j].found)
+                       continue;
+
+               torture_result(tctx, TORTURE_FAIL,
+                   "(%s): expected to find %s, but didn't\n",
+                   __location__, files[j].name);
+               ret = false;
+               goto done;
+       }
+done:
+       smb2_util_close(tree, h);
+       smb2_deltree(tree, DNAME);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+struct torture_suite *torture_smb2_dir_init(void)
+{
+       struct torture_suite *suite =
+           torture_suite_create(talloc_autofree_context(), "DIR");
+
+       torture_suite_add_1smb2_test(suite, "FIND", test_find);
+       torture_suite_add_1smb2_test(suite, "FIXED", test_fixed);
+       torture_suite_add_1smb2_test(suite, "ONE", test_one_file);
+       torture_suite_add_1smb2_test(suite, "MANY", test_many_files);
+       torture_suite_add_1smb2_test(suite, "MODIFY", test_modify_search);
+       torture_suite_add_1smb2_test(suite, "SORTED", test_sorted);
+       torture_suite_add_1smb2_test(suite, "FILE-INDEX", test_file_index);
+       torture_suite_add_1smb2_test(suite, "LARGE-FILES", test_large_files);
+       suite->description = talloc_strdup(suite, "SMB2-DIR tests");
+
+       return suite;
+}
index c4ab31f4cff56f51b45f2ece8b64aae304ab1c4d..166c3f694f06254c3788422375b83f1a53c5f989 100644 (file)
@@ -49,9 +49,9 @@ static struct {
  { LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
  { LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
  { LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
-/*
+
  { LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
-*/
+
  { LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
  { LEVEL(RAW_FILEINFO_SEC_DESC) }
 };
index a5730a7eb39a28182544c7c0377d4850a7f36b1e..9766620867c090ff8a5976d0d6b948f70a47e638 100644 (file)
@@ -141,6 +141,7 @@ NTSTATUS torture_smb2_init(void)
        torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
        torture_suite_add_suite(suite, torture_smb2_durable_open_init());
        torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1);
+       torture_suite_add_suite(suite, torture_smb2_dir_init());
        torture_suite_add_suite(suite, torture_smb2_lease_init());
        torture_suite_add_suite(suite, torture_smb2_compound_init());
 
index f67f13348887fc31e0b4d8f6ad224f1ab6b25791..755d45786b5ffac3b5b020f2fb047689e939cb75 100644 (file)
@@ -33,7 +33,7 @@ struct cmd_list_users_state {
 
        struct wbsrv_domain *domain;
        char *domain_name;
-       uint resume_index;
+       uint32_t resume_index;
        char *result;
 };