summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in22
-rw-r--r--source3/auth/auth.c10
-rw-r--r--source3/auth/auth_sam.c5
-rw-r--r--source3/client/client.c4
-rw-r--r--source3/include/ads.h127
-rw-r--r--source3/include/passdb.h22
-rw-r--r--source3/include/proto.h185
-rw-r--r--source3/include/smb.h16
-rw-r--r--source3/include/smb_macros.h1
-rw-r--r--source3/include/util_tdb.h2
-rw-r--r--source3/lib/account_pol.c148
-rw-r--r--source3/lib/ads_flags.c150
-rw-r--r--source3/lib/charcnv.c8
-rw-r--r--source3/lib/ctdbd_conn.c2
-rw-r--r--source3/lib/dbwrap_tdb.c2
-rw-r--r--source3/lib/dbwrap_util.c173
-rw-r--r--source3/lib/errmap_unix.c1
-rw-r--r--source3/lib/events.c2
-rw-r--r--source3/lib/gencache.c529
-rw-r--r--source3/lib/ldap_escape.c25
-rw-r--r--source3/lib/netapi/netapi.c1
-rw-r--r--source3/lib/netapi/user.c2
-rw-r--r--source3/lib/smbldap_util.c12
-rw-r--r--source3/lib/system.c4
-rw-r--r--source3/lib/tldap.c6
-rw-r--r--source3/lib/util_sock.c3
-rw-r--r--source3/lib/util_str.c36
-rw-r--r--source3/lib/util_tdb.c19
-rw-r--r--source3/libads/dns.c8
-rw-r--r--source3/libads/ldap_user.c6
-rw-r--r--source3/libnet/libnet_samsync_passdb.c23
-rw-r--r--source3/libsmb/clidgram.c3
-rw-r--r--source3/libsmb/clifile.c543
-rw-r--r--source3/libsmb/clikrb5.c4
-rw-r--r--source3/libsmb/clispnego.c18
-rw-r--r--source3/libsmb/dsgetdcname.c33
-rw-r--r--source3/libsmb/libsmb_context.c1
-rw-r--r--source3/libsmb/libsmb_thread_posix.c2
-rw-r--r--source3/libsmb/namecache.c34
-rw-r--r--source3/libsmb/namequery.c12
-rw-r--r--source3/libsmb/spnego.c23
-rw-r--r--source3/libsmb/trustdom_cache.c67
-rw-r--r--source3/locking/brlock.c4
-rw-r--r--source3/locking/locking.c29
-rw-r--r--source3/locking/posix.c37
-rw-r--r--source3/modules/nfs4_acls.c34
-rw-r--r--source3/modules/onefs_acl.c51
-rw-r--r--source3/modules/onefs_open.c18
-rw-r--r--source3/modules/onefs_streams.c10
-rw-r--r--source3/modules/vfs_acl_tdb.c98
-rw-r--r--source3/modules/vfs_acl_xattr.c263
-rw-r--r--source3/modules/vfs_afsacl.c35
-rw-r--r--source3/modules/vfs_aixacl2.c16
-rw-r--r--source3/modules/vfs_audit.c4
-rw-r--r--source3/modules/vfs_cacheprime.c2
-rw-r--r--source3/modules/vfs_cap.c10
-rw-r--r--source3/modules/vfs_catia.c3
-rw-r--r--source3/modules/vfs_default.c67
-rw-r--r--source3/modules/vfs_dirsort.c3
-rw-r--r--source3/modules/vfs_extd_audit.c8
-rw-r--r--source3/modules/vfs_full_audit.c97
-rw-r--r--source3/modules/vfs_gpfs.c38
-rw-r--r--source3/modules/vfs_hpuxacl.c20
-rw-r--r--source3/modules/vfs_hpuxacl.h2
-rw-r--r--source3/modules/vfs_shadow_copy2.c7
-rw-r--r--source3/modules/vfs_smb_traffic_analyzer.c18
-rw-r--r--source3/modules/vfs_streams_xattr.c25
-rw-r--r--source3/modules/vfs_tsmsm.c6
-rw-r--r--source3/modules/vfs_zfsacl.c11
-rw-r--r--source3/nmbd/nmbd.c2
-rw-r--r--source3/param/loadparm.c3
-rw-r--r--source3/passdb/passdb.c16
-rw-r--r--source3/passdb/pdb_ads.c24
-rw-r--r--source3/passdb/pdb_get_set.c6
-rw-r--r--source3/passdb/pdb_interface.c16
-rw-r--r--source3/passdb/pdb_ldap.c119
-rw-r--r--source3/passdb/pdb_wbc_sam.c11
-rw-r--r--source3/printing/printfsp.c10
-rw-r--r--source3/registry/reg_backend_db.c904
-rw-r--r--source3/registry/reg_backend_netlogon_params.c2
-rw-r--r--source3/registry/reg_objects.c29
-rw-r--r--source3/rpc_parse/parse_prs.c318
-rw-r--r--source3/rpc_server/srv_lsa_nt.c287
-rw-r--r--source3/rpc_server/srv_samr_nt.c104
-rw-r--r--source3/rpc_server/srv_samr_util.c2
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c10
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c12
-rw-r--r--source3/rpcclient/cmd_lsarpc.c366
-rw-r--r--source3/rpcclient/cmd_spoolss.c43
-rwxr-xr-xsource3/script/tests/test_smbtorture_s3.sh4
-rw-r--r--source3/smbd/aio.c28
-rw-r--r--source3/smbd/blocking.c15
-rw-r--r--source3/smbd/chgpasswd.c6
-rw-r--r--source3/smbd/close.c160
-rw-r--r--source3/smbd/dosmode.c6
-rw-r--r--source3/smbd/error.c30
-rw-r--r--source3/smbd/fake_file.c29
-rw-r--r--source3/smbd/file_access.c10
-rw-r--r--source3/smbd/fileio.c58
-rw-r--r--source3/smbd/filename.c502
-rw-r--r--source3/smbd/filename_util.c206
-rw-r--r--source3/smbd/files.c89
-rw-r--r--source3/smbd/globals.c5
-rw-r--r--source3/smbd/globals.h50
-rw-r--r--source3/smbd/ipc.c2
-rw-r--r--source3/smbd/msdfs.c20
-rw-r--r--source3/smbd/notify.c7
-rw-r--r--source3/smbd/nttrans.c173
-rw-r--r--source3/smbd/open.c98
-rw-r--r--source3/smbd/oplock.c24
-rw-r--r--source3/smbd/oplock_irix.c13
-rw-r--r--source3/smbd/oplock_linux.c9
-rw-r--r--source3/smbd/oplock_onefs.c41
-rw-r--r--source3/smbd/password.c37
-rw-r--r--source3/smbd/pipes.c42
-rw-r--r--source3/smbd/posix_acls.c271
-rw-r--r--source3/smbd/process.c5
-rw-r--r--source3/smbd/reply.c776
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/sesssetup.c1
-rw-r--r--source3/smbd/smb2_close.c7
-rw-r--r--source3/smbd/smb2_create.c22
-rw-r--r--source3/smbd/smb2_flush.c2
-rw-r--r--source3/smbd/smb2_getinfo.c172
-rw-r--r--source3/smbd/smb2_lock.c180
-rw-r--r--source3/smbd/smb2_notify.c2
-rw-r--r--source3/smbd/smb2_read.c4
-rw-r--r--source3/smbd/smb2_server.c4
-rw-r--r--source3/smbd/smb2_setinfo.c118
-rw-r--r--source3/smbd/smb2_write.c6
-rw-r--r--source3/smbd/statcache.c15
-rw-r--r--source3/smbd/trans2.c1954
-rw-r--r--source3/smbd/vfs.c110
-rw-r--r--source3/torture/cmd_vfs.c13
-rw-r--r--source3/torture/locktest.c4
-rw-r--r--source3/torture/locktest2.c2
-rw-r--r--source3/torture/pdbtest.c6
-rw-r--r--source3/torture/torture.c104
-rw-r--r--source3/utils/net.c45
-rw-r--r--source3/utils/net.h9
-rw-r--r--source3/utils/net_ads.c93
-rw-r--r--source3/utils/net_cache.c27
-rw-r--r--source3/utils/net_dom.c8
-rw-r--r--source3/utils/net_help.c1
-rw-r--r--source3/utils/net_proto.h3
-rw-r--r--source3/utils/net_rpc.c74
-rw-r--r--source3/utils/net_rpc_join.c3
-rw-r--r--source3/utils/net_rpc_samsync.c15
-rw-r--r--source3/utils/net_rpc_shell.c9
-rw-r--r--source3/utils/net_sam.c8
-rw-r--r--source3/utils/net_usershare.c33
-rw-r--r--source3/utils/net_util.c109
-rw-r--r--source3/utils/pdbedit.c2
-rw-r--r--source3/winbindd/winbindd.c2
-rw-r--r--source3/winbindd/winbindd_ads.c8
-rw-r--r--source3/winbindd/winbindd_dual.c4
-rw-r--r--source3/winbindd/winbindd_passdb.c10
-rw-r--r--source3/winbindd/winbindd_sid.c5
-rw-r--r--source3/winbindd/winbindd_util.c3
160 files changed, 6578 insertions, 4835 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 4c927e7346..e6d0cf00dd 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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)
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index fd4c503752..ce8722a1b4 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -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) {
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index a2634feb6c..26b45e47e5 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -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;
diff --git a/source3/client/client.c b/source3/client/client.c
index ed45f4e2ca..6b273b47b0 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -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));
}
diff --git a/source3/include/ads.h b/source3/include/ads.h
index afa4e12175..9761d54086 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -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_ */
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 4e53311eba..2b4f9c2e43 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -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);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f887b4e796..77283d9cf0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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_ */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 9afeb67b00..94ed2186fb 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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;
@@ -834,20 +834,6 @@ struct pipe_open_rec {
#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.
*/
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 7528883c2d..10ee78b394 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -115,7 +115,6 @@
#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 */
diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h
index c79436434f..80b95921d7 100644
--- a/source3/include/util_tdb.h
+++ b/source3/include/util_tdb.h
@@ -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__ */
diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c
index 1e435ca53e..f4101e96bc 100644
--- a/source3/lib/account_pol.c
+++ b/source3/lib/account_pol.c
@@ -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
index a8fa062f2a..0000000000
--- a/source3/lib/ads_flags.c
+++ /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;
-}
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index a1663c1f38..272f107138 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -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;
}
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index dde377581b..449e049ffa 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -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;
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index c71e073b41..297a351764 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -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));
diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c
index 3be3a49e7d..c3ab93c4df 100644
--- a/source3/lib/dbwrap_util.c
+++ b/source3/lib/dbwrap_util.c
@@ -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;
+}
diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c
index 0c39a572ad..00c5475394 100644
--- a/source3/lib/errmap_unix.c
+++ b/source3/lib/errmap_unix.c
@@ -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
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 08debb4252..7a06ad0829 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -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;
};
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 7f133f20b0..ee1f4b70b3 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -26,12 +26,13 @@
#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);
}
diff --git a/source3/lib/ldap_escape.c b/source3/lib/ldap_escape.c
index d101bc5ecd..a731cb9864 100644
--- a/source3/lib/ldap_escape.c
+++ b/source3/lib/ldap_escape.c
@@ -32,10 +32,10 @@
* 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 */
diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c
index 2f8474b37f..e80879a1d2 100644
--- a/source3/lib/netapi/netapi.c
+++ b/source3/lib/netapi/netapi.c
@@ -170,7 +170,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
gfree_charcnv();
gfree_interfaces();
- gencache_shutdown();
secrets_shutdown();
TALLOC_FREE(ctx);
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 39472b20d7..9fa3ddd9a8 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -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;
}
diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c
index 66aef6ba66..478a3d24ca 100644
--- a/source3/lib/smbldap_util.c
+++ b/source3/lib/smbldap_util.c
@@ -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));
diff --git a/source3/lib/system.c b/source3/lib/system.c
index ffc236e93b..6a4f5d5413 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -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;
}
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index 451bc18d2e..fa56763a33 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -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)
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 31261afd72..af64f370ba 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -349,6 +349,9 @@ static const smb_socket_option socket_options[] = {
#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}};
/****************************************************************************
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index cdd7d0a300..c197fd7515 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -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++;
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 78fa7cd0a1..5b3d94dabe 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -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;
+}
diff --git a/source3/libads/dns.c b/source3/libads/dns.c
index 3a9e849668..5cf768de67 100644
--- a/source3/libads/dns.c
+++ b/source3/libads/dns.c
@@ -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 {
diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c
index eecd9045e5..69dc05335e 100644
--- a/source3/libads/ldap_user.c
+++ b/source3/libads/ldap_user.c
@@ -30,18 +30,18 @@
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;
}
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 27c7aac7e7..41a9b3d9f3 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -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;
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 349a8331b4..f5dbd72f22 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -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;
}
-
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index af67fcb746..5ea0579839 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -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);
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index 8a567dc751..152c23bd15 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -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);
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index fb95d71925..e586d976cf 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -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, "
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index fb87b4dc9a..3e0f4977aa 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -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,
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index 98885876b3..8b22ee5023 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -123,7 +123,6 @@ SMBC_module_init(void * punused)
static void
SMBC_module_terminate(void)
{
- gencache_shutdown();
secrets_shutdown();
gfree_all();
SMBC_initialized = false;
diff --git a/source3/libsmb/libsmb_thread_posix.c b/source3/libsmb/libsmb_thread_posix.c
index 411ffbdfbb..6519659c25 100644
--- a/source3/libsmb/libsmb_thread_posix.c
+++ b/source3/libsmb/libsmb_thread_posix.c
@@ -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"
diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
index d3230cffef..dcfc609dcd 100644
--- a/source3/libsmb/namecache.c
+++ b/source3/libsmb/namecache.c
@@ -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)
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 50fb9f1620..05143270b9 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -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 );
diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c
index ee2c3c3d5a..528c7f4009 100644
--- a/source3/libsmb/spnego.c
+++ b/source3/libsmb/spnego.c
@@ -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:
diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c
index 6755de3814..eb52b3588d 100644
--- a/source3/libsmb/trustdom_cache.c
+++ b/source3/libsmb/trustdom_cache.c
@@ -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.
@@ -46,15 +45,9 @@
* @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;
}
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index be2948c531..e238ec959b 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -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. */
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 91fe137fdc..fba871c704 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -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);
diff --git a/source3/locking/posix.c b/source3/locking/posix.c
index 9b51c3aa6a..33ffaf95ca 100644
--- a/source3/locking/posix.c
+++ b/source3/locking/posix.c
@@ -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
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 9b3c8725d5..748f17d457 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -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);
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 5c72d10a6b..2753a9e885 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -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;
}
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index b51d516956..31f27e907a 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -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;
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index ded7dc672d..66eda57a34 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -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;
}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 64ad3e1a78..ce84bd0e3a 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -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;
}
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 66bf21c4f7..b18bc658ff 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -27,13 +27,45 @@
#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;
diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
index 55371c60f5..e6f43c9680 100644
--- a/source3/modules/vfs_afsacl.c
+++ b/source3/modules/vfs_afsacl.c
@@ -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);
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index 5ebc3a12f8..01de33ed0b 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -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;
}
diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c
index cf2e27301d..dab3d78cec 100644
--- a/source3/modules/vfs_audit.c
+++ b/source3/modules/vfs_audit.c
@@ -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) : "");
diff --git a/source3/modules/vfs_cacheprime.c b/source3/modules/vfs_cacheprime.c
index 71b850505a..3997dcbcfc 100644
--- a/source3/modules/vfs_cacheprime.c
+++ b/source3/modules/vfs_cacheprime.c
@@ -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) {
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 7e363b6be7..aa77da7cd7 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -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);
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 1fd101282c..3b691c0350 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -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;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index c4db8fa393..cdfd28c571 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -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;
diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
index 53d1820c11..f6fc9256d0 100644
--- a/source3/modules/vfs_dirsort.c
+++ b/source3/modules/vfs_dirsort.c
@@ -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;
diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c
index 68b85516ea..c9d1862fa4 100644
--- a/source3/modules/vfs_extd_audit.c
+++ b/source3/modules/vfs_extd_audit.c
@@ -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) : ""));
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index e8702aa2c8..76fbc8a8ae 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -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;
}
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 47858cb352..cde80f0021 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -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;
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index 35341a5c3e..32e8539202 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -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)));
}
diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h
index 07b32d628c..9baed5790a 100644
--- a/source3/modules/vfs_hpuxacl.h
+++ b/source3/modules/vfs_hpuxacl.h
@@ -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);
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 1f300a055c..7c338e7268 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -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);
}
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c
index a7fbeadbbe..6f7aee0e50 100644
--- a/source3/modules/vfs_smb_traffic_analyzer.c
+++ b/source3/modules/vfs_smb_traffic_analyzer.c
@@ -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;
}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index eccc2379c9..c32c4f3190 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -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);
}
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index 57807105f6..753b2bcd26 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -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;
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index a5b0490c8d..a92d5dae26 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -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;
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 848baeff3d..961e930728 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -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);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 7e4371bf0b..dbbd6e327d 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -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(),
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 4ed04e4e7a..0678181669 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -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"));
diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c
index eec63728ca..70d550042b 100644
--- a/source3/passdb/pdb_ads.c
+++ b/source3/passdb/pdb_ads.c
@@ -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;
};
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index f55b77f675..30775e49fe 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -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
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 465a6bf595..5d0b625da5 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -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)
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 3579325769..1b1e22f2c8 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -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;
diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c
index ec54d553d1..df80411a7a 100644
--- a/source3/passdb/pdb_wbc_sam.c
+++ b/source3/passdb/pdb_wbc_sam.c
@@ -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;
}
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index a8e175a684..9185fc84b1 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -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)) {
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index e296d319e2..dec43ae741 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -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
@@ -27,8 +28,16 @@
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;
}
diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c
index 682c7fe9a5..6fc87efb1d 100644
--- a/source3/registry/reg_backend_netlogon_params.c
+++ b/source3/registry/reg_backend_netlogon_params.c
@@ -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;
}
diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c
index 5ae1cd8aa7..0c0455aada 100644
--- a/source3/registry/reg_objects.c
+++ b/source3/registry/reg_objects.c
@@ -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;
}
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 0f4829dec3..621ccf4bc9 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -637,42 +637,6 @@ bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
}
/*******************************************************************
- 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.
********************************************************************/
@@ -784,36 +748,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.
********************************************************************/
@@ -952,60 +854,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin
}
/******************************************************************
- 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.
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 324483b3ee..ace045cfa5 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -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) {
@@ -657,6 +702,28 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
}
/***************************************************************************
+ _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);
@@ -1913,6 +2010,51 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
}
/***************************************************************************
+ _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;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 8560ee97c6..b27603f261 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -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;
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 69daa31e9c..1e5988af33 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -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();
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 9d72168202..9dc1a26e3b 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -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;
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 44acf4d647..b9d1ed6d73 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -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;
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index ef3187579a..d7f8041779 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -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 }
};
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index cbff69ff17..48f9df3cac 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -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 }
};
diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh
index c577ed18d4..602433bd91 100755
--- a/source3/script/tests/test_smbtorture_s3.sh
+++ b/source3/script/tests/test_smbtorture_s3.sh
@@ -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"
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index c6f700f17a..ed415c5e13 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -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;
}
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 4c61428692..e752194ca5 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -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,
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 2eb09d176d..64f988f1f7 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -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));
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index a0672f3949..788b0a7cec 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -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;
}
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index ca926aa33c..bd0c7df959 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -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;
}
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index ce22f86414..874efa2a0b 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -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);
-}
diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c
index ef54398bc4..743d88f360 100644
--- a/source3/smbd/fake_file.c
+++ b/source3/smbd/fake_file.c
@@ -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) {
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index d8fee1db06..7d0a552956 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -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;
}
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 0c13b845df..bd609d3e86 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -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);
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 29ebc37d1a..09f9a418bd 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -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
index 0000000000..867709a373
--- /dev/null
+++ b/source3/smbd/filename_util.c
@@ -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;
+}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 0e6dd7e457..a170f774fe 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -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;
}
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 15550ed455..317304a86d 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -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");
+ }
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3d195c84f0..434204b60d 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -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);
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 1067dab074..96a411dd70 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -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));
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index d40b8a8902..2b63eb1743 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -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) {
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index ded888c021..8f37923865 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -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))) {
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b65af26eca..43212dc800 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -272,30 +272,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,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index e01350f2bf..87cab1966b 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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;
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index e9b2a6cf95..dd8d5372fb 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -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;
}
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index 89b8e0f7b5..dd32177988 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -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) );
}
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 273fbfdc01..b4a5495e4b 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -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) );
}
diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c
index d359f9c6f2..a73100abdf 100644
--- a/source3/smbd/oplock_onefs.c
+++ b/source3/smbd/oplock_onefs.c
@@ -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"));
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 928ef0169e..b1a749736d 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -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;
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 7ae7435646..091db09987 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -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;
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 76eee9b56a..0a3b0dff75 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -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;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index b26bc150db..c2065caf79 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -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;
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 1fd4e50ea6..76d32a2f98 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 6951fac171..4b1c803d75 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -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
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 0124b2b047..a043288bc9 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -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);
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 3988105fa4..2d2e5141ee 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -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 =
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index 6724e5cc15..acb5da7751 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -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;
}
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index bdff1939e5..b455f82d80 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -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);
}
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 8ce683923b..1d3ae2eb06 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -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);
}
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index ba725fdec9..5a6e3d7ecb 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -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);
}
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 3ffe053481..121b4eb24d 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -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);
}
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 7ab93ce574..f6d83aeeed 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -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);
}
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index c9f281f73e..42993511ec 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -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);
}
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 43afb1b901..204e57d860 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -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];
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 110ce6c64a..08c4a7f5bf 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -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);
}
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 31460a01a1..f1606be623 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -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);
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index daed9f8225..da52cc05d4 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -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,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 4bf27863bd..856fd9432d 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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,296 +3957,55 @@ 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;
-
- 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;
- }
-
- 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->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(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;
- }
-
- 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_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);
- }
-
- } else {
- /* 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(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;
- }
- 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_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;
- }
- }
-
- 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_unixerror(req, ERRDOS, ERRbadpath);
- 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, fname,
- &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_unixerror(req, ERRDOS, ERRbadpath);
- 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;
- }
- }
+ 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;
- /* 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;
+ return NT_STATUS_INVALID_LEVEL;
}
- 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));
+ status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- p = strrchr_m(smb_fname->base_name,'/');
- if (!p)
- base_name = smb_fname->base_name;
- else
- base_name = p+1;
+ 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));
if (ms_dfs_link) {
mode = dos_mode_msdfs(conn, smb_fname);
@@ -4187,102 +4025,15 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
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;
+ if (*ppdata == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
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);
}
@@ -4301,28 +4052,67 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
mtime = convert_timespec_to_time_t(mtime_ts);
atime = convert_timespec_to_time_t(atime_ts);
+ p = strrchr_m(smb_fname->base_name,'/');
+ if (!p)
+ base_name = smb_fname->base_name;
+ else
+ base_name = p+1;
+
/* 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, "\\");
+ dos_fname = talloc_strdup(mem_ctx, "\\");
if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
} else {
- dos_fname = talloc_asprintf(ctx,
+ dos_fname = talloc_asprintf(mem_ctx,
"\\%s",
fname);
if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
string_replace(dos_fname, '/', '\\');
}
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf);
+
+ 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);
+ }
+ }
+
+ if (!(mode & aDIR)) {
+ file_size = get_file_size_stat(&sbuf);
+ }
+
+ if (fsp) {
+ pos = fsp->fh->position_information;
+ }
+
+ if (fsp) {
+ access_mask = fsp->access_mask;
+ } else {
+ /* GENERIC_EXECUTE mapping from Windows */
+ access_mask = 0x12019F;
+ }
+
+ /* This should be an index number - looks like
+ dev/ino to me :-)
+
+ 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 */
+
switch (info_level) {
case SMB_INFO_STANDARD:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
+ 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);
@@ -4335,7 +4125,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
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"));
+ 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);
@@ -4348,14 +4138,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
case SMB_INFO_IS_NAME_VALID:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
- if (tran_call == TRANSACT2_QFILEINFO) {
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
+ if (fsp) {
/* os/2 needs this ? really ?*/
- reply_doserror(req, ERRDOS, ERRbadfunc);
- return;
+ return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
}
+ /* This is only reached for qpathinfo */
data_size = 0;
- param_size = 0;
break;
case SMB_INFO_QUERY_EAS_FROM_LIST:
@@ -4363,9 +4152,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
size_t total_ea_len = 0;
struct ea_list *ea_file_list = NULL;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
+ 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)) {
@@ -4374,7 +4163,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
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;
}
@@ -4383,16 +4172,45 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
- ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
+ 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 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,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
+
+ /*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;
+ }
+
+ 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 {
- reply_nterror(req, status);
- return;
+ 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:
+ 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);
@@ -6826,7 +7015,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
NULL);
if (lck == NULL) {
DEBUG(0, ("smb_posix_unlink: Could not get share mode "
- "lock for file %s\n", fsp->fsp_name));
+ "lock for file %s\n", fsp_str_dbg(fsp)));
close_file(req, fsp, NORMAL_CLOSE);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -6867,200 +7056,42 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
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)
+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 *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;
- }
- 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_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
- }
-
- /* Set sbuf for use below. */
- sbuf = smb_fname->st;
+ *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)) {
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 2b4124bf7b..cd78c7962e 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -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;
+}
+
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 33ced8fa54..cd550a4f48 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -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;
diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c
index 30b84c073d..a90c2e2dfe 100644
--- a/source3/torture/locktest.c
+++ b/source3/torture/locktest.c
@@ -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 ||
diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c
index 93adcb51a6..5c8a2d8019 100644
--- a/source3/torture/locktest2.c
+++ b/source3/torture/locktest2.c
@@ -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;
diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index ab7edde85d..950177c3ca 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -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) {
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index aa7e83bcc8..f9192b12b7 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -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},
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 0e3946f5a5..f8bfab3e99 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -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);
diff --git a/source3/utils/net.h b/source3/utils/net.h
index f604d96361..d88f962d41 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -28,8 +28,11 @@
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;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index d82715eb45..8f76c0eb09 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -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,
diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c
index 5e7db38515..36cd12fb82 100644
--- a/source3/utils/net_cache.c
+++ b/source3/utils/net_cache.c
@@ -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}
};
diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
index a13f52c519..401079777f 100644
--- a/source3/utils/net_dom.c
+++ b/source3/utils/net_dom.c
@@ -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);
}
diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c
index 5a170790c5..0502373aa2 100644
--- a/source3/utils/net_help.c
+++ b/source3/utils/net_help.c
@@ -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);
}
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index 8a09147aad..75ac032db9 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -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);
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 0118b4818a..f6f90030fe 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -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);
}
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index cae2491aed..ed0311317d 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -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
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index bd5047c1ff..309be171cc 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -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;
diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c
index dc13e91423..3aaed1ed18 100644
--- a/source3/utils/net_rpc_shell.c
+++ b/source3/utils/net_rpc_shell.c
@@ -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);
}
diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c
index 62abef000d..41daa4180d 100644
--- a/source3/utils/net_sam.c
+++ b/source3/utils/net_sam.c
@@ -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;
diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c
index 992a03d813..6eacb1386c 100644
--- a/source3/utils/net_usershare.c
+++ b/source3/utils/net_usershare.c
@@ -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);
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index 50f3c1db01..8bf9aac6f2 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -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)
{
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index a464299438..dce2f05a83 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -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;
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index d617fe1f0b..34eaeb2d79 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -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");
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 0f40419a0e..08afb46674 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -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);
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 92f0d60817..ab07c9767d 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -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;
}
diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c
index b18f0ff595..9a43c6d6a2 100644
--- a/source3/winbindd/winbindd_passdb.c
+++ b/source3/winbindd/winbindd_passdb.c
@@ -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;
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index c091cd7f53..f8cf7db920 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -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;
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 283eee09af..44ae814ae9 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -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;
}